Wîkîferheng kuwiktionary https://ku.wiktionary.org/wiki/Destp%C3%AAk MediaWiki 1.47.0-wmf.11 case-sensitive Medya Taybet Gotûbêj Bikarhêner Gotûbêja bikarhêner Wîkîferheng Gotûbêja Wîkîferhengê Wêne Gotûbêja wêneyî MediaWiki Gotûbêja MediaWiki Şablon Gotûbêja şablonê Alîkarî Gotûbêja alîkariyê Kategorî Gotûbêja kategoriyê Pêvek Gotûbêja pêvekê Nimînok Gotûbêja nimînokê Portal Gotûbêja portalê Tewandin Gotûbêja tewandinê Jinûvesazî Gotûbêja jinûvesaziyê TimedText TimedText talk Modul Gotûbêja modulê Event Event talk serbajar 0 2966 6265736 6243285 2026-07-20T05:45:40Z Wikihez 7344 [[Bikarhêner:Wikihez/templateScript2.js|TS]]: sererastkirin 6265736 wikitext text/x-wiki == {{ziman|ku}} == === Bilêvkirin === * {{ku-IPA}} * {{ku-kîte}} === Navdêr === {{ku-tewîn-nav|serbajar|nêr}} {{navdêr|ku|z=n}} # [[bajar|Bajarê]] piraniya [[rêveberî|rêveberiya]] [[dewlet]]ekê lê ye (bi taybetî [[perleman]], [[hikûmet]], [[serokdewlet]] û hwd) #* {{jêder|ku|jêgirtin=Mala pîran li Marengoyê ye, heyştê kîlomitrî dûrî '''serbajarê''' Cezayirê ye.|''[[w:Biyanî|Biyanî]]'', [[w:Albert Camus|Albert Camus]], Weşanên [[w:Nûdem|Nûdem]]}} ==== Formên alternatîv ==== * {{g|ku|serbajarr}} * {{g|ku|serbajêr}} ==== Hevmane ==== * {{g|ku|paytext}} ==== Jê ==== * {{g|ku|serbajarî}} ==== Etîmolojî ==== Ji {{qertaf|ku|ser|bajar}}. ==== Werger ==== {{werger-ser}} * {{Z|de}}: {{W+|de|Hauptstadt}} {{m}} * {{Z|fa}}: {{W-|fa|پایتخت|tr=pāytext}} * {{Z|fi}}: {{W+|fi|pääkaupunki}} * {{Z|fr}}: {{W+|fr|capitale}} * {{Z|en}}: {{W-|en|capital city}}, {{W+|en|capital}} * {{Z|it}}: {{W+|it|capitale}} * {{Z|ko}}: {{W-|ko|수도|tr=su.do}} * {{Z|pt}}: {{W+|pt|capital}} * {{Z|es}}: {{W+|es|capital}} * {{Z|sv}}: {{W+|sv|huvudstad}} * {{Z|ta}}: {{W-|ta|தலை நகரம்|tr=talai nakaram}} * {{Z|tr}}: {{W+|tr|başkent}}, {{W+|tr|başşehir}}, {{W+|tr|payitaht}} {{werger-bin}} a8lilpt33gqe710opevnj29uc39cgm1 Kurdistan 0 3098 6265557 6261879 2026-07-19T12:45:20Z Ghybu 1393 /* Bilêvkirin */ 6265557 wikitext text/x-wiki {{bnr-h|Kurdistán|Kúrdistan|Kürdistan}} == {{ziman|ku}} == === Bilêvkirin === * {{ku-IPA|k(h)urdistan}} * {{deng|ku|Ku-Kurdistan.oga|ipa=/kʰʉ̞ɾ.dɨ̞s.ˈtäːn/}} * {{deng|ku|LL-Q36163 (kmr)-Ebulfîda-Kurdistan.wav|dever=Bidlîs}} * {{kîte|ku|Kur|dis|tan}} === Serenav === {{ku-tewîn-nav|Kurdistan|mê|y}} [[Wêne:Gegenwärtiges_Kerngebiet_der_kurdischen_Siedlungsgebiete.jpg|thumb|250px|[[nexşe|Nexşeya]] Kurdistanê]] {{wp}} {{serenav|ku|z=m}} # [[welat|Welatê]] [[kurd]]an, [[welat]]ek [[bindest]] e li [[Rojhilata Navîn]] û di [[navber]]a [[sinor]]ên [[Tirkiye]] û [[Sûriye]] û [[Iraq]] û [[Îran]]ê de hatiye [[parçe]]kirin. #* {{jêder|ku|jêgirtin='''Kurdistan'''<br>Bilind e bejn û bala te<br>Li ser taca te esman e|[[w:Cegerxwîn|Cegerxwîn]], 1903 - 1984}} # [[herêm|Herêma]] [[otonom]] ya [[Kurdistana Iraqê]], [[parçe]]yek e ji Kurdistanê ku li [[Başûrê Kurdistanê]] (Iraqê) ji alî kurdan ve tê [[birêvebirin]]. #* {{bêmînak|ku}} # [[parêzgeh|Parêzgehek]] e li [[Rojhilata Kurdistanê]]. #* {{bêmînak|ku}} ==== Bi alfabeyên din ==== * {{ku-ar|کوردستان}} * {{ku-kr| К'ӧрдьстан}} ==== Formên alternatîv ==== * [[Kurdistana Mezin]] * (''Kurdiya başûr'') [[Kursan]] ==== Bernav ==== * [[Dayika Niştiman]] ==== Jê ==== * [[kurdistanî]] * [[kurdistanîtî]] ==== Etîmolojî ==== Ji {{paş|ku|kurd|-istan}}. ==== Bi zaravayên din ==== * {{Z|ckb}}: {{g|ckb|کوردستان}} * {{Z|sdh}}: [[Kursan]] * {{Z|zza}}: {{g|zza|Kurdistan}} ==== Werger ==== {{werger-ser}} * {{Z|sq}}: {{W-|sq|Kurdistan|n}}, {{W-|sq|Kurdistani|n}} * {{Z|de}}: {{W+|de|Kurdistan|nt}} * {{Z|az}}: {{W+|az|Kürdistan}} * {{Z|eu}}: {{W-|eu|Kurdistan}} * {{Z|be}}: {{W-|be|Курдыста́н|n}} * {{Z|bn}}: {{W-|bn|কুর্দিস্তান}} * {{Z|bg}}: {{W+|bg|Кюрдиста́н|n}} * {{Z|my}}: {{W-|my|ကာဒစ်စတန်}} * {{Z|ce}}: {{W-|ce|Кхурдойчоь}} * {{Z|cs}}: {{W+|cs|Kurdistán|n}} * {{Z|zh}}: *: {{Z|cmn}}: {{W+|cmn|庫爾德斯坦}}, {{W-|cmn|庫德斯坦}} * {{Z|da}}: {{W+|da|Kurdistan|nt}} * {{Z|id}}: {{W-|id|Kurdistan}} * {{Z|ar}}: {{W-|ar|كُرْدِسْتَان|m}} * {{Z|hy}}: {{W-|hy|Քրդստան}} * {{Z|et}}: {{W+|et|Kurdistan}} * {{Z|fa}}: {{W+|fa|کردستان|tr=kordestân}} * {{Z|fi}}: {{W+|fi|Kurdistan}} * {{Z|fr}}: {{W+|fr|Kurdistan|n}} * {{Z|gag}}: {{W-|gag|Kürdistan}} * {{Z|ka}}: {{W-|ka|ქურთისტანი}} * {{Z|hi}}: {{W-|hi|कुर्दिस्तान|n}} * {{Z|nl}}: {{W-|nl|Koerdistan|nt}} * {{Z|he}}: {{W-|he|כּוּרְדִּיסְטָן|n|tr=kurdistan}} * {{Z|en}}: {{W+|en|Kurdistan}} * {{Z|ia}}: {{W-|ia|Kurdistan}} * {{Z|ga}}: {{W-|ga|Cordastáin|m|cuda=An Chordastáin}} * {{Z|it}}: {{W+|it|Kurdistan|n}}, {{W-|it|Curdistan|n}} * {{Z|is}}: {{W-|is|Kúrdistan|nt}} * {{Z|ja}}: {{W+|ja|クルディスタン|tr=Kurudisutan}} * {{Z|ca}}: {{W-|ca|Kurdistan}} * {{Z|ky}}: {{W-|ky|Курдистан}} * {{Z|ko}}: {{W-|ko|^쿠르디스탄}} * {{Z|la}}: {{W-|la|Corduēna|m}} * {{Z|lv}}: {{W-|lv|Kurdistāna|m}} * {{Z|lt}}: {{W-|lt|Kurdistanas|n}} * {{Z|mk}}: {{W-|mk|Курдиста́н|n}} * {{Z|ms}}: {{W-|ms|Kurdistan}} * {{Z|mr}}: {{W-|mr|कुर्दिस्तान|n}} * {{Z|hu}}: {{W+|hu|Kurdisztán}} * {{Z|no}}: *: {{Z|nb}}: {{W-|nb|Kurdistan|nt}} *: {{Z|nn}}: {{W-|nn|Kurdistan|nt}} * {{Z|or}}: {{W+|or|ଗୁର୍ଦିସ୍ଥାନ୍}} * {{Z|ug}}: {{W-|ug|كۇردىستان}} * {{Z|uz}}: {{W-|uz|Kurdiston}} * {{Z|ps}}: {{W-|ps|کردستان|n|tr=kurdestān}} * {{Z|pl}}: {{W+|pl|Kurdystan|n}} * {{Z|pt}}: {{W+|pt|Curdistão|n}}, {{W-|pt|Kurdistão|n}} * {{Z|kk}}: {{W-|kk|Күрдістан}} * {{Z|ro}}: {{W-|ro|Kurdistan|n}} * {{Z|ru}}: {{W+|ru|Курдиста́н|n}} * {{Z|sh}}: *: Kirîlî: {{W-|sh|Ку̏рдистан|n}} *: Latînî: {{W+|sh|Kȕrdistan|n}} * {{Z|sk}}: {{W-|sk|Kurdistan|n}} * {{Z|sl}}: {{W-|sl|Kurdistan|n}} * {{Z|es}}: {{W+|es|Kurdistán|n}} * {{Z|sv}}: {{W-|sv|Kurdistan|nt}} * {{Z|tg}}: {{W-|tg|Курдистон}} * {{Z|th}}: {{W-|th|เคอร์ดิสถาน}} * {{Z|tt}}: {{W-|tt|Көрдстан}} * {{Z|tr}}: {{W+|tr|Kürdistan}} * {{Z|tk}}: {{W-|tk|Kürdistan}} * {{Z|ur}}: {{W-|ur|کُرْدِسْتان|n}} * {{Z|uk}}: {{W-|uk|Курдиста́н|n}} * {{Z|yi}}: {{W-|yi|קורדיסטאַן|n}} * {{Z|el}}: {{W-|el|Κουρδιστάν|nt}} *: Kevn: {{W-|grc|Γορδυηνή|m}} {{werger-bin}} :{{werger çavkanî|en|Kurdistan|beş=Ev qismê Wergerê|oldid=78546157}} == {{ziman|zza}} == === Bilêvkirin === * {{zza-IPA}} * {{zza-kîte}} === Serenav === {{serenav|zza|z=m}} # {{g|ku|Kurdistan}} #* {{bêmînak|ku}} ==== Formên alternatîv ==== {{kol3|ku | {{hw|zza|Kurdîstan}} | {{hw|zza|Kurdîstanî}} | {{hw|zza|Kurdîston}} | {{hw|zza|Kurdîstûn}} | {{hw|zza|Kurdıstan||Jacobson}} }} ==== Jê ==== * {{hw|zza|Kurdistanî}} ==== Binêre herwiha ==== * {{hw|zza|Kirdane}} * {{hw|zza|Kirmancîye}} ====Tewandin==== {{zza-tewîn-nav|z=m}} === Serenav 2 === {{serenav|zza|z=m}} # {{awayekî din|zza|cu=Jacobson|Kurdîstan}} == {{ziman|de}} == === Bilêvkirin === * {{deng|de|De-Kurdistan.ogg|Deng}} === Serenav === {{serenav|de|z=nt}} # {{g|ku|Kurdistan}} #* {{bêmînak|de}} == {{ziman|fr}} == === Bilêvkirin === * {{IPA|fr|\kyʁdistɑ̃\}} * {{kîte|fr|kur|dis|tan}} === Serenav === {{serenav|fr|z=n}} # {{g|ku|Kurdistan}} #* {{bêmînak|fr}} == {{ziman|en}} == === Serenav === {{serenav|en}} # {{g|ku|Kurdistan}} #* {{bêmînak|en}} othneoix73udu3wn8hjco6dte9du5wc çûn 0 3143 6265617 6261937 2026-07-19T16:54:32Z Ghybu 1393 /* Lêker */ 6265617 wikitext text/x-wiki {{bnr-h|cun|cûn|cün|çun|çûn|çün}} == {{ziman|ku}} == === Bilêvkirin === * {{IPA|ku|/t͡ʃʰuːn/}} * {{deng|ku|LL-Q36368 (kur)-Dildadil-çûn.wav|Deng|Amed}} * {{deng|ku|LL-Q36163 (kmr)-Ebulfîda-çûn.wav|Deng|dever=Bidlîs}} * {{ku-kîte}} === Lêker === {{ku-tewîn-lk|çûn|form=negerguhêz|niha=her-er-r|niha2=ç|borî=çû}} [[Wêne:Elephant_Walking_animated.gif|thumb|[[fîl|Fîlek]] bi rê ve [[çûn|diçe]].]] {{lêker|ku|c=x-ngh}} # Ji [[der]]ekê [[dûr ketin]], [[cih]]ek [[bi cih hêlan]] / [[bi cih hiştin]], [[dûr]]î derekê bûn. #: {{hevmane|ku|herîn|rewtin|bi rê ketin}} #: {{dijmane|ku|hatin}} #* {{jêder-pirtûk|ku|jêgirtin=Nezer ji mala dewatê der tê û di riya xwe de '''diçe'''.|nivîskar=Têmûrê Xelîl Mûradov|sernav=Nezerê Mêrxas|sal=1937|rûpel=}} #* {{jêder|ku|jêgirtin=Gor gotina apê min, ew '''terin''' di mêrga Şêx da gihê diçinin.|İkram Oğuz, ''Jîyan bi kurdî xweş e'', '''2022''', ''Weşanên NavKurd'', r.187}} #* {{jêder|ku|jêgirtin=Jinikê digote xelkê: Ev mêrê min Boẍoçêf e. Berê xwe dide Pêtro û digot-ê: Boẍoçêf, tu '''çûyî''' kû; ez û zarowên xwe tazî û birçî hiştin...|{{w|Ronahî}}, hj.25, '''1944''', Boẍoçef an Petroyê siseyan''}} # [[hinda|Hinda]] bûn, [[neman]], [[berze bûn]], [[rabûn]]. #* {{jêder|ku|jêgirtin=Xelk pir kenî bi me tama<br>Genim '''çû''' ewîr û ka ma<br>Têvedan kevirê dama<br>Me derda û wan vexwarî|Mihemedê Cezawîr, ''[https://www.xelat.org/welato-2201 Welato]'' (helbest)|}} ==== Ji wêjeya klasîk ==== * {{jêder|ku|{{Jêgirtin/Mela Hisênê Bateyî/Mewlûda Kurdî}}|jêgirtin='''Çûn''' ji behrê me'rîfet ew hate der<br>[[qetre|Qetre]] jêr werya bi ilham ew qeder}} * {{jêder|ku|{{Jêgirtin/Feqiyê Teyran}}|jêgirtin=Taziyê uryan im ez<br>Perde '''çû''' ez mame tazî<br>Dil sera mehbûb dixwazî}} ==== Bi alfabeyên din ==== * {{ku-ar|چوون}} * {{ku-kr|ч'ӧн}} ==== Formên alternatîv ==== * {{g|ku|çûndin}} * {{g|ku|çûyin}} * {{g|ku|çûyîn}} ==== Têkildar ==== {{kol3|ku | bezîn | gerîn | livîn | meşîn }} ==== Jê ==== {{kol3|ku | çûn anîn | çûnanîn | çûyî | derçûn | jê çûn | ji ber çûn | ji bîrê çûn | ji dest çûn | jihev çûn | pev çûn }} ==== Etîmolojî ==== Ji {{ji|ine-pro|ku|*ḱey-}}. Guherîna ''*ḱ''-ya [[proto-hindûewropî]] bi /ç/ di zimanên [[hindûîranî]] de diyardeyeke berbelav e, binêrin bo nimûne: ''[[çar]], [[çav]], [[çend]], [[çi]]''... Hevreha {{hv|ckb|چوون}}, [[kurdiya başûrî]] ''[[çûn]]'', [[şêxbizinî]] ''[[cigin]]'', zazakî ''[[şiyayene]]'', goranî/hewramî ''[[şiyay]]'', osetî [[цӕуын]] (çæwyn), {{hv|fa|شدن|tr=berê /şuden/ bi wateya ''çûn'', niha /şoden/ bi manaya ''bûn, bûn tiştek''}}, tacikî [[шудан]] (şudan), {{hv|pal||şuten|sc=Latn}}, hexamenişî [[𐎠𐏁𐎡𐎹𐎺𐎶]] (š(i)yav-, /şiyev/), peştûyî {{g|ps|شول|tr=şwəl}}, {{hv|ae||ş(ii)aw-|sc=Latn}} (/şyew-/), {{hv|sa|च्य्अवते}} (cyávate: [[ketin]]), {{hv|grc|σεύω}} (seúō: [[dan pey]], li [[pey]] çûn; [[lezîn]]) û [[κῐ́ω]] (kíō: çûn) û [[κῑνέω]] (kīnéō: [[livandin]]), latînî ''[[cieō]]'' ([[livandin]]), albanî ''[[qoj]]'' (bixwîne: /çoy/, [[hişyar]] kirin)... Bêjeka kurdî ketiye ermenî wek {{hv|xcl|չուեմ|w=çûn}} û {{hv|hy|չու|w=rêwîtî}}, {{q|hy|չվել|w=bar kirin, koç kirin}}. Peyva {{hv|grc|κῑνέω}} (kīnéō: [[livandin]]) wek [[kîne-]] û [[sîne-]] ketiye gelek zimanan û kurdî jî, bo nimûne: ''[[kînetîk]], [[sînema]]''. ;{{biçûk|Çavkanî: * {{Cheung}} * {{Chyet}} * {{Lubotsky}} * {{Tsabolov}} }} ==== Bi zaravayên din ==== * {{Z|ckb}}: {{W-|ckb|چوون}} * {{Z|zza}}: {{W-|zza|şîyayene}} ==== Werger ==== {{werger-ser|dûr ketin}} * {{Z|de}}: {{W+|de|gehen}}, {{W+|de|fahren}} * {{Z|az}}: {{W+|az|getmək}} * {{Z|ba}}: {{W-|ba|барыу}} * {{Z|br}}: {{W+|br|mont}}, {{W+|br|monet}} * {{Z|bg}}: {{W+|bg|отивам|n}} * {{Z|cs}}: {{W+|cs|jít}} * {{Z|zh}}: {{W+|zh|去|tr=qǜ}} * {{Z|da}}: {{W+|da|gå}} * {{Z|ar}}: {{W+|ar|راح|tr=raḧe|cuda=راحَ}}, {{W+|ar|ذهب|tr=ḏehebe}} * {{Z|eo}}: {{W+|eo|iri}} * {{Z|fa}}: {{W+|fa|رفتن|tr=reften}} * {{Z|fi}}: {{W+|fi|mennä}}, {{W+|fi|lähteä}} * {{Z|vls}}: {{W-|vls|goan}} * {{Z|fr}}: {{W+|fr|aller}}, {{W+|fr|partir}} * {{Z|gag}}: {{W-|gag|gitmää}} * {{Z|roa-gal}}: {{W-|roa-gal|aler}}, {{W-|roa-gal|alae}} * {{Z|got}}: {{W-|got|𐌲𐌰𐌲𐌲𐌰𐌽|tr=gaggan}} * {{Z|en}}: {{W+|en|go}} * {{Z|ga}}: {{W-|ga|dul}} * {{Z|it}}: {{W+|it|andare}} * {{Z|ja}}: {{W+|ja|行く|tr=iku}} * {{Z|krc}}: {{W-|krc|барыргъа}} * {{Z|ca}}: {{W+|ca|anar}} * {{Z|ky}}: {{W+|ky|баруу}} * {{Z|ki}}: {{W-|ki|thie}} * {{Z|ko}}: {{W+|ko|가다|tr=gada}} * {{Z|kum}}: {{W-|kum|бармакъ}} * {{Z|lb}}: {{W+|lb|goen}} * {{Z|mk}}: {{W-|mk|оди|tr=ódi}} * {{Z|mi}}: {{W-|mi|haere}} * {{Z|hu}}: {{W+|hu|megy}} * {{Z|nrf}}: {{W-|nrf|marchi}} * {{Z|oc}}: {{W+|oc|anar}} * {{Z|oia}}: {{W-|oia|mara}} * {{Z|pt}}: {{W+|pt|ir}} * {{Z|kk}}: {{W+|kk|бару|tr=baruw}} * {{Z|ro}}: {{W+|ro|merge}}, se {{W+|ro|duce}} * {{Z|se}}: {{W-|se|mannat}}, {{W-|se|johtit}}, {{W-|se|fitnat}} * {{Z|sh}}: {{W+|sh|ići}}, {{W-|sh|ићи}} * {{Z|sk}}: {{W+|sk|ísť}} * {{Z|es}}: {{W+|es|ir}} * {{Z|sv}}: {{W+|sv|gå}}, {{W+|sv|åka}} * {{Z|zdj}}: {{W-|zdj|hwenɗa}}, {{W-|zdj|henɗa}} * {{Z|tt}}: {{W-|tt|бару}} * {{Z|tr}}: {{W+|tr|gitmek}} * {{Z|tk}}: {{W-|tk|gitmek}} * {{Z|vi}}: {{W+|vi|đi}} * {{Z|kjh}}: {{W-|kjh|парарға}} * {{Z|sah}}: {{W-|sah|бар}} * {{Z|el}}: {{W+|el|πάω|tr=páo}}, {{W+|el|πηγαίνω|tr=piyéno}} {{werger-bin}} === Navdêr === {{ku-tewîn-nav|çûn|mê}} {{navdêr|ku|z=m}} # [[birêketin]], [[dûrketin]], [[dûr]]bûn, [[royîştin]], [[rewtin]], [[sefer]]kirin #: {{mk|ku|'''Çûna''' we bixêr be!|Hûn bixêr biçin!|rêz=1}} #* {{bêmînak|ku}} ==== Bi zaravayên din ==== * {{Z|zza}}: {{W-|zza|şiyayiş}} ==== Werger ==== {{werger-ser}} * {{Z|tr}}: {{W+|tr|gitme}} {{werger-bin}} {{bend}} === Hoker === {{hoker|ku}} # [[wek|Wek]], [[mîna]], [[şibî]], [[nola]], [[fena]] (li [[pey]] peyvan bi kar tê). #: {{mk|ku|Mirov '''çûn'''.|Wek mirovan.|rêz=1}} #* {{bêmînak|ku}} ==== Etîmolojî ==== Têkilî {{q|ku|çawa}}. ==== Werger ==== {{werger-ser}} {{werger-bin}} == {{ziman|ckb}} == === Lêker === {{lêker|ckb|sc=Latn}} # {{ckb-Arab|چوون}} o374m9zu0hzkg20frb2vjl5ux0cc3jj hêj 0 3772 6265823 6249142 2026-07-20T09:09:16Z Wikihez 7344 [[Bikarhêner:Wikihez/templateScript2.js|TS]]: sererastkirin 6265823 wikitext text/x-wiki {{bnr-h|hej}} == {{ziman|ku}} == === Hoker === {{hoker|ku}} # [[ta|Ta]] [[niha]], [[heta]] [[noke]], [[heya]] [[niho]]. #: {{mk|ku|Ez '''hêj''' diçim dibistanê.}} # ta hingê, heta wê demê, heya wî wextî #: {{mk|ku|Dema ez derketim, '''hêj''' nehatibû.}} # [[ji wê]], [[ji wî]], ji wan; ji hindê, ji wê yekê, ji vê yekê #: {{mk|ku|Ev '''hêj''' mezintir e.|Ev ji wê jî mezintir e.|birêz=1}} # Hin yên din jî. #: {{mk|ku|'''Hêj''' pirs di serê min de mane.}} ==== Ji wêjeya klasîk ==== * {{jêder|ku|{{Jêgirtin/Mela Hisênê Bateyî/Mewlûda Kurdî}}|jêgirtin='''Hêj''' ne lewh û enbiyayê muhteşem</br>Salîha tesbîh kirî nûra şikelf}} ==== Formên alternatîv ==== {{stûn| * {{g|ku|hê}} * {{g|ku|hê jî}} * {{g|ku|hêş}} * {{g|ku|hêşta}} }} ==== Hevmane ==== {{stûn| * {{g|ku|hîn}} * {{g|ku|hîna}} * {{g|ku|hêna}} * {{g|ku|deha}} }} ==== Bide ber ==== * {{g|ku|her}} * {{g|ku|heta}} * {{g|ku|-tir|tir}} ==== Etîmolojî ==== Ji {{ji|ira}}, hevreha farisî {{hv|fa|هنوز|tr=hanuz}}, {{hv|pal||ehenûz|sc=Latn}}. "j" ya kurmancî li hevberî "z" ya farisî ye, wek "jin/zen", "bajar/bazarr". ==== Werger ==== {{werger-ser}} * {{Z|de}}: {{W+|de|noch}}, {{W+|de|überdies}} * {{Z|fa}}: {{W|fa|هنوز}} * {{Z|en}}: {{W|en|yet}}, {{W|en|still}}, {{W|en|further}}, {{W|en|else}} * {{Z|tr}}: {{W|tr|daha}}, {{W|tr|hâlâ}}, {{W|tr|henüz}} {{werger-bin}} === Rengdêr === {{rengdêr|ku}} # {{mane|bêdeng}} {{guherto|ku|hiş|id=bêdeng}} #* {{bêmînak|ku}} 2ryyxgvevb3kc3zkcglngqbtk7rbvaf 6265824 6265823 2026-07-20T09:09:55Z Wikihez 7344 6265824 wikitext text/x-wiki {{bnr-h|hej}} == {{ziman|ku}} == === Hoker === {{hoker|ku}} # [[ta|Ta]] [[niha]], [[heta]] [[noke]], [[heya]] [[niho]]. #: {{mk|ku|Ez '''hêj''' diçim dibistanê.}} # ta hingê, heta wê demê, heya wî wextî #: {{mk|ku|Dema ez derketim, '''hêj''' nehatibû.}} # [[ji wê]], [[ji wî]], ji wan; ji hindê, ji wê yekê, ji vê yekê #: {{mk|ku|Ev '''hêj''' mezintir e.|Ev ji wê jî mezintir e.|birêz=1}} # Hin yên din jî. #: {{mk|ku|'''Hêj''' pirs di serê min de mane.}} ==== Ji wêjeya klasîk ==== * {{jêder|ku|{{Jêgirtin/Mela Hisênê Bateyî/Mewlûda Kurdî}}|jêgirtin='''Hêj''' ne lewh û enbiyayê muhteşem</br>Salîha tesbîh kirî nûra şikelf}} ==== Formên alternatîv ==== {{kol3|ku|cure=Herwiha |hê |hê jî |hêş |hêşta }} ==== Hevmane ==== {{kol3|ku |hîn |hîna |hêna |deha }} ==== Bide ber ==== * {{g|ku|her}} * {{g|ku|heta}} * {{g|ku|-tir|tir}} ==== Etîmolojî ==== Ji {{ji|ira}}, hevreha farisî {{hv|fa|هنوز|tr=hanuz}}, {{hv|pal||ehenûz|sc=Latn}}. "j" ya kurmancî li hevberî "z" ya farisî ye, wek "jin/zen", "bajar/bazarr". ==== Werger ==== {{werger-ser}} * {{Z|de}}: {{W+|de|noch}}, {{W+|de|überdies}} * {{Z|fa}}: {{W|fa|هنوز}} * {{Z|en}}: {{W|en|yet}}, {{W|en|still}}, {{W|en|further}}, {{W|en|else}} * {{Z|tr}}: {{W|tr|daha}}, {{W|tr|hâlâ}}, {{W|tr|henüz}} {{werger-bin}} === Rengdêr === {{rengdêr|ku}} # {{mane|bêdeng}} {{guherto|ku|hiş|id=bêdeng}} #* {{bêmînak|ku}} 1ae3v57m9bc2xorys2so850mui6pu27 karîn 0 3979 6265593 6262033 2026-07-19T15:13:22Z Kesek000 15138 /* Werger */ 6265593 wikitext text/x-wiki {{bnr-h|Karîn}} == {{ziman|ku}} == === Bilêvkirin === * {{ku-IPA}} * {{deng|ku|LL-Q36368 (kur)-Dildadil-karîn.wav|Deng|Amed}} * {{ku-kîte}} === Lêker === {{ku-tewîn-lk|karîn|form=gerguhêz|niha=kar|borî=karî}} [[Wêne:Olympic-style weight lifting training.JPG|thumb|Ev kes '''dikarin''' tiştên [[giran]] [[hilgirtin|hilgirin]].]] {{lêker|ku|c=x-gh}}, {{k-ya nerm}} # [[hêz|Hêz]] / [[taqet]] yan [[hinêr]] yan [[derfet]] / [[delîv]] yan [[zanîn]] hebûn bo kirina tiştekî. #: {{hevmane|ku|şiyan}} #* {{jêder|ku|{{Jêgirtin/Melayê Cizîrî/Dîwana Melayê Cizirî}}|jêgirtin=Tu narê firqetê zanî</br>'''Dikarim''' ez tehemmul kim</br>Diyarê kohê Qendîl im}} # [[qezenc kirin]], [[jê birin]], [[bi ser ketin]]: #: {{mk|ku|Di avjenîyê de min '''karî''' te.}} ==== Bikaranîn ==== Lêkerên "karîn/kanîn" (anku "şiyan", "hêz hebûn") û "zanîn" bi hin awayan ji lêkerên din yên kurmancî cuda ditewin. Bo nimûne di dema niha de di hin devokan de pêşqertafa "di-" nakeve pêşiya wan. Loma "ez di-kim, tu di-bêjî, ew di-xwe" lê "ez karim, tu zanî, ew kane" (li cihê "ez dikarim, tu dizanî, ew dikane"). Herwiha neyînîkirina wan ne bi "na-" ya giştî lê bi "ni-" ye: Loma "ez na-kim, tu na-çî, ew na-bêje" lê "ez ni-zanim, tu ni-karî, ew nikane". Herwiha di rewşên din de jî hin cudahî hene. Ji hemû lêkerên din re di raweya şertî de (kondîsyonal yan subjunktîv) bi giştî lêker bi formûlaya "bi- + rehê dema niha + qertafa kesandinê ne": "ez bi-ç-im, tu bi-k-î, ew bi-bêj-e". Ev qaydeya giştî di hin devokan de dîsa li gel lêkerên "karîn/kanîn" û "zanîn" jî li kar e: "ez bi-zan-im, tu bi-kar-î, ew bi-kan-e". Lê di hin devokan de jî ew bi formûlaya "rehê dema niha + -i- + -b- + qertafa kesandinê" tê çêkirin: "ez kar-i-b-im, tu zan-i-bî, ew kan-i-b-e". Di hin devokan de jî îcar ev herdu qayde di heman demê de tên bikaranîn: "ez bi-zan-i-b-im, tu bi-kar-i-bî". Lê ji van awarteyiyan tenê "ni-" ya neyînîkirinê di kurmancî de di hemû devokan de awrte ye. Lê awarteyiyên din tenê di hin devokan de hene. Devokên din qeydeyên giştî bi kar tînin. Loma divê em di mesela "di-" de li gor qaydeya giştî biçin: "ez dikarim" ne "ez karim". Herwiha ji ber ku "ez bi-zan-im, tu bi-kar-î, ew bi-kan-e" li gor qaydeya giştî ne û formên wek "ez zan-i-bim, tu kar-i-bî, ew kan-i-be" yan jî "ez bi-zan-i-bim, tu bi-kar-i-bî, ew bi-kar-i-be" awarte ne, divê em wek "bizanim, bikarî, bikane" tercih bikin. Herwiha ev ''karibû'' bi teşeya raboriya dûr ''karîbû'' hemanî nayê lêvandin. ==== Bi alfabeyên din ==== * {{ku-ar|کارین}} * {{ku-kr|карин}} ==== Formên alternatîv ==== * [[kanîn]] * [[kaynîn]] (kurmanciya Xorasanê) ==== Jê ==== * [[kara]] ==== Etîmolojî ==== Ji {{ji|hy|ku|-}}{{çp}}, bi ermeniya rojava {{g|hy|կարնալ|tr=arenal/garenal}}, ermeniya rojhilat {{g|hy|կարողանալ|tr=karoġanal}}, têkilî ermeniya kevn {{g|xcl|կարող|tr=karoł|w=[[xurt]], [[bihêz]]}} ji {{g|xcl|կար|tr=kar|w=[[hêz]], [[îmkan]]}}. Di lêkera ermenî de di nava peyvê de hem "r" û hem jî "n" heye loma di hin devokên kurmancî de "karîn" û di hinan de jî "kanîn" e. Di devokên kurmancî yên dûrî ermenî de û di zaravayên din yên kurdî û di zimanên din yên îranî de peyda nabe loma ihtimala ku ji ermenî be gelekî mezin e. Bi hin devokên kurmancî [[şiyan]] e ku [[hevreh]]a [[şiyan]] ([[mimkin]] bûn) ya soranî, [[şayed]] ya ji farisî û [[şikayene, eşkayene, şayene]] ya zazakî ye. Di soranî de [[tiwanîn]] (rehê dema niha "-tiwan-") e ku hevreha {{g|fa|توانستن|tr=tevanesten}} ya farisî ye ku rehê wê yê dema niha "-tevan-" e. Ne têkilî [[can]] (bixwîne: ken yan kan) ya îngilîzî û hevrehên wê yên zimanên cermenî ye ji ber ku eger ew hevreh bûna, "k" ya proto-hindûewropî divê di kurdî de bûbûya "s" û di zimanên cermenî de jî "h". Idiaya [[Şablon:Beghyani|Beghyani]], ku dibêje ji [[kirin]] e, bi ti [[belge]]yan nehatiye [[peyitandin]]. [[Şablon:Hesendost|Hesendost]] bi xeletî li ber peyva "tevanisten" ya farisî nivîsiye: "kirmaşanî: twanîn, karîn, û: karîn, kan, kanî". Di rastiyê de li ber "karîn, -kan-, kanî" diviyabû ku "kurmancî" hatibûya nivîsîn. Bi Kirmaşanî û lekî [[tüenîn]] / [[tüenisin]] e. Peyva ermenî jî ji zimanekî gurcî-zanî wergirtiye<ref>Ačaṙean, Hračʿeay (1973), “կռիւ”, in Hayerēn armatakan baṙaran [Armenian Etymological Dictionary] (in Armenian), volume II, 2nd edition, a reprint of the original 1926–1935 seven-volume edition, Yerevan: University Press, rûpel 671b http://www.nayiri.com/imagedDictionaryBrowser.jsp?dictionaryId=7&printPage=671&volume=2</ref>, ji proto-gurcî-zanî {{q|ccs-gzn-pro|*ḳar-|w=[[bestin]]}}, ji proto-kartvelî ''[[*ḳar-]]'' ku bûye [[lazî]] {{g|lzz|ო-კორ-უ|tr=o-ǩor-u|w=bestin}}, mingrelî {{g|xmf|კჷრ-უ-ა|w=bestin}}, gurcî {{g|ka|კრვა|tr=ḳrva}}<ref>Klimov, G. A. (1998) Etymological Dictionary of the Kartvelian Languages (Trends in linguistics. Documentation; 16), New York, Berlin: Mouton de Gruyter, rûpel 86 https://archive.org/details/KlimovEtymological/Klimov?view=theater#page/n102/mode/1up</ref><ref>Fähnrich, Heinz (2007) Kartwelisches Etymologisches Wörterbuch [Kartvelian Etymological Dictionary] (Handbuch der Orientalistik; VIII.18) (in German), Leiden, Boston: Brill, rûpel 222 https://archive.org/details/Fahnrich_2007/page/n221/mode/1up?view=theater</ref>... Ev dikare bê maneya ku ew peyveke substrat a hevpar e ku ketiye ermenî û hin zaravayên kurdî ji zimanên [[Qefqaz]]î, lê ew ne[[vebirî]] ye. Herwiha bi zimanê [[partî]] hatiye qeydkirin ku lêkera {{q|ku|kirin}} bo diyarkirina [[pêkanî|pêkaniya]] tiştek jî li kar bûye.<ref>Dictionary Of Manichean Middle Persian & Parthian by Durkin-Meisterernst, Desmond, rûpel 206, '''kr-, qr- Pa lkar-1 vtr. "to do, make'. Used as an auxiliary verb following a pp. in the 'potentialis', to indicate a possibility, eg MKG(726i fr'm](r)g kyrd kr'n "if- I could make (her) forgetful"''', https://archive.org/details/DictionaryOfMMP/page/n236/mode/1up?q=could</ref>mînak: "''framereg kird keran''" = (ku min wê) bikariya [[bîroke]] bikim (framereg: [[bîroke]] - ji reha fremûşten/ji bîr kirin / kird: kir - dema bihûrî a sade / keran: bikim - kesê yekjimar ê 1. dema niha a bilanî). Di soranî de jî rrewşa pasîf a lêkera "{{g|ckb|کردن}}" wek hevwateya {{g|ckb|شیان|w=mimkin bûn}} tê bikaranîn (wek "dekirêt rû bidat" = "tê kirin ku rû de" anku [[pêkan]] e ku rû de) an jî "deyekat" = ew wî dike/ew dikare... lê ne wek hevmaneya {{g|ckb|tiwanîn|sc=Latn|w=karîn}}. Anku ne ku di zimanên îranî ên din de peyda nabe, [[nexasma]] di zimanên kurdî de. ==== Werger ==== {{werger-ser}} * {{Z|sq}}: {{W-|sq|mund}}, {{W+|sq|mundem}} * {{Z|de}}: {{W+|de|können}} *: {{Z|gsw}}: {{W-|gsw|chöne}} * {{Z|an}}: {{W-|an|poder}} * {{Z|rup}}: {{W-|rup|pot}} * Assamese: *: {{Z|as}}: {{W-|as|পাৰা}} *: {{Z|as}}: {{W-|as|পৰা}} * {{Z|ast}}: {{W+|ast|poder}} * {{Z|az}}: {{W+|az|bilmək}}, {{W+|az|bacarmaq}} * {{Z|eu}}: {{W-|eu|ahal izan}} * {{Z|be}}: {{W-|be|магчы́|impf}}, {{W-|be|змагчы́|pf}}; {{W-|be|уме́ць|impf}}, {{W-|be|ўмець|impf}}, {{W-|be|суме́ць|pf}} * {{Z|br}}: {{W-|br|gallout}} * {{Z|bg}}: {{W-|bg|мо́га|impf}}, {{W-|bg|уме́я|impf}} * {{Z|my}}: {{W+|my|နိုင်|sc=Mymr}} * {{Z|cs}}: {{W-|cs|moci}}, {{W-|cs|umět}} * {{Z|zh}}: *: {{Z|yue}}: {{W-|yue|識得|tr=sik1 dak1}} *: {{Z|cmn}}: {{W+|cmn|會|tr=huì}}, {{W+|cmn|能|tr=néng}}, /{{W+|cmn|不了|tr=-buliǎo}}}}, {{W+|cmn|能夠|tr=nénggòu}} *: {{Z|nan}}: {{W+|nan|會得|tr=ē-tit}}, {{W+|nan|會當|tr=ē-tàng}}, {{W-|nan|會凍|tr=ē-tàng}} * {{Z|dlm}}: {{W-|dlm|potar}} * {{Z|da}}: {{W-|da|kunne}} * {{Z|id}}: {{W+|id|boleh}}, {{W+|id|bisa}} * {{Z|ar}}: {{W-|ar|قَدَرَ}}, {{W-|ar|اِسْتَطَاعَ}}, {{W-|ar|أَمْكَنَ}} *: {{Z|arz}}: {{W-|arz|قدر|tr=ʾadar|sc=Arab}} * {{Z|hy}}: {{W+|hy|կարողանալ}}, {{W+|hy|կրնալ}} * {{Z|eo}}: {{W+|eo|povi}} * {{Z|et}}: {{W-|et|osata}}, {{W-|et|võima}} * {{Z|fa}}: {{W-|fa|توانستن|tr=tavânestan}}, {{W-|fa|قادر بودن}} * {{Z|fo}}: {{W+|fo|kunna}} * {{Z|fi}}: {{W+|fi|osata}}, {{W+|fi|voida}}, {{W+|fi|pystyä}} * {{Z|frp}}: {{W-|frp|povêr}}, {{W-|frp|possêr}} * {{Z|fr}}: {{W+|fr|pouvoir}} * {{Z|fur}}: {{W-|fur|podê}} * {{Z|frr}}: {{W-|frr|koone}}, {{W-|frr|kön}}, {{W-|frr|kan}} * {{Z|ofs}}: {{W-|ofs|kunna}} * {{Z|stq}}: {{W-|stq|konne}} * {{Z|gd}}: {{W-|gd|'s urrainn do}}, {{W-|gd|faod}} * {{Z|gl}}: {{W+|gl|poder}} * {{Z|roa-gal}}: {{W-|roa-gal|póeir}} * {{Z|got}}: {{W-|got|𐌼𐌰𐌲𐌰𐌽}}, {{W-|got|𐌺𐌿𐌽𐌽𐌰𐌽}} * {{Z|ka}}: {{W-|ka|შეუძლია}} * {{Z|ht}}: {{W-|ht|ka}}, {{W-|ht|kapab}}, {{W-|ht|kab}} * {{Z|hi}}: {{W-|hi|सकना}}, {{W-|hi|समर्थ होना}} * {{Z|nl}}: {{W+|nl|kunnen}}, {{W+|nl|vermogen}} * {{Z|he}}: {{W+|he|יכול|n|tr=yakhól|cuda=יכול / יָכֹל}}, {{W-|he|מסוגל|n|tr=m'sugál|cuda=מסוגל / מְסֻגָּל}} * {{Z|ang}}: {{W-|ang|magan}}, {{W-|ang|cunnan}} * {{Z|ga}}: {{W-|ga|is féidir le}}, {{W-|ga|tig le}}, {{W-|ga|féad}}, {{W-|ga|bí}} {{W-|ga|in ann}} *: {{Z|sga}}: {{W-|sga|con·icc}} * {{Z|it}}: {{W+|it|potere}}, {{W+|it|riuscire}}, {{W+|it|sapere}} * {{Z|is}}: {{W+|is|geta}} * {{Z|ja}}: {{W+|ja|できる|tr=dekiru|sc=Jpan}}, {{W+|ja|れる|cuda=-れる|tr=-reru|sc=Jpan}}, {{W+|ja|られる|cuda=-られる|tr=-rareru|sc=Jpan}} * {{Z|kn}}: {{W+|kn|ಬಹುದು}} * {{Z|ca}}: {{W-|ca|poder}}, {{W-|ca|poguer}} * {{Z|qu}}: {{W+|qu|atiy}} * {{Z|gil}}: {{W-|gil|kona}} * {{Z|ko}}: {{W-|ko|수|cuda=...을/ᄅ 수 있다|tr=...-l su itda}}, {{W+|ko|eu}} * {{Z|kw}}: {{W-|kw|gallos}} * {{Z|la}}: {{W+|la|possum}}, {{W-|la|queo}}, {{W+|la|scio}} * {{Z|lv}}: {{W+|lv|prast}}, {{W+|lv|spēt}}, {{W+|lv|varēt}} * {{Z|lo}}: {{W-|lo|ໄດ້}} * {{Z|lt}}: {{W+|lt|galėti}} * {{Z|liv}}: {{W-|liv|mȯistõ}}, {{W-|liv|võidõ}} * {{Z|khb}}: {{W-|khb|ᦺᦡᧉ}} * {{Z|lb}}: {{W+|lb|kënnen}} * {{Z|mk}}: {{W-|mk|може}} * {{Z|ml}}: {{W-|ml|കഴിയും}} * {{Z|ms}}: {{W-|ms|dapat}}, {{W-|ms|boleh}}, {{W+|ms|bisa}} * {{Z|mt}}: {{W-|mt|seta'}} * {{Z|gv}}: {{W-|gv|jarg}} * {{Z|hu}}: {{W+|hu|tud}}, {{W+|hu|képes}} * {{Z|mn}}: {{W+|mn|чадах}}, {{W-|mn|ᠴᠢᠳᠠᠬᠤ}} * {{Z|nah}}: {{W-|nah|huelīti}} * {{Z|nap}}: {{W-|nap|putè}} * {{Z|nds}}: {{W-|nds|könen}} * {{Z|no}}: {{W+|no|kunne}} * {{Z|oc}}: {{W-|oc|pòder}}, {{W-|oc|podre}} * {{Z|ppl}}: {{W-|ppl|weli}}, {{W-|ppl|hueli}} * {{Z|pl}}: {{W+|pl|móc}}, {{W+|pl|umieć}}, {{W+|pl|potrafić}} * {{Z|pt}}: {{W+|pt|conseguir}}, {{W+|pt|saber}} * {{Z|rm}}: {{W-|rm|pudair}}, {{W-|rm|puder}}, {{W-|rm|pudeir}} * {{Z|ro}}: {{W+|ro|putea}} * {{Z|ru}}: {{W+|ru|мочь|impf}}, {{W+|ru|смочь|pf}}, {{W-|ru|уме́ть|impf}}, {{W-|ru|быть в состоя́нии}} * {{Z|osx}}: {{W-|osx|kunnan}} * {{Z|sc}}: {{W-|sc|podere}}, {{W-|sc|podi}}, {{W-|sc|podiri}}, {{W-|sc|pori}}, {{W-|sc|porrere}}, {{W-|sc|potere}} * {{Z|scn}}: {{W+|scn|putiri}} * {{Z|sh}}: *: Kirîlî: {{W-|sh|моћи}}, {{W-|sh|умети}}, {{W-|sh|умјети}} *: Latînî: {{W+|sh|moći}}, {{W+|sh|umeti}}, {{W+|sh|umjeti}} * {{Z|syl}}: {{W-|syl|ꠙꠣꠞꠣ}} * {{Z|sk}}: {{W-|sk|môcť}} * {{Z|sl}}: {{W+|sl|moči}} * Sorbî: *: {{Z|dsb}}: {{W-|dsb|móc}} * {{Z|es}}: {{W+|es|poder}}, {{W+|es|saber}} * {{Z|sv}}: {{W+|sv|kunna}} * {{Z|zdj}}: {{W-|zdj|djua|cuda=udjua}} * {{Z|ta}}: {{W-|ta|செய்யக்கூடிய}} * {{Z|th}}: {{W+|th|ได้}}, {{W+|th|ย่อม}}, {{W+|th|สามารถ}} * {{Z|otk}}: {{W-|otk|𐰆|ts=u-}} * {{Z|tr}}: {{W+|tr|-ebilmek}}, {{W+|tr|-abilmek}} {{W+|tr|yenmek}} * {{Z|txb}}: {{W-|txb|yāt-}} * {{Z|ur}}: {{W-|ur|سکنا|tr=saknā|sc=ur-Arab}} * {{Z|uk}}: {{W-|uk|могти́|impf}}, {{W-|uk|змогти́|pf}}; {{W-|uk|вмі́ти|impf}}, {{W-|uk|умі́ти|impf}}, {{W-|uk|зумі́ти|pf}} * {{Z|vec}}: {{W-|vec|poder}} * {{Z|vi}}: {{W+|vi|có thể}}, {{W+|vi|được}} * {{Z|wa}}: {{W+|wa|poleur}}, {{W+|wa|saveur}}, {{W+|wa|sawè}} * {{Z|cy}}: {{W+|cy|gallu}}, {{W+|cy|medru}} * {{Z|km}}: {{W+|km|បាន|tr=baan}} * {{Z|yi}}: {{W-|yi|קענען}} * {{Z|esu}}: {{W-|esu|-yugnga}} * {{Z|el}}: {{W+|el|μπορώ}}, {{W+|el|δύναμαι}} *: Kevn: {{W-|grc|δύναμαι}} * {{Z|za}}: {{W-|za|maenz}} * {{Z|ase}}: {{W-|ase|S@Sternumhigh-PalmDown-S@Sternumhigh-PalmDown S@Chesthigh-PalmDown-S@Chesthigh-PalmDown}} {{werger-bin}} === Navdêr === {{ku-tewîn-nav|karîn|mê}} {{navdêr|ku|z=m}} # [[şiyan]], [[taqet]], [[hêz]], [[qudret]] #* {{mk|ku|Bi serketinê wî '''karîna''' xwe nîşan da.}} ==== Werger ==== {{werger-ser}} * {{Z|tr}}: {{W|tr|edebilme}}, {{W|tr|yapabilme}}, {{W|tr|güç}}, {{W|tr|kudret}}, {{W|tr|erk}}, {{W|tr|yapabilme}}, {{W|tr|nüfuz}} {{werger-bin}} {{bend}} === Lêker 2 === {{lêker|ku|c=x-ngh}} # [[girîn]] #: {{mk|ku|Çêla zer ji birsan '''karî'''.}} ==== Etîmolojî ==== {{etîmolojî?}} ==== Werger ==== {{werger-ser}} * {{Z|en}}: {{W|en|cry}} * {{Z|tr}}: {{W|tr|ağlamak}} {{werger-bin}} === Çavkanî === {{çavkanî}} cgrrcliou0m0e9rwhwxc9rrsy6tqwnq seat 0 4788 6265786 6081895 2026-07-20T08:14:45Z Wikihez 7344 /* */ bi [[MediaWiki:Gadget-AjaxEdit.js|AjaxEdit]]ê re 6265786 wikitext text/x-wiki == {{ziman|ku}} == === Navdêr === {{ku-tewîn-nav|seat|mê}} {{navdêr|ku|z=m}} # {{guharto|ku|saet}} #* {{Jêgirtin/Mela Hisênê Bateyî/Mewlûda Kurdî|jêgirtin=Têkveda heta ku ew qenc bû xemîr</br>Bû wekî durra sipî wê '''se'atê'''</br>Xewte da der çûyî barê Cennetê}} == {{ziman|en}} == === Bilêvkirin === * {{ku-tîp|sît}} * {{deng|en|en-us-seat.ogg|dever=DYA}} * {{deng|en|LL-Q1860 (eng)-Nattes à chat-seat.wav|Deng|dever=}} * {{deng|en|LL-Q1860 (eng)-Wodencafe-seat.wav|Deng|dever=Teksas, DYA}} * {{deng|en|LL-Q1860 (eng)-Grendelkhan-seat.wav|Deng|dever=Connecticut, DYA}} ==== Navdêr ==== {{navdêr|en}} # [[kursî]], [[rûniştek]], [[meqeet]] #* {{bêmînak|en}} # [[meqeet]] #: {{mk|en|There is a new '''seat''' for linguistics at the university}} # [[rûniştin]] #: {{mk|en|Have a seat, please.|Kerem kin, rûnin.}} ky5186omja18vxb7e71to0nn4uny5qx dawî 0 7899 6265754 6102288 2026-07-20T06:06:39Z Wikihez 7344 [[Bikarhêner:Wikihez/templateScript2.js|TS]]: sererastkirin 6265754 wikitext text/x-wiki == {{ziman|ku}} == === Bilêvkirin === * {{ku-IPA}} * {{deng|ku|LL-Q36163 (kmr)-Ebulfîda-dawî.wav|Deng|Bidlîs}} * {{ku-kîte}} === Navdêr === {{ku-tewîn-nav|dawî|mê}} {{navdêr|ku|z=m}} # [[talî]], [[soxî]], [[dûmahî]], [[encam]], [[akam]], [[netîce]], [[songî]] #: {{hevmane|ku|dawîng|axir|kutahî}} #: {{dijmane|ku|destpêk|bidayet|sereta|ibtida}} #: {{mk|ku|Û li '''dawiyê''' ew biser ketin.}} #* {{jêder|ku|jêgirtin=Bi wî awayî, maça wan bi yanzdeh û deh '''dawî''' hat.|{{Jêgirtin/Firat Cewerî/Girtî}}}} #* {{jêder|ku|jêgirtin=Wek serxweşek bê hiş''<br/>''Ketime riya çep û rast''<br/>''Qediya qediya''<br/>''Şeva '''dawî''' hejiya|[[w:Ciwan Haco|Ciwan Haco]], ''Dil Ketimê''}} #* {{jêder|ku|jêgirtin=Mala keçkê li taxa jorî ye''<br/>''Sewda daye, hêş nemaye''<br/>''Gotinên xelkê '''dawî''' naye|[[w:Xelîl Xemgîn|Xelîl Xemgîn]], ''Nîne Nîne''}} #* {{jêder|ku|{{Jêgirtin/Ehmedê Xanî/Mem û Zîn}}|jêgirtin=Axir bide wî tu husn-i meqte'</br>– DAWÎ –}} # [[paşîn]] #* {{jêder-pirtûk|ku|jêgirtin=...li '''dawîya''' rêzê...|nivîskar={{w|J.R.R. Tolkien}}|sernav=Hobbit|wergêr=Samî Hêzil|cîh=Enqere|weşanxane={{w|Weşanên Cervantes|Cervantes}}|sal=2023|çap=1|rûpel=72|isbn=9786257724838}} ==== Jê ==== {{kol2|ku|cure=Jê |bi dawî bûn<q:lêker> |bi dawî hatin<q:lêker> |bi dawî kirin |dawî anîn |dawî kirin |dawî dan |dawî bûn |bidawîbûn<q:navdêr> |bidawîhatin<q:navdêr> |bidawîkirin<q:navdêr> |dawîbûn |dawîanîn |dawîkirin |dawîdan |bidawîbûyî<q:rengdêr> |bidawîhatî<q:rengdêr> |bidawîkirî |dawîbûyî |dawîkirî |dawîn }} ==== Etîmolojî ==== Hevreha soranî {{g|ckb|دوای|tr=diwahî}}, dimilkî {{g|zza|dimayîn}}, {{g|zza|dimaîn}}, ji {{paş|ku|dûv|-ahî}}.. Guherîna dengî dibe ku wisan bûbe: *divahî > bi [[metatez|metatezê]] *dihavî > -ih- dikeve wekî di *çihar>çar de û dibe *davî û > *dahî>dawî. Bo h>v/w di kurmanciyan de binêre soranî {{g|ckb|چوار|w=[[çwar|çiWar]]}}, {{g|ckb|نواڕین|tr=niWarrîn|w=[[nihêrîn]]}}, [[şirove]]... Bo guherîna v>h/w binêre [[bawer]]. Li devera Badînan wek "[[dûmahîk]]" maye, mihtemelen ji ber ku têkildarî [[dû]] û [[mayîn]] bawer kirine lewma. Bide ber [[farisî]] {{q|fa|افدم|tr=efdom|w=dawî}} ji [[pehlewî|farisiya navîn]] {{g|pal|tr=ebdum}}, ku bixwe ne ji [[heman]] [[reh]]ê ye (ji [[farisî|farisiya]] [[kevn]] *epetemeh, ji [[reh]]eke [[din]] a [[hindûewropî]] lê bi [[şaşî]] [[têkildar]]î {{g|pal|tr=dom|w=dûv}} kirine. ==== Werger ==== {{werger-ser}} * {{Z|de}}: {{W+|de|Ende|nt}}, {{W+|de|Schluss|n}} *: {{Z|gsw}}: {{W-|gsw|Endi}} * {{Z|as}}: {{W-|as|ওৰ}}, {{W-|as|শেষ}} * {{Z|ast}}: {{W+|ast|fin|n|m}} * {{Z|az}}: {{W+|az|son}}, {{W+|az|axır}}, {{W+|az|baş}} * {{Z|eu}}: {{W+|eu|amai}} * {{Z|ba}}: {{W-|ba|аҙаҡ|sc=Cyrl}} * {{Z|be}}: {{W-|be|кане́ц|n|sc=Cyrl}}, {{W-|be|край|n|sc=Cyrl}} * {{Z|br}}: {{W+|br|diwezh|n}} * {{Z|bg}}: {{W+|bg|край|n}} * {{Z|my}}: {{W+|my|အဆုံး}} * {{Z|cs}}: {{W+|cs|konec|n}} * {{Z|zh}}: *: {{Z|cmn}}: {{W+|cmn|結束|tr=jiéshù}}, {{W+|cmn|末尾|tr=mòwěi}}, {{W+|cmn|端|tr=duān}} * {{Z|cv}}: {{W-|cv|вӗҫ|sc=Cyrl}} * {{Z|dlm}}: {{W-|dlm|fain|n}} * {{Z|da}}: {{W+|da|ende}}, {{W+|da|afslutning}} * {{Z|id}}: {{W+|id|akhir}}, {{W+|id|ujung}} * {{Z|ar}}: {{W+|ar|نِهَايَة|m}}, {{W-|ar|غَايَة|m}} *: {{Z|arz}}: {{W-|arz|نهاية|m|tr=nehāya|sc=Arab}} *: {{Z|ary}}: {{W-|ary|خر|n|tr=ḵar}} * {{Z|hy}}: {{W+|hy|վերջ}}, {{W+|hy|ծայր}} * {{Z|eo}}: {{W+|eo|fino}} * {{Z|et}}: {{W+|et|lõpp}} * {{Z|eve}}: {{W-|eve|мудан}} * {{Z|evn}}: {{W-|evn|мудан}} * {{Z|ee}}: {{W-|ee|nuwuwu|nt}} * {{Z|fa}}: {{W+|fa|انتها|tr=entehâ}}, {{W+|fa|پایان|tr=pâyân|}}, {{W+|fa|آخر|tr=âxar|}} * {{Z|fi}}: {{W+|fi|pää}}, {{W+|fi|pääty}} ; {{W+|fi|loppu}} * {{Z|fr}}: {{W+|fr|fin|m}}, {{W+|fr|bout|n}}, {{W+|fr|extrémité|m}} * {{Z|fur}}: {{W-|fur|fin}} * {{Z|fy}}: {{W+|fy|ein}} * {{Z|gd}}: {{W-|gd|eàrr|n|m}} * {{Z|gl}}: {{W+|gl|fin|n|m}} * {{Z|got}}: {{W-|got|𐌰𐌽𐌳𐌴𐌹𐍃|n}} * {{Z|ka}}: {{W-|ka|დასასრული}}, {{W-|ka|ბოლო}}, {{W-|ka|მიწურული}} * {{Z|ht}}: {{W-|ht|fen}} * {{Z|hi}}: {{W+|hi|अंत|n|sc=Deva}} * {{Z|nl}}: {{W+|nl|einde|nt}}, {{W+|nl|uiteinde|nt}} * {{Z|he}}: {{W+|he|סוֹף|n|tr=sof|sc=Hebr}}, {{W+|he|קצה|n|tr=q'tzeh|lit=edge}} *: Îbranî: {{W-|lad|פין|m}} *: Latînî: {{W-|lad|fin}} * {{Z|io}}: {{W+|io|fino}} * {{Z|en}}: {{W+|en|end}} * {{Z|ist}}: {{W-|ist|feîn|n}} * {{Z|it}}: {{W+|it|fine|m}} * {{Z|is}}: {{W+|is|endir}} * {{Z|ja}}: {{W+|ja|終了|tr=shūryō|sc=Jpan}}, {{W+|ja|終わり|tr=owari|sc=Jpan}}, {{W-|ja|終い|tr=shimai|sc=Jpan}}, {{W+|ja|端|tr=hashi|sc=Jpan}}, {{W+|ja|最後|tr=saigo|sc=Jpan}}, {{W+|ja|エンド|tr=endo}} * {{Z|pam}}: {{W-|pam|danggut}}, {{W-|pam|sepu}} * {{Z|ca}}: {{W+|ca|fi|m}} * {{Z|ko}}: {{W+|ko|끝}}, {{W+|ko|종료}} * {{Z|lad}}: *: Îbranî: {{W-|lad|פ׳ין}}, {{W-|lad|קאב׳ו}} *: Latînî: {{W-|lad|fin|m}}, {{W-|lad|kavo|n}} * {{Z|ltg}}: {{W-|ltg|beigys}}, {{W-|ltg|gols|n}}, {{W-|ltg|pabeigys}} * {{Z|la}}: {{W+|la|finis|n|m}}, {{W+|la|terminus|n}}, {{W-|la|termen|nt}}, {{W-|la|exitus|n}}, {{W-|la|extremum|nt}}, {{W-|la|extremus|n}}, {{W-|la|peractio|m}}, {{W-|la|finalitas}} * {{Z|lv}}: {{W+|lv|gals|n}}, {{W-|lv|beigas|m-p}} * {{Z|lo}}: {{W-|lo|ຈົບ}} * {{Z|lt}}: {{W+|lt|pabaiga|m}}, {{W+|lt|galas|n}} * {{Z|lb}}: {{W-|lb|Enn|nt}} * {{Z|mk}}: {{W-|mk|крај|n|sc=Cyrl}} * {{Z|ms}}: {{W+|ms|akhir}}, {{W+|ms|hujung}}, {{W-|ms|هوجوڠ}} * {{Z|mt}}: {{W-|mt|tmiem}}, {{W-|mt|għeluq}} * {{Z|mnc}}: {{W-|mnc|ᡩᡠᠪᡝ}} * {{Z|gv}}: {{W-|gv|arbyl|n}} * {{Z|mi}}: {{W-|mi|hikutau}}, {{W-|mi|mutunga}}, {{W-|mi|paunga}} * {{Z|hu}}: {{W+|hu|vég}} * {{Z|mn}}: {{W+|mn|төгсгөл|sc=Cyrl}} * {{Z|gld}}: {{W-|gld|дуэ}}, {{W-|gld|модан}} * {{Z|nap}}: {{W-|nap|scompetura|m}} * {{Z|no}}: *: {{Z|nb}}: {{W+|nb|ende|n}}, {{W-|nb|slutt|n}} * {{Z|oc}}: {{W+|oc|fin}} * {{Z|om}}: {{W-|om|dhuma}} * {{Z|pl}}: {{W+|pl|koniec|n}} * {{Z|pt}}: {{W+|pt|fim}}, {{W+|pt|cabo|n}}, {{W+|pt|término|n}} * {{Z|rm}}: {{W-|rm|fin}}, {{W-|rm|fegn}} * {{Z|ro}}: {{W+|ro|sfârșit}}, {{W+|ro|terminație}}, {{W+|ro|capăt}} * {{Z|ru}}: {{W+|ru|коне́ц|n}}, {{W+|ru|край|n}} * {{Z|sa}}: {{W+|sa|अन्त|n|nt}}, {{W+|sa|समाप्ति|m}} * {{Z|sc}}: {{W-|sc|fine}}, {{W-|sc|fini}}, {{W-|sc|finis}} * {{Z|scn}}: {{W+|scn|fini}} * {{Z|sh}}: *: Kirîlî: {{W-|sh|крај|n|sc=Cyrl}} *: Latînî: {{W+|sh|kraj|n}} * {{Z|sk}}: {{W+|sk|koniec|n}} * {{Z|sl}}: {{W+|sl|konec|n}} * {{Z|so}}: {{W-|so|dhammaad}} * Sorbî: *: {{Z|dsb}}: {{W-|dsb|kóńc|n}} * {{Z|es}}: {{W+|es|fin|n|m}} * {{Z|sw}}: {{W+|sw|mwisho}}, {{W+|sw|ncha|c9|c10}}, {{W+|sw|tamati}} * {{Z|sv}}: {{W+|sv|slut}}, {{W+|sv|ände}} * {{Z|tg}}: {{W+|tg|охир}} * {{Z|tl}}: {{W-|tl|katapusan}}, {{W+|tl|dulo}} * {{Z|th}}: {{W+|th|จบ}} * {{Z|tr}}: {{W+|tr|son}} * {{Z|bo}}: {{W-|bo|མཇུག}} * {{Z|ur}}: {{W-|ur|انت|n|tr=ant|sc=ur-Arab}} * {{Z|uk}}: {{W+|uk|кіне́ць|n|sc=Cyrl}}, {{W+|uk|край|n|sc=Cyrl}} * {{Z|vec}}: {{W-|vec|fin|m}}, {{W+|vec|tèrmine|n}} * {{Z|vi}}: {{W+|vi|chóp}}, {{W+|vi|mút}} * {{Z|wa}}: {{W+|wa|fén|m}}, {{W+|wa|dibout|n}}, {{W+|wa|coron|n}} * {{Z|cy}}: {{W+|cy|diwedd}} * {{Z|km}}: {{W+|km|ចុង|tr=coŋ|sc=Khmr}} * {{Z|yai}}: {{W-|yai|охир}} * {{Z|yi}}: {{W-|yi|סוף|n|tr=sof}} * {{Z|el}}: {{W+|el|τέλος|nt}}, {{W+|el|πέρας|nt}}, {{W+|el|τέρμα|nt}}, {{W+|el|λήξη|m}}, {{W+|el|άκρο|nt}}, {{W+|el|άκρη|m}} *: Kevn: {{W-|grc|τελευτή|m}} {{werger-bin}} :{{werger çavkanî|en|end|beş=Ev qismê Wergerê|oldid=75874142}} kwbqsvhufqo1lwzop9e6o5pg7j6k3cz 6265755 6265754 2026-07-20T06:07:11Z Wikihez 7344 ? 6265755 wikitext text/x-wiki == {{ziman|ku}} == === Bilêvkirin === * {{ku-IPA}} * {{deng|ku|LL-Q36163 (kmr)-Ebulfîda-dawî.wav|Deng|Bidlîs}} * {{ku-kîte}} === Navdêr === {{ku-tewîn-nav|dawî|mê}} {{navdêr|ku|z=m}} # [[talî]], [[soxî]], [[dûmahî]], [[encam]], [[akam]], [[netîce]], [[songî]] #: {{hevmane|ku|dawîng|axir|kutahî}} #: {{dijmane|ku|destpêk|bidayet|sereta|ibtida}} #: {{mk|ku|Û li '''dawiyê''' ew biser ketin.}} #* {{jêder|ku|jêgirtin=Bi wî awayî, maça wan bi yanzdeh û deh '''dawî''' hat.|{{Jêgirtin/Firat Cewerî/Girtî}}}} #* {{jêder|ku|jêgirtin=Wek serxweşek bê hiş''<br/>''Ketime riya çep û rast''<br/>''Qediya qediya''<br/>''Şeva '''dawî''' hejiya|[[w:Ciwan Haco|Ciwan Haco]], ''Dil Ketimê''}} #* {{jêder|ku|jêgirtin=Mala keçkê li taxa jorî ye''<br/>''Sewda daye, hêş nemaye''<br/>''Gotinên xelkê '''dawî''' naye|[[w:Xelîl Xemgîn|Xelîl Xemgîn]], ''Nîne Nîne''}} # [[paşîn]] #* {{jêder-pirtûk|ku|jêgirtin=...li '''dawîya''' rêzê...|nivîskar={{w|J.R.R. Tolkien}}|sernav=Hobbit|wergêr=Samî Hêzil|cîh=Enqere|weşanxane={{w|Weşanên Cervantes|Cervantes}}|sal=2023|çap=1|rûpel=72|isbn=9786257724838}} ==== Jê ==== {{kol2|ku|cure=Jê |bi dawî bûn<q:lêker> |bi dawî hatin<q:lêker> |bi dawî kirin |dawî anîn |dawî kirin |dawî dan |dawî bûn |bidawîbûn<q:navdêr> |bidawîhatin<q:navdêr> |bidawîkirin<q:navdêr> |dawîbûn |dawîanîn |dawîkirin |dawîdan |bidawîbûyî<q:rengdêr> |bidawîhatî<q:rengdêr> |bidawîkirî |dawîbûyî |dawîkirî |dawîn }} ==== Etîmolojî ==== Hevreha soranî {{g|ckb|دوای|tr=diwahî}}, dimilkî {{g|zza|dimayîn}}, {{g|zza|dimaîn}}, ji {{paş|ku|dûv|-ahî}}.. Guherîna dengî dibe ku wisan bûbe: *divahî > bi [[metatez|metatezê]] *dihavî > -ih- dikeve wekî di *çihar>çar de û dibe *davî û > *dahî>dawî. Bo h>v/w di kurmanciyan de binêre soranî {{g|ckb|چوار|w=[[çwar|çiWar]]}}, {{g|ckb|نواڕین|tr=niWarrîn|w=[[nihêrîn]]}}, [[şirove]]... Bo guherîna v>h/w binêre [[bawer]]. Li devera Badînan wek "[[dûmahîk]]" maye, mihtemelen ji ber ku têkildarî [[dû]] û [[mayîn]] bawer kirine lewma. Bide ber [[farisî]] {{q|fa|افدم|tr=efdom|w=dawî}} ji [[pehlewî|farisiya navîn]] {{g|pal|tr=ebdum}}, ku bixwe ne ji [[heman]] [[reh]]ê ye (ji [[farisî|farisiya]] [[kevn]] *epetemeh, ji [[reh]]eke [[din]] a [[hindûewropî]] lê bi [[şaşî]] [[têkildar]]î {{g|pal|tr=dom|w=dûv}} kirine. ==== Werger ==== {{werger-ser}} * {{Z|de}}: {{W+|de|Ende|nt}}, {{W+|de|Schluss|n}} *: {{Z|gsw}}: {{W-|gsw|Endi}} * {{Z|as}}: {{W-|as|ওৰ}}, {{W-|as|শেষ}} * {{Z|ast}}: {{W+|ast|fin|n|m}} * {{Z|az}}: {{W+|az|son}}, {{W+|az|axır}}, {{W+|az|baş}} * {{Z|eu}}: {{W+|eu|amai}} * {{Z|ba}}: {{W-|ba|аҙаҡ|sc=Cyrl}} * {{Z|be}}: {{W-|be|кане́ц|n|sc=Cyrl}}, {{W-|be|край|n|sc=Cyrl}} * {{Z|br}}: {{W+|br|diwezh|n}} * {{Z|bg}}: {{W+|bg|край|n}} * {{Z|my}}: {{W+|my|အဆုံး}} * {{Z|cs}}: {{W+|cs|konec|n}} * {{Z|zh}}: *: {{Z|cmn}}: {{W+|cmn|結束|tr=jiéshù}}, {{W+|cmn|末尾|tr=mòwěi}}, {{W+|cmn|端|tr=duān}} * {{Z|cv}}: {{W-|cv|вӗҫ|sc=Cyrl}} * {{Z|dlm}}: {{W-|dlm|fain|n}} * {{Z|da}}: {{W+|da|ende}}, {{W+|da|afslutning}} * {{Z|id}}: {{W+|id|akhir}}, {{W+|id|ujung}} * {{Z|ar}}: {{W+|ar|نِهَايَة|m}}, {{W-|ar|غَايَة|m}} *: {{Z|arz}}: {{W-|arz|نهاية|m|tr=nehāya|sc=Arab}} *: {{Z|ary}}: {{W-|ary|خر|n|tr=ḵar}} * {{Z|hy}}: {{W+|hy|վերջ}}, {{W+|hy|ծայր}} * {{Z|eo}}: {{W+|eo|fino}} * {{Z|et}}: {{W+|et|lõpp}} * {{Z|eve}}: {{W-|eve|мудан}} * {{Z|evn}}: {{W-|evn|мудан}} * {{Z|ee}}: {{W-|ee|nuwuwu|nt}} * {{Z|fa}}: {{W+|fa|انتها|tr=entehâ}}, {{W+|fa|پایان|tr=pâyân|}}, {{W+|fa|آخر|tr=âxar|}} * {{Z|fi}}: {{W+|fi|pää}}, {{W+|fi|pääty}} ; {{W+|fi|loppu}} * {{Z|fr}}: {{W+|fr|fin|m}}, {{W+|fr|bout|n}}, {{W+|fr|extrémité|m}} * {{Z|fur}}: {{W-|fur|fin}} * {{Z|fy}}: {{W+|fy|ein}} * {{Z|gd}}: {{W-|gd|eàrr|n|m}} * {{Z|gl}}: {{W+|gl|fin|n|m}} * {{Z|got}}: {{W-|got|𐌰𐌽𐌳𐌴𐌹𐍃|n}} * {{Z|ka}}: {{W-|ka|დასასრული}}, {{W-|ka|ბოლო}}, {{W-|ka|მიწურული}} * {{Z|ht}}: {{W-|ht|fen}} * {{Z|hi}}: {{W+|hi|अंत|n|sc=Deva}} * {{Z|nl}}: {{W+|nl|einde|nt}}, {{W+|nl|uiteinde|nt}} * {{Z|he}}: {{W+|he|סוֹף|n|tr=sof|sc=Hebr}}, {{W+|he|קצה|n|tr=q'tzeh|lit=edge}} *: Îbranî: {{W-|lad|פין|m}} *: Latînî: {{W-|lad|fin}} * {{Z|io}}: {{W+|io|fino}} * {{Z|en}}: {{W+|en|end}} * {{Z|ist}}: {{W-|ist|feîn|n}} * {{Z|it}}: {{W+|it|fine|m}} * {{Z|is}}: {{W+|is|endir}} * {{Z|ja}}: {{W+|ja|終了|tr=shūryō|sc=Jpan}}, {{W+|ja|終わり|tr=owari|sc=Jpan}}, {{W-|ja|終い|tr=shimai|sc=Jpan}}, {{W+|ja|端|tr=hashi|sc=Jpan}}, {{W+|ja|最後|tr=saigo|sc=Jpan}}, {{W+|ja|エンド|tr=endo}} * {{Z|pam}}: {{W-|pam|danggut}}, {{W-|pam|sepu}} * {{Z|ca}}: {{W+|ca|fi|m}} * {{Z|ko}}: {{W+|ko|끝}}, {{W+|ko|종료}} * {{Z|lad}}: *: Îbranî: {{W-|lad|פ׳ין}}, {{W-|lad|קאב׳ו}} *: Latînî: {{W-|lad|fin|m}}, {{W-|lad|kavo|n}} * {{Z|ltg}}: {{W-|ltg|beigys}}, {{W-|ltg|gols|n}}, {{W-|ltg|pabeigys}} * {{Z|la}}: {{W+|la|finis|n|m}}, {{W+|la|terminus|n}}, {{W-|la|termen|nt}}, {{W-|la|exitus|n}}, {{W-|la|extremum|nt}}, {{W-|la|extremus|n}}, {{W-|la|peractio|m}}, {{W-|la|finalitas}} * {{Z|lv}}: {{W+|lv|gals|n}}, {{W-|lv|beigas|m-p}} * {{Z|lo}}: {{W-|lo|ຈົບ}} * {{Z|lt}}: {{W+|lt|pabaiga|m}}, {{W+|lt|galas|n}} * {{Z|lb}}: {{W-|lb|Enn|nt}} * {{Z|mk}}: {{W-|mk|крај|n|sc=Cyrl}} * {{Z|ms}}: {{W+|ms|akhir}}, {{W+|ms|hujung}}, {{W-|ms|هوجوڠ}} * {{Z|mt}}: {{W-|mt|tmiem}}, {{W-|mt|għeluq}} * {{Z|mnc}}: {{W-|mnc|ᡩᡠᠪᡝ}} * {{Z|gv}}: {{W-|gv|arbyl|n}} * {{Z|mi}}: {{W-|mi|hikutau}}, {{W-|mi|mutunga}}, {{W-|mi|paunga}} * {{Z|hu}}: {{W+|hu|vég}} * {{Z|mn}}: {{W+|mn|төгсгөл|sc=Cyrl}} * {{Z|gld}}: {{W-|gld|дуэ}}, {{W-|gld|модан}} * {{Z|nap}}: {{W-|nap|scompetura|m}} * {{Z|no}}: *: {{Z|nb}}: {{W+|nb|ende|n}}, {{W-|nb|slutt|n}} * {{Z|oc}}: {{W+|oc|fin}} * {{Z|om}}: {{W-|om|dhuma}} * {{Z|pl}}: {{W+|pl|koniec|n}} * {{Z|pt}}: {{W+|pt|fim}}, {{W+|pt|cabo|n}}, {{W+|pt|término|n}} * {{Z|rm}}: {{W-|rm|fin}}, {{W-|rm|fegn}} * {{Z|ro}}: {{W+|ro|sfârșit}}, {{W+|ro|terminație}}, {{W+|ro|capăt}} * {{Z|ru}}: {{W+|ru|коне́ц|n}}, {{W+|ru|край|n}} * {{Z|sa}}: {{W+|sa|अन्त|n|nt}}, {{W+|sa|समाप्ति|m}} * {{Z|sc}}: {{W-|sc|fine}}, {{W-|sc|fini}}, {{W-|sc|finis}} * {{Z|scn}}: {{W+|scn|fini}} * {{Z|sh}}: *: Kirîlî: {{W-|sh|крај|n|sc=Cyrl}} *: Latînî: {{W+|sh|kraj|n}} * {{Z|sk}}: {{W+|sk|koniec|n}} * {{Z|sl}}: {{W+|sl|konec|n}} * {{Z|so}}: {{W-|so|dhammaad}} * Sorbî: *: {{Z|dsb}}: {{W-|dsb|kóńc|n}} * {{Z|es}}: {{W+|es|fin|n|m}} * {{Z|sw}}: {{W+|sw|mwisho}}, {{W+|sw|ncha|c9|c10}}, {{W+|sw|tamati}} * {{Z|sv}}: {{W+|sv|slut}}, {{W+|sv|ände}} * {{Z|tg}}: {{W+|tg|охир}} * {{Z|tl}}: {{W-|tl|katapusan}}, {{W+|tl|dulo}} * {{Z|th}}: {{W+|th|จบ}} * {{Z|tr}}: {{W+|tr|son}} * {{Z|bo}}: {{W-|bo|མཇུག}} * {{Z|ur}}: {{W-|ur|انت|n|tr=ant|sc=ur-Arab}} * {{Z|uk}}: {{W+|uk|кіне́ць|n|sc=Cyrl}}, {{W+|uk|край|n|sc=Cyrl}} * {{Z|vec}}: {{W-|vec|fin|m}}, {{W+|vec|tèrmine|n}} * {{Z|vi}}: {{W+|vi|chóp}}, {{W+|vi|mút}} * {{Z|wa}}: {{W+|wa|fén|m}}, {{W+|wa|dibout|n}}, {{W+|wa|coron|n}} * {{Z|cy}}: {{W+|cy|diwedd}} * {{Z|km}}: {{W+|km|ចុង|tr=coŋ|sc=Khmr}} * {{Z|yai}}: {{W-|yai|охир}} * {{Z|yi}}: {{W-|yi|סוף|n|tr=sof}} * {{Z|el}}: {{W+|el|τέλος|nt}}, {{W+|el|πέρας|nt}}, {{W+|el|τέρμα|nt}}, {{W+|el|λήξη|m}}, {{W+|el|άκρο|nt}}, {{W+|el|άκρη|m}} *: Kevn: {{W-|grc|τελευτή|m}} {{werger-bin}} :{{werger çavkanî|en|end|beş=Ev qismê Wergerê|oldid=75874142}} 9pdage4sm54pwze0jaief6yj071lvx2 6265756 6265755 2026-07-20T06:07:37Z Wikihez 7344 /* */ bi [[MediaWiki:Gadget-AjaxEdit.js|AjaxEdit]]ê re 6265756 wikitext text/x-wiki == {{ziman|ku}} == === Bilêvkirin === * {{ku-IPA}} * {{deng|ku|LL-Q36163 (kmr)-Ebulfîda-dawî.wav|Deng|Bidlîs}} * {{ku-kîte}} === Navdêr === {{ku-tewîn-nav|dawî|mê}} {{navdêr|ku|z=m}} # [[talî]], [[soxî]], [[dûmahî]], [[encam]], [[akam]], [[netîce]], [[songî]] #: {{hevmane|ku|dawîng|axir|kutahî}} #: {{dijmane|ku|destpêk|bidayet|sereta|ibtida}} #: {{mk|ku|Û li '''dawiyê''' ew biser ketin.}} #* {{jêder|ku|jêgirtin=Bi wî awayî, maça wan bi yanzdeh û deh '''dawî''' hat.|{{Jêgirtin/Firat Cewerî/Girtî}}}} #* {{jêder|ku|jêgirtin=Wek serxweşek bê hiş''<br/>''Ketime riya çep û rast''<br/>''Qediya qediya''<br/>''Şeva '''dawî''' hejiya|[[w:Ciwan Haco|Ciwan Haco]], ''Dil Ketimê''}} #* {{jêder|ku|jêgirtin=Mala keçkê li taxa jorî ye''<br/>''Sewda daye, hêş nemaye''<br/>''Gotinên xelkê '''dawî''' naye|[[w:Xelîl Xemgîn|Xelîl Xemgîn]], ''Nîne Nîne''}} # [[paşîn]] #* {{jêder-pirtûk|ku|jêgirtin=...li '''dawîya''' rêzê...|nivîskar={{w|J.R.R. Tolkien}}|sernav=Hobbit|wergêr=Samî Hêzil|cîh=Enqere|weşanxane={{w|Weşanên Cervantes|Cervantes}}|sal=2023|çap=1|rûpel=72|isbn=9786257724838}} ==== Jê ==== {{kol3|ku|cure=Jê |bi dawî bûn<q:lêker> |bi dawî hatin<q:lêker> |bi dawî kirin |dawî anîn |dawî kirin |dawî dan |dawî bûn |bidawîbûn<q:navdêr> |bidawîhatin<q:navdêr> |bidawîkirin<q:navdêr> |dawîbûn |dawîanîn |dawîkirin |dawîdan |bidawîbûyî<q:rengdêr> |bidawîhatî<q:rengdêr> |bidawîkirî |dawîbûyî |dawîkirî |dawîn }} ==== Etîmolojî ==== Hevreha soranî {{g|ckb|دوای|tr=diwahî}}, dimilkî {{g|zza|dimayîn}}, {{g|zza|dimaîn}}, ji {{paş|ku|dûv|-ahî}}.. Guherîna dengî dibe ku wisan bûbe: *divahî > bi [[metatez|metatezê]] *dihavî > -ih- dikeve wekî di *çihar>çar de û dibe *davî û > *dahî>dawî. Bo h>v/w di kurmanciyan de binêre soranî {{g|ckb|چوار|w=[[çwar|çiWar]]}}, {{g|ckb|نواڕین|tr=niWarrîn|w=[[nihêrîn]]}}, [[şirove]]... Bo guherîna v>h/w binêre [[bawer]]. Li devera Badînan wek "[[dûmahîk]]" maye, mihtemelen ji ber ku têkildarî [[dû]] û [[mayîn]] bawer kirine lewma. Bide ber [[farisî]] {{q|fa|افدم|tr=efdom|w=dawî}} ji [[pehlewî|farisiya navîn]] {{g|pal|tr=ebdum}}, ku bixwe ne ji [[heman]] [[reh]]ê ye (ji [[farisî|farisiya]] [[kevn]] *epetemeh, ji [[reh]]eke [[din]] a [[hindûewropî]] lê bi [[şaşî]] [[têkildar]]î {{g|pal|tr=dom|w=dûv}} kirine. ==== Werger ==== {{werger-ser}} * {{Z|de}}: {{W+|de|Ende|nt}}, {{W+|de|Schluss|n}} *: {{Z|gsw}}: {{W-|gsw|Endi}} * {{Z|as}}: {{W-|as|ওৰ}}, {{W-|as|শেষ}} * {{Z|ast}}: {{W+|ast|fin|n|m}} * {{Z|az}}: {{W+|az|son}}, {{W+|az|axır}}, {{W+|az|baş}} * {{Z|eu}}: {{W+|eu|amai}} * {{Z|ba}}: {{W-|ba|аҙаҡ|sc=Cyrl}} * {{Z|be}}: {{W-|be|кане́ц|n|sc=Cyrl}}, {{W-|be|край|n|sc=Cyrl}} * {{Z|br}}: {{W+|br|diwezh|n}} * {{Z|bg}}: {{W+|bg|край|n}} * {{Z|my}}: {{W+|my|အဆုံး}} * {{Z|cs}}: {{W+|cs|konec|n}} * {{Z|zh}}: *: {{Z|cmn}}: {{W+|cmn|結束|tr=jiéshù}}, {{W+|cmn|末尾|tr=mòwěi}}, {{W+|cmn|端|tr=duān}} * {{Z|cv}}: {{W-|cv|вӗҫ|sc=Cyrl}} * {{Z|dlm}}: {{W-|dlm|fain|n}} * {{Z|da}}: {{W+|da|ende}}, {{W+|da|afslutning}} * {{Z|id}}: {{W+|id|akhir}}, {{W+|id|ujung}} * {{Z|ar}}: {{W+|ar|نِهَايَة|m}}, {{W-|ar|غَايَة|m}} *: {{Z|arz}}: {{W-|arz|نهاية|m|tr=nehāya|sc=Arab}} *: {{Z|ary}}: {{W-|ary|خر|n|tr=ḵar}} * {{Z|hy}}: {{W+|hy|վերջ}}, {{W+|hy|ծայր}} * {{Z|eo}}: {{W+|eo|fino}} * {{Z|et}}: {{W+|et|lõpp}} * {{Z|eve}}: {{W-|eve|мудан}} * {{Z|evn}}: {{W-|evn|мудан}} * {{Z|ee}}: {{W-|ee|nuwuwu|nt}} * {{Z|fa}}: {{W+|fa|انتها|tr=entehâ}}, {{W+|fa|پایان|tr=pâyân|}}, {{W+|fa|آخر|tr=âxar|}} * {{Z|fi}}: {{W+|fi|pää}}, {{W+|fi|pääty}} ; {{W+|fi|loppu}} * {{Z|fr}}: {{W+|fr|fin|m}}, {{W+|fr|bout|n}}, {{W+|fr|extrémité|m}} * {{Z|fur}}: {{W-|fur|fin}} * {{Z|fy}}: {{W+|fy|ein}} * {{Z|gd}}: {{W-|gd|eàrr|n|m}} * {{Z|gl}}: {{W+|gl|fin|n|m}} * {{Z|got}}: {{W-|got|𐌰𐌽𐌳𐌴𐌹𐍃|n}} * {{Z|ka}}: {{W-|ka|დასასრული}}, {{W-|ka|ბოლო}}, {{W-|ka|მიწურული}} * {{Z|ht}}: {{W-|ht|fen}} * {{Z|hi}}: {{W+|hi|अंत|n|sc=Deva}} * {{Z|nl}}: {{W+|nl|einde|nt}}, {{W+|nl|uiteinde|nt}} * {{Z|he}}: {{W+|he|סוֹף|n|tr=sof|sc=Hebr}}, {{W+|he|קצה|n|tr=q'tzeh|lit=edge}} *: Îbranî: {{W-|lad|פין|m}} *: Latînî: {{W-|lad|fin}} * {{Z|io}}: {{W+|io|fino}} * {{Z|en}}: {{W+|en|end}} * {{Z|ist}}: {{W-|ist|feîn|n}} * {{Z|it}}: {{W+|it|fine|m}} * {{Z|is}}: {{W+|is|endir}} * {{Z|ja}}: {{W+|ja|終了|tr=shūryō|sc=Jpan}}, {{W+|ja|終わり|tr=owari|sc=Jpan}}, {{W-|ja|終い|tr=shimai|sc=Jpan}}, {{W+|ja|端|tr=hashi|sc=Jpan}}, {{W+|ja|最後|tr=saigo|sc=Jpan}}, {{W+|ja|エンド|tr=endo}} * {{Z|pam}}: {{W-|pam|danggut}}, {{W-|pam|sepu}} * {{Z|ca}}: {{W+|ca|fi|m}} * {{Z|ko}}: {{W+|ko|끝}}, {{W+|ko|종료}} * {{Z|lad}}: *: Îbranî: {{W-|lad|פ׳ין}}, {{W-|lad|קאב׳ו}} *: Latînî: {{W-|lad|fin|m}}, {{W-|lad|kavo|n}} * {{Z|ltg}}: {{W-|ltg|beigys}}, {{W-|ltg|gols|n}}, {{W-|ltg|pabeigys}} * {{Z|la}}: {{W+|la|finis|n|m}}, {{W+|la|terminus|n}}, {{W-|la|termen|nt}}, {{W-|la|exitus|n}}, {{W-|la|extremum|nt}}, {{W-|la|extremus|n}}, {{W-|la|peractio|m}}, {{W-|la|finalitas}} * {{Z|lv}}: {{W+|lv|gals|n}}, {{W-|lv|beigas|m-p}} * {{Z|lo}}: {{W-|lo|ຈົບ}} * {{Z|lt}}: {{W+|lt|pabaiga|m}}, {{W+|lt|galas|n}} * {{Z|lb}}: {{W-|lb|Enn|nt}} * {{Z|mk}}: {{W-|mk|крај|n|sc=Cyrl}} * {{Z|ms}}: {{W+|ms|akhir}}, {{W+|ms|hujung}}, {{W-|ms|هوجوڠ}} * {{Z|mt}}: {{W-|mt|tmiem}}, {{W-|mt|għeluq}} * {{Z|mnc}}: {{W-|mnc|ᡩᡠᠪᡝ}} * {{Z|gv}}: {{W-|gv|arbyl|n}} * {{Z|mi}}: {{W-|mi|hikutau}}, {{W-|mi|mutunga}}, {{W-|mi|paunga}} * {{Z|hu}}: {{W+|hu|vég}} * {{Z|mn}}: {{W+|mn|төгсгөл|sc=Cyrl}} * {{Z|gld}}: {{W-|gld|дуэ}}, {{W-|gld|модан}} * {{Z|nap}}: {{W-|nap|scompetura|m}} * {{Z|no}}: *: {{Z|nb}}: {{W+|nb|ende|n}}, {{W-|nb|slutt|n}} * {{Z|oc}}: {{W+|oc|fin}} * {{Z|om}}: {{W-|om|dhuma}} * {{Z|pl}}: {{W+|pl|koniec|n}} * {{Z|pt}}: {{W+|pt|fim}}, {{W+|pt|cabo|n}}, {{W+|pt|término|n}} * {{Z|rm}}: {{W-|rm|fin}}, {{W-|rm|fegn}} * {{Z|ro}}: {{W+|ro|sfârșit}}, {{W+|ro|terminație}}, {{W+|ro|capăt}} * {{Z|ru}}: {{W+|ru|коне́ц|n}}, {{W+|ru|край|n}} * {{Z|sa}}: {{W+|sa|अन्त|n|nt}}, {{W+|sa|समाप्ति|m}} * {{Z|sc}}: {{W-|sc|fine}}, {{W-|sc|fini}}, {{W-|sc|finis}} * {{Z|scn}}: {{W+|scn|fini}} * {{Z|sh}}: *: Kirîlî: {{W-|sh|крај|n|sc=Cyrl}} *: Latînî: {{W+|sh|kraj|n}} * {{Z|sk}}: {{W+|sk|koniec|n}} * {{Z|sl}}: {{W+|sl|konec|n}} * {{Z|so}}: {{W-|so|dhammaad}} * Sorbî: *: {{Z|dsb}}: {{W-|dsb|kóńc|n}} * {{Z|es}}: {{W+|es|fin|n|m}} * {{Z|sw}}: {{W+|sw|mwisho}}, {{W+|sw|ncha|c9|c10}}, {{W+|sw|tamati}} * {{Z|sv}}: {{W+|sv|slut}}, {{W+|sv|ände}} * {{Z|tg}}: {{W+|tg|охир}} * {{Z|tl}}: {{W-|tl|katapusan}}, {{W+|tl|dulo}} * {{Z|th}}: {{W+|th|จบ}} * {{Z|tr}}: {{W+|tr|son}} * {{Z|bo}}: {{W-|bo|མཇུག}} * {{Z|ur}}: {{W-|ur|انت|n|tr=ant|sc=ur-Arab}} * {{Z|uk}}: {{W+|uk|кіне́ць|n|sc=Cyrl}}, {{W+|uk|край|n|sc=Cyrl}} * {{Z|vec}}: {{W-|vec|fin|m}}, {{W+|vec|tèrmine|n}} * {{Z|vi}}: {{W+|vi|chóp}}, {{W+|vi|mút}} * {{Z|wa}}: {{W+|wa|fén|m}}, {{W+|wa|dibout|n}}, {{W+|wa|coron|n}} * {{Z|cy}}: {{W+|cy|diwedd}} * {{Z|km}}: {{W+|km|ចុង|tr=coŋ|sc=Khmr}} * {{Z|yai}}: {{W-|yai|охир}} * {{Z|yi}}: {{W-|yi|סוף|n|tr=sof}} * {{Z|el}}: {{W+|el|τέλος|nt}}, {{W+|el|πέρας|nt}}, {{W+|el|τέρμα|nt}}, {{W+|el|λήξη|m}}, {{W+|el|άκρο|nt}}, {{W+|el|άκρη|m}} *: Kevn: {{W-|grc|τελευτή|m}} {{werger-bin}} :{{werger çavkanî|en|end|beş=Ev qismê Wergerê|oldid=75874142}} 7q5db94km2vgtxzsnimnkijqgp9ro7j grûp 0 7936 6265718 6262578 2026-07-20T01:09:24Z Wikihez 7344 6265718 wikitext text/x-wiki == {{ziman|ku}} == === Bilêvkirin === * {{ku-IPA}} * {{ku-kîte}} === Navdêr === {{ku-tewîn-nav|grûp|mê}} {{navdêr|ku|z=m}} # [[çendîn|Çendîn]] kes yan tişt bi hev re, [[gelek]] kes yan tişt li gel hev. #: {{hevmane|ku|kom|ref|celeb|kerî}} #* {{bêmînak|ku}} # {{kontrol|rêz=erê|[[revde]], [[bir]], [[hoz]], [[koz]], [[ajal]], [[col]], [[colek]]}} #* {{bêmînak|ku}} ==== Formên alternatîv ==== {{kol3|ku|cure=Herwiha | girob | girop | grob | grop | girub | girup | grub | grup | girûb | girûp | grûb | gurob | gurop | gurub | gurup | gurûb | gurûp }} ==== Jê ==== {{kol3|ku | grûpane | grûp-grûp | grûpî }} ==== Etîmolojî ==== Bi riya fransî {{q|ku|groupe}} lê fransî jî bixwe ji îtalî deyn kiriye. Ji îtalî {{q|it|gruppo|w=[[girê]]}} û ji jermenî 'kruppa'( girseya gilover, koma gilover) û girêk ya kurdî bi peyva 'groupe' ra hevreh e. ==== Werger ==== {{werger-ser}} * {{Z|de}}: {{W|de|Gang}} {{m}}, {{W|de|Partie|guman=erê}} {{m}}, {{W|de|Trupp|guman=erê}} {{n}} * {{Z|ar}}: {{W|ar|طاقم|guman=erê}} * {{Z|fa}}: {{W|fa|گروه}} * {{Z|en}}: {{W|en|bloc}}, {{W|en|group}}, {{W|en|league}}, {{W|en|team}} * {{Z|tr}}: {{W|tr|fraksiyon}}, {{W|tr|kitle}}, {{W|tr|koz}}, {{W|tr|lig}}, {{W|tr|grup|guman=erê}} {{werger-bin}} {{kontrolWergerr}} d08of5f0f4hr0x71us7k2sqn5t06c1a bixar 0 8254 6265703 6249792 2026-07-19T23:24:47Z Bikarhêner 3719 6265703 wikitext text/x-wiki == {{ziman|ku}} == === Bilêvkirin === * {{ku-IPA}} * {{ku-kîte}} === Navdêr === {{ku-tewîn-nav|bixar|mê}} {{navdêr|ku|z=m}} # [[av|Av]]a [[kel]] ya ku dibe [[gaz]] û [[hilketin|hildikeve]]. #: {{hevmane|ku|hilm|dûxan}} #* {{bêmînak|ku}} ==== Bi alfabeyên din ==== * {{ku-ar|بخار}} ==== Formên alternatîv ==== * {{g|ku|buxar}} * {{g|ku|bûx}} ==== Jê ==== {{stûn| * {{mj|Lêker}} bûn bixar * kirin bixar * {{mj|Navdêr}} {{g|ku|bixarbûn}} * {{mj|Navdêr}} {{g|ku|bixarkirin}} * {{mj|Rengdêr}} {{g|ku|bixarbûyî}} * {{mj|Rengdêr}} {{g|ku|bixarkirî}} * {{g|ku|bibixar}} * {{g|ku|bibixarî}} * {{g|ku|bixarî}} * {{g|ku|bixardar}} * {{g|ku|bixardarî}} }} ==== Etîmolojî ==== Ji {{deyn|ar|ku|بخار|tr=buxar}}, hevreha aramî (bi [[metatez]]ê) [[ܚܒܘܪܐ]] (xebbura), {{hv|akk||buxru|sc=Latn}} ==== Werger ==== {{werger-ser}} * {{Z|de}}: {{W+|de|Dampf|guman=erê}} {{n}} * {{Z|fi}}: {{W+|fi|höyry}} * {{Z|en}}: {{W+|en|steam}}, {{W+|en|vapor}}, {{W+|en|vapour}} * {{Z|tr}}: {{W+|tr|buhar}} {{werger-bin}} === Rengdêr === {{rengdêr|ku}} # [[bilez]], [[hêl]], [[seri]], [[lezgîn]], [[zû]], [[xêra]], [[acil]], bi [[pele]] #* {{bêmînak|ku}} ==== Bi alfabeyên din ==== * {{ku-ar|ب غار}} ==== Etîmolojî ==== Ji {{pêş|ku|bi-|xar}}. ==== Werger ==== {{werger-ser}} * {{Z|en}}: {{W+|en|quickly}}, {{W+|en|fast}}, {{W+|en|hurry}} {{werger-bin}} === Hoker === {{hoker|ku}} # {{rastnivîs|ku|bi xar}} #* {{bêmînak|ku}} 3plnwzv3p3ciefdbu7r23nrb8jk5plg 6265704 6265703 2026-07-19T23:40:21Z Wikihez 7344 /* Jê */ 6265704 wikitext text/x-wiki == {{ziman|ku}} == === Bilêvkirin === * {{ku-IPA}} * {{ku-kîte}} === Navdêr === {{ku-tewîn-nav|bixar|mê}} {{navdêr|ku|z=m}} # [[av|Av]]a [[kel]] ya ku dibe [[gaz]] û [[hilketin|hildikeve]]. #: {{hevmane|ku|hilm|dûxan}} #* {{bêmînak|ku}} ==== Bi alfabeyên din ==== * {{ku-ar|بخار}} ==== Formên alternatîv ==== * {{g|ku|buxar}} * {{g|ku|bûx}} ==== Jê ==== {{kol3|ku|cure=Jê|cure=Jê |bûn bixar<crz:lêker> |kirin bixar<crz:lêker> |bixarbûn<q:navdêr> |bixarkirin<q:navdêr> |bixarbûyî<q:rengdêr> |bixarkirî<q:rengdêr> |bibixar |bibixarî |bixarî |bixardar |bixardarî }} ==== Etîmolojî ==== Ji {{deyn|ar|ku|بخار|tr=buxar}}, hevreha aramî (bi [[metatez]]ê) [[ܚܒܘܪܐ]] (xebbura), {{hv|akk||buxru|sc=Latn}} ==== Werger ==== {{werger-ser}} * {{Z|de}}: {{W+|de|Dampf|guman=erê}} {{n}} * {{Z|fi}}: {{W+|fi|höyry}} * {{Z|en}}: {{W+|en|steam}}, {{W+|en|vapor}}, {{W+|en|vapour}} * {{Z|tr}}: {{W+|tr|buhar}} {{werger-bin}} === Rengdêr === {{rengdêr|ku}} # [[bilez]], [[hêl]], [[seri]], [[lezgîn]], [[zû]], [[xêra]], [[acil]], bi [[pele]] #* {{bêmînak|ku}} ==== Bi alfabeyên din ==== * {{ku-ar|ب غار}} ==== Etîmolojî ==== Ji {{pêş|ku|bi-|xar}}. ==== Werger ==== {{werger-ser}} * {{Z|en}}: {{W+|en|quickly}}, {{W+|en|fast}}, {{W+|en|hurry}} {{werger-bin}} === Hoker === {{hoker|ku}} # {{rastnivîs|ku|bi xar}} #* {{bêmînak|ku}} k2n8if3f0qw9iyrvf6kb8f4atj9g180 xweda 0 8316 6265775 5893085 2026-07-20T08:07:05Z Wikihez 7344 /* */ bi [[MediaWiki:Gadget-AjaxEdit.js|AjaxEdit]]ê re 6265775 wikitext text/x-wiki {{bnr-h|Xweda}} == {{ziman|ku}} == === Bilêvkirin === * {{ku-IPA}} * {{deng|ku|LL-Q36163 (kmr)-Ebulfîda-xweda.wav|Deng|Bidlîs}} * {{ku-kîte}} === Navdêr === {{navdêr|ku}} # {{guharto|ku|Xwedê}} #* {{bêmînak|ku}} kwiab5fg90yido71a8hseisrra90ef3 êxsîr 0 8601 6265801 5015584 2026-07-20T08:27:10Z Wikihez 7344 /* Navdêr */ 6265801 wikitext text/x-wiki == {{ziman|ku}} == === Navdêr === {{navdêr|ku|z=mn}} # {{bnr|esîr}} #* {{jêder|ku|jêgirtin=Biner daxa me '''êxsîra''' xezal zerbûn rezê mîra, Rîhan barî di avê da rîhan barî di eywanê|[[w:Mela Hisênê Bateyî]]}} 11tepfbcnhy9vtk6oxvv16qr0yzdhlg binavûdeng 0 8764 6265854 6263043 2026-07-20T10:32:29Z Wikihez 7344 /* Rengdêr */ [[Bikarhêner:Wikihez/templateScript2.js|TS]]: sererastkirin 6265854 wikitext text/x-wiki == {{ziman|ku}} == === Bilêvkirin === * {{ku-kîte}} === Rengdêr === {{ku-tewîn-rd|binavûdeng}} {{rengdêr|ku}} # Kesê yan tişta/ê pirr tê [[nasîn]]. #: {{hevmane|ku|navdar|nas|naskirî|meşhûr|bernas|meşûr}} #* {{bêmînak|ku}} ==== Formên alternatîv ==== {{kol3|ku |bi nav û deng |bi navûdeng }} ==== Jê ==== {{kol3|ku|cure=Jê |binavûdeng bûn<pos:lêker> |binavûdeng kirin<pos:lêker> |binavûdengbûn<pos:navdêr> |binavûdengkirin<pos:navdêr> |binavûdengbûyî<pos:rengdêr> |binavûdengkirî<pos:rengdêr> |binavûdengî |binavûdengîtî |binavûdengtî }} ==== Etîmolojî ==== Ji {{qf|ku|bi-|nav|û|deng}}. ==== Werger ==== {{werger-ser}} * {{Z|de}}: {{W+|de|bekannt}}, {{W+|de|beliebt}}, {{W+|de|berühmt}}, {{W+|de|gängig|guman=erê}}, {{W+|de|offenkundig|guman=erê}} * {{Z|ar}}: {{W+|ar|مشهور|guman=erê}} * {{Z|fa}}: {{W+|fa|مشهور}}, {{W+|fa|معروف}} * {{Z|en}}: {{W+|en|celebrated}}, {{W+|en|illustrious}}, {{W+|en|well known}}, {{W+|en|celebrity|guman=erê}}, {{W+|en|renowned|guman=erê}}, {{W+|en|reputed|guman=erê}} * {{Z|tr}}: {{W+|tr|adlı}}, {{W+|tr|anlı şanlı}}, {{W+|tr|sanlı}}, {{W+|tr|şöhretli}}, {{W+|tr|meşhur}}, {{W+|tr|tanınmış}}, {{W+|tr|ünlü}}, {{W+|tr|şanlı}} {{werger-bin}} tbypet197csy5oxmwok064p1t3d7wfh qebûl 0 9190 6265794 6262325 2026-07-20T08:19:49Z Wikihez 7344 /* */ bi [[MediaWiki:Gadget-AjaxEdit.js|AjaxEdit]]ê re 6265794 wikitext text/x-wiki == {{ziman|ku}} == === Bilêvkirin === * {{ku-kîte}} === Rengdêr === {{ku-tewîn-rd|qebûl}} {{rengdêr|ku}} # Kesa/ê yan tişta/ê [[destûr]] bo hatiye dan; kesa/ê yan tişta/ê [[rê]] lê nehatiye [[girtin]]. #: {{hevmane|ku|pejirandî}} #* {{Jêgirtin/Mela Hisênê Bateyî/Mewlûda Kurdî|jêgirtin=Hurmeta navê Muhemmed an Resûl<br />Tewbeya te bû '''qebûl''' û her '''qebûl'''.<br />Ger divêtin hûn ji narê bin necat}} ==== Formên alternatîv ==== {{kol3|ku|cure=Herwiha |qabûl |qebîl |qebwîl }} ==== Dijmane ==== * {{g|ku|red}} ==== Bide ber ==== * {{g|ku|qedexe}} ==== Jê ==== {{kol3|ku|cure=Jê |qebûl bûn<pos:lêker> |qebûl kirin<pos:lêker> |qebûlkirin<pos:navdêr> |qebûlbûn<pos:navdêr> |qebûlbûyî<pos:rengdêr> |qebûlkirî<pos:rengdêr> |qebilandin |qebilandî |qebilînerî }} ==== Etîmolojî ==== Ji {{deyn|ar|ku|قِبُول}}. ==== Werger ==== {{werger-ser}} * {{Z|de}}: {{W-|de|in Ordnung}}, {{W+|de|einlenken}}, {{W+|de|Akzeptanz|guman=erê}}, {{W+|de|Annahme|guman=erê}}, {{W+|de|Aufnahme|guman=erê}}, {{W+|de|Zulassung|guman=erê}} * {{Z|fa}}: {{W+|fa|اعتراف}}, {{W+|fa|پذیرش}}, {{W+|fa|پسند}}, {{W+|fa|تأیید}}, {{W+|fa|قبول}} * {{Z|en}}: {{W+|en|recognizance}}, {{W+|en|acceptation}}, {{W+|en|admission}}, {{W+|en|assent}}, {{W+|en|presumption}}, {{W+|en|recognition}}, {{W+|en|ditto|guman=erê}}, {{W+|en|word up|guman=erê}} * {{Z|sv}}: {{W+|sv|godkännande}} * {{Z|tr}}: {{W+|tr|kabul}}, {{W+|tr|resepsiyon}} {{werger-bin}} lozu35yypts0z1z3hekvbtkq6oahzpd mizgînî 0 10081 6265829 6107493 2026-07-20T09:14:30Z Wikihez 7344 /* */ bi [[MediaWiki:Gadget-AjaxEdit.js|AjaxEdit]]ê re 6265829 wikitext text/x-wiki {{bnr-h|Mizgînî}} == {{ziman|ku}} == === Navdêr === {{navdêr|ku|z=m}} # Xelata ji bo [[mizgîn]]ê #: ''Min mizgîn da te, ka mizgîniya min?'' # {{bnr|mizgîn}} #: ''Her kesê guhdarê Mewlûda Nebî''</br>''Dergehê '''mizgîniyan''' dê lê vebî'' — ([[w:Mela Hisênê Bateyî|Mela Hisênê Bateyî]]) ==== Bi alfabeyên din ==== * {{ku-ar|مزگینی}} ==== Werger ==== {{werger-ser}} * {{Z|en}}: {{W-|en|[[reward|the reward for bringing good news]] (1)}}, {{W-|en|[[good news|good news (2)]]}} {{werger-bin}} et3jmaq5c84u3jgbgsgqda86ifvjgsx zeft 0 13063 6265762 6262607 2026-07-20T06:41:41Z Bikarhêner 3719 /* */ bi [[MediaWiki:Gadget-AjaxEdit.js|AjaxEdit]]ê re 6265762 wikitext text/x-wiki == {{ziman|ku}} == === Bilêvkirin === * {{ku-kîte}} === Rengdêr === {{ku-tewîn-rd|zeft}} {{rengdêr|ku}} # [[girtî]], [[şidandî]], [[şidayî]], ne [[berdayî]] #* {{bêmînak|ku}} ==== Formên alternatîv ==== {{kol3|ku|cure=Herwiha |zemt |zevt |zebt |zept |zep }} ==== Jê ==== {{kol3|ku|cure=Jê |zeft kirin<pos:lêker> |zeftbûn<pos:navdêr> |zeftkirin<pos:navdêr> |zeftbûyî<pos:rengdêr> |zeftkirî<pos:rengdêr> |zeftî |zeftker }} ==== Etîmolojî ==== Ji {{deyn|ar|ku|ضبط|cuda=ضَبْط|w=zeft}} ji lêkera {{g|ar|ضبط|cuda=ضَبَطَ|w=[[girtin]], zeft kirin}}, hevreha ''[[zabit]]'', ''[[mezbût]]''... Herwiha hevrehên [[akadî]] ''ṣabtu, ṣabātu, ṣābitānu, ṣābitu, ṣabbutītu''. ==== Werger ==== {{werger-ser}} * {{Z|de}}: {{W+|de|Eroberung|f}}, {{W+|de|Einnahme|guman=erê}}, {{W+|de|Repression|guman=erê}} * {{Z|ar}}: {{W+|ar|ضبط}}, {{W-|ar|سيطرة}} * {{Z|fa}}: {{W-|fa|رها نکردن}}, {{W-|fa|محکم گرفتن}}, {{W+|fa|ضبط|guman=erê}} * {{Z|tr}}: {{W+|tr|ceride}}, {{W+|tr|zabıt}}, {{W+|tr|zapt}} {{werger-bin}} 9h33einkkn8oaem9tjvadwbaw8tf310 serf 0 13879 6265844 6242840 2026-07-20T09:27:38Z Wikihez 7344 /* */ bi [[MediaWiki:Gadget-AjaxEdit.js|AjaxEdit]]ê re 6265844 wikitext text/x-wiki == {{ziman|ku}} == === Bilêvkirin === * {{IPA|ku|/sɛɾf/}} * {{ku-kîte}} === Navdêr === {{ku-tewîn-nav|serf|mê}} {{navdêr|ku|z=m}} # [[bikaranîn|Bikaranîn]]a [[mal]]î yan [[pare]]yî; [[pûç]]kirin(a [[mal]]î yan [[pare]]yî; [[xwarin]]a [[mal]]î yan [[pare]]yî. #: {{hevmane|ku|lêçûn|xerc|mesref|misref}} #* {{bêmînak|ku}} # {{f|ku|rêzimanî|bi taybetî|rêzimana erebî}} [[morfolojî|Morfolojî]]. #* {{bêmînak|ku}} ==== Ji wêjeya klasîk ==== * {{jêder|ku|{{Jêgirtin/Mela Hisênê Bateyî/Mewlûda Kurdî}}|jêgirtin=Serfê Mewlûda me yek derhem fere</br>Hemberê yek guhê zêrê ehmere}} ==== Formên alternatîv ==== * {{g|ku|serif}} ==== Bide ber ==== * {{g|ku|zerf}} ==== Jê ==== {{kol3|ku|cure=Jê |serf bûn<pos:lêker> |serf kirin<pos:lêker> |serfbûn<pos:navdêr> |serfkirin<pos:navdêr> |serfbûyî<pos:rengdêr> |serfkirî<pos:rengdêr> |serifandin |serifandî |serifî |serifîn }} ==== Etîmolojî ==== Ji {{deyn|ar|ku|صرف}} (ș-r-f-: serf kirin; [[zivirandin]], [[wergerrandin]], [[vegerrandin]]), têkilî [[sirf]], [[mesref]], [[seraf]]... ==== Werger ==== {{werger-ser|[[lêçûn]], [[xerc]], [[mesref]]|1}} * {{Z|de}}: {{W+|de|Aufwendung|f|guman=erê}} * {{Z|fa}}: {{W+|fa|ضایع|guman=erê}} * {{Z|en}}: {{W+|en|expenditure}}, {{W+|en|expense}} {{werger-bin}} == {{ziman|fr}} == === Navdêr === {{navdêr|fr|z=n}} # {{g|ku|kole}}, {{g|ku|benî}}, {{g|ku|bende}} #* {{bêmînak|fr}} === Çavkanî === {{rûpela wergerê|fr|kole}} == {{ziman|en}} == === Navdêr === {{navdêr|en}} # [[benî]], [[bende]], [[kolî]], [[zêrkirrî]] <ref>Ferhenga Kurdî-Îngîlîzî ya Salah Sadallah</ref> #* {{bêmînak|en}} ==== Çavkanî ==== {{çavkanî}} oet7cgw4iahto626gafdnb4xyqvfc2v zelût 0 14063 6265739 6244248 2026-07-20T05:48:59Z Wikihez 7344 /* Jê */ 6265739 wikitext text/x-wiki == {{ziman|ku}} == === Bilêvkirin === * {{ku-kîte}} === Rengdêr === {{ku-tewîn-rd|zelût}} {{rengdêr|ku}} # [[rût]], [[tazî]], [[çîp]], [[rûs]], [[verûtandî]], [[verûçikandî]], [[bêpûrt]], [[bêmû]] #* {{jêder|ku|jêgirtin=Tê ragihandin ku stêrka Popê Britney Spears piştî ku ji mêrê xwe Kevin Faderline veqetiyaye ketiye depresyonê û nuha jî serê xwe '''zilût''' kir. Li gor hin agahiyan Britney Spears piştî ku porrê xwe jêkiriye çûye nexweşxanê û li wir alîkarî xwestiye û giriye.|Netkurd.com, 2/2007}} ==== Formên alternatîv ==== * {{g|ku|zelît}} * {{g|ku|zelwît}} * {{g|ku|zilût}} * {{g|ku|zilît}} * {{g|ku|zilwît}} ==== Bide ber ==== * {{g|ku|zil}} ==== Jê ==== {{kol3|ku|cure=Jê |zelût bûn<q:lêker> |zelût kirin<q:lêker> |zelûtbûn<q:navdêr> |zelûtkirin<q:navdêr> |zelûtbûyî<q:rengdêr> |zelûtkirî<q:rengdêr> |zelitandin |zelitandî |zelitiyayî |zelitî |zelitîn |zelitîner |zelûtî }} ==== Etîmolojî ==== {{bêetîmolojî}} ==== Werger ==== {{werger-ser}} * {{Z|de}}: {{W+|de|kahl}} * {{Z|fa}}: {{W+|fa|بیمو}}, {{W+|fa|کچل}}, {{W+|fa|بی مو}} * {{Z|en}}: {{W+|en|stripped}} * {{Z|tr}}: {{W+|tr|cascavlak}}, {{W+|tr|cavlak}}, {{W+|tr|dazlak}}, {{W+|tr|tüysüz}}, {{W+|tr|badik}} {{werger-bin}} c2r57i0vjelovb81bt16grxhz4q15rd hed 0 14847 6265803 6243137 2026-07-20T08:29:32Z Wikihez 7344 /* {{ziman|ku}} */ [[Bikarhêner:Wikihez/templateScript2.js|TS]]: sererastkirin 6265803 wikitext text/x-wiki == {{ziman|ku}} == === Bilêvkirin === * {{ku-IPA}} * {{ku-kîte}} === Navdêr === {{navdêr|ku|z=n}} # [[sinor]], [[hidûd]], [[tixûb]], [[merz]] #* {{Jêgirtin/Mela Hisênê Bateyî/Mewlûda Kurdî|jêgirtin=Çûn di erdê da û pa û mayî mat</br>Pirr girî û xweş girî bê '''hed''' gelek}} # [[hesp|Hesp]], [[kihêl]] #* {{jêder-kitêb|ku|nivîskar=Fêrîkê Ûsiv|sernav=Hemû Berhemên Wî|cild= II|jêgirtin=Û baz dide ser '''hed'''ekî, </br>Ser '''hed'''ekî kumêtekî.}} ==== Formên alternatîv ==== * {{g|ku|ḧed}} ==== Bide ber ==== * {{g|ku|hemd}} ==== Jê ==== {{kol3|ku|cure=Jê |bêhed |bêhedî |bihed |bihedî |hednas |hednasî |hednenas |hednenasî |hednezan |hednezanî |hedzan |hedzanî |hed kirin<pos:lêker> |hed danîn<pos:lêker> |hedkirin<pos:navdêr> |heddanîn<pos:navdêr> |hedkirî<pos:rengdêr> }} ==== Etîmolojî ==== Deyn ji {{deyn|fa|ku|حد}}, ji {{ji|ar|ku|حَدّ}}. ==== Werger ==== {{werger-ser}} * {{Z|de}}: {{W|de|Ende|n}} * {{Z|ar}}: {{W|ar|النیاط|guman=erê}} * {{Z|fa}}: {{W+|fa|حد}} * {{Z|en}}: {{W+|en|extent}}, {{W+|en|limit}}, {{W+|en|perimeter}} * {{Z|tr}}: {{W+|tr|limit}}, {{W+|tr|sınır}}, {{W+|tr|tol}}, {{W+|tr|had}}, {{W+|tr|kapak taşıl}}, {{W+|tr|kapak taşı|guman=erê}} {{werger-bin}} 5hk37kxvy0p24svwshunv0kmylemr80 hêvîdar 0 15388 6265842 6243390 2026-07-20T09:25:49Z Wikihez 7344 6265842 wikitext text/x-wiki == {{ziman|ku}} == === Bilêvkirin === * {{ku-kîte}} === Rengdêr === {{ku-tewîn-rd|hêvîdar}} {{rengdêr|ku}} # Kesê [[hêvî]] dike. #: {{nm|ku|Ez '''hêvîdar''' im ku tu alîkariya me bikî.}} # Kesê [[hêvî]] heye. #: {{hevmaneyên peyvê|ku|bihêvî|xweşbîn|optîmîst|geşbîn}} #: {{nm|ku|Em herdem ji azadbûnê '''hêvîdar''' in.}} #* {{Jêgirtin/Mela Hisênê Bateyî/Mewlûda Kurdî|jêgirtin='''Hêvîdar''' in em ji te, Şahê Kerîm<br />Îhdîna, ya Reb, sîratel musteqîm}} ==== Formên alternatîv ==== * {{g|ku|hîvîdar}} ==== Hevmane ==== * {{g|ku|biawat}} * {{g|ku|biumêd}} * {{g|ku|umêdewar}} ==== Dijmane ==== * {{g|ku|bêhêvî}} ==== Jê ==== {{kol2|ku|cure=Jê |hêvîdar bûn<q:lêker> |hêvîdar kirin<q:lêker> |hêvîdarbûn<q:navdêr> |hêvîdarkirin<q:navdêr> |hêvîdarbûyî<q:rengdêr> |hêvîdarkirî<q:rengdêr> |hêvîdarî |hêvîdarîtî |hêvîdartî }} ==== Bide ber ==== * {{g|ku|hêvîder}} * {{g|ku|hêvîdêr}} ==== Etîmolojî ==== Ji {{paş|ku|hêvî|-dar}}. ==== Werger ==== {{werger-ser}} * {{Z|de}}: {{W+|de|Optimistisch}}, {{W|de|hoffnungsfreudig}}, {{W|de|hoffnungsvoll}}, {{W|de|vielversprechend}}, {{W|de|hoffentlich}}, {{W|de|aussichtsreich|guman=erê}} * {{Z|zh}}: {{W+|zh|有希望的}} * {{Z|ar}}: {{W|ar|راغب|guman=erê}}, {{W|ar|متمني|guman=erê}}, {{W|ar|مرجو|guman=erê}} * {{Z|fa}}: {{W-|fa|امیدوار|tr=umîdwar}}, [[امیدبخش]] (umîdbexş), {{W+|fa|امیدوار}}, {{W+|fa|امیدواری}} * {{Z|fi}}: {{W+|fi|toiveikas}} * {{Z|en}}: {{W+|en|hopeful}}, {{W+|en|sanguine}}, {{W+|en|sanguineous}}, {{W+|en|upandcoming}}, {{W+|en|wishful}}, {{W+|en|aspirant}}, {{W+|en|precatory|guman=erê}}, {{W|en|anticipative|guman=erê}}, {{W|en|expectorant|guman=erê}}, {{W|en|precative|guman=erê}}, {{W|en|proleptic|guman=erê}}, {{W|en|towardly|guman=erê}}, {{W|en|up-and-coming|guman=erê}} * {{Z|it}}: {{W+|it|speranzoso}} * {{Z|hu}}: {{W+|hu|reményteljes}} * {{Z|pl}}: {{W+|pl|optymistyczny}} * {{Z|tr}}: {{W+|tr|umutlu}}, {{W+|tr|ümitli}}, {{W+|tr|umutvar}} {{werger-bin}} ecpm8v513vwphvskbt7hs6atq2u4223 hurmet 0 16918 6265840 6249039 2026-07-20T09:24:11Z Wikihez 7344 6265840 wikitext text/x-wiki == {{ziman|ku}} == === Bilêvkirin === * {{ku-IPA|ḧurmet}} * {{ku-kîte}} === Navdêr === {{ku-tewîn-nav|hurmet|mê}} {{navdêr|ku|z=m}} # [[peyv]]ek [[rêzgirtin]]ê ye li [[şûn]]a: [[jin]], [[afret]], [[pîrek]], [[kuflet]] #* {{bêmînak|ku}} # [[rêzgirtin]], [[qedir]], [[qîmet]], [[nirx]], [[rûmet]] #* {{Jêgirtin/Mela Hisênê Bateyî/Mewlûda Kurdî|jêgirtin=Hurmeta navê Muhemmed an Resûl</br>Tewbeya te bû qebûl û her qebûl.”}} ==== Bi alfabeyên din ==== * {{ku-ar|حورمه‌ت}} ===== Jê ===== {{kol3|ku |hurmet kirin<pos:lêker> |hurmet girtin<pos:lêker> |hurmetkirin<pos:navdêr> |hurmetgirtin<pos:navdêr> |hurmetkirî<pos:rengdêr> }} ==== Formên alternatîv ==== {{kol3|ku |hirmet |hirme |hurme |ḧirmet |ḧurmet }} ==== Jê ==== {{kol3|ku |bêhurmet |bêhurmetî |bihurmet |bihurmetî |hurmetdar |hurmetdarî |hurmetder |hurmetderî |hurmetdêr |hurmetdêrî |hurmetî }} ==== Etîmolojî ==== Ji {{deyn|ar|ku|حُرْمَة}} ji rehê {{g|ar|ح ر م}} ([[pîroz]] bûn). ==== Werger ==== {{werger-ser}} * {{Z|de}}: {{W|de|Ehre|f}}, {{W|de|Achtung|f}}, {{W|de|Respekt|m}}, {{W|de|Verehrung|f}}, {{W|de|Hochachtung|f|guman=erê}} * {{Z|ar}}: {{W+|ar|اجلال}}, {{W+|ar|ثناء}}, {{W+|ar|احترام}}, {{W+|ar|امرأة}}, {{W+|ar|مرة}}, {{W+|ar|قدر}}, {{W+|ar|قيمة}}, {{W+|ar|مجد}}, {{W|ar|الذمام|guman=erê}} * {{Z|fa}}: {{W+|fa|حرمت}} * {{Z|en}}: {{W+|en|lady}}, {{W|en|woman}}, (2) {{W|en|respect}}, {{W+|en|tribute}} * {{Z|tr}}: {{W+|tr|hürmet}}, {{W+|tr|keban}}, {{W+|tr|madam}}, {{W+|tr|saygı}}, {{W|tr|hanım|guman=erê}} {{werger-bin}} cp9i5z9jwx6ax4yuguiwxzdq9kio6fo 6265841 6265840 2026-07-20T09:24:23Z Wikihez 7344 6265841 wikitext text/x-wiki == {{ziman|ku}} == === Bilêvkirin === * {{ku-IPA|ḧurmet}} * {{ku-kîte}} === Navdêr === {{ku-tewîn-nav|hurmet|mê}} {{navdêr|ku|z=m}} # [[peyv]]ek [[rêzgirtin]]ê ye li [[şûn]]a: [[jin]], [[afret]], [[pîrek]], [[kuflet]] #* {{bêmînak|ku}} # [[rêzgirtin]], [[qedir]], [[qîmet]], [[nirx]], [[rûmet]] #* {{Jêgirtin/Mela Hisênê Bateyî/Mewlûda Kurdî|jêgirtin='''Hurmeta''' navê Muhemmed an Resûl</br>Tewbeya te bû qebûl û her qebûl.”}} ==== Bi alfabeyên din ==== * {{ku-ar|حورمه‌ت}} ===== Jê ===== {{kol3|ku |hurmet kirin<pos:lêker> |hurmet girtin<pos:lêker> |hurmetkirin<pos:navdêr> |hurmetgirtin<pos:navdêr> |hurmetkirî<pos:rengdêr> }} ==== Formên alternatîv ==== {{kol3|ku |hirmet |hirme |hurme |ḧirmet |ḧurmet }} ==== Jê ==== {{kol3|ku |bêhurmet |bêhurmetî |bihurmet |bihurmetî |hurmetdar |hurmetdarî |hurmetder |hurmetderî |hurmetdêr |hurmetdêrî |hurmetî }} ==== Etîmolojî ==== Ji {{deyn|ar|ku|حُرْمَة}} ji rehê {{g|ar|ح ر م}} ([[pîroz]] bûn). ==== Werger ==== {{werger-ser}} * {{Z|de}}: {{W|de|Ehre|f}}, {{W|de|Achtung|f}}, {{W|de|Respekt|m}}, {{W|de|Verehrung|f}}, {{W|de|Hochachtung|f|guman=erê}} * {{Z|ar}}: {{W+|ar|اجلال}}, {{W+|ar|ثناء}}, {{W+|ar|احترام}}, {{W+|ar|امرأة}}, {{W+|ar|مرة}}, {{W+|ar|قدر}}, {{W+|ar|قيمة}}, {{W+|ar|مجد}}, {{W|ar|الذمام|guman=erê}} * {{Z|fa}}: {{W+|fa|حرمت}} * {{Z|en}}: {{W+|en|lady}}, {{W|en|woman}}, (2) {{W|en|respect}}, {{W+|en|tribute}} * {{Z|tr}}: {{W+|tr|hürmet}}, {{W+|tr|keban}}, {{W+|tr|madam}}, {{W+|tr|saygı}}, {{W|tr|hanım|guman=erê}} {{werger-bin}} 0fyzt2hzvgqkzfu67x4q0l4s5400hmj dûkêl 0 17887 6265699 6243145 2026-07-19T23:11:32Z Bikarhêner 3719 6265699 wikitext text/x-wiki {{ds|dûkel|dûkêl}} == {{ziman|ku}} == === Bilêvkirin === * {{ku-IPA|dû"k(h)êl}} === Navdêr === {{ku-tewîn-nav|dûkêl|nêr}} [[Wêne:Ognisko ubt 0126.jpeg|thumb|250px|dûkêl]] {{navdêr|ku|z=m}} # [[toz|Toz]]a yan [[ba]]yê [[gewr]] yê ku ji [[agir]]î [[hilketin|hildikeve]]. #: {{hevmane|ku|dûman|dûxan|dû|moran}} #: {{mk|ku|'''Dûkêla''' cigareya wî dihat min.}} ==== Bi alfabeyên din ==== * {{ku-ar|دووكێل}} ==== Formên alternatîv ==== * {{hw|ku|dîkêl}} * {{hw|ku|dwîkêl}} * {{hw|ku|dûkel}} ==== Jê ==== {{kol3|ku|cure=Jê |bêdûkêl |bêdûkêlî |bêdûkêlîtî |bêdûkêltî |bidûkêl |bidûkêlî |bidûkêlîtî |bidûkêltî |dûkêldar |dûkêldarî |dûkêldarîtî |dûkêldartî |dûkêlder |dûkêlderî |dûkêlderîtî |dûkêldertî |dûkêldêr |dûkêldêrî |dûkêldêrîtî |dûkêldêrtî |dûkêlî |dûkêlker }} ==== Etîmolojî ==== Herwiha {{q|ku|dûkel}}, dibe ji {{pêk|ku|dû|w1=dûkêl|kel|w2=[[gur]], [[agir]]}} hevreha soranî {{g|ckb|دووکه‌ڵ|tr=[[dûkeł]]}}, hewramî {{q|hac|sc=Latn|dûkeł}}. ==== Werger ==== {{werger-ser}} * {{Z|abq}}: {{W-|abq|лгӏва}} * {{Z|ab}}: {{W-|ab|алҩа}} * {{Z|ace}}: {{W-|ace|asap}} * {{Z|ady}}: {{W-|ady|ӏугъу}} * {{Z|aa}}: {{W-|aa|qeri}} * {{Z|af}}: {{W-|af|rook}} * {{Z|aht}}: {{W-|aht|łet}} * {{Z|akk}}: {{W-|akk|𒆪𒌓𒊒|tr=qu₂-ut-ru|ts=qutru}} * {{Z|akl}}: {{W-|akl|aso}} * {{Z|akz}}: {{W-|akz|sobotli}} * {{Z|sq}}: {{W+|sq|tym|n}} * {{Z|gmh}}: {{W-|gmh|smouch}} * {{Z|pdc}}: {{W-|pdc|schmoke}} * {{Z|de}}: {{W+|de|Rauch|n}}, {{W+|de|Qualm|n}} *: {{Z|gsw}}: {{W-|gsw|Ràuich}}, {{W-|gsw|Ràusch}} *: {{Z|gmw-cfr}}: {{W-|gmw-cfr|Quallem}} * {{Z|alt}}: {{W-|alt|ыш}}, {{W-|alt|тӱдӱн}} * {{Z|am}}: {{W-|am|ትኪ}} * {{Z|ani}}: {{W-|ani|кӏкӏой}} * {{Z|an}}: {{W-|an|fumo|n}} * {{Z|arc}}: *: {{Z|syc}}: {{W-|syc|ܬܢܢܐ|n|tr=tennānā}} * {{Z|arp}}: {{W-|arp|ceetéé}} * {{Z|rup}}: {{W-|rup|fum}} * {{Z|aer}}: {{W-|aer|kwerte}} * {{Z|as}}: {{W-|as|ধোঁৱা}} * {{Z|ast}}: {{W+|ast|fumu|n}} * {{Z|av}}: {{W-|av|цӏцӏазе}}, {{W-|av|кӏкӏуй}} * {{Z|ay}}: {{W-|ay|jiwq'i}}, {{W-|ay|hiki}} * {{Z|ain}}: {{W-|ain|スプヤ|tr=supuya}} * {{Z|az}}: {{W+|az|tüstü}} * {{Z|bdr}}: {{W-|bdr|umbu}} * {{Z|bm}}: {{W-|bm|sisi}} * {{Z|bjn}}: {{W-|bjn|palak}}, {{W-|bjn|kukus}} * {{Z|bjb}}: {{W-|bjb|booyoo}} * {{Z|eu}}: {{W+|eu|ke}} * {{Z|ba}}: {{W-|ba|төтөн}} * {{Z|bbl}}: {{W-|bbl|kʼur}} * {{Z|brg}}: {{W-|brg|kotiskon}} * {{Z|be}}: {{W+|be|дым|n}} * {{Z|bal}}: {{W-|bal|دوت|tr=dot}} * {{Z|bn}}: {{W+|bn|ধোঁয়া}} * {{Z|kap}}: {{W-|kap|хъо}} * {{Z|bil}}: {{W-|bil|kusi}}, {{W-|bil|uksi}} * {{Z|bcl}}: {{W-|bcl|aso}} * {{Z|bi}}: {{W-|bi|smok}} * {{Z|br}}: {{W+|br|moged|n}} * {{Z|kxd}}: {{W-|kxd|asap}} * {{Z|mbb}}: {{W-|mbb|evel}} * {{Z|bg}}: {{W+|bg|дим|n}}, {{W-|bg|пу́шек|n}} * {{Z|my}}: {{W+|my|အခိုး}} * {{Z|bua}}: {{W-|bua|утаан}} * {{Z|cjp}}: {{W-|cjp|shikapo}} * {{Z|dz}}: {{W-|dz|དུ་པ}} * {{Z|crn}}: {{W-|crn|cʌʌtzí}} * {{Z|caa}}: {{W-|caa|b'utz'}} * {{Z|cbi}}: {{W-|cbi|nibuyo}} * {{Z|ccc}}: {{W-|ccc|kawsa}} * {{Z|ch}}: {{W-|ch|aso}} * {{Z|ce}}: {{W-|ce|кӏур}} * {{Z|cs}}: {{W+|cs|dým|n}}, {{W+|cs|kouř|n}} * {{Z|cdm}}: {{W-|cdm|म्हेःकुः|tr=hmeʔkuʔ}} * {{Z|chr}}: {{W-|chr|ᏧᎦᏒᏍᏗ}} * {{Z|chy}}: {{W-|chy|-atová}} * {{Z|ny}}: {{W-|ny|utsi}} * Chinantec: *: {{Z|cle}}: {{W-|cle|ñi|cuda=ñi²}} *: {{Z|chz}}: {{W-|chz|ñe|cuda=ñe{{sup|/}}}}, {{W-|chz|wañe|cuda=wa{{sup|/}}ñe{{sup|/}}}} * {{Z|zh}}: *: {{Z|yue}}: {{W-|yue|煙|tr=jin1}} *: {{Z|dng}}: {{W-|dng|ян}} *: {{Z|cmn}}: {{W+|cmn|煙|tr=yān}} *: {{Z|nan}}: {{W+|nan|煙|tr=ian}} *: {{Z|wuu}}: {{W-|wuu|煙}} * {{Z|ctu}}: {{W-|ctu|buts'}} * {{Z|cac}}: {{W-|cac|tap'}} * {{Z|cv}}: {{W-|cv|тӗтӗм}} * {{Z|dak}}: {{W-|dak|šota}} * {{Z|da}}: {{W+|da|røg|g}} * {{Z|xda}}: {{W-|xda|kudyal}} * {{Z|dv}}: {{W-|dv|ދުމް}} * {{Z|dgr}}: {{W-|dgr|ło}} * {{Z|dlg}}: {{W-|dlg|буруо}} * {{Z|ovd}}: {{W-|ovd|räk|n}} * {{Z|egl}}: {{W-|egl|fomm}} * {{Z|id}}: {{W+|id|asap}} * {{Z|ar}}: {{W-|ar|دُخَان|n}} *: {{Z|arz}}: {{W-|arz|دخان|n|tr=duḵān}} * {{Z|hy}}: {{W+|hy|ծուխ}}, {{W+|hy|մուխ}} * {{Z|myv}}: {{W-|myv|качамо}} * {{Z|eo}}: {{W+|eo|fumo}} * {{Z|et}}: {{W+|et|suits}} * {{Z|eve}}: {{W-|eve|ханин}} * {{Z|evn}}: {{W-|evn|саңнян}} * {{Z|ee}}: {{W-|ee|adzudzɔ}} * {{Z|ext}}: {{W-|ext|humu|n}} * {{Z|fa}}: {{W+|fa|دود|tr=dud}} * {{Z|fo}}: {{W+|fo|roykur|n}}, {{W-|fo|dampur|n}} * {{Z|hif}}: {{W-|hif|dhuuan}} * {{Z|fi}}: {{W+|fi|savu}} * {{Z|fro}}: {{W-|fro|fum|n}} * {{Z|fr}}: {{W+|fr|fumée|m}} * Frisian: *: {{Z|frr}}: {{W-|frr|riik}} *: {{Z|stq}}: {{W-|stq|Rook}} *: {{Z|fy}}: {{W+|fy|reek|g}} * {{Z|fur}}: {{W-|fur|fum|n}} * {{Z|fud}}: {{W-|fud|ʻafu}} * {{Z|gd}}: {{W-|gd|toit|m}} * {{Z|gag}}: {{W-|gag|tütün}} * {{Z|gl}}: {{W+|gl|fume|n}} * {{Z|got}}: {{W-|got|𐌳𐌰𐌿𐌽𐍃}} * {{Z|gu}}: {{W-|gu|ધુમાડો}} * {{Z|ka}}: {{W-|ka|ბოლი}}, {{W-|ka|კვამლი}} * {{Z|gn}}: {{W-|gn|timbo}}, {{W-|gn|tatatĩ}} * {{Z|ht}}: {{W-|ht|lafimen}} * {{Z|haw}}: {{W-|haw|uahi}} * {{Z|ha}}: {{W-|ha|hayaƙi}} * {{Z|mba}}: {{W-|mba|obol}} * {{Z|hi}}: {{W+|hi|धूआँ|n}}, {{W+|hi|धूम्र|n}} * {{Z|gin}}: {{W-|gin|кутӏи}} * {{Z|hil}}: {{W-|hil|asó}} * {{Z|hit}}: {{W-|hit|tuhhuwais}} * {{Z|nl}}: {{W+|nl|rook|n}}, {{W+|nl|walm|n}} * {{Z|huv}}: {{W-|huv|nasop}} * {{Z|hrx}}: {{W-|hrx|Damp|n}} * {{Z|huz}}: {{W-|huz|хъо}} * {{Z|iba}}: {{W-|iba|asap}} * {{Z|he}}: {{W+|he|עָשָׁן|n|tr=ashán}} * {{Z|io}}: {{W+|io|fumo}} * {{Z|ilo}}: {{W-|ilo|asok}} * {{Z|ang}}: {{W-|ang|rēc|n}}, {{W-|ang|smoca|n}} * {{Z|en}}: {{W+|en|smoke}} * {{Z|inh}}: {{W-|inh|кӏур}} * {{Z|ia}}: {{W-|ia|fumo}} * {{Z|iu}}: {{W-|iu|ᐃᓯᖅ}} * {{Z|ik}}: {{W-|ik|isiq}}, {{W-|ik|puyuq}} * {{Z|ill}}: {{W-|ill|bel}} * {{Z|ga}}: {{W+|ga|deatach|n}}, {{W+|ga|toit|m}} * {{Z|ist}}: {{W-|ist|fòumo|n}} * {{Z|isk}}: {{W-|isk|dit}} * {{Z|it}}: {{W+|it|fumo|n}} * {{Z|is}}: {{W+|is|reykur|n}} * {{Z|jac}}: {{W-|jac|nhub'}} * {{Z|ja}}: {{W+|ja|煙|tr=けむり, kemuri}} * {{Z|jv}}: {{W-|jv|asep}}, {{W+|jv|ꦏꦼꦧꦸꦭ꧀}}, {{W+|jv|ꦏꦸꦏꦸꦱ꧀}} * {{Z|quc}}: {{W-|quc|sïb}} * {{Z|kbd}}: {{W-|kbd|ӏугъуэ}} * {{Z|kab}}: {{W-|kab|awwu}}, {{W-|kab|ddexxan}} * {{Z|kl}}: {{W-|kl|pujoq}} * {{Z|xal}}: {{W-|xal|утан}} * {{Z|kn}}: {{W+|kn|ಧೂಮ}}, {{W+|kn|ಹೊಗೆ}} * {{Z|ksk}}: {{W-|ksk|shóje}}, {{W-|ksk|šótte}}, {{W-|ksk|šóce}} * {{Z|pam}}: {{W-|pam|asuk}}, {{W-|pam|usuk}} * {{Z|krc}}: {{W-|krc|тютюн}} * {{Z|krl}}: {{W-|krl|savu}} * {{Z|csb}}: {{W-|csb|dim}} * {{Z|ca}}: {{W+|ca|fum|n}} * {{Z|ket}}: {{W-|ket|ду’|tr=du’}} * {{Z|khv}}: {{W-|khv|гутӏ}} * {{Z|ky}}: {{W+|ky|түтүн}} * {{Z|si}}: {{W-|si|දුමාරය}} * {{Z|rw}}: {{W-|rw|umwotsi|3|4}} * {{Z|gil}}: {{W-|gil|bubu}} * {{Z|koi}}: {{W-|koi|тшын}} * {{Z|kpv}}: {{W-|kpv|тшын}} * {{Z|ko}}: {{W+|ko|연기}} * {{Z|kw}}: {{W-|kw|mog|n}} * {{Z|co}}: {{W-|co|fume|n}}, {{W+|co|fumu|n}} * {{Z|kpy}}: {{W-|kpy|ӈылӈыл|tr=ŋəlŋəl}}, {{W-|kpy|ипиип|tr=ipiip}} * {{Z|crk}}: {{W-|crk|ᑲᐢᑳᐸᐦᑌᐤ|tr=kaskâpahtêw}} * {{Z|kum}}: {{W-|kum|тютюн}} * {{Z|lld}}: {{W-|lld|fum|n}} * {{Z|la}}: {{W+|la|fūmus|n}} * {{Z|lv}}: {{W+|lv|dūmi|n-p}} * {{Z|lo}}: {{W-|lo|ຄວັນ}}, {{W-|lo|ຄວັນໄຟ}} * {{Z|lzz}}: {{W-|lzz|კომა}}, {{W-|lzz|მკომა}}, {{W-|lzz|ნკომა}} * {{Z|lez}}: {{W-|lez|гум}} * {{Z|ln}}: {{W-|ln|molinga|3|4}} * {{Z|lij}}: {{W-|lij|fumme}} * {{Z|li}}: {{W+|li|rouk|n}} * {{Z|lt}}: {{W+|lt|dūmas|n}} * {{Z|liv}}: {{W-|liv|sov}} * Lombard: *: {{Z|lmo}}: {{W-|lmo|föm|n}} *: {{Z|lmo}}: {{W-|lmo|fumm|n}} * {{Z|khb}}: {{W-|khb|ᦩᦸᧃ}} * {{Z|lb}}: {{W-|lb|Damp|n}} * {{Z|mcb}}: {{W-|mcb|tsitsíenka}}, {{W-|mcb|énkatsi}} * {{Z|mdh}}: {{W-|mdh|bel}} * {{Z|mk}}: {{W-|mk|чад|n}}, {{W-|mk|дим|n}} * {{Z|mg}}: {{W+|mg|setroka}} * {{Z|ml}}: {{W+|ml|പുക}} * {{Z|ms}}: {{W+|ms|asap}} * {{Z|mt}}: {{W-|mt|duħħan}} * {{Z|mgm}}: {{W-|mgm|fuma}} * {{Z|mnc}}: {{W-|mnc|ᡧᠠᠩᡤᡳᠶᠠᠨ}} * {{Z|mni}}: {{W-|mni|ꯃꯩꯈꯨ}} * {{Z|gv}}: {{W-|gv|jaagh}} * {{Z|msk}}: {{W-|msk|ubul}} * {{Z|mns-nor}}: {{W-|mns-nor|посым}} * {{Z|mi}}: {{W-|mi|auahi}}, {{W-|mi|paoa}}, {{W-|mi|ponguru}} * {{Z|arn}}: {{W-|arn|fixun}}, {{W-|arn|fitruñ}} * {{Z|mrw}}: {{W-|mrw|bel}} * {{Z|mr}}: {{W-|mr|धूर}} * Marî: *: {{Z|mhr}}: {{W-|mhr|шикш}} *: {{Z|mrj}}: {{W-|mrj|шӹкш}} * {{Z|mas}}: {{W-|mas|empurúó}} * {{Z|yua}}: {{W-|yua|buuts’}} * {{Z|mfy}}: {{W-|mfy|buichiria}} * {{Z|maq}}: {{W-|maq|nihndi}} * {{Z|hu}}: {{W+|hu|füst}} * {{Z|ruq}}: {{W-|ruq|fum|n}} * {{Z|xmf}}: {{W-|xmf|ლოლი}}, {{W-|xmf|ფურკი}}, {{W-|xmf|ფუტი}} * {{Z|mel}}: {{W-|mel|tugun}} * {{Z|egy}}: {{W-egy|ḥtj|h=H-t:y-Q7}} * {{Z|mpm}}: {{W-|mpm|ñu'ma}} * {{Z|min}}: {{W-|min|asok}} * {{Z|mwl}}: {{W-|mwl|fumo|n}} * {{Z|mdf}}: {{W-|mdf|качам}} * {{Z|mn}}: *: Kirîlî: {{W+|mn|утаа}} *: Mongolî: {{W-|mn|ᠤᠲᠤᠭ᠎ᠠ}} * {{Z|mnw}}: {{W-|mnw|ယက်|tr=jak}} * {{Z|mzp}}: {{W-|mzp|bujru}} * {{Z|wmw}}: {{W-|wmw|rosi}} * {{Z|nah}}: {{W+|nah|poctli}} *: {{Z|nhx}}: {{W-|nhx|po̱cti}}, {{W-|nhx|ipo̱cyo}} * {{Z|gld}}: {{W-|gld|сангнян}} * {{Z|nap}}: {{W-|nap|fummo|n}} * {{Z|nv}}: {{W-|nv|łid}} * {{Z|na}}: {{W-|na|ebadetsi}} * {{Z|nds}}: {{W-|nds|Rauk|n}} * {{Z|yrk}}: {{W-|yrk|якэ|tr=jake}} * {{Z|ne}}: {{W-|ne|धुँवा}}, {{W-|ne|धूवाँ}} * {{Z|nio}}: {{W-|nio|кинтә|tr=kintĕ}}, {{W-|nio|дякагә|tr=djakagĕ}} * {{Z|niv}}: {{W-|niv|тʼуф}} * {{Z|nog}}: {{W-|nog|туьтин}} * {{Z|nrf}}: {{W-|nrf|feunmée|m}}, {{W-|nrf|fumaïe|m}} * {{Z|non}}: {{W-|non|reykr|n}} * {{Z|no}}: *: {{Z|nb}}: {{W-|nb|røyk|n}} *: {{Z|nn}}: {{W-|nn|røyk|n}} * {{Z|nuj}}: {{W-|nuj|eriisi}} * {{Z|nys}}: {{W-|nys|booyoo}} * {{Z|oc}}: {{W+|oc|fum|n}} * {{Z|or}}: {{W+|or|ଧୂଆଁ}} * {{Z|om}}: {{W-|om|haara}} * {{Z|os}}: {{W-|os|фӕздӕг}} * {{Z|osc}}: {{W-|osc|𐌚𐌄𐌔𐌚}} * {{Z|ota}}: {{W-|ota|دومان|tr=duman}}, {{W-|ota|دخان|tr=duhân}}, {{W-|ota|توتون|tr=tütün}} * {{Z|ote}}: {{W-|ote|'bifi}} * {{Z|ug}}: {{W-|ug|ئىس}}, {{W-|ug|تۈتۈن}} * {{Z|uz}}: {{W+|uz|tutun}}, {{W+|uz|dud}} * {{Z|pi}}: {{W-|pi|dhūma|n}} * {{Z|pap}}: {{W-|pap|huma}} * {{Z|ps}}: {{W+|ps|دود|tr=dud}} * {{Z|pms}}: {{W-|pms|fum|n}} * {{Z|pcd}}: {{W-|pcd|finquée|m}}, {{W-|pcd|finquère|m}} * {{Z|pjt}}: {{W-|pjt|puyu}} * {{Z|pdt}}: {{W-|pdt|Ruak|nt}} * {{Z|pl}}: {{W+|pl|dym|n}} * {{Z|poe}}: {{W-|poe|ihnchi}} * {{Z|pt}}: {{W+|pt|fumo|n}}, {{W+|pt|fumaça|m}} * {{Z|prg}}: {{W-|prg|dumis}} * {{Z|pa}}: {{W-|pa|ਧੂੰ}} * Quechua: *: {{Z|qu}}: {{W-|qu|goshtay}} *: {{Z|qu}}: {{W-|qu|qusñi}}, {{W-|qu|q'osñe}}, {{W-|qu|wapsi}} * {{Z|kk}}: {{W-|kk|түтін}} * {{Z|cop}}: {{W-|cop|ⲭⲣⲉⲙⲧⲥ|n}} * {{Z|rap}}: {{W-|rap|au}} * {{Z|rar}}: {{W-|rar|au}} * {{Z|rhg}}: {{W-|rhg|dúañ}} * {{Z|rgn}}: {{W-|rgn|fọmm|n}} * {{Z|rm}}: {{W-|rm|fim|n}}, {{W-|rm|fem|n}}, {{W-|rm|füm|n}} * {{Z|rom}}: {{W-|rom|thūv}} * {{Z|ro}}: {{W+|ro|fum|nt}} * {{Z|ru}}: {{W+|ru|дым|n}}, {{W+|ru|чад|n}} * {{Z|rue}}: {{W-|rue|дим}} * {{Z|ssy}}: {{W-|ssy|tika}} * {{Z|se}}: {{W-|se|suovva}} * {{Z|sjd}}: {{W-|sjd|сӯвв}} * {{Z|sm}}: {{W+|sm|asu}} * {{Z|azg}}: {{W-|azg|tseoon}} * {{Z|sg}}: {{W+|sg|gürü}} * {{Z|sa}}: {{W+|sa|धूम}} * {{Z|sc}}: {{W-|sc|fummu|n}}, {{W-|sc|fumu|n}} * {{Z|ceb}}: {{W-|ceb|aso}} * {{Z|sei}}: {{W-|sei|hamcaaxat}} * {{Z|scn}}: {{W+|scn|fumu}} * {{Z|sd}}: {{W-|sd|دوُنھون|tr=dū̃hon}} * {{Z|srn}}: {{W-|srn|smoko}} * {{Z|sh}}: *: Kirîlî: {{W-|sh|ди̏м|n}} *: Latînî: {{W+|sh|dȉm|n}} * {{Z|syl}}: {{W-|syl|ꠗꠥꠝꠣ}} * {{Z|sco}}: {{W-|sco|reek}} * {{Z|cu}}: *: Kirîlî: {{W-|cu|дꙑмъ|n}} *: Glagolîtîk: {{W-|cu|ⰴⱏⰹⰿⱏ|n}} * {{Z|orv}}: {{W-|orv|дꙑмъ|n}} * {{Z|sk}}: {{W-|sk|dym|n}} * {{Z|sl}}: {{W+|sl|dìm|n}} * {{Z|so}}: {{W-|so|qiiq}} * Sorbî: *: {{Z|dsb}}: {{W-|dsb|dym|n}}, {{W-|dsb|kuŕ|n}} *: {{Z|hsb}}: {{W-|hsb|dym|n}}, {{W-|hsb|kur|n}} * {{Z|st}}: {{W-|st|mosi}} * {{Z|es}}: {{W+|es|humo|n}} * {{Z|su}}: {{W-|su|ᮠᮞᮩᮕ᮪}} * {{Z|sux}}: {{W-|sux|ibi}} * {{Z|sva}}: {{W-|sva|კუ̂ა̈მ}} * {{Z|sw}}: {{W+|sw|moshi}} * {{Z|sv}}: {{W+|sv|bloss|nt}} * {{Z|xsr}}: {{W-|xsr|तुत}} * {{Z|sn}}: {{W-|sn|utsi}} * {{Z|cjs}}: {{W-|cjs|тӱдӱн|tr=tüdün}} * {{Z|sgh}}: {{W-|sgh|д̌уд}} * {{Z|tab}}: {{W-|tab|кум}} * {{Z|chf}}: {{W-|chf|butz'}}, {{W-|chf|butz'i}} * {{Z|tg}}: {{W+|tg|дуд}} * {{Z|tl}}: {{W-|tl|usok}} * {{Z|ty}}: {{W-|ty|auauhi}} * {{Z|tna}}: {{W-|tna|judhu}} * {{Z|ta}}: {{W+|ta|புகை}} * {{Z|tcb}}: {{W-|tcb|łet}} * {{Z|taa}}: {{W-|taa|łet}} * {{Z|roa-tar}}: {{W-|roa-tar|fume|n}} * {{Z|rif}}: {{W-|rif|ddexxan|n}} * {{Z|shi}}: {{W-|shi|aggu}} * {{Z|tsg}}: {{W-|tsg|asu}} * {{Z|th}}: {{W+|th|ควัน}} * {{Z|ctd}}: {{W-|ctd|khu}}, {{W-|ctd|meikhu}} * {{Z|te}}: {{W+|te|పొగ}} * {{Z|tzm}}: {{W-|tzm|ⴰⴳⴳⵓ|n}} * {{Z|stp}}: {{W-|stp|kuubhɨx}} * {{Z|cux}}: {{W-|cux|y'am'i|cuda=y'a³m'i³}} * {{Z|tft}}: {{W-|tft|nyaso}} * {{Z|crh}}: {{W-|crh|тютюн}} * {{Z|tt}}: {{W+|tt|төтен}} * {{Z|tet}}: {{W-|tet|ahi-suar}} * {{Z|ti}}: {{W-|ti|ትኪ}} * {{Z|tin}}: {{W-|tin|гутӏ|tr=gut'}} * {{Z|tr}}: {{W+|tr|sis}}, {{W+|tr|duman}} * {{Z|tk}}: {{W-|tk|tüsse}} * {{Z|bo}}: {{W-|bo|དུ་བ}} * {{Z|tli}}: {{W-|tli|s'eekh}}, {{W-|tli|s'eikh}} * {{Z|trs}}: {{W-|trs|gatse'e|cuda=gatse'⁴e}} * {{Z|ddo}}: {{W-|ddo|гутӏ}} * {{Z|cas}}: {{W-|cas|jị'sa'}}, {{W-|cas|jï'sä'}} * {{Z|tn}}: {{W-|tn|mosi}} * {{Z|tum}}: {{W-|tum|josi}} * {{Z|enh}}: {{W-|enh|кочи|tr=koči}} * {{Z|tpn}}: {{W-|tpn|timbora}} * {{Z|tvl}}: {{W-|tvl|au}} * {{Z|tyv}}: {{W-|tyv|ыш}} * {{Z|tzh}}: {{W-|tzh|ch'ahil}} * {{Z|tzo}}: {{W-|tzo|ch'ail}} * {{Z|udm}}: {{W-|udm|ӵын}} * {{Z|uga}}: {{W-|uga|𐎖𐎉𐎗}} * {{Z|ur}}: {{W-|ur|دھواں|n|tr=dhūā̃}} * {{Z|ure}}: {{W-|ure|chqeti}}, {{W-|ure|heqay}} * {{Z|uk}}: {{W+|uk|дим|n}} * {{Z|vec}}: {{W+|vec|fum|n}} * {{Z|vep}}: {{W-|vep|savu}} * {{Z|vi}}: {{W+|vi|khói}} * {{Z|vo}}: {{W+|vo|smok}} * {{Z|vro}}: {{W-|vro|sau}} * {{Z|wls}}: {{W-|wls|ʻahu}}, {{W-|wls|kohu}}, {{W-|wls|kokofu}} * {{Z|wa}}: {{W-|wa|fumêre}} * {{Z|wba}}: {{W-|wba|hehuku}} * {{Z|war}}: {{W-|war|asu}} * {{Z|cy}}: {{W+|cy|mwg|n}} * {{Z|wym}}: {{W-|wym|raojch|n}} * {{Z|wo}}: {{W+|wo|saxaar}} * {{Z|kjh}}: {{W-|kjh|тӱдӱн}}, {{W-|kjh|ыс}} * {{Z|kca}}: {{W-|kca|нусаӈ}} * {{Z|km}}: {{W+|km|ផ្សែង}}, {{W-|km|ធុមី}} * {{Z|xh}}: {{W-|xh|umsi}} * {{Z|yka}}: {{W-|yka|umbu}} * {{Z|sah}}: {{W-|sah|буруо}} * {{Z|yag}}: {{W-|yag|ušku}} * {{Z|yah}}: {{W-|yah|dhad}} * {{Z|yi}}: {{W-|yi|רויך}} * {{Z|yo}}: {{W-|yo|èéfín}} * {{Z|yur}}: {{W-|yur|mera·}}, {{W-|yur|meraa}} * Zapotec: *: {{Z|zaa}}: {{W-|zaa|tse̱ní}}, {{W-|zai|gu'xhu'}} *: {{Z|zpq}}: {{W-|zpq|žen}} * {{Z|el}}: {{W+|el|καπνός|n}} *: Kevn: {{W-|grc|καπνός|n}} *: {{Z|grk-ita}}: {{W-|grk-ita|kannò|n}} * {{Z|zea}}: {{W-|zea|roôk|n}} * {{Z|za}}: {{W-|za|ien}} * {{Z|zoc}}: {{W-|zoc|jocoj}} * {{Z|zu}}: {{W-|zu|intuthu|9|10}}, {{W-|zu|umusi|3}} {{werger-bin}} :{{werger çavkanî|en|smoke|beş=Ev qismê Wergerê|oldid=76416788}} sv35h92gwrg2kltcf6ccw3g1e8gvz3x şerîf 0 18522 6265818 6131173 2026-07-20T09:03:30Z Wikihez 7344 /* */ bi [[MediaWiki:Gadget-AjaxEdit.js|AjaxEdit]]ê re 6265818 wikitext text/x-wiki == {{ziman|ku}} == === Bilêvkirin === * {{ku-kîte}} === Rengdêr === {{rengdêr|ku}} # [[bişeref]], [[binamûs]], [[birûmet]] #* {{Jêgirtin/Mela Hisênê Bateyî/Mewlûda Kurdî|jêgirtin=Lew '''şerîf''' in Zemzem û rukn û meqam</br>Sellî ya Rebbî 'ela xeyr-il wera}} ==== Jê ==== * {{g|ku|şerîfî}} * {{g|ku|şerîfîtî}} * {{g|ku|şerîftî}} ==== Etîmolojî ==== Ji {{deyn|ar|ku}}, têkildarî {{q|ku|şeref}}. ==== Werger ==== {{werger-ser}} * {{Z|ar}}: {{W-|ar|شريف}} * {{Z|fi}}: {{W+|fi|kunniallinen}} * {{Z|en}}: {{W+|en|honest}}, (''emerîkî'':) [[honorable]], (''brîtanî'':) [[honourable]] {{werger-bin}} === Navdêr === {{navdêr|ku|z=}} # [[polîs]] (bi taybetî li welatin [[îngilîzî]]ziman) #* {{bêmînak|ku}} ==== Jê ==== * {{g|ku|şerîfî}} * {{g|ku|şerîfîtî}} * {{g|ku|şerîftî}} ==== Etîmolojî ==== Ji {{deyn|en|ku|sheriff}}. ==== Werger ==== {{werger-ser}} * {{Z|fi}}: {{W+|fi|sheriffi}}, {{W+|fi|poliisi}} * {{Z|en}}: {{W+|en|sheriff}} {{werger-bin}} qcqb2c3tzlwgtvljapf2rh6yrer1pgu dêrîn 0 19667 6265607 6265532 2026-07-19T15:57:54Z Ghybu 1393 /* Lêker */ 6265607 wikitext text/x-wiki {{bnr-h|derin|dêrin|derîn}} == {{ziman|ku}} == === Bilêvkirin === * {{ku-kîte}} === Rengdêr === {{rengdêr|ku}} # [[kevnar]], [[kevn]], [[qedîm]], [[mêjîn]], [[gelek]] [[kevn]] #* {{bêmînak|ku}} ==== Bi alfabeyên din ==== * {{ku-ar|دێرین}} ==== Formên alternatîv ==== * {{g|ku|dêrin}} ==== Jê ==== {{kol3|ku | {{g|ku|dêrînî|z=m}} | {{g|ku|dêrînîtî|z=m}} | {{g|ku|dêrîntî|z=m}} | {{g|ku|dêrînbûn}} | {{g|ku|derîn bûn}} | {{g|ku|dêrînbûyîn}} | {{g|ku|dêrîn bûyîn}} }} ==== Etîmolojî ==== Hevreha {{q|ku|dîrok}}, {{hv|zza|dêr|w=stran}}, binêre {{q|ku|dîrok}}. ==== Werger ==== {{werger-ser}} * {{Z|af}}: {{W|af|antiek}} * {{Z|de}}: {{W|de|antik}}, {{W|de|alt}}, {{W|de|altertümlich}}, {{W|de|uralt}}, {{W|de|altmodisch}} * {{Z|da}}: {{W|da|antik}} * {{Z|ar}}: {{W|ar|قديم}}, {{W|ar|عتيق}} * {{Z|eo}}: {{W|eo|antikva}} * {{Z|fa}}: {{W|fa|اصیل زاده|guman=erê}}, {{W|fa|میرزا|guman=erê}} * {{Z|fo}}: {{W|fo|gamal}}, {{W|fo|fortíðar-}} * {{Z|fi}}: {{W|fi|vanha}}, {{W|fi|muinainen}}, {{W|fi|ikivanha}} * {{Z|fr}}: {{W|fr|antique}}, {{W|fr|ancien}} * {{Z|fy}}: {{W|fy|antyk}} * {{Z|gd}}: {{W|gd|aosda}} * {{Z|nl}}: {{W|nl|aloud}}, {{W|nl|antiek}}, {{W|nl|ouderwets}} * {{Z|io}}: {{W|io|antiqua}}, {{W|io|ancienega}} * {{Z|en}}: {{W|en|antique}} (1), {{W|en|ancient}}, {{W|en|orbit}}, {{W|en|archaeo-}}, {{W|en|archeo-}}, {{W|en|obsolete}} * {{Z|it}}: {{W|it|antico}}, {{W|it|vecchissimo}} * {{Z|ca}}: {{W|ca|antic}} * {{Z|hu}}: {{W|hu|antik}}, {{W|hu|régi}} * {{Z|pap}}: {{W|pap|antik}} * {{Z|pt}}: {{W|pt|antigo}}, {{W|pt|velho}}, {{W|pt|vetusto}} * {{Z|es}}: {{W|es|antiguo}}, {{W|es|anciano}} * {{Z|tr}}: {{W|tr|antika}}, {{W|tr|antik}}, {{W|tr|eski}}, {{W|tr|ayrışmak}}, {{W|tr|savrulmak}}, {{W|tr|savruluş}}, {{W|tr|asaletli|guman=erê}}, {{W|tr|bayrı|guman=erê}}, {{W|tr|ilkel|guman=erê}}, {{W|tr|kadim|guman=erê}}, {{W|tr|savrulma|guman=erê}} * {{Z|cy}}: {{W|cy|hen|cuda=hen beth}} {{werger-bin}} === Lêker === {{ku-tewîn-lk|dêrîn|form=gerguhêz|niha=dêr|borî=dêrî}} {{lêker|ku|c=x-gh}} # [[hebûn]], [[heyîn]], [[xwedî bûn]] #: {{mk|ku|Ew gelek tiştan '''didêre'''.|Wî gelek tişt hene.|rêz=1}} #* {{jêder-malper|ku|jêgirtin=Ew dara mezin pênc guliyên sereke '''didêre''', yanî pênc guliyên wê yên sereke hene.|malper=komkareu.com|sernav=Cihê Zimanê Kurdî Di Nav Zimanên Hindî û Ewropî De (Ferhenga Kurdî)|nivîskar=M. Emîn Bozarslan|sal=2011|url=https://www.komkareu.com/kurdistan/ziman/}} #* {{jêder-kitêb|ku|jêgirtin=...Yezîd bîn Muawîye meyla jina Hezretî Hesen '''didêra'''|nivîskar={{w|Mela Mûsayê Hekarî}}|sernav=Durrû’l Mecalîs|amadekar=Hêmin Omer|sala weşandinê=2022|sal=1857|rûpel=158}} #* {{jêder|ku|2=Beyta Subehê|url=https://bnk.institutkurde.org/images/pdf/3PV25PWC3E.pdf|jêgirtin=Roj hate erşêd êlî<br>Aşiqan bang '''didêrî'''<br>Mang u nederêd Şêşim da berî u behrêd jêrî}} # [[dîtîn]], [[zanîn]], [[fikirîn]] #* {{bêmînak|ku}} ==== Formên alternatîv ==== * {{g|ku|dêran}} ==== Têkildar ==== * {{g|ku|dêrandin}} ==== Jê ==== * {{g|ku|dêrî}} ==== Etîmolojî ==== Binêre lêkera {{q|ku|dêran}}. {{bêetîmolojî}} ==== Werger ==== {{werger-ser|xwedî tiştekî bûn|1}} * {{Z|de}}: {{W+|de|haben}} * {{Z|az}}: {{W-|az|sahib olmaq}} * {{Z|ar}}: {{W-|ar|أن يكون لديك}} * {{Z|fa}}: {{W+|fa|داشتن}} * {{Z|fr}}: {{W+|fr|avoir}}, {{W+|fr|détenir}}, {{W+|fr|posséder}} * {{Z|en}}: {{W+|en|have}}, {{W+|en|possess}} * {{Z|ca}}: {{W+|ca|tenir}} * {{Z|ps}}: {{W+|ps|درلودل}} * {{Z|pt}}: {{W+|pt|ter}} * {{Z|ru}}: {{W+|ru|иметь}} * {{Z|es}}: {{W+|es|tener}} * {{Z|tr}}: {{W+|tr|sahip olmak}}, {{W+|tr|malik olmak}} * {{Z|uk}}: {{W+|uk|мати}} * {{Z|el}}: {{W-|el|να έχω}} {{werger-bin}} ==== Çavkanî ==== * {{i|mane 1}} Kovara ''Kurmancî'', hejmar 41, payîz 2007 (''Peyvên di qewlên Êzîdiyan de'', Reşo ZÎLAN) === Navdêr === {{ku-tewîn-nav|dêrîn|mê}} {{navdêr|ku|z=m}} # [[maliyet]], [[milk]], [[serwet]], [[saman]], [[sermiyan]] #* {{jêder|ku|jêgirtin=Ev gotineke tirş û tehle, û bê guman ji wî kesî hatiye, ku di rewşeke xweyî ya nebaş de ye, ji ber ku Kurd xwe wekî pareke giring ji Iraqê dibînin û xwe wilo didin nasîn, hema di rastîniyê de, eve gelek gotinên berê tînin bîra me, ji wan jî: Petrola Ereban ya Ereban e, Sûriye ya Ereban e, Teviya Iraqê '''dêrîna''' Ereban e, û bo Kurdan tiştek di van welatan de nîne...|Cankurd: ''Gotina serekê parlamenta Iraqê çi gotin bû?'', Serwext.com, 12/2008}} # (têkildarî dêrê) ''Binere'': '''[[dêrî]]''' ==== Etîmolojî ==== {{bêetîmolojî}} ==== Werger ==== {{werger-ser}} {{werger-bin}} {{bend}} gjfrj2q386yrdw98eij82l0q2e1c524 çerx 0 19812 6265852 6242558 2026-07-20T09:39:56Z Wikihez 7344 /* */ bi [[MediaWiki:Gadget-AjaxEdit.js|AjaxEdit]]ê re 6265852 wikitext text/x-wiki == {{ziman|ku}} == === Bilêvkirin === * {{ku-IPA|ç(h)erx}} * {{ku-kîte}} === Navdêr === {{ku-tewîn-nav|çerx|mê}} [[Wêne:Wheel Iran.jpg|thumb|çerxek]] {{navdêr|ku|z=m}} # [[xirrxal]], [[tekel]], [[tayre]], [[tole]] #* {{jêder|ku|jêgirtin=Kesên li wê derê kar dikirin jê re gotibûn ku belkî ew di bin '''çerxên''' trumbêlekê de hatibû perçiqandin.|''[[w:Biyanî|Biyanî]]'', [[w:Albert Camus|Albert Camus]], Weşanên [[w:Nûdem|Nûdem]]}} # [[dewr]], [[zivir]], [[ger]] li [[dor]] tiştekî #* {{bêmînak|ku}} # [[dewran]], [[zeman]], [[serdem]] #* {{bêmînak|ku}} # [[sedsal]], [[sede]] #* {{bêmînak|ku}} # çeqmaq #* {{bêmînak|ku}} # perê paxir #* {{bêmînak|ku}} ==== Ji wêjeya klasîk ==== * {{jêder|ku|{{Jêgirtin/Melayê Cizîrî/Dîwana Melayê Cizirî}}|jêgirtin=Bi awazê ney û sazî</br>Bibî ber '''çerxê''' perwazî</br>Tuzed min hubbihe s-sefwa}} ==== Formên alternatîv ==== * {{g|ku|çerix}} ==== Bide ber ==== * {{g|ku|çax}} ==== Jê ==== {{kol3|ku|cure=Jê |çerx bûn<q:lêker> |çerx kirin<q:lêker> |çerx dan<q:lêker> |çerxbûn<q:navdêr> |çerxkirin<q:navdêr> |çerxdan<q:navdêr> |çerxbûyî<q:rengdêr> |çerxkirî<q:rengdêr> |çerixandin |çerixandî |çerixiyayî |çerixî |çerixîn |çerixîner |çerxik |çerxok |{{w|Cerxêk}}<q:serenav> }} ==== Etîmolojî ==== {{etymon|ku|id=teker|inh|ira-pro>*čaxrám>çerx|tree=1|text=++}} Hevreha {{hv|fa|چرخ|tr=čarx}}, {{hv|ae|𐬗𐬀𐬑𐬭𐬀||çerx, teker}}, {{hv|sa|चक्र|tr=cakrá}}. {{cotreh|ku|kultûr}} ;{{biçûk|Çavkanî: * {{Watkins|r=45}} * {{Etymonline|wheel}} }} ==== Werger ==== {{werger-ser}} * {{Z|de}}: {{W+|de|Achse|f}}, {{W+|de|Feuerzeug|n}}, {{W+|de|Mühlrad|n}}, {{W+|de|Reifen|m}}, {{W+|de|Runde|f}}, {{W+|de|Umlauf}}, {{W+|de|Zyklus|m}}, {{W+|de|Wegbiegung|f}}, {{W+|de|Lenkrad|guman=erê}} * {{Z|ar}}: {{W+|ar|دولاب}}, {{W+|ar|دائرة}}, {{W-|ar|دوران}}, {{W+|ar|دورة}}, {{W+|ar|دور}}, {{W+|ar|عصر}}, {{W+|ar|عقد}}, {{W-|ar|عجلة|guman=erê}} * {{Z|fa}}: {{W+|fa|پریود}}, {{W+|fa|تایر}}, {{W+|fa|چرخ}}, {{W+|fa|دنده}}, {{W+|fa|غل}}, {{W-|fa|سنگ سوهان}}, {{W+|fa|سوهان}}, {{W+|fa|مداد تراش}} * {{Z|en}}: {{W+|en|circle}}, {{W+|en|rotation}}, {{W+|en|gyro-}}, {{W+|en|turn}}, {{W+|en|cycle}}, {{W+|en|era}}, {{W+|en|century}}, {{W+|en|lathe}}, {{W+|en|periodic}}, {{W+|en|tropic}}, {{W+|en|tropical}}, {{W+|en|orbit|guman=erê}}, {{W+|en|trochal|guman=erê}}, {{W+|en|tyre|guman=erê}} * {{Z|tr}}: {{W+|tr|ahit}}, {{W+|tr|çağ}}, {{W+|tr|devir}}, {{W+|tr|dönence}}, {{W+|tr|döngü}}, {{W+|tr|edvar}}, {{W+|tr|esir}}, {{W+|tr|felek}}, {{W+|tr|teker}}, {{W+|tr|tol}}, {{W+|tr|kuruş}}, {{W+|tr|dönüş}}, {{W+|tr|zamane}}, {{W+|tr|burç}}, {{W-|tr|beş kuruş}}, {{W+|tr|çark|guman=erê}}, {{W+|tr|deveran|guman=erê}} {{werger-bin}} nwz56frp93wv3oyb5zitb20lvnwte95 qepax 0 23394 6265731 6263141 2026-07-20T05:40:40Z Wikihez 7344 /* Navdêr */ [[Bikarhêner:Wikihez/templateScript2.js|TS]]: sererastkirin 6265731 wikitext text/x-wiki == {{ziman|ku}} == === Bilêvkirin === * {{ku-IPA}} * {{ku-kîte}} === Navdêr === {{ku-tewîn-nav|qepax|mê}} {{navdêr|ku|z=m}} # [[serik|Serik]]ê [[aman]]an yê ku kare were [[vekirin]] û [[girtin]]. #: {{hevmane|ku|derdank|devdank|serdank}} #: {{nm|ku|'''Qepaxê''' ji ser qazanê raneke daku girar sar nebe.}} #: {{nm|ku|'''Qepax''' ji ser qûşxanê rakir û birinc jê kir sênîka xwe.}} # Hin tiştên din yên dikarin bên [[vekirin]] û [[girtin]]. #: {{nm|ku|'''qepaxa''' çavî}} #: {{nm|ku|'''qepaxa''' pirtûkê|bergê pirtûkê}} ==== Formên alternatîv ==== * {{g|ku|qapax}} ==== Bide ber ==== * {{g|ku|qap}} ==== Jê ==== * {{g|ku|bêqepax}} * {{g|ku|biqepax}} * {{g|ku|qepaxdar}} * {{g|ku|qepaxdêr}} * {{g|ku|qepaxk}} ==== Etîmolojî ==== Ji {{ji|tr|ku|kapak}}. ==== Werger ==== {{werger-ser}} * {{Z|sq}}: {{W+|sq|kapak|m}} * {{Z|de}}: {{W+|de|Deckel|m}}, {{W+|de|Topfdeckel}}, {{W+|de|Glocke|f|guman=erê}}, {{W+|de|Abdeckung|f|guman=erê}} * {{Z|ar}}: {{W-|ar|غطاء}} (xêta) * {{Z|fa}}: {{W+|fa|دریچه}} * {{Z|fi}}: {{W+|fi|kansi}} * {{Z|fr}}: {{W+|fr|couvercle|m}} * {{Z|nl}}: {{W+|nl|deksel|n}} * {{Z|en}}: {{W+|en|lid}}, {{W+|en|deck}}, {{W+|en|cover}}, {{W+|en|closure|guman=erê}} * {{Z|it}}: {{W+|it|coperchio|m}} * {{Z|ca}}: {{W+|ca|tapa|f}} * {{Z|hu}}: {{W+|hu|fedél}} * {{Z|pt}}: {{W+|pt|tampa}} * {{Z|ro}}: {{W-|ro|capac}} / * {{Z|sh}}: {{W+|sh|poklopac|m}} * {{Z|te}}: {{W-|te|మూత|tr=moota}} * {{Z|tr}}: {{W+|tr|kapak}} {{werger-bin}} qflb0w7e9xe4ar6ft11bcw8a9czxh7b 6265732 6265731 2026-07-20T05:40:49Z Wikihez 7344 /* */ bi [[MediaWiki:Gadget-AjaxEdit.js|AjaxEdit]]ê re 6265732 wikitext text/x-wiki == {{ziman|ku}} == === Bilêvkirin === * {{ku-IPA}} * {{ku-kîte}} === Navdêr === {{ku-tewîn-nav|qepax|mê}} {{navdêr|ku|z=m}} # [[serik|Serik]]ê [[aman]]an yê ku kare were [[vekirin]] û [[girtin]]. #: {{hevmane|ku|derdank|devdank|serdank}} #: {{nm|ku|'''Qepaxê''' ji ser qazanê raneke daku girar sar nebe.}} #: {{nm|ku|'''Qepax''' ji ser qûşxanê rakir û birinc jê kir sênîka xwe.}} # Hin tiştên din yên dikarin bên [[vekirin]] û [[girtin]]. #: {{nm|ku|'''qepaxa''' çavî}} #: {{nm|ku|'''qepaxa''' pirtûkê|bergê pirtûkê|rêz=1}} ==== Formên alternatîv ==== * {{g|ku|qapax}} ==== Bide ber ==== * {{g|ku|qap}} ==== Jê ==== * {{g|ku|bêqepax}} * {{g|ku|biqepax}} * {{g|ku|qepaxdar}} * {{g|ku|qepaxdêr}} * {{g|ku|qepaxk}} ==== Etîmolojî ==== Ji {{ji|tr|ku|kapak}}. ==== Werger ==== {{werger-ser}} * {{Z|sq}}: {{W+|sq|kapak|m}} * {{Z|de}}: {{W+|de|Deckel|m}}, {{W+|de|Topfdeckel}}, {{W+|de|Glocke|f|guman=erê}}, {{W+|de|Abdeckung|f|guman=erê}} * {{Z|ar}}: {{W-|ar|غطاء}} (xêta) * {{Z|fa}}: {{W+|fa|دریچه}} * {{Z|fi}}: {{W+|fi|kansi}} * {{Z|fr}}: {{W+|fr|couvercle|m}} * {{Z|nl}}: {{W+|nl|deksel|n}} * {{Z|en}}: {{W+|en|lid}}, {{W+|en|deck}}, {{W+|en|cover}}, {{W+|en|closure|guman=erê}} * {{Z|it}}: {{W+|it|coperchio|m}} * {{Z|ca}}: {{W+|ca|tapa|f}} * {{Z|hu}}: {{W+|hu|fedél}} * {{Z|pt}}: {{W+|pt|tampa}} * {{Z|ro}}: {{W-|ro|capac}} / * {{Z|sh}}: {{W+|sh|poklopac|m}} * {{Z|te}}: {{W-|te|మూత|tr=moota}} * {{Z|tr}}: {{W+|tr|kapak}} {{werger-bin}} cs7l4p93qzxe4r5pxaalcs57rdpuw70 0 23753 6265796 6249219 2026-07-20T08:20:55Z Wikihez 7344 /* Hoker */ 6265796 wikitext text/x-wiki {{bnr-h|Ne|ne|nê|ne-|nê-}} == {{ziman|ku}} == === Bilêvkirin === * {{ku-kîte}} === Hoker === {{hoker|ku}} # [[jixwe]], [[manê]], [[nexwe]], [[zaten]] #: '''''Nê''' eger te bela xwe ji marî vekiriba, marî bi te venedida.'' #* {{jêder|ku|{{Jêgirtin/Mela Hisênê Bateyî/Mewlûda Kurdî}}|jêgirtin='''Nê''' ji me sûc û xeta tên û sîtem<br />Lê ji te îhsan û xufran û kerem}} #* {{jêder|ku|jêgirtin=Peyva “'''nê'''”: Di gelek berhemên klasîk da derbaz dibît, kelîmeyek e ku Hekkariyî hema hero bikartînin ku maneya wê “jixwe/zaten” e, lê hema bêje hemû gava ligel “jixwe” dihête karînan her wekî vê mîsalê: “nê jixwe min tu dîtibûy” lê bi [[tinka]] serê xwe jî dihête karînan, ji bo mînak: “'''nê''' tu nehatî da em bixebitin” anko bi nêzik mena “lê/lêbelê/feqet”, an jî wekî Bateyî dibêje: “Nê ji tirs û heybetê qed nanivî” ...|[[w:Ayhan Geverî|Ayhan Geverî]]: ''Mewlûda Bateyî û Pişavtina Devoka Hekarî'', Kovara [Nûbihar], hj. 79, 9/2006}} ==== Bide ber ==== {{stûn| * [[na]] * [[ne]] * [[ni-]] * [[nî]] * [[no]] * [[nû]] }} ==== Etîmolojî ==== Hevreha {{hv|fa-cls|اندی|tr=endê}}, {{hv|pal|tr=enê|w=lê, nexwe, neku, nê}}. Ramana serdest di [[sede]]nên dawîn de hatiye girtin û di wêjeya klasîk de wek ''[[lê]], [[lêbelê]]'' bi kar hatiye. ==== Werger ==== {{werger-ser}} * {{Z|en}}:{{W|en|you know|guman=erê}} {{werger-bin}} === Formeke lêkerê === {{lêker|ku|form=erê}} # [[neyê]] # [[nayê]] == {{ziman|zza}} == === Hoker === {{hoker|zza}} # [[na]] #: {{hevmane|zza|nêxêr}} #: {{dijmane|zza|eya}} ==== Formên alternatîv ==== * {{g|zza|ney}} === Cînav === {{cînav|zza}} # [[van]], [[ev]]: cînavê diyarker yê pirjimariyê #* {{jêder-kovar|zza|jêgirtin=Verî ke ez derheqê muhtewaya '''nê''' kitabê ma de malumatan bida şima, ez wazena nuştoxê nê kitabê ma, yanî Mela Mehemed Elîyê Hunî bida şinasnayîş.|werger=Berî ku ez li ser naveroka vê pirtûka me agadariyan bidim we, ez dixwazim nivîskarê vê pirtûka me anku Mela Mehemed Eliyê Hunî binasînim.|nivîskar=[[w:Roşan Lezgîn|Roşan Lezgîn]]|sernav=Mewlid – Yîsif û Zelîxa – Qesîdeyê Kerbela|kovar=Kovara Mehname|hejmar=80|sal=10/2006|wergêr=Husein Muhammed}} jisgjxa94efc8fqgr8b8sv7j0uq7fx6 bêwêne 0 30448 6265764 6133134 2026-07-20T07:00:22Z Wikihez 7344 /* {{ziman|ku}} */ [[Bikarhêner:Wikihez/templateScript2.js|TS]]: sererastkirin 6265764 wikitext text/x-wiki == {{ziman|ku}} == === Bilêvkirin === * {{ku-kîte}} === Rengdêr === {{ku-tewîn-rd|bêwêne}} {{rengdêr|ku}} # Tiştê ku [[wêne]] [[nînin]]. #: {{hevmane|ku|bêresim|bêdîmen|bêfoto|bêhempa}} #: {{nm|ku|pirtûkek bêwêne}} # Tiştê ku ti tiştek [[mîna]] wî [[nîne]]. #: {{hevmane|ku|yekta|yekane|unîk|bêmînak}} [[bênimûne]], [[bêmîsal]], #: {{nm|ku|qehremanek bêwêne}} #* {{jêdêr-kitêb|ku|jg=...li havîna sala 1983an, Rejîma Bexdadê bi fermana rastexwo ya Sedamê Dîttator, gunehkariyeke mezin a '''bêwêne''' (bêhempa) derheq mirovayetîyê da bi giştî û miletê Kurd bi taybetî encam pê da.|nivîskar=Sîyamend Sêlekî|sernav=Jinavbirina Berzaniyan|weşanxane=Pencînar|sal=2011|r=60}} ==== Jê ==== * {{g|ku|bêwênehî}} * {{g|ku|bêwênetî}} * {{g|ku|bêwêneyî}} ==== Etîmolojî ==== Ji {{qertaf|ku|bê-|wêne}}. ==== Werger ==== {{werger-ser}} * {{Z|ar}}: {{W-|ar|الفرد|guman=erê}} * {{Z|fi}}: {{W+|fi|uniikki}}, {{W+|fi|ainutlaatuinen}}, {{W+|fi|verraton}} * {{Z|en}}: {{W+|en|unparalleled}}, {{W+|en|formless|guman=erê}}, {{W+|en|shapeless|guman=erê}} * {{Z|en}}: {{W+|en|unique}} * {{Z|tr}}: {{W-|tr|resimsiz}}, {{W+|tr|sade}}, {{W+|tr|yekta}} {{werger-bin}} 815bff51q2ydd5srdwoqaz2ty0hirzm 6265765 6265764 2026-07-20T07:00:36Z Wikihez 7344 /* */ bi [[MediaWiki:Gadget-AjaxEdit.js|AjaxEdit]]ê re 6265765 wikitext text/x-wiki == {{ziman|ku}} == === Bilêvkirin === * {{ku-kîte}} === Rengdêr === {{ku-tewîn-rd|bêwêne}} {{rengdêr|ku}} # Tiştê ku [[wêne]] [[nînin]]. #: {{hevmane|ku|bêresim|bêdîmen|bêfoto|bêhempa}} #: {{nm|ku|pirtûkek bêwêne}} # Tiştê ku ti tiştek [[mîna]] wî [[nîne]]. #: {{hevmane|ku|yekta|yekane|unîk|bêmînak}} [[bênimûne]], [[bêmîsal]], #: {{nm|ku|qehremanek bêwêne}} #* {{jêder-kitêb|ku|jg=...li havîna sala 1983an, Rejîma Bexdadê bi fermana rastexwo ya Sedamê Dîttator, gunehkariyeke mezin a '''bêwêne''' (bêhempa) derheq mirovayetîyê da bi giştî û miletê Kurd bi taybetî encam pê da.|nivîskar=Sîyamend Sêlekî|sernav=Jinavbirina Berzaniyan|weşanxane=Pencînar|sal=2011|r=60}} ==== Jê ==== * {{g|ku|bêwênehî}} * {{g|ku|bêwênetî}} * {{g|ku|bêwêneyî}} ==== Etîmolojî ==== Ji {{qertaf|ku|bê-|wêne}}. ==== Werger ==== {{werger-ser}} * {{Z|ar}}: {{W-|ar|الفرد|guman=erê}} * {{Z|fi}}: {{W+|fi|uniikki}}, {{W+|fi|ainutlaatuinen}}, {{W+|fi|verraton}} * {{Z|en}}: {{W+|en|unparalleled}}, {{W+|en|formless|guman=erê}}, {{W+|en|shapeless|guman=erê}} * {{Z|en}}: {{W+|en|unique}} * {{Z|tr}}: {{W-|tr|resimsiz}}, {{W+|tr|sade}}, {{W+|tr|yekta}} {{werger-bin}} 4zjsa0pf48ptjlmk8041ep4qw0wpp3e 6265766 6265765 2026-07-20T07:00:55Z Wikihez 7344 6265766 wikitext text/x-wiki == {{ziman|ku}} == === Bilêvkirin === * {{ku-kîte}} === Rengdêr === {{ku-tewîn-rd|bêwêne}} {{rengdêr|ku}} # Tiştê ku [[wêne]] [[nînin]]. #: {{hevmane|ku|bêresim|bêdîmen|bêfoto|bêhempa}} #: {{nm|ku|pirtûkek bêwêne}} # Tiştê ku ti tiştek [[mîna]] wî [[nîne]]. #: {{hevmane|ku|yekta|yekane|unîk|bêmînak}} [[bênimûne]], [[bêmîsal]], #: {{nm|ku|qehremanek '''bêwêne'''}} #* {{jêder-kitêb|ku|jg=...li havîna sala 1983an, Rejîma Bexdadê bi fermana rastexwo ya Sedamê Dîttator, gunehkariyeke mezin a '''bêwêne''' (bêhempa) derheq mirovayetîyê da bi giştî û miletê Kurd bi taybetî encam pê da.|nivîskar=Sîyamend Sêlekî|sernav=Jinavbirina Berzaniyan|weşanxane=Pencînar|sal=2011|r=60}} ==== Jê ==== * {{g|ku|bêwênehî}} * {{g|ku|bêwênetî}} * {{g|ku|bêwêneyî}} ==== Etîmolojî ==== Ji {{qertaf|ku|bê-|wêne}}. ==== Werger ==== {{werger-ser}} * {{Z|ar}}: {{W-|ar|الفرد|guman=erê}} * {{Z|fi}}: {{W+|fi|uniikki}}, {{W+|fi|ainutlaatuinen}}, {{W+|fi|verraton}} * {{Z|en}}: {{W+|en|unparalleled}}, {{W+|en|formless|guman=erê}}, {{W+|en|shapeless|guman=erê}} * {{Z|en}}: {{W+|en|unique}} * {{Z|tr}}: {{W-|tr|resimsiz}}, {{W+|tr|sade}}, {{W+|tr|yekta}} {{werger-bin}} f0vw2kw7uv2pn5ftbsd0oni9j7o6788 stone 0 32266 6265668 6082755 2026-07-19T20:50:31Z Wikihez 7344 /* Navdêr */ [[Bikarhêner:Wikihez/templateScript2.js|TS]]: Ji [[en:stone|en.wikt]] 6265668 wikitext text/x-wiki == {{ziman|en}} == === Bilêvkirin === * {{deng|en|en-us-stone.ogg|dever=DYA}} * {{deng|en|LL-Q1860 (eng)-Nattes à chat-stone.wav|Deng|dever=}} * {{deng|en|LL-Q1860 (eng)-Back ache-stone.wav|Deng|dever=London, QY}} * {{deng|en|LL-Q1860 (eng)-Wodencafe-stone.wav|Deng|dever=Teksas, DYA}} === Navdêr === {{en-navdêr|~|+}} # [[kevir]], [[ber]], [[heshas]], [[kuç]], [[tat]], [[helan]], [[ferş]], [[berd]], [[zinar]], [[teht]] #* {{bêmînak|en}} === Lêker === {{lêker|en}} # [[ber baran kirin]] #* {{bêmînak|en}} 4g0pm7touwlaheb1rvnwko6d9gwxqq4 bêmîsal 0 34006 6265763 6133699 2026-07-20T06:57:49Z Wikihez 7344 [[Bikarhêner:Wikihez/templateScript2.js|TS]]: sererastkirin 6265763 wikitext text/x-wiki == {{ziman|ku}} == === Bilêvkirin === * {{ku-kîte}} === Rengdêr === {{ku-tewîn-rd|bêmîsal}} {{rengdêr|ku}} # Tiştê ti tişt [[mîna]] wê / wî [[nîne]]; ne wek ti tiştek [[din]]. #: {{hevmane|ku|yekta|yekane|unîk|bêwêne}} #* {{jêder|ku|{{Jêgirtin/Mela Hisênê Bateyî/Mewlûda Kurdî}}|jêgirtin=Ew Xudayê bê nezîr û zulcelal<br />Bêmîsal û bêheval û bêzewal}} ==== Jê ==== * {{g|ku|bêmîsalî}} * {{g|ku|bêmîsalîtî}} * {{g|ku|bêmîsaltî}} ==== Etîmolojî ==== Ji {{qertaf|ku|bê-|mîsal}}. ==== Werger ==== {{werger-ser}} * {{Z|tr}}: {{W+|tr|yekta}}, {{W+|tr|benzersiz}} {{werger-bin}} negp5e6z595uh2907ncft2tamja1bmn lewhe 0 40388 6265827 5931243 2026-07-20T09:12:41Z Wikihez 7344 [[Bikarhêner:Wikihez/templateScript2.js|TS]]: sererastkirin, [[Bikarhêner:Wikihez/templateScript2.js|TS]]: sererastkirin 6265827 wikitext text/x-wiki == {{ziman|ku}} == === Bilêvkirin === * {{ku-IPA}} * {{ku-kîte}} === Navdêr === {{ku-tewîn-nav|lewhe|nêr}} {{navdêr|ku|z=n}} # [[wêne|Wêne]]yê ku [[bi dest]] hatiye [[çêkirin]] û hatiye [[hilawîstin]]. #: {{hevmane|ku|tablo|keval|nîgar}} #* {{jêder|ku|{{Jêgirtin/Mela Hisênê Bateyî/Mewlûda Kurdî}}|jêgirtin=Niveka dî çêkirin jê çarî çîz</br>'Erş û kursî û qelem '''lewhe''' temîz</br>Hate emrê Padîşahê Layezal}} ==== Bi alfabeyên din ==== * {{ku-ar|لەوحە}} ==== Jê ==== * {{g|ku|lewheçêker}} * {{g|ku|lewhesaz}} * {{g|ku|lewhesazî}} * {{g|ku|lewhevan}} * {{g|ku|lewheyî}} * {{g|ku|lewhenivîsî}} ==== Etîmolojî ==== Ji {{ji|ar|ku|لوحة|tr=lewḥe}} ji {{ji|arc|ku|לוחא|tr=lewḥe}} ji {{ji|he|ku|לוח}} (bi taybetî [[tablo]]yê ku her deh [[ferman]]ên [[Mûsa]] pêxemberî li ser hatibûn [[nivîsîn]]). ==== Werger ==== {{werger-ser}} * {{Z|de}}: {{W|de|Tafel}} {{m}}, {{W|de|Schild}} {{n}}, {{W|de|Platte|f}} * {{Z|ar}}: {{W|ar|لوح}} * {{Z|fa}}: {{W|fa|لوح}}, {{W|fa|چارچوب}} * {{Z|en}}: {{W|en|tablet}}, {{W|en|view}} * {{Z|tr}}: {{W|tr|levha}}, {{W|tr|pafta}}, {{W|tr|safiha}}, {{W|tr|tabelâ}}, {{W|tr|tablet}}, {{W|tr|tablo}}, {{W|tr|plak}} {{werger-bin}} dginsz9vinjwoq6ucif53ce86pdionb 6265828 6265827 2026-07-20T09:12:50Z Wikihez 7344 /* */ bi [[MediaWiki:Gadget-AjaxEdit.js|AjaxEdit]]ê re 6265828 wikitext text/x-wiki == {{ziman|ku}} == === Bilêvkirin === * {{ku-IPA}} * {{ku-kîte}} === Navdêr === {{ku-tewîn-nav|lewhe|nêr}} {{navdêr|ku|z=n}} # [[wêne|Wêne]]yê ku [[bi dest]] hatiye [[çêkirin]] û hatiye [[hilawîstin]]. #: {{hevmane|ku|tablo|keval|nîgar}} #* {{Jêgirtin/Mela Hisênê Bateyî/Mewlûda Kurdî|jêgirtin=Niveka dî çêkirin jê çarî çîz</br>'Erş û kursî û qelem '''lewhe''' temîz</br>Hate emrê Padîşahê Layezal}} ==== Bi alfabeyên din ==== * {{ku-ar|لەوحە}} ==== Jê ==== * {{g|ku|lewheçêker}} * {{g|ku|lewhesaz}} * {{g|ku|lewhesazî}} * {{g|ku|lewhevan}} * {{g|ku|lewheyî}} * {{g|ku|lewhenivîsî}} ==== Etîmolojî ==== Ji {{ji|ar|ku|لوحة|tr=lewḥe}} ji {{ji|arc|ku|לוחא|tr=lewḥe}} ji {{ji|he|ku|לוח}} (bi taybetî [[tablo]]yê ku her deh [[ferman]]ên [[Mûsa]] pêxemberî li ser hatibûn [[nivîsîn]]). ==== Werger ==== {{werger-ser}} * {{Z|de}}: {{W|de|Tafel}} {{m}}, {{W|de|Schild}} {{n}}, {{W|de|Platte|f}} * {{Z|ar}}: {{W|ar|لوح}} * {{Z|fa}}: {{W|fa|لوح}}, {{W|fa|چارچوب}} * {{Z|en}}: {{W|en|tablet}}, {{W|en|view}} * {{Z|tr}}: {{W|tr|levha}}, {{W|tr|pafta}}, {{W|tr|safiha}}, {{W|tr|tabelâ}}, {{W|tr|tablet}}, {{W|tr|tablo}}, {{W|tr|plak}} {{werger-bin}} qjtxpi0z5xkhqi65mzdljfjynclnh4y rehîm 0 40690 6265795 6261760 2026-07-20T08:20:10Z Wikihez 7344 /* */ bi [[MediaWiki:Gadget-AjaxEdit.js|AjaxEdit]]ê re 6265795 wikitext text/x-wiki {{bnr-h|Rehîm}} == {{ziman|ku}} == === Bilêvkirin === * {{ku-IPA}} * {{deng|ku|LL-Q36163 (kmr)-Ebulfîda-rehîm.wav|Deng|Bidlîs}} * {{ku-kîte}} === Rengdêr === {{rengdêr|ku}} #[[dilovîn]], [[dilnerm]], [[mihrevan]], [[bexşende]], [[birehm]], [[piyar]], [[rehman]], [[muşfîq]], [[şefîq]] #* {{Jêgirtin/Mela Hisênê Bateyî/Mewlûda Kurdî|jêgirtin='''Rehîm''' û Rehman, letîf û mihriban</br>Bi navê Xwedayê dilnerm û dilovan}} ==== Formên alternatîv ==== * [[rahîm]] ==== Jê ==== * [[Rehîma]] * [[Rehîme]] * [[rehîmî]] * [[rehîmîtî]] * [[rehîmtî]] ==== Etîmolojî ==== Ji {{deyn|ar|ku|رَحِيم}}, têkildarî {{q|ku|rehm}}, {{q|ku|rehman}}, {{q|ku|merhemet}}. ==== Werger ==== {{werger-ser}} * {{Z|fa}}: {{W+|fa|بخشایشگر}} * {{Z|fi}}: {{W+|fi|armollinen}}, {{W+|fi|armelias}}, {{W-|fi|armahtaja}} * {{Z|fr}}: {{W+|fr|indulgent}} * {{Z|en}}: {{W+|en|merciful}} * {{Z|ca}}: {{W-|ca|misericordiós}}, {{W+|ca|pietat}}, {{W-|ca|pietós}}, {{W-|ca|piadós}}, {{W-|ca|compassiu}}, {{W+|ca|indulgent}}, {{W+|ca|comprensiu}}, {{W-|ca|perdonador}} * {{Z|es}}: {{W+|es|caritativo}} * {{Z|tr}}: {{W+|tr|merhametli}}, {{W+|tr|sevecan}}, {{W+|tr|müşfik}}, {{W+|tr|şefik}}, {{W+|tr|rakik}}, {{W+|tr|rahim}}, {{W+|tr|uterus}} {{werger-bin}} dnu56i2vileavgo2tqk8ft8npvmua28 eksen 0 40710 6265543 6265541 2026-07-19T12:03:41Z Wikihez 7344 6265543 wikitext text/x-wiki == {{ziman|ku}} == === Bilêvkirin === * {{ku-IPA}} * {{ku-kîte}} === Navdêr === {{navdêr|ku|z=n}} # [[xet|Xet]]a [[xeyalî]] ya ku tiştek li dor [[zivirîn|dizivire]]. #:[[mihwer]], [[tewere]], [[mijane]], #:[[dingil]], [[germiçank]], [[sirnî]], #:''Zemîn her roj carekê li dor eksenê xwe dizivire.'' ==== Etîmolojî ==== Bi riya {{deyn|tr|ku|eksen}} ji {{ji|el|ku|άξων|tr=akson|w=mihwer}}. ==== Werger ==== {{werger-ser}} * {{Z|fi}}: {{W+|fi|akseli}} * {{Z|en}}: {{W+|en|axis}}, {{W+|en|axle}} * {{Z|tr}}: {{W+|tr|eksen}}, {{W+|tr|mihver}} {{werger-bin}} == {{ziman|tr}} == === Navdêr === {{navdêr|tr}} # [[tewere]], [[germiçank]] #* {{bêmînak|tr}} # [[mijane]], [[sirnî]], [[şaft]] #: {{nm|ku|'''Mijaneya''' matorê nazivire.}} 3z96v1sje6u135qau4s1ut5fceh04pf 6265544 6265543 2026-07-19T12:04:12Z Wikihez 7344 /* */ bi [[MediaWiki:Gadget-AjaxEdit.js|AjaxEdit]]ê re 6265544 wikitext text/x-wiki == {{ziman|ku}} == === Bilêvkirin === * {{ku-IPA}} * {{ku-kîte}} === Navdêr === {{navdêr|ku|z=n}} # [[xet|Xet]]a [[xeyalî]] ya ku tiştek li dor [[zivirîn|dizivire]]. #:[[mihwer]], [[tewere]], [[mijane]], #:[[dingil]], [[germiçank]], [[sirnî]], #:''Zemîn her roj carekê li dor eksenê xwe dizivire.'' ==== Etîmolojî ==== Bi riya {{deyn|tr|ku|eksen}} ji {{ji|el|ku|άξων|tr=akson|w=mihwer}}. ==== Werger ==== {{werger-ser}} * {{Z|fi}}: {{W+|fi|akseli}} * {{Z|en}}: {{W+|en|axis}}, {{W+|en|axle}} * {{Z|tr}}: {{W+|tr|eksen}}, {{W+|tr|mihver}} {{werger-bin}} == {{ziman|tr}} == === Navdêr === {{navdêr|tr}} # [[tewere]], [[germiçank]] #* {{bêmînak|tr}} # [[mijane]], [[sirnî]], [[şaft]] #: {{nm|tr||Mijaneya matorê nazivire.}} 5ir2o7w2yqil2qw33cl26fdyq2qeb3m 6265545 6265544 2026-07-19T12:04:47Z Wikihez 7344 [[Bikarhêner:Wikihez/templateScript2.js|TS]]: sererastkirin 6265545 wikitext text/x-wiki == {{ziman|ku}} == === Bilêvkirin === * {{ku-IPA}} * {{ku-kîte}} === Navdêr === {{navdêr|ku|z=n}} # [[xet|Xet]]a [[xeyalî]] ya ku tiştek li dor [[zivirîn|dizivire]]. #: {{hevmane|ku|mihwer|tewere|mijane|dingil|germiçank|sirnî}} #: {{nm|ku|Zemîn her roj carekê li dor eksenê xwe dizivire.}} ==== Etîmolojî ==== Bi riya {{deyn|tr|ku|eksen}} ji {{ji|el|ku|άξων|tr=akson|w=mihwer}}. ==== Werger ==== {{werger-ser}} * {{Z|fi}}: {{W+|fi|akseli}} * {{Z|en}}: {{W+|en|axis}}, {{W+|en|axle}} * {{Z|tr}}: {{W+|tr|eksen}}, {{W+|tr|mihver}} {{werger-bin}} == {{ziman|tr}} == === Navdêr === {{navdêr|tr}} # [[tewere]], [[germiçank]] #* {{bêmînak|tr}} # [[mijane]], [[sirnî]], [[şaft]] #: {{nm|tr||Mijaneya matorê nazivire.}} 85p8knnw2psgrrgem7ummtl42kp3hoi 6265546 6265545 2026-07-19T12:05:19Z Wikihez 7344 /* */ bi [[MediaWiki:Gadget-AjaxEdit.js|AjaxEdit]]ê re 6265546 wikitext text/x-wiki == {{ziman|ku}} == === Bilêvkirin === * {{ku-IPA}} * {{ku-kîte}} === Navdêr === {{navdêr|ku|z=n}} # [[xet|Xet]]a [[xeyalî]] ya ku tiştek li dor [[zivirîn|dizivire]]. #: {{hevmane|ku|mihwer|tewere|mijane|dingil|germiçank|sirnî}} #: {{nm|ku|Zemîn her roj carekê li dor '''eksenê''' xwe dizivire.}} ==== Etîmolojî ==== Bi riya {{deyn|tr|ku|eksen}} ji {{ji|el|ku|άξων|tr=akson|w=mihwer}}. ==== Werger ==== {{werger-ser}} * {{Z|fi}}: {{W+|fi|akseli}} * {{Z|en}}: {{W+|en|axis}}, {{W+|en|axle}} * {{Z|tr}}: {{W+|tr|eksen}}, {{W+|tr|mihver}} {{werger-bin}} == {{ziman|tr}} == === Navdêr === {{navdêr|tr}} # [[tewere]], [[germiçank]] #* {{bêmînak|tr}} # [[mijane]], [[sirnî]], [[şaft]] #: {{nm|tr||Mijaneya matorê nazivire.}} aa17nq2n5cwe8ftk9pxhaelcin7t2oh îlhes 0 43795 6265730 6250801 2026-07-20T05:37:06Z Wikihez 7344 [[Bikarhêner:Wikihez/templateScript2.js|TS]]: sererastkirin 6265730 wikitext text/x-wiki == {{ziman|ku}} == === Bilêvkirin === * {{ku-kîte}} === Hoker === {{hoker|ku}} # [[xasma]], [[bi taybetî]], [[xaseten]], [[nemaze]], [[nexwasma]], [[xusûsen]] #* {{jêder|ku|jêgirtin=Hinarên Dêrikê, hijîr, tirî û '''îlhes''' jî zeytûnên wê bi nav û deng in/bûn. Av û kaniyên wê mekanê keç û xortên bermirad in ko bi dengên serxwînk û bilbilan re dixuşxuşin.|Enwer Karahan: ''Kêvo'', Nefel.com, 8/2007}} ==== Formên alternatîv ==== * {{g|ku|îlhas}} * {{g|ku|îlxas}} ==== Etîmolojî ==== Ji {{ji|ar|ku}} ==== Werger ==== {{werger-ser}} * {{Z|af}}: {{W|af|hoofsaaklik}} * {{Z|sq}}: {{W|sq|kryesisht}} * {{Z|de}}: {{W|de|hauptsächlich}}, {{W|de|in der Hauptsache}}, {{W|de|ausdrücklich}}, {{W|de|besonders}}, {{W|de|speziell}}, {{W|de|eigens}}, {{W|de|getrennt}}, {{W|de|für sich}}, {{W|de|selten}} * {{Z|eo}}: {{W|eo|ĉefe}}, {{W|eo|speciale}}, {{W|eo|aparte}} * {{Z|fo}}: {{W|fo|serliga}}, {{W|fo|fyri seg}} * {{Z|fi}}: {{W|fi|erityisesti}}, {{W|fi|etenkin}}, {{W|fi|varsinkin}} * {{Z|fr}}: {{W|fr|particulièrement}}, {{W|fr|autrement}}, {{W|fr|considérablement}}, {{W|fr|en particulier}}, {{W|fr|expressément}}, {{W|fr|extrêmement}}, {{W|fr|principalement}}, {{W|fr|prodigieusement}}, {{W|fr|singulièrement}}, {{W|fr|surtout}} * {{Z|nl}}: {{W|nl|hoofdzakelijk}}, {{W|nl|inzonderheid}}, {{W|nl|voornamelijk}}, {{W|nl|in het bijzonder}}, {{W|nl|speciaal}}, {{W|nl|vooral}}, {{W|nl|afzonderlijk}}, {{W|nl|apart}}, {{W|nl|gescheiden}}, {{W|nl|terzijde}}, {{W|nl|vaneen}} * {{Z|en}}: {{W|en|especially}} ; {{W|en|in particular}} ; {{W|en|particularly}}, {{W|en|chiefly}}, {{W|en|principally}}, {{W|en|apart}}, {{W|en|separately}} * {{Z|it}}: {{W|it|particolarmente}}, {{W|it|principalmente}}, {{W|it|soprattutto}} * {{Z|ca}}: {{W|ca|cabdalment}}, {{W|ca|principalment}} * {{Z|la}}: {{W|la|potissimum}} * {{Z|hu}}: {{W|hu|főleg}}, {{W|hu|különösen}} * {{Z|oc}}: {{W|oc|particularment}} * {{Z|pl}}: {{W|pl|głównie}}, {{W|pl|osobno}}, {{W|pl|oddzielnie}}, {{W|pl|szczególnie}} * {{Z|pt}}: {{W|pt|principalmente}}, {{W|pt|à parte}}, {{W|pt|em separado}} * {{Z|es}}: {{W|es|particularmente}}, {{W|es|principalmente}}, {{W|es|sobretodo}}, {{W|es|aparte}}, {{W|es|por separado}} * {{Z|tr}}: {{W|tr|ayrı}} {{werger-bin}} qg2m2pv3dupkv3h0umxxtvaip2p4pll nazil 0 45241 6265782 6135398 2026-07-20T08:13:22Z Wikihez 7344 /* Navdêr */ [[Bikarhêner:Wikihez/templateScript2.js|TS]]: sererastkirin 6265782 wikitext text/x-wiki == {{ziman|ku}} == === Bilêvkirin === * {{ku-kîte}} === Navdêr === {{ku-tewîn-nav|nazil|mê}} {{navdêr|ku|z=m}} # {{f|ku|Îslam}} [[dahatin|Dahatin]]a [[peyam]]ekê ji alî [[xweda|Xwedê]] ve bo [[pêxember]]ekî. #: {{hevmane|ku|wehî}} #: {{nm|ku|Tê bawerkirin ku Quran di meha remezanê de ji Mihemed-pêxember re '''nazil''' bûye.}} #* {{jêder|ku|{{Jêgirtin/Mela Hisênê Bateyî/Mewlûda Kurdî}}|jêgirtin=Rehmî '''nazil''' cumleê 'îlet dibit</br>Her cihê lê bête xwendin rehmet lê}} ==== Bide ber ==== * {{g|ku|nazik}} ==== Etîmolojî ==== Ji {{ji|ar|ku}} ==== Werger ==== {{werger-ser}} * {{Z|tr}}: {{W+|tr|nazil}} {{werger-bin}} == {{ziman|tr}} == === Rengdêr === {{rengdêr|tr}} # [[dahatin]], [[nazil]] #* {{bêmînak|tr}} # ê ku qûnax datîne #* {{bêmînak|tr}} 5t9iqchvhi0pmt0eriuf2ftfj5t1o9g 6265783 6265782 2026-07-20T08:13:35Z Wikihez 7344 /* */ bi [[MediaWiki:Gadget-AjaxEdit.js|AjaxEdit]]ê re 6265783 wikitext text/x-wiki == {{ziman|ku}} == === Bilêvkirin === * {{ku-kîte}} === Navdêr === {{ku-tewîn-nav|nazil|mê}} {{navdêr|ku|z=m}} # {{f|ku|Îslam}} [[dahatin|Dahatin]]a [[peyam]]ekê ji alî [[xweda|Xwedê]] ve bo [[pêxember]]ekî. #: {{hevmane|ku|wehî}} #: {{nm|ku|Tê bawerkirin ku Quran di meha remezanê de ji Mihemed-pêxember re '''nazil''' bûye.}} #* {{Jêgirtin/Mela Hisênê Bateyî/Mewlûda Kurdî|jêgirtin=Rehmî '''nazil''' cumleê 'îlet dibit</br>Her cihê lê bête xwendin rehmet lê}} ==== Bide ber ==== * {{g|ku|nazik}} ==== Etîmolojî ==== Ji {{ji|ar|ku}} ==== Werger ==== {{werger-ser}} * {{Z|tr}}: {{W+|tr|nazil}} {{werger-bin}} == {{ziman|tr}} == === Rengdêr === {{rengdêr|tr}} # [[dahatin]], [[nazil]] #* {{bêmînak|tr}} # ê ku qûnax datîne #* {{bêmînak|tr}} 53agkvtceqmerqq94rxic9ld07gqbi6 wesselam 0 46750 6265744 6250988 2026-07-20T06:01:39Z Wikihez 7344 6265744 wikitext text/x-wiki == {{ziman|ku}} == === Bilêvkirin === * {{ku-kîte}} === Rengdêr === {{ku-tewîn-rd|wesselam}} {{rengdêr|ku}} # {{i|li dawiya gotinekê yan nivîsekê}} û [[silav]] û [[rêz]] #* {{jêder|ku|{{Jêgirtin/Mela Hisênê Bateyî/Mewlûda Kurdî}}|jêgirtin=Ya Reb, îmanê dixwazin em mudam<br />Jêrê alaya Muhemmed '''wesselam'''}} ==== Formên alternatîv ==== * [[we sellam]] * [[we selam]] * [[weselam]] ==== Etîmolojî ==== Ji {{deyn|ar|ku}} ji îfadeya {{q|ar|والسلام عليكم ورحمة الله وبركاته|وَالسَّلَامُ عَلَيْكُمْ وَرَحْمَةُ اللّٰهِ وَبَرَكَاتُهُ}} ==== Werger ==== {{werger-ser}} * {{Z|tr}}: {{W+|tr|vesselam}}, {{W-|tr|vesselâm}} {{werger-bin}} es3w5cdqdq9n6ox4t2yfuks912ks3v7 6265745 6265744 2026-07-20T06:02:03Z Wikihez 7344 /* */ bi [[MediaWiki:Gadget-AjaxEdit.js|AjaxEdit]]ê re 6265745 wikitext text/x-wiki == {{ziman|ku}} == === Bilêvkirin === * {{ku-kîte}} === Rengdêr === {{ku-tewîn-rd|wesselam}} {{rengdêr|ku}} # {{i|li dawiya gotinekê yan nivîsekê}} û [[silav]] û [[rêz]] #* {{jêder|ku|{{Jêgirtin/Mela Hisênê Bateyî/Mewlûda Kurdî}}|jêgirtin=Ya Reb, îmanê dixwazin em mudam<br />Jêrê alaya Muhemmed '''wesselam'''}} ==== Formên alternatîv ==== * [[we sellam]] * [[we selam]] * [[weselam]] ==== Etîmolojî ==== Ji {{deyn|ar|ku}} ji îfadeya {{q|ar|والسلام عليكم ورحمة الله وبركاته|وَالسَّلَامُ عَلَيْكُمْ وَرَحْمَةُ اللّٰهِ وَبَرَكَاتُهُ|tr=wa-s-salāmu ʕalaykum wa-raḥmatu llāhi wa-barakātuhu|}} ==== Werger ==== {{werger-ser}} * {{Z|tr}}: {{W+|tr|vesselam}}, {{W-|tr|vesselâm}} {{werger-bin}} 6x8dxriatjbj32cwfkh2ncaxbiffvju 6265746 6265745 2026-07-20T06:02:09Z Wikihez 7344 /* */ bi [[MediaWiki:Gadget-AjaxEdit.js|AjaxEdit]]ê re 6265746 wikitext text/x-wiki == {{ziman|ku}} == === Bilêvkirin === * {{ku-kîte}} === Rengdêr === {{ku-tewîn-rd|wesselam}} {{rengdêr|ku}} # {{i|li dawiya gotinekê yan nivîsekê}} û [[silav]] û [[rêz]] #* {{jêder|ku|{{Jêgirtin/Mela Hisênê Bateyî/Mewlûda Kurdî}}|jêgirtin=Ya Reb, îmanê dixwazin em mudam<br />Jêrê alaya Muhemmed '''wesselam'''}} ==== Formên alternatîv ==== * [[we sellam]] * [[we selam]] * [[weselam]] ==== Etîmolojî ==== Ji {{deyn|ar|ku}} ji îfadeya {{q|ar|والسلام عليكم ورحمة الله وبركاته|وَالسَّلَامُ عَلَيْكُمْ وَرَحْمَةُ اللّٰهِ وَبَرَكَاتُهُ|tr=wa-s-salāmu ʕalaykum wa-raḥmatu llāhi wa-barakātuhu}} ==== Werger ==== {{werger-ser}} * {{Z|tr}}: {{W+|tr|vesselam}}, {{W-|tr|vesselâm}} {{werger-bin}} doobmuwyd3x68m4mdowh4lqdikkorfu 6265747 6265746 2026-07-20T06:02:42Z Wikihez 7344 6265747 wikitext text/x-wiki == {{ziman|ku}} == === Bilêvkirin === * {{ku-kîte}} === Baneşan === {{baneşan|ku}} # {{i|li dawiya gotinekê yan nivîsekê}} û [[silav]] û [[rêz]] #* {{jêder|ku|{{Jêgirtin/Mela Hisênê Bateyî/Mewlûda Kurdî}}|jêgirtin=Ya Reb, îmanê dixwazin em mudam<br />Jêrê alaya Muhemmed '''wesselam'''}} ==== Formên alternatîv ==== * [[we sellam]] * [[we selam]] * [[weselam]] ==== Etîmolojî ==== Ji {{deyn|ar|ku}} ji îfadeya {{q|ar|والسلام عليكم ورحمة الله وبركاته|وَالسَّلَامُ عَلَيْكُمْ وَرَحْمَةُ اللّٰهِ وَبَرَكَاتُهُ|tr=wa-s-salāmu ʕalaykum wa-raḥmatu llāhi wa-barakātuhu}} ==== Werger ==== {{werger-ser}} * {{Z|tr}}: {{W+|tr|vesselam}}, {{W-|tr|vesselâm}} {{werger-bin}} m88k9xaggy6dbnack5bw0jddf364bbu 6265749 6265747 2026-07-20T06:03:47Z Wikihez 7344 6265749 wikitext text/x-wiki == {{ziman|ku}} == === Bilêvkirin === * {{ku-kîte}} === Baneşan === {{baneşan|ku}} # {{i|li dawiya gotinekê yan nivîsekê}} [[silav]] û [[rêz]], [[ew qas]], gotina dawî ev e #* {{jêder|ku|{{Jêgirtin/Mela Hisênê Bateyî/Mewlûda Kurdî}}|jêgirtin=Ya Reb, îmanê dixwazin em mudam<br />Jêrê alaya Muhemmed '''wesselam'''}} ==== Formên alternatîv ==== * [[we sellam]] * [[we selam]] * [[weselam]] ==== Etîmolojî ==== Ji {{deyn|ar|ku}} ji îfadeya {{q|ar|والسلام عليكم ورحمة الله وبركاته|وَالسَّلَامُ عَلَيْكُمْ وَرَحْمَةُ اللّٰهِ وَبَرَكَاتُهُ|tr=wa-s-salāmu ʕalaykum wa-raḥmatu llāhi wa-barakātuhu}} ==== Werger ==== {{werger-ser}} * {{Z|tr}}: {{W+|tr|vesselam}}, {{W-|tr|vesselâm}} {{werger-bin}} 3fosvvsp4jcox0k4a0jx5unqjx42ka5 6265790 6265749 2026-07-20T08:16:16Z Wikihez 7344 [[Bikarhêner:Wikihez/templateScript2.js|TS]]: sererastkirin 6265790 wikitext text/x-wiki == {{ziman|ku}} == === Bilêvkirin === * {{ku-kîte}} === Baneşan === {{baneşan|ku}} # {{i|li dawiya gotinekê yan nivîsekê}} [[silav]] û [[rêz]], [[ew qas]], gotina dawî ev e #* {{Jêgirtin/Mela Hisênê Bateyî/Mewlûda Kurdî|jêgirtin=Ya Reb, îmanê dixwazin em mudam<br />Jêrê alaya Muhemmed '''wesselam'''}} ==== Formên alternatîv ==== * {{g|ku|we sellam}} * {{g|ku|we selam}} * {{g|ku|weselam}} ==== Etîmolojî ==== Ji {{deyn|ar|ku}} ji îfadeya {{q|ar|والسلام عليكم ورحمة الله وبركاته|وَالسَّلَامُ عَلَيْكُمْ وَرَحْمَةُ اللّٰهِ وَبَرَكَاتُهُ|tr=wa-s-salāmu ʕalaykum wa-raḥmatu llāhi wa-barakātuhu}} ==== Werger ==== {{werger-ser}} * {{Z|tr}}: {{W+|tr|vesselam}}, {{W-|tr|vesselâm}} {{werger-bin}} pfqwlpk629oyeyh660axiuc2sk46a2g muqteda 0 55171 6265743 6138094 2026-07-20T05:59:32Z Wikihez 7344 6265743 wikitext text/x-wiki == {{ziman|ku}} == === Bilêvkirin === * {{ku-kîte}} === Navdêr === {{navdêr|ku|z=mn}} # [[pêşeng]], [[pêşewa]], [[pêşrew]], [[birêveber]] #* {{jêder|ku|{{Jêgirtin/Mela Hisênê Bateyî/Mewlûda Kurdî}}|jêgirtin=Hemdê bêhed bo Xudayê 'alemîn<br>Ew Xudayê da ye me dînê mubîn<br><br>Em kirine ummeta xeyr-ul beşer<br>Tabi'ê wî [[muqteda]]yê namûwer.}} ==== Etîmolojî ==== Ji {{ji|ar}}. ==== Werger ==== {{werger-ser}} {{werger-bin}} sl8jac3yzg5ng55iwf8b0m1cfw7ziz9 namuwer 0 55464 6265799 6138127 2026-07-20T08:26:40Z Wikihez 7344 6265799 wikitext text/x-wiki == {{ziman|ku}} == === Bilêvkirin === * {{ku-kîte}} === Rengdêr === {{ku-tewîn-rd|namuwer}} {{rengdêr|ku}} # [[navdar]], [[binavûdeng]] #* {{mewlûd|jg=Paşê Wî çêkir ji nûra '''namuwer'''<br>Cewherek lê kir nezer ew bû du ker}} ==== Etîmolojî ==== Ji {{deyn|fa|ku}}. 3ngo8pa6d52jnyp1wwcpaag52e079fu 6265800 6265799 2026-07-20T08:26:47Z Wikihez 7344 /* */ bi [[MediaWiki:Gadget-AjaxEdit.js|AjaxEdit]]ê re 6265800 wikitext text/x-wiki == {{ziman|ku}} == === Bilêvkirin === * {{ku-kîte}} === Rengdêr === {{ku-tewîn-rd|namuwer}} {{rengdêr|ku}} # [[navdar]], [[binavûdeng]] #* {{mewlûd|jg=Paşê Wî çêkir ji nûra '''namuwer'''<br>Cewherek lê kir nezer ew bû du ker}} ==== Etîmolojî ==== Ji {{deyn|fa|ku}}. kqiftobmvynxwrft3xmlcplj9us2vld sîma 0 55468 6265802 5931862 2026-07-20T08:27:57Z Wikihez 7344 /* */ bi [[MediaWiki:Gadget-AjaxEdit.js|AjaxEdit]]ê re 6265802 wikitext text/x-wiki == {{ziman|ku}} == === Bilêvkirin === * {{ku-IPA}} * {{ku-kîte}} === Navdêr === {{navdêr|ku|z=n}} # [[rû|Rû]], [[dêm]], [[xwiyang]], [[serçav]], [[rûxsar]], [[şikil]], [[xasiyet]]. #* {{Jêgirtin/Mela Hisênê Bateyî/Mewlûda Kurdî|jêgirtin=Ew kelîmê xweşnewayê çerxî tûr</br>Daxîdar im bo wî '''sîma'''yê bi nûr}} ==== Bi alfabeyên din ==== * {{ku-ar|سیما}} ==== Bide ber ==== * [[sema]] ==== Jê ==== * [[serûsîma]] ==== Etîmolojî ==== {{bêetîmolojî}} ==== Werger ==== {{werger-ser}} * {{Z|ar}}: {{W-|ar|خصلة}}, {{W-|ar|سيماء}} * {{Z|fa}}: {{W+|fa|آبرو}}, {{W+|fa|سیما}}, {{W+|fa|صورت}}, {{W+|fa|لقا}}, {{W+|fa|سیما}}, {{W+|fa|رو}} * {{Z|en}}: {{W+|en|face}}, {{W+|en|appearance}}, {{W+|en|looking}}, {{W+|en|form}} * {{Z|tr}}: {{W+|tr|sima}}, {{W+|tr|yüz}}, {{W+|tr|çehre}} {{werger-bin}} f66mii01770fmo4q9uodrctvacc6skr facir 0 55488 6265757 6138132 2026-07-20T06:08:27Z Wikihez 7344 [[Bikarhêner:Wikihez/templateScript2.js|TS]]: sererastkirin 6265757 wikitext text/x-wiki == {{ziman|ku}} == === Bilêvkirin === * {{ku-kîte}} === Navdêr === {{navdêr|ku}} # [[gunehkar]] #* {{jêder|ku|{{Jêgirtin/Mela Hisênê Bateyî/Mewlûda Kurdî}}|jêgirtin=Hate eslabê butunî tahir e</br>Qet nebû yek jî, xerab û '''facir''' e}} ====Bide ber==== * {{g|ku|fecir}} ==== Binêre herwiha ==== * {{g|ku|faxir}} ==== Etîmolojî ==== Ji {{ji|ar|ku}} ==== Werger ==== {{werger-ser}} * {{Z|fa}}: {{W+|fa|گناهکار بزرگ}} {{werger-bin}} rmgp5mzhrqsam7ckppqiaksvtc6ykcf mudam 0 55496 6265822 6138135 2026-07-20T09:07:46Z Wikihez 7344 6265822 wikitext text/x-wiki == {{ziman|ku}} == === Bilêvkirin === * {{ku-kîte}} === Rengdêr === {{ku-tewîn-rd|mudam}} {{rengdêr|ku}} # [[herdem]], [[berdewam]] #* {{mewlûd|jg=Ya Reb, îmanê dixwazin em '''mudam'''<br>Jêrê alaya Muhemmed wesselam}} ==== Etîmolojî ==== Ji {{deyn|ar|ku}} q83ehjcn64zz31d2vhmat3jcl1vadav necat 0 55498 6265833 5784450 2026-07-20T09:20:57Z Wikihez 7344 /* {{ziman|ku}} */ 6265833 wikitext text/x-wiki == {{ziman|ku}} == === Navdêr === {{navdêr|ku}} # [[rizgar]], [[azad]], [[parastî]] #* {{mewlûd|jg=Ger divêtin hûn ji narê bin '''necat'''<br>Bi 'işq û şewqek hûn bibêjin esselat}} == {{ziman|la}} == === Formeke lêkerê === {{lêker|la|form=erê}} # {{la-dema-niha|necare|sêyem|yekjimar}} gbp7e4vpojp4q6q1jihfq9wml1fhewq 6265834 6265833 2026-07-20T09:21:07Z Wikihez 7344 /* {{ziman|ku}} */ 6265834 wikitext text/x-wiki == {{ziman|ku}} == === Navdêr === {{navdêr|ku}} # [[rizgar]], [[azad]], [[parastî]] #* {{mewlûd|jg=Ger divêtin hûn ji narê bin '''necat'''<br>Bi 'işq û şewqek hûn bibêjin esselat}} ==== Etîmolojî ==== {{bêetîmolojî}} ==== Werger ==== {{werger-ser}} {{werger-bin}} == {{ziman|la}} == === Formeke lêkerê === {{lêker|la|form=erê}} # {{la-dema-niha|necare|sêyem|yekjimar}} ddm5w1qkt8gb7qmvh131ic1vs9p731m çihar 0 55536 6265778 6251767 2026-07-20T08:09:27Z Wikihez 7344 6265778 wikitext text/x-wiki == {{ziman|ku}} == === Bilêvkirin === * {{ku-kîte}} === Hejmar === {{hejmar|ku}} # [[çar]], [[4]] #* {{mewlûd|Paşê avête '''çihar''' behrê mezin<br>Wî Xudayê “Layezalê” ins û cin}} ==== Formên alternatîv ==== * [[çehar]] ==== Etîmolojî ==== Ji {{deyn|fa|ku}} ==== Werger ==== {{werger-bnr|çar}} kvobtu6ms37jl6s66zl05z7z5vpi174 6265779 6265778 2026-07-20T08:11:51Z Wikihez 7344 /* */ bi [[MediaWiki:Gadget-AjaxEdit.js|AjaxEdit]]ê re 6265779 wikitext text/x-wiki == {{ziman|ku}} == === Bilêvkirin === * {{ku-kîte}} === Hejmar === {{hejmar|ku}} # [[çar]], [[4]] #* {{mewlûd|jg=Paşê avête '''çihar''' behrê mezin<br>Wî Xudayê “Layezalê” ins û cin}} ==== Formên alternatîv ==== * [[çehar]] ==== Etîmolojî ==== Ji {{deyn|fa|ku}} ==== Werger ==== {{werger-bnr|çar}} frs0gkhm7zlmbo8ragqzzssvuh2uxe4 6265780 6265779 2026-07-20T08:12:14Z Wikihez 7344 /* */ bi [[MediaWiki:Gadget-AjaxEdit.js|AjaxEdit]]ê re 6265780 wikitext text/x-wiki == {{ziman|ku}} == === Bilêvkirin === * {{ku-kîte}} === Hejmar === {{hejmar|ku}} # [[çar]], [[4]] #* {{mewlûd|jg=Paşê avête '''çihar''' behrê mezin<br>Wî Xudayê “Layezalê” ins û cin}} ==== Formên alternatîv ==== * [[çehar]] ==== Etîmolojî ==== Ji {{deyn|fa|ku|چهار|tr=čahâr}}. ==== Werger ==== {{werger-bnr|çar}} i88lpbjzm8dklezrub9g9xq028u3fol miskal 0 154585 6265716 4619436 2026-07-20T01:03:52Z Wikihez 7344 6265716 wikitext text/x-wiki == {{ziman|tr}} == === Navdêr === {{navdêr|tr}} # [[misqal]] ([[yeke|yekeya]] [[pîvan|pîvana]] [[giranî|giraniyê]] [[ya ku]] [[bi qasî]] [[dirhem]] û [[nîv]] e) 50zrpogtf3cwlrtlkfz7l48vzsj59be 6265717 6265716 2026-07-20T01:04:02Z Wikihez 7344 [[Bikarhêner:Wikihez/templateScript2.js|TS]]: +[[Şablon:îzah|îzah]] 6265717 wikitext text/x-wiki == {{ziman|tr}} == === Navdêr === {{navdêr|tr}} # [[misqal]] {{îzah|[[yeke|yekeya]] [[pîvan|pîvana]] [[giranî|giraniyê]] [[ya ku]] [[bi qasî]] [[dirhem]] û [[nîv]] e}} i2yg5uwwiy4xd0zhlduqh07i1andxfo usta elinden çıkmak 0 169203 6265625 4644472 2026-07-19T17:09:32Z Wikihez 7344 /* */ bi [[MediaWiki:Gadget-AjaxEdit.js|AjaxEdit]]ê re 6265625 wikitext text/x-wiki == {{ziman|tr}} == === Lêker === {{lêker|tr|c=b}} # ji destê hosteyê xwe derketin t4986bwpoycb97w4ul5ak4q2ck6yvuu vesselam 0 170021 6265748 5802944 2026-07-20T06:02:54Z Wikihez 7344 6265748 wikitext text/x-wiki == {{ziman|tr}} == === Baneşan === {{baneşan|tr}} # [[wesselam]] lwtb3p8vwgdjkq34fd8u2e5fnpinad9 6265750 5801550 2026-07-20T06:04:10Z Wikihez 7344 Wikihezî/ê navê [[vesselâm]] weke [[vesselam]] guhart 5801550 wikitext text/x-wiki == {{ziman|tr}} == === Mane === {{cure?|tr}} # [[ew qas]], gotina dawî ev e, [[weselam]] j2r6evq58ciiuclsd6vrnvz151ftnih 6265752 6265750 2026-07-20T06:04:56Z Wikihez 7344 6265752 wikitext text/x-wiki == {{ziman|tr}} == === Baneşan === {{baneşan|tr}} # [[weselam]] {{îzah|[[ew qas]], gotina dawî ev e}} dzhfp2dgwjn93hgdzyh2h4d2cdc6nd0 6265753 6265752 2026-07-20T06:05:15Z Wikihez 7344 6265753 wikitext text/x-wiki == {{ziman|tr}} == === Baneşan === {{baneşan|tr}} # [[weselam]] {{îzah|[[ew qas]], [[gotin|gotina]] [[dawî]] [[ev e]]}} 9gomkwsjo05d55trdr88j9tvpwcjkjl bereyîşk 0 178328 6265598 5784523 2026-07-19T15:47:05Z Wikihez 7344 6265598 wikitext text/x-wiki == {{ziman|ku}} == === Bilêvkirin === * {{ku-kîte}} === Navdêr === {{navdêr|ku|c=?}} # [[mencenîq]] #* {{bênimûne|ku}} ==== Etîmolojî ==== {{bêetîmolojî}} ==== Werger ==== {{werger-ser}} * {{Z|fa}}: {{W+|fa|منجنیق}} * {{Z|en}}: {{W+|en|mangonel|guman=erê}}, {{W+|en|ballista|guman=erê}}, {{W+|en|petard|guman=erê}} {{werger-bin}} 93y08knsjoy0ntdhtvj8pu94blrslnm 6265599 6265598 2026-07-19T15:47:27Z Wikihez 7344 6265599 wikitext text/x-wiki == {{ziman|ku}} == === Bilêvkirin === * {{ku-kîte}} === Navdêr === {{navdêr|ku|c=?}} # [[mencenîq]] #* {{bênimûne|ku}} ==== Formên alternatîv ==== * {{alt|ku|bereyişk}}} ==== Etîmolojî ==== {{bêetîmolojî}} ==== Werger ==== {{werger-ser}} * {{Z|fa}}: {{W+|fa|منجنیق}} * {{Z|en}}: {{W+|en|mangonel|guman=erê}}, {{W+|en|ballista|guman=erê}}, {{W+|en|petard|guman=erê}} {{werger-bin}} j9ycj807og8z9w21tdqr4a73nr3h5x6 6265601 6265599 2026-07-19T15:47:38Z Wikihez 7344 [[Bikarhêner:Wikihez/skrîpt/js/şablon-lêke.js|T]]: +{{bêçavkanî}} 6265601 wikitext text/x-wiki {{bêçavkanî}} == {{ziman|ku}} == === Bilêvkirin === * {{ku-kîte}} === Navdêr === {{navdêr|ku|c=?}} # [[mencenîq]] #* {{bênimûne|ku}} ==== Formên alternatîv ==== * {{alt|ku|bereyişk}}} ==== Etîmolojî ==== {{bêetîmolojî}} ==== Werger ==== {{werger-ser}} * {{Z|fa}}: {{W+|fa|منجنیق}} * {{Z|en}}: {{W+|en|mangonel|guman=erê}}, {{W+|en|ballista|guman=erê}}, {{W+|en|petard|guman=erê}} {{werger-bin}} lyectnto5zeehnw3zd52jf7apurr7og 6265602 6265601 2026-07-19T15:47:48Z Wikihez 7344 /* */ bi [[MediaWiki:Gadget-AjaxEdit.js|AjaxEdit]]ê re 6265602 wikitext text/x-wiki {{bêçavkanî}} == {{ziman|ku}} == === Bilêvkirin === * {{ku-kîte}} === Navdêr === {{navdêr|ku|c=?}} # [[mencenîq]] #* {{bênimûne|ku}} ==== Formên alternatîv ==== * {{alt|ku|bereyişk}} ==== Etîmolojî ==== {{bêetîmolojî}} ==== Werger ==== {{werger-ser}} * {{Z|fa}}: {{W+|fa|منجنیق}} * {{Z|en}}: {{W+|en|mangonel|guman=erê}}, {{W+|en|ballista|guman=erê}}, {{W+|en|petard|guman=erê}} {{werger-bin}} t1ahpqof8jlijydz7ilchnu9hbulcjw berjewendîperest 0 178345 6265605 5784528 2026-07-19T15:53:02Z Wikihez 7344 6265605 wikitext text/x-wiki == {{ziman|ku}} == === Navdêr === {{navdêr|ku|z=mn}} # Kesê ku li [[meslehet|meslehet]]a xwe tenê digere. ==== Etîmolojî ==== {{bêetîmolojî}} ==== Werger ==== {{werger-ser}} * {{Z|fa}}: {{W+|fa|فرصت طلب}}, {{W-|fa|منفعت طلب}} * {{Z|tr}}: {{W+|tr|aferist|guman=erê}}, {{W+|tr|çıkarcı|guman=erê}}, {{W+|tr|hesapçı|guman=erê}}, {{W-|tr|menfaatçı|guman=erê}}, {{W+|tr|menfaatperest|guman=erê}}, {{W+|tr|mideci|guman=erê}} {{werger-bin}} 4t58aao8pbu3isprb2dkhfc2ap4ztgp dûkel 0 179083 6265700 6139647 2026-07-19T23:12:45Z Bikarhêner 3719 6265700 wikitext text/x-wiki {{ds|dûkel|dûkêl}} == {{ziman|ku}} == === Bilêvkirin === * {{ku-kîte}} === Navdêr === {{navdêr|ku|z=m}} # [[bixar]], [[bixûr]] # [[hilm û gilm]] ==== Herwiha ==== * {{hw|ku|dûkêl}} ==== Ji wêjeya klasîk ==== * {{jêder|ku|{{Jêgirtin/Ehmedê Xanî/Mem û Zîn}}|jêgirtin=Naçar-i dilê dilî bi wî sot</br>'''Dûkel''' ji herareta suweyda</br>Rabû tejî bû mehellê sewda}} ==== Etîmolojî ==== {{bêetîmolojî}} ==== Werger ==== {{werger-ser}} * {{Z|de}}: {{W|de|Wasserdampf|m}} * {{Z|fa}}: {{W|fa|بخار}}, {{W|fa|مه}} * {{Z|tr}}: {{W|tr|buhar}}, {{W|tr|islim}}, {{W|tr|istim}} {{werger-bin}} 7ef2pmzlccdndygw5cry686a9tg264w 6265713 6265700 2026-07-20T00:56:13Z Balyozbot 7867 Bot: Herwiha --> Formên alternatîv ([[Wîkîferheng:Dîwan/2025#Guhertina_"Herwiha"|gotûbêjê]]) 6265713 wikitext text/x-wiki {{ds|dûkel|dûkêl}} == {{ziman|ku}} == === Bilêvkirin === * {{ku-kîte}} === Navdêr === {{navdêr|ku|z=m}} # [[bixar]], [[bixûr]] # [[hilm û gilm]] ==== Formên alternatîv ==== * {{hw|ku|dûkêl}} ==== Ji wêjeya klasîk ==== * {{jêder|ku|{{Jêgirtin/Ehmedê Xanî/Mem û Zîn}}|jêgirtin=Naçar-i dilê dilî bi wî sot</br>'''Dûkel''' ji herareta suweyda</br>Rabû tejî bû mehellê sewda}} ==== Etîmolojî ==== {{bêetîmolojî}} ==== Werger ==== {{werger-ser}} * {{Z|de}}: {{W|de|Wasserdampf|m}} * {{Z|fa}}: {{W|fa|بخار}}, {{W|fa|مه}} * {{Z|tr}}: {{W|tr|buhar}}, {{W|tr|islim}}, {{W|tr|istim}} {{werger-bin}} lm7wlth0r4dn0eo6fbrdm8xqxqfx21t firgeh 0 179282 6265733 6242915 2026-07-20T05:42:45Z Wikihez 7344 /* */ bi [[MediaWiki:Gadget-AjaxEdit.js|AjaxEdit]]ê re 6265733 wikitext text/x-wiki == {{ziman|ku}} == === Bilêvkirin === * {{ku-IPA|fiřgeh}}, fiřgeh, firrgeh, فڕگەھ === Navdêr === {{ku-tewîn-nav|firgeh|mê}} {{navdêr|ku|z=m}}, {{r-ya req}} # [[meydan|Meydana]] ku [[balafir]] anku [[firoke]] jê [[firîn|difirin]] û lê [[dadan|dadidin]]. ==== Formên alternatîv ==== {{kol3|ku|cure=Herwiha | {{herwiha|ku|firga}} | {{herwiha|ku|firgah}} | {{herwiha|ku|firge}} | {{herwiha|ku|firgih}} | {{herwiha|ku|firxane}} | {{herwiha|ku|firokga}} | {{herwiha|ku|firokgah}} | {{herwiha|ku|firokge}} | {{herwiha|ku|firokgeh}} | {{herwiha|ku|firokgih}} | {{herwiha|ku|firokega}} | {{herwiha|ku|firokegah}} | {{herwiha|ku|firokege}} | {{herwiha|ku|firokegeh}} | {{herwiha|ku|firokegih}} | {{herwiha|ku|firokxane}} | {{herwiha|ku|firrga}} | {{herwiha|ku|firrgah}} | {{herwiha|ku|firrge}} | {{herwiha|ku|firrgih}} | {{herwiha|ku|firrxane}} | {{herwiha|ku|firrokga}} | {{herwiha|ku|firrokgah}} | {{herwiha|ku|firrokge}} | {{herwiha|ku|firrokgeh}} | {{herwiha|ku|firrokgih}} | {{herwiha|ku|firrokega}} | {{herwiha|ku|firrokegah}} | {{herwiha|ku|firrokege}} | {{herwiha|ku|firrokegeh}} | {{herwiha|ku|firrokegih}} | {{herwiha|ku|firrokexane}} | {{herwiha|ku|firînga}} | {{herwiha|ku|firîngah}} | {{herwiha|ku|firînge}} | {{herwiha|ku|firîngeh}} | {{herwiha|ku|firîngih}} | {{herwiha|ku|firrînga}} | {{herwiha|ku|firrîngah}} | {{herwiha|ku|firrînge}} | {{herwiha|ku|firrîngeh}} | {{herwiha|ku|firrîngih}} }} ==== Hevmane ==== * [[balafirgeh]] * [[balafirxane]] ==== Bide ber ==== * [[bender]] * [[keştîgeh]] * [[lîman]] * [[otogar]] ==== Etîmolojî ==== Ji {{paş|ku|fir|-geh}} ==== Jê ==== * [[firgehî]] ==== Werger ==== {{werger-ser}} * {{Z|af}}: {{W+|af|lughawe}} * {{Z|akl}}: {{W-|akl|paeuparang}} * {{Z|sq}}: {{W+|sq|aeroport|n}}, {{W+|sq|aerodrom|n}} * {{Z|de}}: {{W+|de|Flughafen|n}}, {{W+|de|Flugplatz|n}}, {{W+|de|Lufthafen|n}} * {{Z|am}}: {{W-|am|የአየር ማረፊያ}} * Apaçî: *: {{Z|apw}}: {{W-|apw|naʼiniihí náńdąąhyú}} * {{Z|aii}}: {{W-|aii|ܒܹܝܬ ܛܲܘܣܵܐ|n|tr=bēt ṭāwsa}} * {{Z|as}}: {{W-|as|বিমানবন্দৰ|tr=bimanbondor}} * {{Z|ast}}: {{W+|ast|aeropuertu|n}} * {{Z|az}}: {{W-|az|aeroport}}, {{W-|az|hava limanı}} * {{Z|ban}}: {{W-|ban|ᬮᬧᬗᬦ᭄ ᬢᭂᬃᬩᬗᬾ|tr=lapangan terbangé}} * {{Z|eu}}: {{W+|eu|aireportu}} * {{Z|bar}}: {{W-|bar|Flughofn|n}} * {{Z|be}}: {{W+|be|аэрапо́рт|n}}, {{W-|be|лётнішча|nt}} * {{Z|bn}}: {{W+|bn|বিমানবন্দর}} * {{Z|bcl}}: {{W-|bcl|palayogan}} * {{Z|br}}: {{W+|br|aerborzh|n}} * {{Z|bg}}: {{W+|bg|лети́ще|nt}}, {{W-|bg|аерога́ра|m}} * {{Z|my}}: {{W+|my|လေဆိပ်}} * {{Z|cs}}: {{W+|cs|letiště|nt}} * {{Z|zh}}: *: {{Z|yue}}: {{W-|yue|機場|tr=gei1 coeng4}}, {{W-|yue|飛機場|tr=fei1 gei1 coeng4}} *: {{Z|dng}}: {{W-|dng|фиҗичон}} *: {{Z|hak}}: {{W-|hak|機場|tr=kî-chhòng}}, {{W-|hak|飛機場|tr=fî-kî-chhòng}} *: {{Z|cmn}}: {{W+|cmn|機場|tr=jīchǎng}}, {{W+|cmn|飛機場|tr=fēijīchǎng}} *: {{Z|cdo}}: {{W-|cdo|機場|tr=gĭ-diòng}} *: {{Z|nan}}: {{W+|nan|機場|tr=ki-tiûⁿ}}, {{W-|nan|飛機場|tr=hui-ki-tiûⁿ}} *: {{Z|wuu}}: {{W-|wuu|機場}} * {{Z|da}}: {{W+|da|lufthavn|g}} * {{Z|dv}}: {{W-|dv|ވައިގެބަނދަރު}}, {{W-|dv|އެއާޕޯޓް}} * {{Z|id}}: {{W+|id|bandar udara}}, {{W+|id|pelabuhan udara}} * {{Z|ar}}: {{W+|ar|مَطَار|n}} *: {{Z|arz}}: {{W-|arz|مطار|n|tr=maṭār}} * {{Z|hy}}: {{W+|hy|օդանավակայան}} * {{Z|eo}}: {{W+|eo|flughaveno}}, {{W+|eo|aerodromo}}, {{W-|eo|aerohaveno}} * {{Z|et}}: {{W+|et|lennujaam}} * {{Z|fa}}: {{W+|fa|فرودگاه|tr=forudgâh}}, {{W-|fa|میدان طیاره|tr=maydân-e tayyâra}}, {{W-|fa|میدان هوایی|tr=maydân-e hawâyi}} * {{Z|fo}}: {{W+|fo|floghavn|nt}}, {{W-|fo|flogvøllur|n}} * {{Z|fi}}: {{W+|fi|lentoasema}}, {{W+|fi|lentokenttä}} * {{Z|fr}}: {{W+|fr|aéroport|n}} * {{Z|gd}}: {{W-|gd|port-adhair|n}} * {{Z|gl}}: {{W+|gl|aeroporto|n}} * {{Z|ka}}: {{W-|ka|აეროპორტი}} * {{Z|gn}}: {{W-|gn|pepo'atãrupa}}, {{W-|gn|aviõrupa}} * {{Z|ht}}: {{W-|ht|ayeropò}} * {{Z|haw}}: {{W-|haw|kahua mokulele}} * {{Z|ha}}: {{W+|ha|filin jirgin sama}} * {{Z|hi}}: {{W-|hi|विमानतल|n}}, {{W-|hi|हवाई अड्डा|n}}, {{W-|hi|विमान-पत्तन|n}}, {{W-|hi|विमानबंदर}}, {{W-|hi|विमानस्थल|n}}, {{W-|hi|विमानाश्रय|n}} * {{Z|hil}}: {{W-|hil|hulugpaan}} * {{Z|nl}}: {{W+|nl|luchthaven|m}}, {{W+|nl|vlieghaven|m}} * {{Z|iba}}: {{W-|iba|padang bilun}} * {{Z|he}}: {{W+|he|נְמַל תְּעוּפָה|n|tr=n'mál t'ufá}} * {{Z|io}}: {{W+|io|aeroportuo}} * {{Z|ilo}}: {{W-|ilo|pagtayaban}} * {{Z|en}}: {{W+|en|airport}} * {{Z|ia}}: {{W-|ia|aeroporto}} * {{Z|iu}}: {{W-|iu|ᖃᖓᑕᓲᒃᑯᕕᒃ}} * {{Z|ga}}: {{W-|ga|aerfort|n}} * {{Z|it}}: {{W+|it|aeroporto|n}}, {{W+|it|aerodromo|n}} * {{Z|itv}}: {{W-|itv|pakkayabban}} * {{Z|is}}: {{W+|is|flugvöllur|n}}, {{W-|is|flughöfn|m}}, {{W+|is|flugstöð|m}} * {{Z|ja}}: {{W+|ja|空港|tr=くうこう, kūkō}} * {{Z|jv}}: {{W-|jv|ꦥꦥꦤꦔ꧀ꦒꦼꦒꦤ|tr=papan anggegana}} * {{Z|kl}}: {{W-|kl|mittarfik}} * {{Z|kn}}: {{W+|kn|ವಿಮಾನ ನಿಲ್ದಾಣ}} * {{Z|kea}}: {{W-|kea|aeroportu}}, {{W-|kea|aeroporte}} * {{Z|csb}}: {{W+|csb|latawiskò|nt}} * {{Z|ca}}: {{W+|ca|aeroport|n}} * {{Z|ky}}: {{W+|ky|аэропорт}}, {{W-|ky|аеропорт}} * {{Z|si}}: {{W-|si|ගුවන්තොට}} * {{Z|kpv}}: {{W-|kpv|аэропорт}} * {{Z|ko}}: {{W+|ko|공항}}, {{W+|ko|항공역}} * {{Z|lad}}: {{W-|lad|aeroporto}} * {{Z|la}}: {{W-|la|āëriportus|n}} * {{Z|lv}}: {{W+|lv|lidosta|m}} * {{Z|lo}}: {{W+|lo|ເດີ່ນຍົນ}}, {{W-|lo|ສນາມບິນ}}, {{W-|lo|ເດີ່ນບິນ}} * {{Z|ln}}: {{W-|ln|libándá-mpɛ́pɔ}}, {{W-|ln|libándá lya mpɛ́pɔ}} * {{Z|lt}}: {{W-|lt|oro uostas|n}} * {{Z|lb}}: {{W+|lb|Fluchhafen}} * {{Z|mk}}: {{W-|mk|аеродро́м|n}}, {{W-|mk|а́еродром|n}} * {{Z|ml}}: {{W-|ml|വിമാനത്താവളം}} * {{Z|ms}}: {{W+|ms|lapangan terbang}} * {{Z|mt}}: {{W-|mt|ajruport}}, {{W-|mt|mitjar}} * {{Z|mi}}: {{W-|mi|taunga rererangi}} * {{Z|mr}}: {{W-|mr|विमानतळ}} * {{Z|msb}}: {{W-|msb|palupadan}} * {{Z|yua}}: {{W-|yua|maskab ch'iich' kaah}} * {{Z|hu}}: {{W+|hu|repülőtér}}, {{W+|hu|reptér}} * {{Z|lus}}: {{W-|lus|ţumhmun}}, {{W-|lus|thlawhna-ţumhmun}} * {{Z|mn}}: *: Kirîlî: {{W-|mn|нисэх онгоцны буудал}}, {{W-|mn|аэропорт}}, {{W+|mn|нисэх буудал}} * {{Z|nah}}: {{W-|nah|ehēcalquixohuayān}}, {{W-|nah|tepoztotoquixohuayan}} * {{Z|nv}}: {{W-|nv|chidí naatʼaʼí ńdinibįįhígi}} * {{Z|nds}}: *: {{Z|nds-de}}: {{W-|nds-de|Flegerhaven|n}} * {{Z|ne}}: {{W-|ne|विमानस्थल}} * {{Z|nrf}}: {{W-|nrf|aéroport|n}} * {{Z|no}}: *: {{Z|nb}}: {{W+|nb|flyplass|n}}, {{W-|nb|lufthavn|n|m}} *: {{Z|nn}}: {{W-|nn|flyplass|n}}, {{W-|nn|lufthamn|m}} * {{Z|oj}}: {{W-|oj|endazhi-booniimagak}} * {{Z|oc}}: {{W+|oc|aeropòrt|n}} * {{Z|or}}: {{W-|or|ବିମାନ ବନ୍ଦର}} * {{Z|os}}: {{W-|os|аэропорт}} * {{Z|ug}}: {{W-|ug|ئايروپورت}} * {{Z|uz}}: {{W+|uz|aeroport}}, {{W-|uz|tayеragoh}} * {{Z|ps}}: {{W-|ps|هوایی ډګر|n|tr=hawāyí-ḍagár}} * {{Z|pdt}}: {{W-|pdt|Loftstazion|m}} * {{Z|pl}}: {{W+|pl|lotnisko|nt}}, {{W+|pl|port lotniczy|n}}, {{W+|pl|aerodrom|n}}, {{W+|pl|aeroport}} * {{Z|pt}}: {{W+|pt|aeroporto|n}} * {{Z|kk}}: {{W-|kk|әуежай}} * {{Z|ro}}: {{W+|ro|aeroport|nt}} * {{Z|rol}}: {{W-|rol|paluparan}} * {{Z|ru}}: {{W+|ru|аэропо́рт|n}}, {{W+|ru|аэродро́м|n}}, {{W+|ru|аэровокза́л|n}} * {{Z|smn}}: {{W-|smn|girdingieddi}} * {{Z|sa}}: {{W-|sa|विमान-पत्तन}} * {{Z|ceb}}: {{W-|ceb|tugpahanan}} * {{Z|scn}}: {{W+|scn|ariuportu|n}} * {{Z|sh}}: *: Kirîlî: {{W-|sh|аеро̀дром|n}}, {{W-|sh|летелиште|nt}}, {{W-|sh|зра́чна лу́ка|m}} *: Latînî: {{W+|sh|aeròdrom|n}}, {{W-|sh|letelište|nt}}, {{W+|sh|zráčna lúka|m}} * {{Z|sk}}: {{W-|sk|letisko|nt}} * {{Z|sl}}: {{W+|sl|letališče|nt}} * {{Z|so}}: {{W-|so|gego diyaarad}} * {{Z|es}}: {{W+|es|aeropuerto|n}} * {{Z|sw}}: {{W-|sw|uwanja wa ndege|cu}} * {{Z|sv}}: {{W+|sv|flygplats}}, {{W+|sv|flygfält|nt}}, {{W+|sv|lufthamn|g}} * {{Z|shn}}: {{W-|shn|တႃႈႁိူဝ်းမိၼ်}} * {{Z|tg}}: {{W+|tg|фурудгоҳ}}, {{W-|tg|аэропорт}} * {{Z|tl}}: {{W+|tl|paliparan}} * {{Z|ta}}: {{W-|ta|வானூர்தி நிலையம்}}, {{W+|ta|விமான நிலையம்}} * {{Z|th}}: {{W+|th|ท่าอากาศยาน}}, {{W+|th|สนามบิน}} * {{Z|te}}: {{W+|te|విమానాశ్రయం}} * {{Z|tzm}}: {{W-|tzm|ⴰⵣⴰⴳⴳⵯⵣ}} * {{Z|tt}}: {{W-|tt|аэропорт}} * {{Z|ti}}: {{W-|ti|መዓርፎ ነፈርቲ}} * {{Z|tr}}: {{W+|tr|havalimanı}}, {{W+|tr|havaalanı}} * {{Z|tk}}: {{W+|tk|aeroport}}, {{W-|tk|howa menzili}} * {{Z|bo}}: {{W-|bo|གནམ་ཐང}}, {{W-|bo|གནམ་གྲུ་ཐང}}, {{W-|bo|གནམ་གྲུ་འབབ་ཐང}} * {{Z|tkl}}: {{W-|tkl|malae vakalele}} * {{Z|tpi}}: {{W-|tpi|ples balus}} * {{Z|to}}: {{W-|to|malaʻe vakapuna}} * {{Z|tyv}}: {{W-|tyv|аэропорт}} * {{Z|ur}}: {{W-|ur|ہوائی اڈا|n|tr=havā'ī aḍḍā}}, {{W-|ur|ہوائی اڈہ|n|tr=havāī aḍḍa}}, {{W-|ur|ہوائی مستقر|n|tr=hawāī mustaqar}}, {{W-|ur|مطار|n|tr=matār}}, {{W-|ur|فرود گاہ|n|tr=farūd-gāh}}, {{W-|ur|طیران گاہ|n|tr=terān-gāh}}{{W-|ur|ومانتل|n|tr=vimāntal}} * {{Z|uk}}: {{W+|uk|аеропо́рт|n}}, {{W-|uk|лето́вище|nt}} * {{Z|vi}}: {{W+|vi|sân bay}}, {{W+|vi|phi trường}}, {{W+|vi|cảng hàng không}} * {{Z|vo}}: {{W-|vo|lutapof}} * {{Z|wls}}: {{W-|wls|mala'e vakalele}} * {{Z|war}}: {{W-|war|paluparan}} * {{Z|cy}}: {{W+|cy|maes awyr}} * {{Z|km}}: {{W-|km|អាកាសយានដ្ឋាន}}, {{W-|km|វាលកប៉ាល់ហោះ}} * {{Z|yi}}: {{W-|yi|אַעראָפּאָרט|n}}, {{W-|yi|פֿליפֿעלד|nt}} * {{Z|el}}: {{W+|el|αεροδρόμιο|nt}}, {{W+|el|αερολιμένας|n}} * {{Z|zu}}: {{W+|zu|inkundla yezindiza}} {{werger-bin}} :{{werger çavkanî|en|airport|beş=Ev qismê Wergerê|oldid=75748528}} mnqtuftnn2hvmjs7geb3qojon1jx1mc herçî 0 183944 6265768 5019304 2026-07-20T07:02:19Z Wikihez 7344 /* */ bi [[MediaWiki:Gadget-AjaxEdit.js|AjaxEdit]]ê re 6265768 wikitext text/x-wiki == {{ziman|ku}} == === Hoker === {{hoker|ku}} # {{guherto|herçi}} #* {{jêder|ku|jêgirtin='''Herçî''' bînit, [[hindî]] tiştê xwarinê<br>Dê [[mubarek]] bit li ber vê xwendinê|[[w:Mela Hisênê Bateyî]]}} === Cînav === {{cînav|ku}} # {{guherto|herçi}} 4fgtnlmbirrku13m6ftkr9ao2x93vaj karpêk 0 263902 6265798 4119108 2026-07-20T08:25:51Z Wikihez 7344 /* {{ziman|ku}} */ 6265798 wikitext text/x-wiki == {{ziman|ku}} == === Navdêr === {{navdêr|ku|z=m}} # [[berhem]], [[eser]] ==== Etîmolojî ==== {{bêetîmolojî}} ==== Werger ==== {{werger-ser}} * {{Z|fa}}: {{W+|fa|محصول}}, {{W+|fa|اثر}} * {{Z|tr}}: {{W+|tr|yapıt}}, {{W+|tr|eser}} {{werger-bin}} ==== Çavkanî ==== * {{Ferhenga Kamêran}} fmzq1r8ko6d6ifj5l860r6ohfaqgyy6 بەغا 0 268453 6265735 5863912 2026-07-20T05:44:47Z Wikihez 7344 [[Bikarhêner:Wikihez/templateScript2.js|TS]]: +[[Şablon:îzah|îzah]] 6265735 wikitext text/x-wiki == {{ziman|ckb}} == === Serenav === {{serenav|ckb}} # [[Bexda]] {{îzah|[[serbajar|serbajarê]] [[Iraq|Iraqê]]}} l6w9y9vdpk3gas4rooom5wjllrbl7kp agir berda malê, revî xwe da palê 0 279597 6265627 6248432 2026-07-19T18:53:37Z Wikihez 7344 /* */ bi [[MediaWiki:Gadget-AjaxEdit.js|AjaxEdit]]ê re 6265627 wikitext text/x-wiki == {{ziman|ku}} == === Gotineke pêşiyan === {{gp|ku}} # {{mane?|ku}} ==== Formên alternatîv ==== * {{g|ku|agir berda komê, xwe da fêza zomê}} 0qdas0vo7av9flse72x3epp04ir4mut bejn tît e mal mecît e 0 280149 6265585 6141670 2026-07-19T15:07:35Z Wikihez 7344 6265585 wikitext text/x-wiki == {{ziman|ku}} == === Bilêvkirin === * {{ku-kîte}} === Gotineke pêşiyan === {{gp|ku}} # Ji bo kesên ku di mal de nanê xwarinê nîn e, lê ji derve ve bejn û bala xwe pir xweş çêdikin û forsê davêjin tê bikaranîn. #: ''rast e ser û guhê m û forsa xwe baş mêze dike, lê bejn tît e, mal mecît e.''<ref>Ferhenga Biwêjan, Mustafa Borak</ref> ==== Binêre herwiha ==== * {{g|ku|mêrê malê bicizme ye, teşta malê teneke ye}} ==== Werger ==== {{werger-ser}} * {{Z|tr}}:{{W-|tr|ayağında donu yok başına fesleğen ister|guman=erê}}, {{W-|tr|ekmek yoktur yemeğe atla gider sıçmağa|guman=erê}}, {{W-|tr|yiğit hoş yancık boş|guman=erê}} {{werger-bin}} === Çavkanî === {{çavkanî}} qyix6lgz1d1amgqrwgni2icej3gojld 6265586 6265585 2026-07-19T15:08:24Z Wikihez 7344 6265586 wikitext text/x-wiki == {{ziman|ku}} == === Bilêvkirin === * {{ku-kîte}} === Gotineke pêşiyan === {{gp|ku}} # [[ji bo|Ji bo]] [[kes]]ên ku di [[mal]] de [[nan]]ê [[xwarin]]ê nîn e, [[lê]] [[ji derve]] ve [[bejn]] û [[bala]] [[xwe]] [[pir xweş]] [[çêdikin]] û [[fors]]ê [[avêtin|davêjin]] tê [[bi kar anîn|bikaranîn]]. #: ''rast e ser û guhê m û forsa xwe baş mêze dike, lê bejn tît e, mal mecît e.''<ref>Ferhenga Biwêjan, Mustafa Borak</ref> ==== Binêre herwiha ==== * {{g|ku|mêrê malê bicizme ye, teşta malê teneke ye}} ==== Werger ==== {{werger-ser}} * {{Z|tr}}:{{W-|tr|ayağında donu yok başına fesleğen ister|guman=erê}}, {{W-|tr|ekmek yoktur yemeğe atla gider sıçmağa|guman=erê}}, {{W-|tr|yiğit hoş yancık boş|guman=erê}} {{werger-bin}} === Çavkanî === {{çavkanî}} edco1lxi4t383acwjlk8qq1q1f2b5k3 6265587 6265586 2026-07-19T15:08:46Z Wikihez 7344 6265587 wikitext text/x-wiki == {{ziman|ku}} == === Bilêvkirin === * {{ku-kîte}} === Gotineke pêşiyan === {{gp|ku}} # [[ji bo|Ji bo]] [[kes]]ên ku di [[mal]] de [[nan]]ê [[xwarin]]ê nîn e, [[lê]] [[ji derve]] ve [[bejn]] û [[bala]] [[xwe]] [[pir xweş]] [[çêdikin]] û [[fors]]ê [[avêtin|davêjin]] tê [[bi kar anîn|bikaranîn]]. #: {{nm|ku|Rast e ser û guhê m û forsa xwe baş mêze dike, lê '''bejn tît e, mal mecît e'''.}}<ref>Ferhenga Biwêjan, Mustafa Borak</ref> ==== Binêre herwiha ==== * {{g|ku|mêrê malê bicizme ye, teşta malê teneke ye}} ==== Werger ==== {{werger-ser}} * {{Z|tr}}:{{W-|tr|ayağında donu yok başına fesleğen ister|guman=erê}}, {{W-|tr|ekmek yoktur yemeğe atla gider sıçmağa|guman=erê}}, {{W-|tr|yiğit hoş yancık boş|guman=erê}} {{werger-bin}} === Çavkanî === {{çavkanî}} 6529twb0rsr7w8yqupbtdt6czvhd67d 6265588 6265587 2026-07-19T15:09:05Z Wikihez 7344 6265588 wikitext text/x-wiki == {{ziman|ku}} == === Bilêvkirin === * {{ku-kîte}} === Gotineke pêşiyan === {{gp|ku}} # [[ji bo|Ji bo]] [[kes]]ên ku di [[mal]] de [[nan]]ê [[xwarin]]ê nîn e, [[lê]] [[ji derve]] ve [[bejn]] û [[bala]] [[xwe]] [[pir xweş]] [[çêdikin]] û [[fors]]ê [[avêtin|davêjin]] tê [[bi kar anîn|bikaranîn]]. #: {{jêder|ku|jg=Rast e ser û guhê m û forsa xwe baş mêze dike, lê '''bejn tît e, mal mecît e'''.|Ferhenga Biwêjan, Mustafa Borak}} ==== Binêre herwiha ==== * {{g|ku|mêrê malê bicizme ye, teşta malê teneke ye}} ==== Werger ==== {{werger-ser}} * {{Z|tr}}:{{W-|tr|ayağında donu yok başına fesleğen ister|guman=erê}}, {{W-|tr|ekmek yoktur yemeğe atla gider sıçmağa|guman=erê}}, {{W-|tr|yiğit hoş yancık boş|guman=erê}} {{werger-bin}} === Çavkanî === {{çavkanî}} d7f9p59mgqcxwgo4vbf4owfpyb6u8j1 6265589 6265588 2026-07-19T15:09:16Z Wikihez 7344 /* */ bi [[MediaWiki:Gadget-AjaxEdit.js|AjaxEdit]]ê re 6265589 wikitext text/x-wiki == {{ziman|ku}} == === Bilêvkirin === * {{ku-kîte}} === Gotineke pêşiyan === {{gp|ku}} # [[ji bo|Ji bo]] [[kes]]ên ku di [[mal]] de [[nan]]ê [[xwarin]]ê nîn e, [[lê]] [[ji derve]] ve [[bejn]] û [[bala]] [[xwe]] [[pir xweş]] [[çêdikin]] û [[fors]]ê [[avêtin|davêjin]] tê [[bi kar anîn|bikaranîn]]. #* {{jêder|ku|jg=Rast e ser û guhê m û forsa xwe baş mêze dike, lê '''bejn tît e, mal mecît e'''.|Ferhenga Biwêjan, Mustafa Borak}} ==== Binêre herwiha ==== * {{g|ku|mêrê malê bicizme ye, teşta malê teneke ye}} ==== Werger ==== {{werger-ser}} * {{Z|tr}}:{{W-|tr|ayağında donu yok başına fesleğen ister|guman=erê}}, {{W-|tr|ekmek yoktur yemeğe atla gider sıçmağa|guman=erê}}, {{W-|tr|yiğit hoş yancık boş|guman=erê}} {{werger-bin}} === Çavkanî === {{çavkanî}} 18bq9j4w9rt9dex9a9auldb9jxmh64j 6265590 6265589 2026-07-19T15:09:32Z Wikihez 7344 /* */ bi [[MediaWiki:Gadget-AjaxEdit.js|AjaxEdit]]ê re 6265590 wikitext text/x-wiki == {{ziman|ku}} == === Bilêvkirin === * {{ku-kîte}} === Gotineke pêşiyan === {{gp|ku}} # [[ji bo|Ji bo]] [[kes]]ên ku di [[mal]] de [[nan]]ê [[xwarin]]ê nîn e, [[lê]] [[ji derve]] ve [[bejn]] û [[bala]] [[xwe]] [[pir xweş]] [[çêdikin]] û [[fors]]ê [[avêtin|davêjin]] tê [[bi kar anîn|bikaranîn]]. #* {{jêder|ku|jg=Rast e ser û guhê m û forsa xwe baş mêze dike, lê '''bejn tît e, mal mecît e'''.|Ferhenga Biwêjan, Mustafa Borak}} ==== Binêre herwiha ==== * {{g|ku|mêrê malê bicizme ye, teşta malê teneke ye}} ==== Werger ==== {{werger-ser}} * {{Z|tr}}:{{W-|tr|ayağında donu yok başına fesleğen ister|guman=erê}}, {{W-|tr|ekmek yoktur yemeğe atla gider sıçmağa|guman=erê}}, {{W-|tr|yiğit hoş yancık boş|guman=erê}} {{werger-bin}} 172xutxt9a7f248o3ehbdlh0t629jpg karîsaz 0 283576 6265741 6142222 2026-07-20T05:56:44Z Wikihez 7344 /* Rengdêr */ 6265741 wikitext text/x-wiki == {{ziman|ku}} == === Bilêvkirin === * {{ku-kîte}} === Rengdêr === {{rengdêr|ku}} # [[jêhatî]], [[bikêrhatî]] #* {{jêder|ku|jg='''Karîsazê''' bende û sultanê can<br/>Rehîm û Rehman, letîf û mihriban|[[w:Mela Hisênê Bateyî|Mela Hisênê Bateyî]]}} ==== Etîmolojî ==== {{bêetîmolojî}} ==== Werger ==== {{werger-ser}} {{werger-bin}} iow75j6vv1xnyraccdiz04s4pgwh385 zulcelal 0 283577 6265774 6251847 2026-07-20T08:06:50Z Wikihez 7344 [[Bikarhêner:Wikihez/templateScript2.js|TS]]: sererastkirin 6265774 wikitext text/x-wiki == {{ziman|ku}} == === Bilêvkirin === * {{ku-kîte}} === Rengdêr === {{rengdêr|ku}} # [[xwedê|Xwedêyê]] [[payedar]]. #* {{mewlûd|jg=Ew Xudayê bê nezîr û '''zulcelal'''<br>Bêmîsal û bêheval û bêzewal}} ==== Formên alternatîv ==== * {{g|ku|celal}} ==== Etîmolojî ==== {{ji?|ku}} ==== Werger ==== {{werger-ser}} {{werger-bin}} tkt5xfj61dl1s79nkqp9n9d4lyaq8ax xeyrul beşer 0 283581 6265831 6253167 2026-07-20T09:19:20Z Wikihez 7344 6265831 wikitext text/x-wiki == {{ziman|ku}} == === Bilêvkirin === * {{ku-kîte}} === Rengdêr === {{rengdêr|ku}} # [[mirov|Mirovê]] [[herî baş]] . # {{e|ku|Îslam}} Mihemed pêxember #* {{mewlûd|jg=Em kirine ummeta '''xeyr-ul beşer'''<br>Tabi'ê wî muqtedayê namuwer}} ==== Etîmolojî ==== Ji {{ji|ar|ku}}. ==== Werger ==== {{werger-ser}} {{werger-bin}} ftc4owne5k742c8j38cwod0dl1w1aph 6265832 6265831 2026-07-20T09:19:37Z Wikihez 7344 6265832 wikitext text/x-wiki == {{ziman|ku}} == === Bilêvkirin === * {{ku-kîte}} === Îfade === {{îfade|ku}} # [[mirov|Mirovê]] [[herî baş]] . # {{e|ku|Îslam}} [[Mihemed]] [[pêxember]] #* {{mewlûd|jg=Em kirine ummeta '''xeyr-ul beşer'''<br>Tabi'ê wî muqtedayê namuwer}} ==== Etîmolojî ==== Ji {{ji|ar|ku}}. ==== Werger ==== {{werger-ser}} {{werger-bin}} k4tka40ufn5j9hlz63ou55l4vr68xt3 Îhdîna, ya Reb, sîratel musteqîm 0 283589 6265821 5786388 2026-07-20T09:06:51Z Wikihez 7344 Requesting speedy deletion (Xelet). ([[:m:User:Xiplus/TwinkleGlobal|TwinkleGlobal]]) 6265821 wikitext text/x-wiki {{jêbirin|1=Xelet}} == {{ziman|ku}} == === Mane === {{cure?|ku}} # [[Xwedêyo]], rêya rast nîşanî me bide ==== Ji wêjeyê ==== Hêvîdar in em ji te, [[şahê kerîm|Şahê Kerîm]], [[Îhdîna, ya Reb, sîratel musteqîm]] [[w:Mela Hisênê Bateyî]] i6i8q9th7368bmj2jyd7a7ny1yj4qn7 ger divêtin hûn 0 283590 6265819 5786389 2026-07-20T09:04:44Z Wikihez 7344 6265819 wikitext text/x-wiki == {{ziman|ku}} == === Îfade === {{îfade|ku}} # [[eger|Eger]] hûn [[xwastin|bixwazin]], eger hûn [[hez kirin|hez bikin]] #* {{mewlûd|jg=Ger divêtin hûn ji narê bin necat<br>Bi 'işq û şewqek hûn bibêjin esselat}} b09x29gqpv1rzqumj74vty1no52itty 6265820 6265819 2026-07-20T09:04:57Z Wikihez 7344 6265820 wikitext text/x-wiki == {{ziman|ku}} == === Îfade === {{îfade|ku}} # [[eger|Eger]] hûn [[xwastin|bixwazin]], eger hûn [[hez kirin|hez bikin]] #* {{mewlûd|jg='''Ger divêtin hûn''' ji narê bin necat<br>Bi 'işq û şewqek hûn bibêjin esselat}} q1j26cqgfvga7xpn1y9rj2djo356wv8 herdu kewn 0 283595 6265792 5786390 2026-07-20T08:18:02Z Wikihez 7344 6265792 wikitext text/x-wiki == {{ziman|ku}} == === Îfade === {{îfade|ku}} # [[dinya|Dinya]] û [[axret]] #* {{mewlûd|jg=Destegîr û mustexasê '''herdu kewn'''<br>Bo gunehkaran penah û pişt û 'ewn}} i8447q10chu4csf6ozczkmlfhcpag8c hamilî 0 283614 6265770 6142235 2026-07-20T08:03:27Z Wikihez 7344 6265770 wikitext text/x-wiki == {{ziman|ku}} == === Bilêvkirin === * {{ku-kîte}} === Rengdêr === {{rengdêr|ku}} # hatî [[hilgirtin]] #* {{mewlûd|jg=Rebbê 'alem gotî Adem ey mûlî<br>Tu ji bo Nûra Muhemmed '''hamilî'''}} ezpiuc6cpy8km61vz5w6ysllgyter9d xeyrî darê 0 283617 6265771 5786391 2026-07-20T08:04:22Z Wikihez 7344 6265771 wikitext text/x-wiki == {{ziman|ku}} == === Îfade === {{îfade|ku}} # [[ji bilî]] (vê) [[dar|darê]] #* {{mewlûd|Paşê bir avête baxê Cennetê<br>Xeyrî darê jê bixwe j' her nî'metê}} ak9wznw35yg0s0y72r9tzapesjils6n 6265772 6265771 2026-07-20T08:04:34Z Wikihez 7344 /* */ bi [[MediaWiki:Gadget-AjaxEdit.js|AjaxEdit]]ê re 6265772 wikitext text/x-wiki == {{ziman|ku}} == === Îfade === {{îfade|ku}} # [[ji bilî]] (vê) [[dar|darê]] #* {{mewlûd|jg=Paşê bir avête baxê Cennetê<br>Xeyrî darê jê bixwe j' her nî'metê}} 2fwt2tfcarwa0jsj1egs7c0z16zj87j teheyyur 0 283619 6265797 6142237 2026-07-20T08:21:48Z Wikihez 7344 6265797 wikitext text/x-wiki == {{ziman|ku}} == === Bilêvkirin === * {{ku-kîte}} === Rengdêr === {{rengdêr|ku}} # [[ecêbmayî]], [[matmayî]] #* {{mewlûd|jg=Mislê rojê hatiye ew car felek<br>Hem '''teheyyur''' Adem û hindî Melek}} ==== Etîmolojî ==== Ji {{deyn|ar|ku}}. ==== Werger ==== {{werger-ser}} {{werger-bin}} iv6zvmp61fkjd8uuy6ipazhq4zvhaij muncelî 0 283621 6265784 6251141 2026-07-20T08:14:14Z Wikihez 7344 6265784 wikitext text/x-wiki == {{ziman|ku}} == === Bilêvkirin === * {{ku-kîte}} === Rengdêr === {{rengdêr|ku}} # [[biriqîn]]î, [[teyisîn]]î #* {{mewlûd|jg=Hate îbhamê dibên nûra 'Elî<br>Şu'lê da tilyan û Cennet '''muncelî'''}} ==== Etîmolojî ==== {{ji?|ku}} ==== Werger ==== {{werger-ser}} {{werger-bin}} 1e1vasx3327ebixmx8meanveoi7ougj 6265785 6265784 2026-07-20T08:14:20Z Wikihez 7344 /* */ bi [[MediaWiki:Gadget-AjaxEdit.js|AjaxEdit]]ê re 6265785 wikitext text/x-wiki == {{ziman|ku}} == === Bilêvkirin === * {{ku-kîte}} === Rengdêr === {{rengdêr|ku}} # [[biriqîn]]î, [[teyisîn]]î #* {{mewlûd|jg=Hate îbhamê dibên nûra 'Elî<br>Şu'lê da tilyan û Cennet '''muncelî'''}} ==== Etîmolojî ==== {{ji?|ku}} ==== Werger ==== {{werger-ser}} {{werger-bin}} 58c9ph6isjklidoman7ni5li6iw6stz nusret 0 283709 6265846 6251467 2026-07-20T09:33:45Z Wikihez 7344 /* {{ziman|ku}} */ 6265846 wikitext text/x-wiki == {{ziman|ku}} == === Bilêvkirin === * {{ku-kîte}} === Navdêr === {{navdêr|ku}} # [[alîkarî]] #* {{mewlûd|jg=Behrê nusret, sanî behrê merheme, Behrê qudret, behrê îrfan in heme}} ==== Etîmolojî ==== {{ji?|ku}} ==== Werger ==== {{werger-ser}} {{werger-bin}} ik72w5mw57i3hrgfdf9mg3gecw76rng 6265847 6265846 2026-07-20T09:33:51Z Wikihez 7344 6265847 wikitext text/x-wiki == {{ziman|ku}} == === Bilêvkirin === * {{ku-kîte}} === Navdêr === {{navdêr|ku}} # [[alîkarî]] #* {{mewlûd|jg=Behrê '''nusret''', sanî behrê merheme, Behrê qudret, behrê îrfan in heme}} ==== Etîmolojî ==== {{ji?|ku}} ==== Werger ==== {{werger-ser}} {{werger-bin}} smd8mjcdai1sk8r7f3i3gv1b6gw20q3 nisf 0 283712 6265830 6247368 2026-07-20T09:17:17Z Wikihez 7344 6265830 wikitext text/x-wiki == {{ziman|ku}} == === Bilêvkirin === * {{ku-kîte}} === Navdêr === {{navdêr|ku}} # [[nîv]] #* {{mewlûd|jg='''Nisfê''' ewwel dayî çavê heybetê,<br>Nisfê sanî dayî çavê şefqetê}} ==== Etîmolojî ==== {{ji?|ku}} ==== Werger ==== {{werger-bnr|nîv}} nfbk2a8b41zaqpnu31g3cpgyluh555h Malik-ul mulkê Celîlê Zulcelal 0 283713 6265805 5786393 2026-07-20T08:31:36Z Wikihez 7344 +{{jêbirin}} 6265805 wikitext text/x-wiki {{jêbirin|deng}} == {{ziman|ku}} == === Mane === {{cure?|ku}} # Padîşahê milkê hêja û rêzdar ==== Ji wêjeyê ==== Hate emrê Padîşahê Layezal [[Malik-ul mulkê Celîlê Zulcelal]] [[w:Mela Hisênê Bateyî]] gqtd7j1q9zgm18zzn5tqig26e9b6dh2 bêhîsab 0 283756 6265835 6142257 2026-07-20T09:21:48Z Wikihez 7344 6265835 wikitext text/x-wiki == {{ziman|ku}} == === Bilêvkirin === * {{ku-kîte}} === Navdêr === {{navdêr|ku}} # {{guharto|ku|bêhesab}} #* {{mewlûd|jg=Her wekî hatiye gotin bêhîsab<br>Lê neşêm bêjim jî tetwîla Kîtab}} c10upadd7ouurmp24bafyk7w5aeawz9 6265836 6265835 2026-07-20T09:22:01Z Wikihez 7344 6265836 wikitext text/x-wiki == {{ziman|ku}} == === Bilêvkirin === * {{ku-kîte}} === Navdêr === {{navdêr|ku}} # {{guharto|ku|bêhesab}} #* {{mewlûd|jg=Her wekî hatiye gotin '''bêhîsab'''<br>Lê neşêm bêjim jî tetwîla Kîtab}} ofab7ia4ohnpdtivegf8b640wefw0nf 6265837 6265836 2026-07-20T09:22:13Z Wikihez 7344 /* {{ziman|ku}} */ 6265837 wikitext text/x-wiki == {{ziman|ku}} == === Bilêvkirin === * {{ku-kîte}} === Rengdêr === {{rengdêr|ku}} # {{guharto|ku|bêhesab}} #* {{mewlûd|jg=Her wekî hatiye gotin '''bêhîsab'''<br>Lê neşêm bêjim jî tetwîla Kîtab}} 1b2fevn6zus0uo9ijs43k5pulsavfny tabi’ 0 283758 6265767 5786395 2026-07-20T07:02:06Z Wikihez 7344 6265767 wikitext text/x-wiki == {{ziman|ku}} == === Mane === {{cure?|ku}} # [[aîd]], bi ser … #* {{jêder|ku|jg=Em kirine ummeta xeyr-ul beşer<br>'''Tabi'ê''' wî muqtedayê namuwer|{{Jêgirtin/Mela Hisênê Bateyî/Mewlûda Kurdî}}}} t62r91g1t9o35dgvsn0zqjmez9jubnt bafitûh 0 283768 6265789 6142259 2026-07-20T08:15:52Z Wikihez 7344 6265789 wikitext text/x-wiki == {{ziman|ku}} == === Bilêvkirin === * {{ku-kîte}} === Rengdêr === {{ku-tewîn-rd|bafitûh}} {{rengdêr|ku}} # [[dilveker]] #* {{mewlûd|jg=Fexrê Îbrahîm û Îsmaîl û Nûh<br>Mustefayê bawefa yê '''bafitûh'''}} ==== Etîmolojî ==== {{bêetîmolojî}} ==== Werger ==== {{werger-ser}} {{werger-bin}} 7scaz7wtajv8vz3w96l19pnn9idvzz7 bawefa 0 283769 6265776 6142260 2026-07-20T08:07:54Z Wikihez 7344 6265776 wikitext text/x-wiki == {{ziman|ku}} == === Bilêvkirin === * {{ku-kîte}} === Rengdêr === {{ku-tewîn-rd|bawefa}} {{rengdêr|ku}} # [[dilsoz]], [[wefadar]], [[biwefa]] #* {{mewlûd|Fexrê Îbrahîm û Îsmaîl û Nûh<br>Mustefayê '''bawefa''' yê bafitûh}} ==== Etîmolojî ==== {{bêetîmolojî}} ==== Werger ==== {{werger-ser}} {{werger-bin}} b4ev4ko3qfs6905rc4ok68j40z2m0j5 6265777 6265776 2026-07-20T08:08:02Z Wikihez 7344 /* */ bi [[MediaWiki:Gadget-AjaxEdit.js|AjaxEdit]]ê re 6265777 wikitext text/x-wiki == {{ziman|ku}} == === Bilêvkirin === * {{ku-kîte}} === Rengdêr === {{ku-tewîn-rd|bawefa}} {{rengdêr|ku}} # [[dilsoz]], [[wefadar]], [[biwefa]] #* {{mewlûd|jg=Fexrê Îbrahîm û Îsmaîl û Nûh<br>Mustefayê '''bawefa''' yê bafitûh}} ==== Etîmolojî ==== {{bêetîmolojî}} ==== Werger ==== {{werger-ser}} {{werger-bin}} hx0hwbv3q6w2wzlgshsosq7w8c77q8c Ma remeyte îz remeyte 0 283771 6265817 5786396 2026-07-20T09:03:09Z Wikihez 7344 Requesting speedy deletion (Xelet). ([[:m:User:Xiplus/TwinkleGlobal|TwinkleGlobal]]) 6265817 wikitext text/x-wiki {{jêbirin|1=Xelet}} == {{ziman|ku}} == === Mane === {{cure?|ku}} # te neavêt dema ku te avêt ==== Ji wêjeyê ==== "[[Ma remeyte îz remeyte]]" [[goşîdar]] Destê wî destê Xuda [[li|der]] kar û bar [[w:Mela Hisênê Bateyî]] cjg0r1k9f0rzlqbjuxu1o0qd9i55h59 menzîlet 0 284121 6265850 6142265 2026-07-20T09:38:10Z Wikihez 7344 /* {{ziman|ku}} */ 6265850 wikitext text/x-wiki == {{ziman|ku}} == === Bilêvkirin === * {{ku-kîte}} === Navdêr === {{navdêr|ku}} # [[paye]], [[pile]], [[payedarî]], [[pilebilindî]] #* {{mewlûd|jg=Qudret û te'zîm û mînnet merhemet<br>Hem se'adet hem keramet '''menzîlet'''}} ==== Etîmolojî ==== {{ji?|ku}} ==== Werger ==== {{werger-ser}} {{werger-bin}} m5ibntosjpl3arbjzb2p6cpsvyokln0 te'zîm 0 284122 6265843 6142266 2026-07-20T09:27:06Z Wikihez 7344 6265843 wikitext text/x-wiki == {{ziman|ku}} == === Bilêvkirin === * {{ku-kîte}} === Navdêr === {{navdêr|ku}} # [[giramînişandan]], [[hurmetnişandan]], [[mezinkirin]] #* {{mewlûd|jg=Qudret û '''te'zîm''' û mînnet merhemet<br>Hem se'adet hem keramet menzîlet}} 2wzrro2ih96j970z71eo81dypdiojaz Rehmî nazil cumleê 'îlet dibit 0 284125 6265825 5786397 2026-07-20T09:10:51Z Wikihez 7344 [[Bikarhêner:Wikihez/templateScript2.js|TS]]: sererastkirin 6265825 wikitext text/x-wiki == {{ziman|ku}} == === Îfade === {{îfade|ku}} # dilovanî datê û hemî êşan jê dibe #* {{mewlûd|jg=Bête xwendin ger li avê û vexwit<br>'''Rehmî nazil cumleê 'îlet dibit'''}} ra50psyy9cbvl6lnb65brugeesly7z5 6265826 6265825 2026-07-20T09:11:22Z Wikihez 7344 6265826 wikitext text/x-wiki == {{ziman|ku}} == === Îfade === {{îfade|ku}} # [[dilovanî]] [[datê]] û [[hemî]] [[êş|êşan]] [[jê dibe]] #* {{mewlûd|jg=Bête xwendin ger li avê û vexwit<br>'''Rehmî nazil cumleê 'îlet dibit'''}} ec11ntitirjnrth7lx6cp4icoqr8321 gazî ket 0 284136 6265740 5841109 2026-07-20T05:54:46Z Wikihez 7344 /* Formeke lêkerê */ 6265740 wikitext text/x-wiki == {{ziman|ku}} == === Formeke lêkerê === {{lêker|ku|form=erê}} # (ew) [[gazî bike]], gazî bikit #* {{jêder|ku|{{Jêgirtin/Mela Hisênê Bateyî/Mewlûda Kurdî}}|jêgirtin='''Gazî ket''' îxwan û hilbêtin çira<br>Bête xwendin Mewlûda xeyr-ul wera}} szqixy0232x87szf0g574bu8bclmxq1 şecer 0 284236 6265845 6256135 2026-07-20T09:32:44Z Wikihez 7344 [[Bikarhêner:Wikihez/templateScript2.js|TS]]: sererastkirin, [[Bikarhêner:Wikihez/templateScript2.js|TS]]: sererastkirin 6265845 wikitext text/x-wiki == {{ziman|ku}} == === Bilêvkirin === * {{ku-kîte}} === Navdêr === {{navdêr|ku}} # [[dar]] #* {{mewlûd|jg=Sellî ya Rebbî 'ela xeyr-îl beşer<br>Ta hebin teyr û bixwînin ber '''şecer'''}} ==== Formên alternatîv ==== * {{g|ku|şecere}} gh2wqo59a2gdromw74yd9x4p5lchgel 'emd 0 284240 6265758 5786400 2026-07-20T06:09:07Z Wikihez 7344 [[Bikarhêner:Wikihez/templateScript2.js|TS]]: sererastkirin, [[Bikarhêner:Wikihez/templateScript2.js|TS]]: sererastkirin 6265758 wikitext text/x-wiki == {{ziman|ku}} == === Mane === {{cure?|ku}} # [[kêmasî]] #* {{jêder|ku|jg=Ey şefî'ê sahibê alayê hemd<br>Min hene bêhed guneh, nisyan û 'emd|[[w:Mela Hisênê Bateyî]]}} 75n1aw271icmfanpxd0g43e06y4q8uc 6265759 6265758 2026-07-20T06:09:17Z Wikihez 7344 /* */ bi [[MediaWiki:Gadget-AjaxEdit.js|AjaxEdit]]ê re 6265759 wikitext text/x-wiki == {{ziman|ku}} == === Mane === {{cure?|ku}} # [[kêmasî]] #* {{jêder|ku|jg=Ey şefî'ê sahibê alayê hemd<br>Min hene bêhed guneh, nisyan û ''''emd'''|[[w:Mela Hisênê Bateyî]]}} 0alrc1w4vw0flv7j0tnba3t2y4gwbyp roja esîr 0 284245 6265793 5786401 2026-07-20T08:19:23Z Wikihez 7344 6265793 wikitext text/x-wiki == {{ziman|ku}} == === Îfade === {{îfade|ku|[[roj|roja]] [[esîr]]}} # [[roj|roja]] [[gir|giran]], [[roja qiyametê]] #* {{mewlûd|jg=Lê me hêvî wasiq e dê ez feqîr<br>Jê rê alaya te bim '''roja 'esîr'''}} 4hjthnxdicmgh73vo11fbdd0djwmlsj daxîdar 0 284303 6265851 6142285 2026-07-20T09:39:27Z Wikihez 7344 /* {{ziman|ku}} */ 6265851 wikitext text/x-wiki == {{ziman|ku}} == === Bilêvkirin === * {{ku-kîte}} === Navdêr === {{navdêr|ku}} # [[xemgîn]], [[derdgiran]] #* {{mewlûd|jg=Ew kelîmê xweşnewayê çerxî tûr<br>'''Daxîdar''' im bo wî sîmayê bi nûr}} ==== Etîmolojî ==== {{bêetîmolojî}} ==== Werger ==== {{werger-ser}} {{werger-bin}} q68fc81d6z688y5qyozsx6e7ril7gm1 xweşnewa 0 284304 6265848 6252084 2026-07-20T09:36:26Z Wikihez 7344 /* {{ziman|ku}} */ 6265848 wikitext text/x-wiki == {{ziman|ku}} == === Navdêr === {{navdêr|ku}} # [[dengxweş]], [[xweşawaz]] # {{mewlûd|jg=Ew kelîmê '''xweşnewayê''' çerxî tûr<br>Daxîdar im bo wî sîmayê bi nûr}} tcmyc3ig3bqavpocxsba1srgs74v4cu 6265849 6265848 2026-07-20T09:36:56Z Wikihez 7344 6265849 wikitext text/x-wiki == {{ziman|ku}} == === Navdêr === {{navdêr|ku}} # [[dengxweş]], [[xweşawaz]] #* {{mewlûd|jg=Ew kelîmê '''xweşnewayê''' çerxî tûr<br>Daxîdar im bo wî sîmayê bi nûr}} ==== Etîmoloj ==== Ji {{qf|ku|xweş|newa}} 56qm0yu70bvegp9slwo68rvlug4goso refî 0 284353 6265781 5841986 2026-07-20T08:12:41Z Wikihez 7344 /* */ bi [[MediaWiki:Gadget-AjaxEdit.js|AjaxEdit]]ê re 6265781 wikitext text/x-wiki == {{ziman|ku}} == === Navdêr === {{navdêr|ku|z=?}} # [[hilgir]], [[raker]], [[hilder]], [[ragir]] #* {{Jêgirtin/Mela Hisênê Bateyî/Mewlûda Kurdî|jêgirtin=Çûn îradet hate sultanê '''refî'''<br>Çêkirî Adem bi vî şiklê bedî}} ==== Etîmolojî ==== {{ji?}} ==== Werger ==== {{werger-ser}} {{werger-bin}} === Formeke navdêrê === {{ku-tew-nav|ref|nêr|çemandî|binavkirî}} {{navdêr|ku|form=erê}} # ''Rewşa [[çemandî]] ya yekjimar a binavkirî ya'' '''[[ref#Navdêr 2|ref]]'''. sjtd4j2in1vq34m4gvf26rv7dci9fii qebde 0 284354 6265787 6142293 2026-07-20T08:15:03Z Wikihez 7344 /* */ bi [[MediaWiki:Gadget-AjaxEdit.js|AjaxEdit]]ê re 6265787 wikitext text/x-wiki == {{ziman|ku}} == === Bilêvkirin === * {{ku-kîte}} === Navdêr === {{navdêr|ku|z=?}} # [[desteyek]], [[mistek]], [[kulmek]] #* {{Jêgirtin/Mela Hisênê Bateyî/Mewlûda Kurdî}}|jêgirtin=Emrî hate goşê Cibrîlê emîn<br>'''Qebde'ê''' bîne ji beyda'ê zemîn}} ==== Etîmolojî ==== {{ji?}} ==== Werger ==== {{werger-ser}} {{werger-bin}} 899zb6c1ch09zzmx9szaj5q3n7b8b5m 6265788 6265787 2026-07-20T08:15:12Z Wikihez 7344 /* */ bi [[MediaWiki:Gadget-AjaxEdit.js|AjaxEdit]]ê re 6265788 wikitext text/x-wiki == {{ziman|ku}} == === Bilêvkirin === * {{ku-kîte}} === Navdêr === {{navdêr|ku|z=?}} # [[desteyek]], [[mistek]], [[kulmek]] #* {{Jêgirtin/Mela Hisênê Bateyî/Mewlûda Kurdî|jêgirtin=Emrî hate goşê Cibrîlê emîn<br>'''Qebde'ê''' bîne ji beyda'ê zemîn}} ==== Etîmolojî ==== {{ji?}} ==== Werger ==== {{werger-ser}} {{werger-bin}} g3xi371x8vf6y25defftmfxz8rhtumv mêrê malê bicizme ye, teşta malê teneke ye 0 289116 6265583 5886710 2026-07-19T15:05:34Z Wikihez 7344 6265583 wikitext text/x-wiki == {{ziman|ku}} == === Gotineke pêşiyan === {{gotineke pêşiyan|ku}} # {{hevmaneya|ku|bejn tît e mal mecît e}} #* {{bênimûne|ku}} ownbq0cmgnafgw9axptz99kyemgyw04 6265584 6265583 2026-07-19T15:06:21Z Wikihez 7344 ([[Mediawiki:Gadget-start.js|WF:NÛ]] v.2.0) +ku:gotineke pêşiyan: 6265584 wikitext text/x-wiki == {{ziman|ku}} == === Gotineke pêşiyan === {{gotineke pêşiyan|ku}} # {{mane?|ku}} #* {{bênimûne|ku}} ==== Binêre herwiha ==== * {{g|ku|bejn tît e mal mecît e}} 5noacc59z0deop959qya8zydvy75zpp Protokoll 0 294556 6265761 6127632 2026-07-20T06:39:38Z Bikarhêner 3719 [[Bikarhêner:Wikihez/templateScript.js|TS]]: Ji [[en:Protokoll|en.wikt]] 6265761 wikitext text/x-wiki == {{ziman|de}} == === Bilêvkirin === * {{IPA|de|/pʁotoˈkɔl/}} * {{deng|de|De-Protokoll.ogg|a=<<Almanya>> (<<Berlîn>>)}} * {{kîte|de|Pro|to|koll}} * {{ku-tîp|pxotokol}} === Navdêr === {{navdêr|de|z=nt|p=Protokolle}} # [[protokol]] # [[zebt]]a civînekê 0nmhkzgligflarv779fpyagl7fdcbf8 Gotûbêja bikarhêner:Mohajeer 3 294724 6265806 6233062 2026-07-20T08:31:36Z Wikihez 7344 [[Bikarhêner:Wikihez/skrîpt/js/şablon-lêke.js|T]]: Agahdarkirin: [[Malik-ul_mulkê_Celîlê_Zulcelal]] 6265806 wikitext text/x-wiki http://ku.wiktionary.org/wiki/%D8%B7%D8%A8%D9%82 interaction=etkileşim=برهم‌کنش=تفاعل == Sûperlatîv hemû xelet in!== Hevalê hêja, li vê derê zêdeyî 1000 peyvan bi formên sûperlatîv hatine nivîsîn. Lê hemû jî xelet in! Di kurdî de sûperlatîv bi "-tirîn" e lê ew hemû bi "-tirînÎN" hatine nivîsîn. Ji qenciya xwe alîkariyê bikin û jê bibin yan jî navê wan biguherînin. Li gel silavên germ! --[[Bikarhêner:Ferhengvan|Ferhengvan]] ([[Gotûbêja bikarhêner:Ferhengvan|gotûbêj]]) 14:40, 12 berfanbar 2013 (UTC) :bi min ew hevalên xudanrobot dikarin hemûyan bi asanî biguherînin,lê ez jî dê li ser xebitim..slav..[[Bikarhêner:Mohajeer|Mohajeer]] ([[Gotûbêja bikarhêner:Mohajeer|gotûbêj]]) 14:46, 12 berfanbar 2013 (UTC)Mohajeer == Global account == Hi Mohajeer! As a [[:m:Stewards|Steward]] I'm involved in the upcoming [[:m:Help:Unified login|unification]] of all accounts organized by the Wikimedia Foundation (see [[:m:Single User Login finalisation announcement]]). By looking at [[Special:CentralAuth/Mohajeer|your account]], I realized that you don't have a global account yet. In order to secure your name, I recommend you to create such account on your own by submitting your password on [[Special:MergeAccount]] and unifying your local accounts. If you have any problems with doing that or further questions, please don't hesitate to contact me on my [[User talk:DerHexer|talk page]]. Cheers, [[Bikarhêner:DerHexer|DerHexer]] ([[Gotûbêja bikarhêner:DerHexer|gotûbêj]]) 21:47, 16 rêbendan 2015 (UTC) == Names of Wikimedia languages == Dear Mohajeer , we are initiating a long needed action - we would like to '''translate names of all Wikimedia languages to all Wikimedia languages''' in the next two months. We have noticed that you are very active on Wiktionary and that is the reason why we are taking liberty to contact you. We hope that you would be interesting to help us in our endeavor - To make this action easier we have already prepared the list of all [[:meta:Names of Wikimedia languages|Wikimedia languages]], and for each language we have already prepared the page with existing and missing translations. So when you go to the page for your language you would have two tasks - to check whether existing translations are OK and to fill in the missing one. The more detailed instruction are on the language page. What are the benefits of this work? * We believe it is about time to have all Wikimedia languages translated to all Wikimedia languages :) * Translated languages will be parsed into Wiktionary and the resulting number of Wiktionary entries will be significant for each language. That could significantly increase the number of entries for less developed Wiktionaries, and improve the quality of entries in general. * Wikidata - this would be great contribution to Wikidata. * All other projects could benefit from this list (Wiki Travel :)), as we believe that certain amount of terms has to be properly translated to all languages. We are gathered around the project [[meta:Grants:PEG/Interglider.ORG/Wiktionary_Meets_Matica_Srpska|Wiktionary Meets Matica Srpska]] and we hope that you would be interesting in working with us! If you have any questions you can ask them on the Names of Wikimedia languages [[meta:Talk:Names_of_Wikimedia_languages|discussion page]] or via personal emails. ''Important notice: The data are licensed under CC0, as they should be incorporated into Wikidata at the end of the process.'' If you '''don’t want''' to receive future announcement about the project, please leave a note on [[meta:Talk:Names_of_Wikimedia_languages|discussion page]]. Thank you and looking forward to hear from you! Interglider.org team *[https://en.wikipedia.org/wiki/User:Senka_Latinovi%C4%87 Senka Latinović] *[https://en.wikipedia.org/wiki/User:Godzzzilica Godzzzilica] *[https://en.wikipedia.org/wiki/User:Millosh Millosh] [[Bikarhêner:Senka Latinović|Senka Latinović]] ([[Gotûbêja bikarhêner:Senka Latinović|gotûbêj]]) 14:09, 24 avrêl 2015 (UTC) == Sîlav == Sîlav Mohajeer, lî cem min jî di destpêkê de ab nîşan da, lê wan carên din ab nîşan neda. Ka dîsa hewl bide. Spas û silavên hêja. PS: Gelo çibû ji hesabê te yê Twîtterê? :( --[[Bikarhêner:George Animal|George Animal]] ([[Gotûbêja bikarhêner:George Animal|gotûbêj]]) 19:43, 20 rezber 2016 (UTC) : silav george, welle min jêbîr hesaba twitterê, lê dikarim numeraya têlefonê bidim //mohajeer == Xwestin == Silav Mohajeer, çend xwestin: * Tu dikarî koda [//ku.wiktionary.org/wiki/Bikarh%C3%AAner:Ghybu/vector.js vira] bikî şûnda [//ku.wiktionary.org/wiki/MediaWiki:Common.js koda din]. * Û bo nivîsên erebî û nivîsên din: # [//ku.wiktionary.org/w/index.php?title=Bikarh%C3%AAner:Ghybu/vector.css&oldid=2796404 Koda vira] bikî [[MediaWiki:Gadget-StyleScripts.css|vira]], # paşê jî va koda <tt><code style="background-color:yellow">* StyleScripts[ResourceLoader|default|type=styles]|StyleScripts.css</code></tt></span> li '''[[MediaWiki:Gadgets-definition|vira]]''' bike bin nivîsên din. :Ew rûpelana tenê Rêveberan dikanin biguherînin. Spas--[[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 19:02, 19 rezber 2017 (UTC) :: {{çêbû}}--[[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 20:06, 4 kewçêr 2017 (UTC) == [[:Kategorî:Gotarên ku bên jêbirin]] == Silav Mohajeer, tu dikarî gortarên ku di nav '''[[:Kategorî:Gotarên ku bên jêbirin|vê kategorî]]''' de ne jê bibî? Spas--[[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 19:40, 20 reşemî 2018 (UTC) :Belê bra dikarim, ez ê her roj hinekan jê bibim, silavên germ [[Bikarhêner:Mohajeer|Mohajeer]] ([[Gotûbêja bikarhêner:Mohajeer#top|gotûbêj]]) 19:59, 20 reşemî 2018 (UTC) == Ji bo peyvçêkirina Kurdî pêşniyarên Farisî == * {{g|fa|آبریز}}(toilet): Ji peyvên av û rêtin pêk tê, avrêt. * {{g|fa|آبزی}}: ji av û jiyanê pêk tê, avjî. :Merhaba Mohajeer, bnr [[Şablon:g]]: bi vê şablonê tîpên erebî rind derdikevin ([https://ku.wiktionary.org/w/index.php?title=%D8%A2%D8%A8_%D8%A8%D8%A7%D8%B2%DB%8C_%DA%A9%D8%B1%D8%AF%D9%86&curid=628847&diff=2929863&oldid=2929858] / [https://ku.wiktionary.org/w/index.php?title=%D8%A2%D8%A8%D8%B1%DB%8C%D8%B2&curid=628843&diff=2929865&oldid=2929838] / [https://ku.wiktionary.org/w/index.php?title=%D8%A2%D8%B3%DB%8C%D8%A7&diff=2929878&oldid=2929862]).--[[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 22:28, 27 reşemî 2018 (UTC) ::Silav {{ragihandin|Ghybu}}, rastî xweş xuya dike lê zêde wext digire. Eger hevalek hebe bi rêya BOTan biguherîne dê gelek baş be [[Bikarhêner:Mohajeer|Mohajeer]] ([[Gotûbêja bikarhêner:Mohajeer#top|gotûbêj]]) 19:25, 28 reşemî 2018 (UTC) * {{g|fa|آبپز}}: ji peyvên av û pehtin pêk tê, avpêj * {{g|fa|آب شویه}}(sifon): ji peyvên av û şûştin pêk tê, avşû * {{g|fa|آبراه سازی}}(sewage): ji peyvên av û çêkirin pêk tê, avrê sazî * {{g|fa|آبرفت}}(alluvion):ji peyvên av û malîn pêk tê, avmalî == MediaWiki:Common.css == Silav Mohajeer, Tu dikarî [//ku.wiktionary.org/wiki/Bikarh%C3%AAner:Ghybu/vector.css vê koda] bikî şûnda [//ku.wiktionary.org/wiki/MediaWiki:Common.css koda din] (bnr. gotara [[kirin]] û yên din di nivîsa "Nevrok"ê da pirsgirêk heye). Spas--[[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 21:28, 21 adar 2018 (UTC) :{{çêbû}}--[[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 07:17, 1 gulan 2018 (UTC) == Powder, whitwash == Silav kek Mohajer, te pirsa "powder, pudra" û "whitewash" kiribû ku di kurmancî de * powder: "spiyav, spîav" in. * whitewash: "spî kirin" (lêker) û "spîkirin" (navdêr). Silavên germ, --[[Bikarhêner:Ferhengvan|Ferhengvan]] ([[Gotûbêja bikarhêner:Ferhengvan|gotûbêj]]) 13:04, 31 adar 2018 (UTC) ::Silav kek {{ragihandin|Ferhengvan}} ev baş bû, spas dikem [[Bikarhêner:Mohajeer|Mohajeer]] ([[Gotûbêja bikarhêner:Mohajeer#top|gotûbêj]]) 18:54, 31 adar 2018 (UTC) == Formata standard == Silav Mohajeer, niha formatên nû yên standard ên ferhengê hene. Ji kerema xwe formatên kevn bi kar neyne. Ez ê sibê du-sê girêdanan bi rê bikim ên ku standardên me yên nû nîşan didin. Spas û şev baş--[[Bikarhêner:Şêr|Şêr]] ([[Gotûbêja bikarhêner:Şêr|gotûbêj]]) 21:17, 14 tebax 2019 (UTC) ::Bnr. hema bêje [https://ku.wiktionary.org/wiki/welat] li her rûpelê ev wisa ye. Em rûpelên mane jî li gorî standarda nû diguherînin. --[[Bikarhêner:Şêr|Şêr]] ([[Gotûbêja bikarhêner:Şêr|gotûbêj]]) 21:18, 14 tebax 2019 (UTC) :::Silav {{ragihandin|Şêr}} min lê nêrî, destê we sax be lê barê me we zêde kirîye. Di bin Navderê de ma çi hewcehî heye ku em dîsan binivîsin ? [[Bikarhêner:Mohajeer|Mohajeer]] ([[Gotûbêja bikarhêner:Mohajeer#top|gotûbêj]]) 21:25, 14 tebax 2019 (UTC) :::Niha dereng e, lê sibê êvarê, an jî di van rojên bê de ez ê ji te re rave bikim bracan. :) Xwezî te zanibûya ferheng di nav çi rewşê de bû. Wateyên rengdêr, hoker, navdêr û hwd. hemû di nav hev de bûn. Niha zelaltir bûne ev beş. Em piraniya standardkirinê bi rêya robotan dikin. Ez di rojên bê de li vir binivîsim. {{bişirîn}} --[[Bikarhêner:Şêr|Şêr]] ([[Gotûbêja bikarhêner:Şêr|gotûbêj]]) 21:27, 14 tebax 2019 (UTC) ::::Temam baş e, rastî ez zûda çûbûm leşkerîyê, min jî lêzêdekirinên xwe berdewam nekirin. Rêveberiya te jî bixêr be :) [[Bikarhêner:Mohajeer|Mohajeer]] ([[Gotûbêja bikarhêner:Mohajeer#top|gotûbêj]]) 21:29, 14 tebax 2019 (UTC) ::::Nexwe em ê hev di rojên bê de bibînin. :) --[[Bikarhêner:Şêr|Şêr]] ([[Gotûbêja bikarhêner:Şêr|gotûbêj]]) 21:31, 14 tebax 2019 (UTC) :::::pardonnnnnnnnnnnnnnnnn :))) şêro tu mehê carekê nav diguherî :) [[Bikarhêner:Mohajeer|Mohajeer]] ([[Gotûbêja bikarhêner:Mohajeer#top|gotûbêj]]) 21:32, 14 tebax 2019 (UTC) :::::Ev du sal in ku ez ne li vir bûm :). Lawo telefona min a destan winda bû, Kontaktên Whatsappê, û nimreyên min hemû çûn :(. Gava min telefoneke nû kirî, ez ê peyamekê ji te re bişînim,dikarî nimreya xwe ya telefonê bidî min ji bo Whatsappê . :) --[[Bikarhêner:Şêr|Şêr]] ([[Gotûbêja bikarhêner:Şêr|gotûbêj]]) 21:34, 14 tebax 2019 (UTC) :::::Min nimreya te niha ji bo derve û bikarhêneran veşart. --[[Bikarhêner:Şêr|Şêr]] ([[Gotûbêja bikarhêner:Şêr|gotûbêj]]) 21:40, 14 tebax 2019 (UTC) ::::::Te baş kir, em dikarin di demek bê de, grûbeke watsapp ava bikin. dê gelek baş be. [[Bikarhêner:Mohajeer|Mohajeer]] ([[Gotûbêja bikarhêner:Mohajeer#top|gotûbêj]]) 21:41, 14 tebax 2019 (UTC) ::::::Dibe, ev jî hesabê Wîkîferhengê li ser Twîtterê ye. [https://twitter.com/wikiferheng?lang=de] --[[Bikarhêner:Şêr|Şêr]] ([[Gotûbêja bikarhêner:Şêr|gotûbêj]]) 21:42, 14 tebax 2019 (UTC) ::::::Tu bi silametî hatî, bi xêr hatî cano --[[Bikarhêner:Şêr|Şêr]] ([[Gotûbêja bikarhêner:Şêr|gotûbêj]]) 21:43, 14 tebax 2019 (UTC) :::::::Spas :) {{ragihandin|Bikarhêner}} hevalo rêveberiya te pîroz be. Înş nêz de em ê grûbeke watsappê ava bikin, tu jî tevlî bibe [[Bikarhêner:Mohajeer|Mohajeer]] ([[Gotûbêja bikarhêner:Mohajeer#top|gotûbêj]]) 21:47, 14 tebax 2019 (UTC) :: Gelek spas dikim kekê hêja. Ez jî di wê qenaetê de me ku di vê têkiliya me xurttir bibe. Lewma koma Whatsappê bo min meqbûl e. -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 21:56, 14 tebax 2019 (UTC) :::::::Bikarhêner hesabê twîtterê bi rê ve dibe. Ez bi rastî ji komên whatsappkan zêde hez nakim {{lol}} --[[Bikarhêner:Şêr|Şêr]] ([[Gotûbêja bikarhêner:Şêr|gotûbêj]]) 21:49, 14 tebax 2019 (UTC) ::::::::welle hûn dizanin, lê min got ku em bi rehetî bi hevra biaxivin :) [[Bikarhêner:Mohajeer|Mohajeer]] ([[Gotûbêja bikarhêner:Mohajeer#top|gotûbêj]]) 21:50, 14 tebax 2019 (UTC) ::::::::Ez di komeke kurdî de bûm, lê ji her seriyekî dengek derdiket û dû re hemû belawela dûn. Dûrî te û hevalên hêja, lê piraniya endamên wan koman ji bo "qiştikan" li wir in, karê rind dernakeve holê {{xemgîn}} --[[Bikarhêner:Şêr|Şêr]] ([[Gotûbêja bikarhêner:Şêr|gotûbêj]]) 21:52, 14 tebax 2019 (UTC) :::::::::ê temam, bila niha wiha bisekîne corc :) hade xewa min hat, şevbaş [[Bikarhêner:Mohajeer|Mohajeer]] ([[Gotûbêja bikarhêner:Mohajeer#top|gotûbêj]]) 21:53, 14 tebax 2019 (UTC) :::::::::Corc çû, navekî xweş bû bi rastî :D [https://ku.wiktionary.org/w/index.php?title=Bikarhêner:JiyanBot&diff=3425274&oldid=3070185&diffmode=source]: Şev baş: em ê biaxivin :D --[[Bikarhêner:Şêr|Şêr]] ([[Gotûbêja bikarhêner:Şêr|gotûbêj]]) 21:55, 14 tebax 2019 (UTC) : hevalê {{ragihandin|Bikarhêner}} ji bo pêşniyara te ya hesaba twîtterê bo wîkîpedîyaya kurdî gelo em çi bikin ? amadehiya me dê çawa be ?[[Bikarhêner:Mohajeer|Mohajeer]] ([[Gotûbêja bikarhêner:Mohajeer#top|gotûbêj]]) 20:42, 17 tebax 2019 (UTC) :: Merheba hevalê hêja. Em dikarin hesabeke cuda yê bi navê "Wîkîpediya" jî vebikin, lê ger hesabek wiha neyê vekirin, ez ê ji ser hesaba Wîkîferhengê derbarê Wîkîpediyaya kurdî de jî statîstîk, nûçê û danasîn û dazanînan parve bikim. Û ger bixwazî bo nûçe û dazanînên derbarê Wîkîpediyayê de tu parvekirinan bike. Ji bo vê yekê dikarî werî DMya (DM: "Direct Message" ango cihê peyamşandinê) hesaba Wîkîferhengê. -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 21:08, 17 tebax 2019 (UTC) == pj-fa-navdêr == Silav bro, tu çawa yî? Min ev guhert [https://ku.wiktionary.org/w/index.php?title=ایل‌ها&curid=769891&diff=3640056&oldid=3640053&diffmode=source]. :) --[[Bikarhêner:Şêr|Şêr]] ([[Gotûbêja bikarhêner:Şêr|gotûbêj]]) 18:26, 19 tebax 2019 (UTC) :Û kêmasiya min [https://ku.wiktionary.org/w/index.php?title=ایل‌ها&curid=769891&diff=3640058&oldid=3640056&diffmode=source BNR]: --[[Bikarhêner:Şêr|Şêr]] ([[Gotûbêja bikarhêner:Şêr|gotûbêj]]) 18:28, 19 tebax 2019 (UTC) :: {{ragihandin|Şêr}} Şêro tu çima karê zehmet dikî :), bi botan hemîyan çêke :-) [[Bikarhêner:Mohajeer|Mohajeer]] ([[Gotûbêja bikarhêner:Mohajeer#top|gotûbêj]]) 18:37, 19 tebax 2019 (UTC) ::: Bot her tişt çênakin (zimanan nasnakin)... Û çêkirina botan jî zehmet e!--[[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 22:00, 19 tebax 2019 (UTC) :::: Demekî hûn peyvek farisî çêdikin nivîsandina <code><nowiki>{{g|fa|...}}</nowiki></code> şûnda <code><nowiki>[[...]]</nowiki></code> tiştek pir zor e? Min li jor jî nivîsandibû: [https://ku.wiktionary.org/wiki/Got%C3%BBb%C3%AAja_bikarh%C3%AAner:Mohajeer#Ji_bo_peyv%C3%A7%C3%AAkirina_Kurd%C3%AE_p%C3%AA%C5%9Fniyar%C3%AAn_Faris%C3%AE]</code>--[[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 22:39, 19 tebax 2019 (UTC) == Kategorî:Gotarên ku bên jêbirin == Hi Mohajeer, sorry disturb you but there are several pages in the category above. Are they really to be eliminated or can they be used? If they are to be eliminated I can help. Regards. [[Bikarhêner:DARIO SEVERI|DARIO SEVERI]] ([[Gotûbêja bikarhêner:DARIO SEVERI|gotûbêj]]) 06:10, 1 îlon 2019 (UTC) :{{ragihandin|DARIO SEVERI}}Hi Dario, thanks for your attention. I eliminated all of them. But you can help me for future. Regards :-) [[Bikarhêner:Mohajeer|Mohajeer]] ([[Gotûbêja bikarhêner:Mohajeer#top|gotûbêj]]) 16:48, 1 îlon 2019 (UTC) == Kurdiya başûrî == Silav Mohajeer, Tu dikarî li gotûbêja [[Gotûbêja modulê:ziman/dane#Devokên kurdiya başûrî]] seh bikî... Çend pirsên min hene {{=)}: {{w|kurdiya başûrî}} ziman e: wekî kurmancî û soranî? An jî wekî kurdî ye (makroziman) navê koma çend zimanan e ({{w|kirmaşanî}}, {{w|kelhurî}}, {{w|feylî}}, {{w|lekî}}, {{w|şexbizînî}}, ...). Li ser rêzimanê kurdiya başûrî pirtûk hene? Kîjan alfabe devokên wî bi kar tînin? Bi gotina kurt, kurdiya başurî ziman e an jî koma zimanan e? {{ping|Ferhengvan|Calak|Guherto|Bikarhêner}}--[[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 15:18, 26 gulan 2020 (UTC) :Silav kak {{ragihandin|Ghybu}} Kurdiya Başûrî ji bo navê giştî yê zimanê xelkê Kirmaşan, Îlam, Xaneqîn, Bedrê, Mendelî diaxivin, dihêt gotin. Mixabin ev ziman an zaravayê kurdî hêj nehatiye standardîze kirin, ji ber wê bikarhênerên vî zarava/zimanî an bi navê eşîra xwe (sencabî, kelhûrî, zengeneyî, şêxbizinî..) an bi navê bajarê xwe (kirmaşanî, xaneqînî..) an bi navê xwe yê mezhebî (feylî..) zarava/zimane xwe binav dikin. Ev hemû devok in ku ji hev fêm dikin. Ferqa Kelhûrî û Feylî wekî ferqa Behdînî û Şikakî ye, ferqa kirmaşanî û xaneqînî wekî ferqa hekarîkî û batmanîkî ye. Ev hemû devok in. Ji bo navê hevpar Kurdiya Başûrî tê gotin ji aliyê zimanzanan ve ku hemiyê dikin yek. Niha navê ''Kelhûrî'' pêşve diçe ku bibe navê vî ziman/zaravaayî. Wekî ku li cihê Behdînî, Şikakî êdî em gelemperî navê kurmancî bikartînin. Jixwe li herêmên behdîn û şikakan, bikaranîna kurmancî tine. Ev bi standardîzebûnê çêbûye. Bi giştî Kurdiya Başûrî navê zaravayekê kurdî ye wek kurmancî û soranî. Lekî di nav ''Kurdiya Başûr'' de nayê hesibandin. Hinekî cudatir e ji kurdiya başûrî. Bi tenê serê wek zarava tê hesibandin û wek etnisîte jî sinorên xwe ava kirîne. Navê zimanê wan Lekî ye. Pirtûk li ser Kelhûrî li cem min hene, lê pdf hene, eger hesaba te ya telegramê hebe, ez dikarim ji te re bişînim. Her wisa Lorî/Bextiyarî,Mamêsenî, Kuhgilûyî jî di navbera Farisî û Kurdî de ma ye ku rewşa wê nediyar e, di dîrokê de kurd hatine hesibandin lê niha xwe we gelek serbixwe dibînin. Silav û rêz [[Bikarhêner:Mohajeer|Mohajeer]] ([[Gotûbêja bikarhêner:Mohajeer#top|gotûbêj]]) 21:13, 26 gulan 2020 (UTC) == How we will see unregistered users == <div lang="en" dir="ltr" class="mw-content-ltr"> <section begin=content/> Hi! You get this message because you are an admin on a Wikimedia wiki. When someone edits a Wikimedia wiki without being logged in today, we show their IP address. As you may already know, we will not be able to do this in the future. This is a decision by the Wikimedia Foundation Legal department, because norms and regulations for privacy online have changed. Instead of the IP we will show a masked identity. You as an admin '''will still be able to access the IP'''. There will also be a new user right for those who need to see the full IPs of unregistered users to fight vandalism, harassment and spam without being admins. Patrollers will also see part of the IP even without this user right. We are also working on [[m:IP Editing: Privacy Enhancement and Abuse Mitigation/Improving tools|better tools]] to help. If you have not seen it before, you can [[m:IP Editing: Privacy Enhancement and Abuse Mitigation|read more on Meta]]. If you want to make sure you don’t miss technical changes on the Wikimedia wikis, you can [[m:Global message delivery/Targets/Tech ambassadors|subscribe]] to [[m:Tech/News|the weekly technical newsletter]]. We have [[m:IP Editing: Privacy Enhancement and Abuse Mitigation#IP Masking Implementation Approaches (FAQ)|two suggested ways]] this identity could work. '''We would appreciate your feedback''' on which way you think would work best for you and your wiki, now and in the future. You can [[m:Talk:IP Editing: Privacy Enhancement and Abuse Mitigation|let us know on the talk page]]. You can write in your language. The suggestions were posted in October and we will decide after 17 January. Thank you. /[[m:User:Johan (WMF)|Johan (WMF)]]<section end=content/> </div> 18:17, 4 kanûna paşîn 2022 (UTC) <!-- Message sent by User:Johan (WMF)@metawiki using the list at https://meta.wikimedia.org/w/index.php?title=User:Johan_(WMF)/Target_lists/Admins2022(5)&oldid=22532651 --> == You may be an eligible candidate for the U4C election == <div lang="en" dir="ltr" class="mw-content-ltr"> Greetings, The [[m:Special:MyLanguage/Universal_Code_of_Conduct/Coordinating_Committee|Universal Code of Conduct Coordinating Committee (U4C)]] seeks candidates for the 2026 election. The U4C is the global committee responsible for overseeing enforcement of the [[foundation:Special:MyLanguage/Policy:Universal Code of Conduct|Universal Code of Conduct]]. Elections are held annually, if elected a committee member serves for two years. This year the U4C requires candidates to hold administrator rights on at least one wiki, which is why you are being contacted as you appear to hold this right. There are other requirements, such as candidates must be at least 18 years old and may not be employed by the Wikimedia Foundation or other related chapters and affiliates. You can find more information in the [[m:Special:MyLanguage/Universal_Code_of_Conduct/Coordinating_Committee/Election/2026#Call_for_Candidates|call for candidates on Meta-wiki]]. Additionally, the committee's working language is English; some ability to communicate in English is required. The election opens on 18 May, if you are eligible and interested you have until 10 May to submit your candidacy. There will be a week in between for candidates to answer questions from the community. Voting takes place privately in [[m:Special:MyLanguage/SecurePoll|SecurePoll]], successful candidates must receive at least 60% support. More information is available on [[m:Special:MyLanguage/Universal_Code_of_Conduct/Coordinating_Committee/Election/2026|the 2026 Elections page]], including timelines and other candidacy information. If you read over the material and consider yourself qualified, please consider submitting your name to run for the committee. If you think someone else in your community might be interested and qualified, please encourage them to run. In partnership with the U4C -- [[m:User:Keegan (WMF)|Keegan (WMF)]] ([[m:User_talk:Keegan (WMF)|talk]]) 20:06, 28 nîsan 2026 (UTC) </div> <!-- Message sent by User:Keegan (WMF)@metawiki using the list at https://meta.wikimedia.org/w/index.php?title=User:Keegan_(WMF)/test&oldid=30472432 --> == [[Malik-ul_mulkê_Celîlê_Zulcelal]] == Merheba @[[Bikarhêner:Mohajeer|Mohajeer]], rûpela [[Malik-ul mulkê Celîlê Zulcelal]] namzedê jêbirinê ye. Sebeb: Eserên klasîk de gelek îfade hene ku nehatine tercimekirin loma xistina hemû li ferhengê nabe. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 08:31, 20 tîrmeh 2026 (UTC) ae7h6ypvo51eoc9ey8qow72av7caypo bêhesab 0 341437 6265838 5950794 2026-07-20T09:22:59Z Wikihez 7344 6265838 wikitext text/x-wiki == {{ziman|ku}} == === Bilêvkirin === * {{ku-IPA}} * {{ku-kîte}} === Navdêr === {{ku-tewîn-nav|bêhesab|mê}} {{navdêr|ku|z=m}} # [[bêhejmar]], [[gelek]] #* {{jêder|ku|{{Jêgirtin/Feqiyê Teyran}}|jêgirtin=Wêran ez im malim xirab</br>Sotim biraştim '''bêhesab'''</br>Lê pirsî bo kirme kebab}} ==== Formên alternatîv ==== * {{alt|ku|bêhîsab}} ==== Etîmolojî ==== {{bêetîmolojî}} ==== Werger ==== {{werger-ser}} * {{Z|de}}: {{W+|de|zahllos}}, {{W+|de|unzählig}}, {{W-|de|sehr viele|guman=erê}}, {{W-|de|unbeachtet|guman=erê}}, {{W+|de|unmäßig|guman=erê}} * {{Z|fa}}: {{W+|fa|الکی}} * {{Z|fr}}: {{W+|fr|nombreux}}, {{W+|fr|fréquent}}, {{W+|fr|innombrable}} * {{Z|en}}: {{W+|en|countless}}, {{W+|en|many}}, {{W+|en|a lot of}} * {{Z|tr}}: {{W+|tr|hesapsız}}, {{W+|tr|ölçüsüz}}, {{W+|tr|sayısız}} {{werger-bin}} ppfjc7w9zu2zeddgt79ehbrjhdpknvp 6265839 6265838 2026-07-20T09:23:25Z Wikihez 7344 /* */ bi [[MediaWiki:Gadget-AjaxEdit.js|AjaxEdit]]ê re 6265839 wikitext text/x-wiki == {{ziman|ku}} == === Bilêvkirin === * {{ku-IPA}} * {{ku-kîte}} === Navdêr === {{ku-tewîn-nav|bêhesab|mê}} {{navdêr|ku|z=m}} # [[bêhejmar]], [[gelek]] #* {{Jêgirtin/Feqiyê Teyran|jêgirtin=Wêran ez im malim xirab</br>Sotim biraştim '''bêhesab'''</br>Lê pirsî bo kirme kebab}} ==== Formên alternatîv ==== * {{alt|ku|bêhîsab}} ==== Etîmolojî ==== {{bêetîmolojî}} ==== Werger ==== {{werger-ser}} * {{Z|de}}: {{W+|de|zahllos}}, {{W+|de|unzählig}}, {{W-|de|sehr viele|guman=erê}}, {{W-|de|unbeachtet|guman=erê}}, {{W+|de|unmäßig|guman=erê}} * {{Z|fa}}: {{W+|fa|الکی}} * {{Z|fr}}: {{W+|fr|nombreux}}, {{W+|fr|fréquent}}, {{W+|fr|innombrable}} * {{Z|en}}: {{W+|en|countless}}, {{W+|en|many}}, {{W+|en|a lot of}} * {{Z|tr}}: {{W+|tr|hesapsız}}, {{W+|tr|ölçüsüz}}, {{W+|tr|sayısız}} {{werger-bin}} cloqc9dkc14c4xfj8wsd05r3ve9rtlz Bexa 0 358788 6265734 4913874 2026-07-20T05:43:38Z Wikihez 7344 /* */ bi [[MediaWiki:Gadget-AjaxEdit.js|AjaxEdit]]ê re 6265734 wikitext text/x-wiki == {{ziman|ckb}} == === Serenav === {{serenav|ckb|sc=Latn}} # {{f|ckb|bajar}} {{ckb-Arab|بەغا}} nh43abf9qj3p5oiqhxniyfr4udb153y berjewendperest 0 381629 6265603 1121402 2026-07-19T15:49:26Z Wikihez 7344 ([[Mediawiki:Gadget-start.js|WF:NÛ]] v.2.0) +ku:navdêr: 6265603 wikitext text/x-wiki == {{ziman|ku}} == === Bilêvkirin === * {{ku-kîte}} === Navdêr === {{ku-tewîn-nav|berjewendperest|mê û nêr}} {{navdêr|ku|c=mn}} # {{guharto|ku|berjewendîperest}} #* {{bênimûne|ku}} 20tryrr62cb3rs930mxruqksujw1yl4 xwegertî 0 423190 6265613 4167904 2026-07-19T16:38:56Z Wikihez 7344 Requesting speedy deletion (Bêçavkanî). ([[:m:User:Xiplus/TwinkleGlobal|TwinkleGlobal]]) 6265613 wikitext text/x-wiki {{jêbirin|1=Bêçavkanî}} == {{ziman|ku}} == === Navdêr === {{navdêr|ku|z=m}} # [[xwebertî]], [[otomatîzm]] ==== Etîmolojî ==== * [[xwe-]] +[[ger]] +[[-tî]] ==== Werger ==== {{werger-ser}} * {{Z|en}}: {{W+|en|automatism}} * {{Z|tr}}: {{W+|tr|otomatizm}}, {{W+|tr|öz devinim|guman=erê}} {{werger-bin}} i8z3e8bnw8lvpub0nhj7sm6gkkvx62z xwebertî 0 448450 6265614 5664138 2026-07-19T16:39:14Z Wikihez 7344 Requesting speedy deletion (Bêçavkanî). ([[:m:User:Xiplus/TwinkleGlobal|TwinkleGlobal]]) 6265614 wikitext text/x-wiki {{jêbirin|1=Bêçavkanî}} == {{ziman|ku}} == === Navdêr === {{navdêr|ku|z=-}} # {{guharto|ku|xwegertî}} gidddbtk41krr2ao7dmwi4hr0gfolsp bêdestûpa 0 450595 6265773 6180428 2026-07-20T08:05:29Z Wikihez 7344 [[Bikarhêner:Wikihez/templateScript2.js|TS]]: sererastkirin 6265773 wikitext text/x-wiki == {{ziman|ku}} == === Bilêvkirin === * {{ku-kîte}} === Rengdêr === {{rengdêr|ku}} # {{e|ku|mecazî}} [[kes|Kes]]ên yan [[heywan]]ên [[bêdestûpê]]. #: {{hevmane|ku|bêçare}} #* {{Jêgirtin/Mela Hisênê Bateyî/Mewlûda Kurdî|jg=Bêmîsal û bêheval û bêzewal<br>Raziqê '''bêdestûpa''' û mar û mûr<br>'Alimê sirra negotî der sudûr}} ==== Etîmolojî ==== {{ji?|ku}} ==== Werger ==== {{werger-ser}} {{werger-bin}} 78gr0x9lparjccgas8yrz38fvgtmfv9 bereyişk 0 450753 6265597 1279532 2026-07-19T15:46:47Z Wikihez 7344 ([[Mediawiki:Gadget-start.js|WF:NÛ]] v.2.0) +ku:navdêr: 6265597 wikitext text/x-wiki == {{ziman|ku}} == === Bilêvkirin === * {{ku-kîte}} === Navdêr === {{navdêr|ku|c=?}} # {{guharto|ku|bereyîşk}} #* {{bênimûne|ku}} f3yvys8go0wvf0r5etnzw3pd3rdbw9f Gotûbêja bikarhêner:Bikarhêner 3 457552 6265687 6250722 2026-07-19T22:02:34Z Bikarhêner 3719 /* zazakînas */ Bersiv 6265687 wikitext text/x-wiki Kîjan mijar birêz? == Girêdan == Silav Bikarhêner, gava ku peyvekê biafirînî/çêkî girêdanek înterwîkiyê bes e. Ji ber ku robotê min lê yên din lê zêde dike [https://ku.wiktionary.org/w/index.php?title=amony%C3%BBmklor%C3%AEd&diff=prev&oldid=1363621 li vir binêre] û [https://ku.wiktionary.org/w/index.php?title=Ma%C3%9Feinheit&curid=457206&diff=1363734&oldid=1348979 li vir] û [https://ku.wiktionary.org/w/index.php?title=Ma%C3%9Feinheit&diff=next&oldid=1363734 li vir]. Spas û silav û rêz --[[Bikarhêner:George Animal|George Animal]] ([[Gotûbêja bikarhêner:George Animal|gotûbêj]]) 18:30, 9 tîrmeh 2015 (UTC) == Share your experience and feedback as a Wikimedian in this global survey == <div class="mw-parser-output"> <div class="plainlinks mw-content-ltr" lang="en" dir="ltr"> Hello! The Wikimedia Foundation is asking for your feedback in a survey. We want to know how well we are supporting your work on and off wiki, and how we can change or improve things in the future. The opinions you share will directly affect the current and future work of the Wikimedia Foundation. You have been randomly selected to take this survey as we would like to hear from your Wikimedia community. The survey is available in various languages and will take between 20 and 40 minutes. <big>'''[https://wikimedia.qualtrics.com/jfe/form/SV_5ABs6WwrDHzAeLr?aud=AE&prj=ot&edc=3&prjedc=ot3 Take the survey now!]'''</big> You can find more information about this survey [[m:Special:MyLanguage/Community_Engagement_Insights/About_CE_Insights|on the project page]] and see how your feedback helps the Wikimedia Foundation support editors like you. This survey is hosted by a third-party service and governed by this [[:foundation:Community_Engagement_Insights_2018_Survey_Privacy_Statement|privacy statement]] (in English). Please visit our [[m:Special:MyLanguage/Community_Engagement_Insights/Frequently_asked_questions|frequently asked questions page]] to find more information about this survey. If you need additional help, or if you wish to opt-out of future communications about this survey, send an email through the EmailUser feature to [[:m:Special:EmailUser/WMF Surveys|WMF Surveys]] to remove you from the list. Thank you! </div> <span class="mw-content-ltr" dir="ltr">[[m:User:WMF Surveys|WMF Surveys]]</span>, 18:36, 29 adar 2018 (UTC) </div> <!-- Message sent by User:WMF Surveys@metawiki using the list at https://meta.wikimedia.org/w/index.php?title=Community_Engagement_Insights/MassMessages/Lists/2018/ot3&oldid=17881400 --> == Reminder: Share your feedback in this Wikimedia survey == <div class="mw-parser-output"> <div class="plainlinks mw-content-ltr" lang="en" dir="ltr"> Every response for this survey can help the Wikimedia Foundation improve your experience on the Wikimedia projects. So far, we have heard from just 29% of Wikimedia contributors. The survey is available in various languages and will take between 20 and 40 minutes to be completed. '''[https://wikimedia.qualtrics.com/jfe/form/SV_5ABs6WwrDHzAeLr?aud=AE&prj=ot&edc=3&prjedc=ot3 Take the survey now.]''' If you have already taken the survey, we are sorry you've received this reminder. We have design the survey to make it impossible to identify which users have taken the survey, so we have to send reminders to everyone. If you wish to opt-out of the next reminder or any other survey, send an email through EmailUser feature to [[:m:Special:EmailUser/WMF Surveys|WMF Surveys]]. You can also send any questions you have to this user email. [[m:Community_Engagement_Insights/About_CE_Insights|Learn more about this survey on the project page.]] This survey is hosted by a third-party service and governed by this Wikimedia Foundation [[:foundation:Community_Engagement_Insights_2018_Survey_Privacy_Statement|privacy statement]]. Thanks! </div> <span class="mw-content-ltr" dir="ltr">[[m:User:WMF Surveys|WMF Surveys]]</span>, 01:34, 13 avrêl 2018 (UTC) </div> <!-- Message sent by User:WMF Surveys@metawiki using the list at https://meta.wikimedia.org/w/index.php?title=Community_Engagement_Insights/MassMessages/Lists/2018/ot3&oldid=17881400 --> == Your feedback matters: Final reminder to take the global Wikimedia survey == <div class="mw-parser-output"> <div class="plainlinks mw-content-ltr" lang="en" dir="ltr"> Hello! This is a final reminder that the Wikimedia Foundation survey will close on '''23 April, 2018 (07:00 UTC)'''. The survey is available in various languages and will take between 20 and 40 minutes. '''[https://wikimedia.qualtrics.com/jfe/form/SV_5ABs6WwrDHzAeLr?aud=AE&prj=ot&edc=3&prjedc=ot3 Take the survey now.]''' '''If you already took the survey - thank you! We will not bother you again.''' We have designed the survey to make it impossible to identify which users have taken the survey, so we have to send reminders to everyone. To opt-out of future surveys, send an email through EmailUser feature to [[:m:Special:EmailUser/WMF Surveys|WMF Surveys]]. You can also send any questions you have to this user email. [[m:Community_Engagement_Insights/About_CE_Insights|Learn more about this survey on the project page.]] This survey is hosted by a third-party service and governed by this Wikimedia Foundation [[:foundation:Community_Engagement_Insights_2018_Survey_Privacy_Statement|privacy statement]]. </div> <span class="mw-content-ltr" dir="ltr">[[m:User:WMF Surveys|WMF Surveys]]</span>, 00:43, 20 avrêl 2018 (UTC) </div> <!-- Message sent by User:WMF Surveys@metawiki using the list at https://meta.wikimedia.org/w/index.php?title=Community_Engagement_Insights/MassMessages/Lists/2018/ot3&oldid=17881400 --> == {{şl|ji}} == Silav Bikarhêner {{=)}}, bi min [https://ku.wiktionary.org/w/index.php?title=rehetsiz&curid=651793&diff=2979854&oldid=2979824&diffmode=source vitira] baştir e. Witira peyv dikevî di nav kategoriya: [[:Kategorî:Peyvên kurdî ji tirkî]]--[[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 18:04, 31 gulan 2018 (UTC) : Merheba, {{ragihandin|Ghybu}}. Min vê şablonê nizanibû. Baş e ku te got. == Common Locale Data Repository (CLDR) == Silav Bikarhêner, Tu dikarî li [http://st.unicode.org/cldr-apps/v#/ku/Food_Drink/369d9a46f208576a vira] peyvên ku tu dizanî kurdî bikî (kurdiya te li yê min baştir e). Ser înternetê tiştekî pirr girîng e ji ber ku hemû agahiyan ser zimanê kurdî li wira tê dayîn (navên mehan, heftan, salname, [http://st.unicode.org/cldr-apps/v#/ku/Fields/ sîstema saetê], [http://st.unicode.org/cldr-apps/v#/ku/Languages_A_D/ ziman], [http://st.unicode.org/cldr-apps/v#/ku/T_Africa/ welat], kurtenav, [http://st.unicode.org/cldr-apps/v#/ku/Alphabetic_Information/ alfabe], [http://st.unicode.org/cldr-apps/v#/ku/Symbols/ hejmar], [http://st.unicode.org/cldr-apps/v#/ku/ElectricalFrequency/ yeke] ...) û bi pirr malperan tê bikaranîn! Pêwîst e ku em hemûyan kurdî bikinê... Pênc sal bû ku min bo zimanê kurdî vekir mixabin tenê ez xwedî dikim: [https://ku.wikipedia.org/wiki/W%C3%AEk%C3%AEpediya:D%C3%AEwan_(p%C3%AA%C5%9Fniyar)#Common_Locale_Data_Repository_(CLDR)] / [http://unicode.org/cldr/trac/ticket/6527] / [http://unicode.org/cldr/trac/ticket/9964] / [http://unicode.org/cldr/trac/ticket/9748]. ping: {{ragihandin|Şêr}}--[[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 22:08, 2 pûşper 2018 (UTC) :Merheba {{ragihandin|Ghybu}} Min li wê sîteyê nêrt lê famkirina sîstema wê sîteyê hinek zehmet tê xuyan. Heke tu ji min re hinek bibî alîkar, ez ê jî ji destê min çi were bikim. Ji min re e-maîla xwe dikarî bişînî?{{bêîmze|Bikarhêner}} ::Pêşta vê '''[https://translatewiki.net/wiki/CLDR#Contribute_to_an_existing_locale nîvîsa]''' bixwîne (Çêkirina hesabê: <small>[..] ''To get an account on the CLDR survey tool, '''just [[Special:EmailUser/Nemo_bis|ask Nemo for an account]]'''. He is Wikimedia's survey tool manager. Then use your account to translate and correct translations of language names and other things, when the survey tool is open.''</small>).<br/>Min e-peyamê xwe winda kir, yê nû jî li vira ye: [[Special:EmailUser/Ghybu]]. Spas--[[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 01:33, 4 pûşper 2018 (UTC) :::Dîsa silav, çênebû?--[[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 00:33, 10 pûşper 2018 (UTC) :::: Merheba {{ragihandin|Ghybu}}. Min ji Nemo bis re peyam şand lê bersiv nehat. Ez vêga dîsa peyamek şandim. Berî nêzî mehek min ji te re jî peyamek şandibû, te jî cewab nedabû. Gelo peyamên min bi rê nakevin, nagihîjin? Belkî tê de problemek hebe.{{bêîmze|Bikarhêner}} :::::Ok! Li vira jî bixwaze: [http://www.unicode.org/reporting.html]. (Min li jor jî got, min e-peyamê xwe winda kiribû û min yekî din çêkir: tu dikarî peyamê xwe dîsa li mi ra bîşînî. Spas)--[[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 18:38, 10 pûşper 2018 (UTC) :::::::Merheba {{ragihandin|Ghybu}}. Hesabê min çêbû. Û van rojan hinek ezmûnên min hene. Ez piştî heftîkî dest pê bikim û hêdî hêdî tercume bikim înşallah. Lê min sîstema vê sîteyê hê jî fam nekir. Mirov nikare vê malperê ji ser translatewiki.net wergerîne? Ez hîn bûme sîstema translatewiki.net. Û di translatewiki.netê de wergerên bi zimanên din jî ji min re dibû alîkar. Gelo di vê malperê de jî mirov dikare wergerên bi zimanên din bibîne? Tu dikarî der heqê sîstema vê malperê de hinek agahiyan bidî min? -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner#top|gotûbêj]]) 16:20, 13 pûşper 2018 (UTC) ::::::::Merheba :) Paşê ku te xwe ser CLDR tomar kir li '''[https://upload.wikimedia.org/wikipedia/ku/archive/2/2a/20180814215641%21Ghybu_test.png vira]''' binêre. Bo wergerên zimanên din şûnda "Kurdish" navê zimanê ku tu dixwazî binivîse. '''Alîkarî bi zimanê îngilîzî:''' '''[http://cldr.unicode.org/index/survey-tool/guide]''' / [https://sites.google.com/site/cldr/translation]. Lîsteya zimanan: [http://www.unicode.org/cldr/charts/latest/supplemental/locale_coverage.html#ku]--[[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 22:50, 13 pûşper 2018 (UTC) * Silav Bikarhêner :) Ew [https://twitter.com/SetsunaSeieiKrd/status/1064202772097179648 wergeran] tu dizanî li kujan derê tên girtin? Ser CLDRê hatine girtin (li [http://st.unicode.org/cldr-apps/v#/ku/Gregorian/ vira]) ji ber ku li ser CLDRê zimanê kurmancî jî niha bi koda "ku" hat vekirin {{=)}} Min li jor jî gotibû; pirr ''software'' (nermalav) an malper ew wergeran dixebitînin, tenê Google nîne.<br/>Alfabeya kurdî jî niha li ser CLDRê ye {{=)}} bnr: [http://www.unicode.org/repos/cldr/trunk/common/collation/] (ku.xml) --> [https://www.unicode.org/repos/cldr/trunk/common/collation/ku.xml]. Niha pirr ''software'' an malperan de zimanê kurmancî jî derdikevî--[[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 23:54, 18 sermawez 2018 (UTC) --[[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 23:54, 18 sermawez 2018 (UTC) ::Merheba {{ragihandin|Ghybu}}, ez nizanim ew werger ji ku hatine girtin. Te li jor di peyamên xwe yên kevin de jî gotibû CLDR malpereke girîng e, lê min baş nizanibû. Eger ew werger ji malpera CLDRê hatibin girtin, divê em giringiyeke zêde bidinê malpera CLDRê. Lê tu pê bawer î yanî emîn î ku ew werger ji malpera CLDRê hatine girtin?. ::Eger wisa be pêşî ez li bin wê twîta ku min avêtiye vê agahiyê jî binivîsim, û eger bixwazî ser malpera teknistan.comê jî em dikarin li ser malpera CLDRê nivîsek kurt amade bikin, gelo ev fikr ji bo te çawa tê xuyan? :: û eger bixwazî ji Twîtterê were DMyê. --[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner#top|gotûbêj]]) 10:02, 19 sermawez 2018 (UTC) ::: '''Twitter''' û Wîndows jî CLDRê dixebitînin {{=)}}. Li vira binêre: ''[http://cldr.unicode.org/ Who uses CLDR?]/ [https://docs.google.com/presentation/d/1LDXP-LYQpaVJRWWX6EejgkRGFUaFwo83t8Ly-IPll8Y/edit#slide=id.p Presentation]'' (Kî CLDRê dixebitîne): {{(|Lîste|stûn=1}} Some of the companies and organizations that use CLDR are: * Apple (macOS, iOS, watchOS, tvOS, and several applications; Apple Mobile Device Support and iTunes for Windows; …) * '''Google''' ('''Web Search''', Chrome, Android, Adwords, Google+, Google Maps', Blogger, Google Analytics, …) * IBM (DB2, Lotus, Websphere, Tivoli, Rational, AIX, i/OS, z/OS,…) * Microsoft (Windows, Office, Visual Studio, …) ;and many others, including: ABAS Software, Adobe, Amazon (Kindle), Amdocs, Apache, Appian, Argonne National Laboratory, Avaya, Babel (Pocoo library), BAE Systems Geospatial eXploitation Products, BEA, BluePhoenix Solutions, BMC Software, Boost, BroadJump, Business Objects, caris, CERN, Debian Linux, Dell, Eclipse, eBay, EMC Corporation, ESRI, Firebird RDBMS, FreeBSD, Gentoo Linux, GroundWork Open Source, GTK+, Harman/Becker Automotive Systems GmbH, HP, Hyperion, Inktomi, Innodata Isogen, Informatica, Intel, Interlogics, IONA, IXOS, Jikes, jQuery, Library of Congress, Mathworks, Mozilla, Netezza, OpenOffice, Oracle (Solaris, Java), Lawson Software, Leica Geosystems GIS & Mapping LLC, Mandrake Linux, OCLC, Perl, Progress Software, Python, QNX, Rogue Wave, SAP, Shutterstock, SIL, SPSS, Software AG, SuSE, Symantec, Teradata (NCR), ToolAware, Trend Micro, '''Twitter''', Virage, webMethods, Wikimedia Foundation (Wikipedia), Wine, WMS Gaming, XyEnterprise, Yahoo!, Yelp {{)}} ::Binêre jî: ::* [https://developers.google.com/international/ Internationalization (i18n) open source libraries and APIs] ([[w:en:Internationalization and localization]]) ::* [[w:en:Common Locale Data Repository]] (<small>''CLDR is maintained by the CLDR technical committee, which includes employees from IBM, Apple, Google, Microsoft, and some government-based organizations. The committee is currently chaired by John Emmons (IBM), with [[:w:en:Mark Davis (Unicode)|Mark Davis]] (Google) as vice-chair.''</small>) ::*[[w:ku:Wîkîpediya:Dîwan (pêşniyar)#Common Locale Data Repository (CLDR)]] ::--[[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 19:58, 19 sermawez 2018 (UTC) :: Spas {{ragihandin|Ghybu}}. Te gelek agahiyan daye. Ji bo ku vê gotarê ez bixwe çêkim newisa :) û tu nehatî DMyê. --[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner#top|gotûbêj]]) 20:42, 19 sermawez 2018 (UTC) :::[[Wêne:Sifflote.png|35px]]--[[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 21:49, 19 sermawez 2018 (UTC) ::{{ragihandin|Ghybu}} Herwiha diyar e ku hin qismên Google Chrome-ê ji ser malpera CLDRê tê wergerandin. Lê em bêjin li cihekî min "Google Wêneger" dîtibû, li gor vê agahiyê CLDR hemû qismên Google Chrome-ê na, tenê hin qismên teknîkî ên Chromeyê werdigerîne. --[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner#top|gotûbêj]]) 20:45, 19 sermawez 2018 (UTC) :::Erê, li ser OSM, Wîkîferheng û Wîkîpediya jî witira ye niha dema ku tu terê ser interwikiyan ziman bi kurdî derdikevin peşta witira nebû. Niha alfabeya kurdî jî hat tevlîkirin (5 sal bû ku min li vira xwestî bû: [http://unicode.org/cldr/trac/ticket/6527 CLDR Ticket #6527]/bnr. jî [http://unicode.org/cldr/trac/ticket/9964] / [http://unicode.org/cldr/trac/ticket/9748]), ew jî baş e ji ber ku lîsteya peyvan di nav maplperan de jî li gorî alfabeya kurdî tên rêz kirin. Bo mînak binêre [[:w:ku:Kategorî:Dewletên Asyayê]] tîpên "ç", "î", "û" bin rûpelê hatine nivsandin (ne li gorî alfabeya kurdî). Di dema nêzkî de ew jî rast diwe...--[[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 22:17, 19 sermawez 2018 (UTC) {{outdent|:::}}Mînakek din, li jêr dema ku tu ser "'''Alfabeya kurdî''" ditikînî peyv ne logorî alfabeya kurdî tên rêz kirin (tîpên dîakrîtîk (ç, î, û, ê) li bin tên rêz kirin). CLDR ew pirsgirêka jî radike ji ber ku niha malper alfabeya kurdî jî nasdikin: dema ku di nav koda HTMLê koda <code>lang="ku"</code> li zêde dikî, ew dizanî ku alfabeya kurdiya latînî li gorî bi vê formê tê rêzekirin: [https://www.unicode.org/repos/cldr/trunk/common/collation/ku.xml] (<small><code> Kurmanji letters.&c<ç<<<Ç&e<ê<<<Ê&i<î<<<Î&s<ş<<<Ş&u<û<<<Û</code></small>) {| class="wikitable sortable" |- ! Alfabeya kurdî !! Test |- | style="background-color: #F0FFF0;" | '''Ç'''av || 3 |- | Anîn || 1 |- | Kirin || 9 |- | Iraq || 7 |- | Cot || 2 |- | Xwarin || 10 |- | style="background-color: #F0FFF0;" | '''Î'''b || 8 |- | Fire || 6 |- | Evîn || 4 |- | style="background-color: #F0FFF0;" | '''Ê'''var || 5 |} Ji bo rêzkirina rast li ser "'''Test'''" bitikîne--[[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 22:48, 19 sermawez 2018 (UTC) ---- Bo agadarî: [http://www.unicode.org/cldr/charts/28/keyboards/layouts/ckb.html soranî]/[http://www.unicode.org/cldr/charts/28/keyboards/layouts/tr.html tirkî] -- [http://cldr.unicode.org/index/charts/keyboards]-[http://cldr.unicode.org/development/testing-keyboards] Bo alfabeya kurdî ya latînî hîn ne hatiye xwestin.--[[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 00:47, 29 sermawez 2018 (UTC) ---- Silav! min peyama te girt.--[[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 01:57, 9 berfanbar 2018 (UTC) ---- * Silav. Bo agadarî, CLDR hat vekirin...--[[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 01:24, 1 pûşper 2019 (UTC) : Silav {{ragihandin|Ghybu}} Dixwazim têkevim malperê lê vê gavê problemeke têketinê derketiye holê di hesabê min de. Li benda vê me. Ka binêre vir: https://unicode-org.atlassian.net/browse/CLDR-13081 -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner#top|gotûbêj]]) 20:24, 1 pûşper 2019 (UTC) :: Çima te li [https://translatewiki.net/w/i.php?title=Special:EmailUser/Nemo_bis&wpTarget=Nemo_bis vira] nexwast? Ji [https://translatewiki.net/wiki/User:Nemo_bis Nemo_bis]--[[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 21:13, 1 pûşper 2019 (UTC) == Kategorî == Silav, bo agadarî {{şl|TDK}} ([https://ku.wiktionary.org/w/index.php?title=Allahualem&curid=651865&diff=2980423&oldid=2980409&diffmode=source]) û [https://ku.wiktionary.org/w/index.php?title=Girav%C3%AAn_Kayman%C3%AA&curid=651869&diff=2980419&oldid=2980415&diffmode=source]--[[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 23:55, 4 pûşper 2018 (UTC) :Bo kategoriyan: [https://ku.wiktionary.org/w/index.php?title=sec%C3%A2vend&diff=2981655&oldid=2981654&diffmode=source] ([[:Kategorî:Peyvên tirkî ji erebî]])--[[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 14:36, 9 pûşper 2018 (UTC) * Bo agadarî: {{şl|IPA}} û {{şl|ku-IPA}}--[[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 20:21, 14 pûşper 2018 (UTC) *:Modula {{şl|ku-IPA}} jî li vira ye: [[Modul:ku-xwendin]] ([https://ku.wiktionary.org/w/index.php?title=%C5%9Fanoniv%C3%AEs&curid=384297&diff=2982718&oldid=2297931&diffmode=source mînak])--[[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 20:24, 14 pûşper 2018 (UTC) ::{{ragihandin|Ghybu}}, peyamê me ya li ser sîstema nivîsa gotaran negihîşt kesên din. Tu dikarî wê peyamê ragihînî kesên din? --[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner#top|gotûbêj]]) 21:08, 14 pûşper 2018 (UTC) :::[https://ku.wiktionary.org/w/index.php?title=W%C3%AEk%C3%AEferheng:D%C3%AEwan&type=revision&diff=2982731&oldid=2982444&diffmode=source] (îmze xwe ji bîr meke:) )--[[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 00:47, 15 pûşper 2018 (UTC) == Sîstema nivîsa gotaran == → ''Bnr. [[Wîkîferheng:Dîwan#Sîstema nivîsa gotaran]]'' :Merheba {{ragihandin|Ghybu}} Li ser vê mijarê ji xeynî min û te, tenê sê kes fikrên xwe gotine. Eger pirraniya xebatkarê wîkîferhengê fikrê xwe diyar bikirana wê çêtir bûya. Ji ber ku eger em vê sîstemê biguherînin divê em hemû maddeyên heyî û yên ku em nû çêbikin jî li gorî vê sîstemê binivîsînin. Yanî nizanim em çawa qerar bidin?{{bêîmze|Bikarhêner}} ::Bi min fikrên {{b|Ferhengvan}} û {{b|Cyrus the virus}} pêwîstên, ji ber ku pirraniya gotran wan çêkirine û kurmanciya wan jî pirr rind e. Bê bersiv vitira dimînî...--[[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 22:47, 3 tîrmeh 2018 (UTC) ::PS: Nizanim te dî an na, berê wîkiya tirkî jî vitira bû, wana jî vê salê hemû şeklên gotaran wekî wikiya îngilîzî guherand: [https://tr.wiktionary.org/wiki/Vikis%C3%B6zl%C3%BCk:K%C3%B6y_%C3%A7e%C5%9Fmesi/2017#Baz%C4%B1_d%C3%BCzenleme_%C3%B6nerileri]--[[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 23:00, 3 tîrmeh 2018 (UTC) == [[Şablon:g]] == Silav, [https://ku.wiktionary.org/w/index.php?title=s%C4%B1ygaya_%C3%A7ekmek&diff=2993421&oldid=2993418&diffmode=source]--[[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 12:29, 18 tîrmeh 2018 (UTC) == Peyva hefteyê == Merheba! Nizanim tu dizanî an na? Peyva hefteyê li vira tê guherandin: [[Wîkîferheng:Peyva hefteyê/30]].--[[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 02:33, 20 tîrmeh 2018 (UTC) :{{merheba|Ghybu}} min digot çiqa hûn bi otomatîkî eyar dikin. Û ji ber ku hûn eyar dikin min nedixwest ku ez zêde midaxele bikim. == Statîstîk == Silav, amûreke baş ji bo Wîkîferhengê: [https://wdcm.wmflabs.org/Wiktionary_CognateDashboard/]--[[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 01:55, 28 tîrmeh 2018 (UTC) :{{merheba|Ghybu}}, ev malper bi kêrî çi tê. Li gorî ku min jê fam kir tê de rûpelên ku di zêdetir zimanan de hene têne nîşandan. Em çawan dikarin van agahiyan bi kar bînin? --[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner#top|gotûbêj]]) 00:07, 29 tîrmeh 2018 (UTC) == [[:Kategorî:Şablon (nîşan)]] == Silav, Kategorî û nivîs bi otomatîk derdikevin, bnr. [https://ku.wiktionary.org/w/index.php?title=adblocker&type=revision&diff=3005482&oldid=3005455&diffmode=source]--[[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 09:31, 17 gelawêj 2018 (UTC) == derbara بادکنک e == silav rez .te nayasty.az xalq e iraneme va farisi zanem.te rast dibiji ,me alefba arabie dabo xavate.me eștebah kiri.bebaxş.ama me xo paşe disa Çêkir.niha do بادکنک haye.yak farisi yak arabi.te niha بادکنکya alefba arabi paqij bik.bra ya farisi bemine.per bebaxşin.[[Bikarhêner:Esn.sh.gh|Esn.sh.gh]] ([[Gotûbêja bikarhêner:Esn.sh.gh|gotûbêj]]) 11:34, 19 gelawêj 2018 (UTC) == uzr xastin == silav rez.te rast dibiji.me ej alefba ya arabi bona nivisandena payven farsi estefada kerebo.paşe me xo zani ke me eştebah keri.az feker dikim 5 payven farsi me bi alefba arabi nivisi.da xenje van tenaye.disa ji az ej te va bikarhener dine uzr dixasim.per bebaxşin.ej agahi ya te ji per spas.da ava kar ra tekrar nabe.dastxuşdikim.spas.bi xir bi.[[Bikarhêner:Esn.sh.gh|Esn.sh.gh]] ([[Gotûbêja bikarhêner:Esn.sh.gh|gotûbêj]]) 08:14, 20 gelawêj 2018 (UTC) {{merheba|Esn.sh.gh}}, uzr ne hewce ye, ez tenê dixwazim sererast bikim. Ji wan peyvên ku bi elfabeya erebî hatine nivîsandin em dikarin vê şablonê deynin: (di nav du parantezê {{}} de em "jêbirin" binivîsin). : Ez tam nizanim ku kîjan peyv hewce ne ku bêne jêbirin? Tu dikarî vê şablona li jor îlaweyî wan peyvên pêwîst in bêne jêbirin bikî? :: Binêre vir: https://ku.wiktionary.org/w/index.php?title=%D8%A8%D8%A7%D8%AF%D9%83%D9%86%D9%83&diff=3006220&oldid=3006191&diffmode=source :: Ji bo peyvên ku bêne jêbirin em wisa dikin: https://ku.wiktionary.org/wiki/%D8%A8%D8%A7%D8%AF%D9%83%D9%86%D9%83 --[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner#top|gotûbêj]]) 10:39, 20 gelawêj 2018 (UTC) == derbara payva عروسی == silav rez.wikiferheng kurdi da do payve عروسی haye,yak bi alefbay arabi va yak ji bi alefbaye farisi.az ej va dixwazem peyva arabi عروسیی paqij biki.bra tene ya farisi bemine.عروسیpeyvaki farisi ye va tene galah bi alefba farisi var nivisandene. : {{ragihandin|Esn.sh.gh}}, silav, ez elfabeya erebî û farisî nikarim ji hev cuda bikim, ji min re eynî xuya dikin. Ji van her du peyvan kîjane em jê bibin, û bra kîjan bimîne, ya 1em an ya 2yem? ''(bi texmîna min em ê ya 2yem jê bibin)'' : ''Ya 1em:'' [[عروسی]], : ''Ya 2yem:'' [[عروسي]] : --[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner#top|gotûbêj]]) 09:05, 26 gelawêj 2018 (UTC) silav rez.ya2ym pakij biki.2yem arabi e.[[Bikarhêner:Esn.sh.gh|Esn.sh.gh]] ([[Gotûbêja bikarhêner:Esn.sh.gh|gotûbêj]]) 05:15, 29 gelawêj 2018 (UTC) == Twitter == Silav Bikarhêner, li ser internetê rûpeleke ser Twittera kurdî hebû (bo dengadayînê) ew li ku derê ye? Hat jêbirin? Spas--[[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 19:53, 9 berfanbar 2018 (UTC) : Merheba {{ragihandin|Ghybu}}. Wek change.org bû qey? Min kampanyayek îmzeyê a derbarê kurdîkirina twîtterê de nedîtibû. Der barê twittera kurdî de li vir nivîsek heye, ka binêre vir: http://tirsik.net/index.php?mijarid=25810&hemu=on : û yek ji wergêrê twittera kurdî Amed Çeko Jiyan bû eger bixwazî ji vir dikarî ser Facebookê pê re bikevî îrtîbatê (dibe ku ew karibe ji te re bibe alîkar di vê mijarê de): https://www.facebook.com/amedcj--{{bêîmze|Bikarhêner}} ::Li '''[https://meta.wikimedia.org/wiki/User_talk:Amire80#Google_and_Twitter vira]''', bikarhêner Amire80 çend endamenên Twitter û Googlê nas dike û li min ra got ku: "eger hûn dixwazin listeyekî wergeran/notên xwe li min ra bişînin ez jî wana dişinim kesên ji Google û Twitterê: belkî çêdikin (bawer nîne)".--[[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 23:30, 9 berfanbar 2018 (UTC) ::: {{ragihandin|Ghybu}} Ji ber ku ez dereng bersiva te dam min bibexşîne kekê Ghybu. Di demeke nêz de ez nivîsek bi zimanê îngilîzî ya li ser çewtiyên di '''Google Searchê''' de ya ji bo zimanê kurdî - kurmancî amade bikim û ya li ser ''teknistan.comê'' an jî li ser bloga xwe ya bi navê ''malcolmakurdan.wordpress.com'' biweşînim. Dîsa spas ji bo alîkariya te. Hêvî dikim ku em bi ser kevin. ::: Herwiha hevala/ê Amire me hinekî xelet fam kiriye. Wekî ku tu dizanî di twitterê de zimanê kurdî qet tine. Lewma em nikarin derbarê çewtiyên ya kurdî de nivîsek amade bikin. Ji bo wergera '''twitter'''ê ya kurdî jî divê em pêşî îfadeyên tê de bibînin ku em karibin wergerînin. Ji bo niha em pêşî nivîsa li ser çewtiyên Google Serach ya kurdî de hazir bikin dû re em vê meseleyê dîsa xeber bidin. Spas. --[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner#top|gotûbêj]]) 14:00, 16 berfanbar 2018 (UTC) == Rêveber == * Serkevtin! {{=)}}--[[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 22:27, 28 reşemî 2019 (UTC)-- ::pîroze!--[[Bikarhêner:Calak|Çalak]]<sup>[[Bikarhêner nîqaş:Calak|Готубеж]] </sup> 22:29, 28 reşemî 2019 (UTC) ::: Spas dikim, mala we ava 🤗 {{ping|Ghybu|Calak}}{{bêîmze|Bikarhêner}} *[https://twitter.com/wikiferheng Te çêkir]? Gelek spas {{=)}}--[[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 14:11, 3 adar 2019 (UTC) * Bo agadarî: [https://ku.wiktionary.org/w/index.php?title=W%C3%AEk%C3%AEferheng:Portala_kom%C3%AA&oldid=3045346#R%C3%BB rûyê Wîkîferhengê bi van rûpelan tê guhartin]. Va jî heye: [[Taybet:SpecialPages]]--[[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 14:22, 3 adar 2019 (UTC) == Wêne == Silav, min wêneyê [https://twitter.com/wikiferheng/status/1133537070687891462 vira] bi kurdî kir: [https://ku.wikipedia.org/wiki/W%C3%AAne:Ghybu_test.jpg]--[[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 19:43, 12 pûşper 2019 (UTC) == Cureyê peyvê == Silav Bikarhêner, gava tu cureyên peyvan lê zêde bikî [https://ku.wiktionary.org/w/index.php?title=instructor&curid=312107&diff=3203103&oldid=3203102 bnr], dê baştir bibe. Spas û silav --[[Bikarhêner:Şêr|Şêr]] ([[Gotûbêja bikarhêner:Şêr|gotûbêj]]) 09:21, 27 tîrmeh 2019 (UTC) == Peyvên hefteyê yên biyanî == :Silav, gelo tu dê [https://ku.wiktionary.org/wiki/Wîkîferheng:Peyva_hefteyê_(biyanî)/9 vê projeyê] bidomînî? (...) ji ber ku peyvên nû nehatine amadekirin... --[[Bikarhêner:Şêr|Şêr]] ([[Gotûbêja bikarhêner:Şêr|gotûbêj]]) 15:17, 29 tîrmeh 2019 (UTC) :Û [https://ku.wiktionary.org/wiki/Destpêk li vir] binêre. Spas --[[Bikarhêner:Şêr|Şêr]] ([[Gotûbêja bikarhêner:Şêr|gotûbêj]]) 15:18, 29 tîrmeh 2019 (UTC) : {{r|Şêr}} Merheba. Belê dixwazim bidomînim vê projeyê. Tenê wextê min zahf çênebû. Lê ez ê van rojan temam bikim. -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner#top|gotûbêj]]) 08:16, 30 tîrmeh 2019 (UTC) : Gelek spas biracan --[[Bikarhêner:Şêr|Şêr]] ([[Gotûbêja bikarhêner:Şêr|gotûbêj]]) 22:30, 4 gelawêj 2019 (UTC) == 700.000 == Silav hevalê min, tu dikarî li ser Twîtterê parve bikî :) --[[Bikarhêner:Şêr|Şêr]] ([[Gotûbêja bikarhêner:Şêr|gotûbêj]]) 22:27, 4 gelawêj 2019 (UTC) :Em niha di rêza 9em de ne [https://meta.wikimedia.org/wiki/Wiktionary bnr]. Berî rojekê em di rêza 11em de bûn :) --[[Bikarhêner:Şêr|Şêr]] ([[Gotûbêja bikarhêner:Şêr|gotûbêj]]) 08:42, 10 tebax 2019 (UTC) :Min niha dîtiye li ser Twîtterê --[[Bikarhêner:Şêr|Şêr]] ([[Gotûbêja bikarhêner:Şêr|gotûbêj]]) :: Merheba {{r|Şêr|Ghybu}}. Ser xêrê be. Ez jixwe li vir (ser hesaba Twîtterê) parve kirime: https://twitter.com/wikiferheng/status/1159978943291777024 :: Ev bikarhêner (@kurdishwikt) tu yî newisa? Ez te jî nîşan kirim li vir: https://twitter.com/wikiferheng/status/1159985740878680064 ::: Serkeftin ji me hemûyan re. -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner#top|gotûbêj]]) 08:53, 10 tebax 2019 (UTC) ::: Silav birako, erê lê ew hesab êdî ne aktîv e. ~ 400 hezar formên din ên navdêran dê hê bên çêkirin. Lê mixabin Kategorî:Navdêr hinekî tevlihev e ji bo bikaranîna ji bo danegeha programa min, ji ber hemû varyante xistine wê kategoriyê (werger, wergerr, werrgerr ...) :( --[[Bikarhêner:Şêr|Şêr]] ([[Gotûbêja bikarhêner:Şêr|gotûbêj]]) 08:56, 10 tebax 2019 (UTC) ::: An jî werger nexitina kategoriya navdêrê, lê wergerr xistinê/tevlî kirine wê derê --[[Bikarhêner:Şêr|Şêr]] ([[Gotûbêja bikarhêner:Şêr|gotûbêj]]) 08:58, 10 tebax 2019 (UTC) ::: Ev hefteya bê em ê bigihîjin 800.000 peyvan li gorî plana min. :) --[[Bikarhêner:Şêr|Şêr]] ([[Gotûbêja bikarhêner:Şêr|gotûbêj]]) 08:59, 10 tebax 2019 (UTC) : Pir baş e, gelek spas ji bo keda te (û ya hevalê Ghybu) ya mezin. Ger hesabek te yê aktîv hebe, ez wê jî etîket bikim. :: Di meseleya wê tevliheviyê de jî ger alîkariya min hewce be, ez jî amade me, lê ji tiştên teknîkî (ên wek botên we) zêde fam nakim. --[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner#top|gotûbêj]]) 09:03, 10 tebax 2019 (UTC) :: Mixabin hin xeletî ji aliyê hin botan ve hatine kirin. Başî û xirabiyên botan jî hene -- :) Ez tenê formên lêkeran, navdêran û hwd. didim lêzêdekirin. Û botê bi piranî ji bo sererastkirina peyvan didim bikaranîn. Tu jî dikarî xwe hînî bikaranîna wan bikî :D --[[Bikarhêner:Şêr|Şêr]] ([[Gotûbêja bikarhêner:Şêr|gotûbêj]]) 09:07, 10 tebax 2019 (UTC) ::[[:Kategorî:Formên navdêran (Kurdî)]] --[[Bikarhêner:Şêr|Şêr]] ([[Gotûbêja bikarhêner:Şêr|gotûbêj]]) 09:08, 10 tebax 2019 (UTC) ::Silav, bi van nûçeyên xweş ve, bi parvekirinên li ser twitterê belkî zêdetir kes werin li vir ji xwe re hesab vekin. Destê we hemûyan sax be. :) --[[Bikarhêner:Bibliophile|Bibliophile]] ([[Gotûbêja bikarhêner:Bibliophile|gotûbêj]]) 09:12, 10 tebax 2019 (UTC) ::Rast e, gelek spas biracan. ::@Bikarhêner: Tu ne hevalê ergatîvîteyê yî, wek ez dibînim :) -- [[Bikarhêner:Şêr|Şêr]] ([[Gotûbêja bikarhêner:Şêr|gotûbêj]]) 09:22, 10 tebax 2019 (UTC) == Format == Silav Bikarhêner, te li vira ({{g|en|pick}}) şablona <code><nowiki>{{l|en}}</nowiki></code> (bin zimanê) di nav gotarê de ranekirye.--[[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 16:46, 10 tebax 2019 (UTC) :Bo formatê binêre: [https://ku.wiktionary.org/w/index.php?title=Bikarh%C3%AAner:Ghybu/test2&oldid=3070143]--[[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 16:48, 10 tebax 2019 (UTC) ::Binêre: [https://ku.wiktionary.org/w/index.php?title=friendly&type=revision&diff=3374819&oldid=3374811&diffmode=source] ("Bilêvkirin" li jor gotarê tê nivîsandin; beşên din 4 caran =)--[[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 17:16, 10 tebax 2019 (UTC) * Dîsa silav :) [https://ku.wiktionary.org/w/index.php?title=browser&diff=3374912&oldid=3374911&diffmode=source] Beşên "Bilêvkirin" û kategoriya rêzimanê (''lêker''/''navdêr''/''rengdêr''/...) 3 çaran "=". Yên din 4 çaran "="--[[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 19:44, 10 tebax 2019 (UTC) == Bilêvkirina peyvên îngilîzî == Silav birêz, bnr [https://ku.wiktionary.org/w/index.php?title=liveliest&curid=754175&diff=3474880&oldid=3472875&diffmode=source]. Ev şablon ne ji bo îngilîzî ye. :) --[[Bikarhêner:Şêr|Şêr]] ([[Gotûbêja bikarhêner:Şêr|gotûbêj]]) 17:13, 12 tebax 2019 (UTC) : Silav rewşa dawî ya peyva te ya lêzêdekirî: [https://ku.wiktionary.org/w/index.php?title=firm_up&action=edit 1]. -- [[Bikarhêner:Şêr|Şêr]] ([[Gotûbêja bikarhêner:Şêr|gotûbêj]]) 20:23, 13 tebax 2019 (UTC) == Community Insights Survey == <div class="plainlinks mw-content-ltr" lang="en" dir="ltr"> '''Share your experience in this survey''' Hi {{PAGENAME}}, The Wikimedia Foundation is asking for your feedback in a survey about your experience with {{SITENAME}} and Wikimedia. The purpose of this survey is to learn how well the Foundation is supporting your work on wiki and how we can change or improve things in the future. The opinions you share will directly affect the current and future work of the Wikimedia Foundation. Please take 15 to 25 minutes to '''[https://wikimedia.qualtrics.com/jfe/form/SV_0pSrrkJAKVRXPpj?Target=CI2019List(other,act5) give your feedback through this survey]'''. It is available in various languages. This survey is hosted by a third-party and [https://foundation.wikimedia.org/wiki/Community_Insights_2019_Survey_Privacy_Statement governed by this privacy statement] (in English). Find [[m:Community Insights/Frequent questions|more information about this project]]. [mailto:surveys@wikimedia.org Email us] if you have any questions, or if you don't want to receive future messages about taking this survey. Sincerely, </div> [[User:RMaung (WMF)|RMaung (WMF)]] 14:34, 9 îlon 2019 (UTC) <!-- Message sent by User:RMaung (WMF)@metawiki using the list at https://meta.wikimedia.org/w/index.php?title=CI2019List(other,act5)&oldid=19352874 --> == Reminder: Community Insights Survey == <div class="plainlinks mw-content-ltr" lang="en" dir="ltr"> '''Share your experience in this survey''' Hi {{PAGENAME}}, A couple of weeks ago, we invited you to take the Community Insights Survey. It is the Wikimedia Foundation’s annual survey of our global communities. We want to learn how well we support your work on wiki. We are 10% towards our goal for participation. If you have not already taken the survey, you can help us reach our goal! '''Your voice matters to us.''' Please take 15 to 25 minutes to '''[https://wikimedia.qualtrics.com/jfe/form/SV_0pSrrkJAKVRXPpj?Target=CI2019List(other,act5) give your feedback through this survey]'''. It is available in various languages. This survey is hosted by a third-party and [https://foundation.wikimedia.org/wiki/Community_Insights_2019_Survey_Privacy_Statement governed by this privacy statement] (in English). Find [[m:Community Insights/Frequent questions|more information about this project]]. [mailto:surveys@wikimedia.org Email us] if you have any questions, or if you don't want to receive future messages about taking this survey. Sincerely, </div> [[User:RMaung (WMF)|RMaung (WMF)]] 19:14, 20 îlon 2019 (UTC) <!-- Message sent by User:RMaung (WMF)@metawiki using the list at https://meta.wikimedia.org/w/index.php?title=CI2019List(other,act5)&oldid=19395141 --> == Reminder: Community Insights Survey == <div class="plainlinks mw-content-ltr" lang="en" dir="ltr"> '''Share your experience in this survey''' Hi {{PAGENAME}}, There are only a few weeks left to take the Community Insights Survey! We are 30% towards our goal for participation. If you have not already taken the survey, you can help us reach our goal! With this poll, the Wikimedia Foundation gathers feedback on how well we support your work on wiki. It only takes 15-25 minutes to complete, and it has a direct impact on the support we provide. Please take 15 to 25 minutes to '''[https://wikimedia.qualtrics.com/jfe/form/SV_0pSrrkJAKVRXPpj?Target=CI2019List(other,act5) give your feedback through this survey]'''. It is available in various languages. This survey is hosted by a third-party and [https://foundation.wikimedia.org/wiki/Community_Insights_2019_Survey_Privacy_Statement governed by this privacy statement] (in English). Find [[m:Community Insights/Frequent questions|more information about this project]]. [mailto:surveys@wikimedia.org Email us] if you have any questions, or if you don't want to receive future messages about taking this survey. Sincerely, </div> [[User:RMaung (WMF)|RMaung (WMF)]] 17:04, 4 çiriya pêşîn 2019 (UTC) <!-- Message sent by User:RMaung (WMF)@metawiki using the list at https://meta.wikimedia.org/w/index.php?title=CI2019List(other,act5)&oldid=19435548 --> == 800.000 == 800.000 peyv li me pîroz bin biracan. Peyva 800.000emîn: rojavayê. --[[Bikarhêner:Şêr|Şêr]] ([[Gotûbêja bikarhêner:Şêr|gotûbêj]]) 19:00, 14 çiriya pêşîn 2019 (UTC) == Beşavend/Rêzbend (Rhymes) == Silav bracan, ez bi Ghybu re jî axivîm. Em dixwazin di demeke nêz de (ez dibêm), beşavendan jî li ser ferhenga xwe çêbikin. Min tablo amade kirine (lê hê xilas nebûne) [https://ku.wiktionary.org/wiki/Bikarhêner:Şêr/Test5 br.] Em ê li gorî notasyona IPAyê û li gorî kirpandina li ser kîteya dawî tevbigerin. Gava dem nêz bû, ez ê mijarê rave bikim û dengdanekê bidim destpêkirin. Li gorî te çawa ye, ku em tiştekî wisa çê bikin? Min li ser ferhenga îngilîzî nêzîkî 133 beş çêkirine bi mînakan. [https://en.wiktionary.org/wiki/Category:Kurdish_rhymes bnr.]. Silav û rêz. --[[Bikarhêner:Şêr|Şêr]] ([[Gotûbêja bikarhêner:Şêr|gotûbêj]]) 21:05, 27 çiriya pêşîn 2019 (UTC) : {{r|Şêr}} Merheba kekê hêja û hêja {{r|Ghybu}} Ez bi birayê {{r|Pispor}} re şêwirîm. Bi min û bi ya hevalê Pispor; ev, projeyekê kêrhatî ye. Wê piçekî dem bigire. Di ya îngilîzî de bi qasî 5 hezaran beşavend hene. Ger em meqseda çêkirina beşa beşavendê û fêdeyên wê bi awayeke rind îzah bikin, wê baş be ji bo piştgiriya tevkarên din ên Wîkîferhengê. -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner#top|gotûbêj]]) 19:57, 28 çiriya pêşîn 2019 (UTC) ::{{r|Bikarhêner}}, gelek spas biracan ji bo bersiva te. Baş e nexwe. Ez ê di demeke nêz de bikim mijar. Niha bota min IPAyan û jihevqetandinan lê zêde dike. Wê hinek dem bigireta ku piraniya peyvan xilas bibe. Ez ê rê û rêbazên beşavendan jî parve bikim. Wekî mînak: [[belê]] (IPA:ˈbɛleː) û [[nelê]] (IPA: nɛˈleː) ne beşavend in, ji ber ku [[kirpandin]]a belê li ser be' ye û ya nelê li ser 'lê ye, gelek mînakên wisa hene. Ji bo formên çemandî, lêkrean û hwd. --[[Bikarhêner:Şêr|Şêr]] ([[Gotûbêja bikarhêner:Şêr|gotûbêj]]) 16:16, 29 çiriya pêşîn 2019 (UTC) :::Û li vir hê gelek tîp kêm in [https://ku.wiktionary.org/wiki/Bikarhêner:Şêr/Test5]. --[[Bikarhêner:Şêr|Şêr]] ([[Gotûbêja bikarhêner:Şêr|gotûbêj]]) 16:21, 29 çiriya pêşîn 2019 (UTC) ::::Lê ez bawer im hejmara beşavendên me me wê kêmtir bin ji ber ku piraniya (vokatîv û formên tewandî ne tê de, û formên neyînî yên lêkerên tewandî û hwd.) kirpandina peyvên kurdî li ser kîteya dawî ye, ne wek îngilîzî û elmanî (ya elmanî niha 15 hezar beşavend hene [https://de.wiktionary.org/wiki/Kategorie:Reim_(Deutsch) bnr])--[[Bikarhêner:Şêr|Şêr]] ([[Gotûbêja bikarhêner:Şêr|gotûbêj]]) 16:28, 29 çiriya pêşîn 2019 (UTC) == Çavkanî == Silav Bikarhêner, tu dikarî vî kodî (<code><nowiki><sup>[[#$1|$3]]</sup></nowiki></code>) bikî şûnda kodê [[MediaWiki:Cite references link many format]]. Spas--[[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 20:59, 8 adar 2020 (UTC) : {{r|Ghybu}} Merheba hevalê hêja. Min çêkir. Spasxweş. -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner#top|gotûbêj]]) 21:25, 8 adar 2020 (UTC) == Kategoriyên ku nayên bikaranîn == Silav Bikarhêner, {{r|Mohajeer|Balyozxane}}, hûn dikarin van kategoriyan jê birin: [https://ku.wiktionary.org/w/index.php?title=Taybet:UnusedCategories&limit=1000&offset=0]. Herwiha vana jî hene: [[Taybet:BrokenRedirects]]--[[Bikarhêner:Ghybu|Ghybu]]--[[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 14:58, 29 gulan 2020 (UTC) :{{r|Şêr}} bi botê?--[[Bikarhêner:Ghybu|Ghybu]] --[[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 14:58, 29 gulan 2020 (UTC) ::{{r|Ghybu}} Wîkîferheng hêdî hêdî mezin dibe. Bi ya min ev kategorî ger di wan de xeletiyeke din nîn be, bila jê neyên birin. Ji ber ku di demên bê de jixwe wê tijî bibin. -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner#top|gotûbêj]]) 15:28, 29 gulan 2020 (UTC) :::{{r|Balyozxane}}Di navên pirraniyan de xeletî hene, bo mînak: [[:Kategorî:Navdêr (Norwecî (Bokmål))]], [[:Kategorî:Navdêr (Ferrarees)]] (niha ziman biçûk tê nivîsandin), ... Û çend navên zimanan jî li [[Modul:ziman/dane|vira]] hatin sererast kirin feqet kategoriyên wan nehatin sererast kirin. Pirr pirsgêrek heye di nav navên kategoriyên ku vala ne. {{agadarî}} Dema ku hûn li vira ([[Modul:ziman/dane]]) zimanan sererast dikin kategoriyên wan ji bîr mekin...--[[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 15:43, 29 gulan 2020 (UTC) ::::{{r|Balyozxane}}Bi min bila hemû werin jêbirin dema ku pêwîst e dîsa tên çêkirin. Di nav kategoriyan de pirr gotarên "vala" hene...--[[Bikarhêner:Ghybu|Ghybu]]--[[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 15:54, 29 gulan 2020 (UTC) == Gotara şaş? == Silav hevalê hêja, min berî hin rojan li ser Rûdawê [https://www.rudaw.net/kurmanci/kurdistan/220720206 vê gotarê] dît. Ji bonî go navê te tê de heye ez ê ji te pirsim. Çima ew dibêjin "1 mîlyon peyvên kurdî"? Di ferhengê de tenê [https://ku.wiktionary.org/wiki/%C5%9Eablon:W%C3%AEk%C3%AEferheng_hejmara_peyvan ~240.000 rûpelên kurdî] hene û go yek guhertoyan (mînak rûpelên tenê bi bnr.) ne jimêrê ez dibêjim tenê ~180.000 rûpelên kurdî hene. Em qet ne nêzîkî 1 mîlyon peyv in û ez bawer nakim em ti carî bigihin wilqasan jî. Hejmar ne girîng e, divê rûpelên xirab pêşî werin berfirehkirin. -- {{bêîmze|Guherto}} : Merheba {{r|Guherto}} Bi rastî min gotineke wisa (wek "1 mîlyon peyvên kurdî") nekiribû. Dibe ku bi xeletî ji hevpeyvîneke din wergirtibin. Bnr: [[Wîkîferheng:Dîwan#Bersiv ji bo rojnameyên kurdî|Wîkîferheng:Dîwan#Bersiv ji bo rojnameyên kurdî]] Li wir şaşiyeke çêbûye. Ez wan haydar bikim. -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner#top|gotûbêj]]) 11:10, 26 tîrmeh 2020 (UTC) == Pirs == li wikiferhengê re em dikarin peyvên heremî jî bar bikin? li ser wikiferngê de dema ku ez oeyvên herêma xwe nebînim dikarim çê bikim, kî kontrolê peyven nû bar kirî dike? mînak; qiçil-qiçilok- an jî peyvên taybet ; elk rewar (heyvanên çîrokî) hwd. {{bêîmze|Fawaz rengzerî}} : {{r|Fawaz rengzerî}} Merheba. Di pêşiyê de dixwazim vê bêjim ku di derbarê vê meseleyê de agahiyên bidetay li vir in: "[[Wîkîferheng:Pîvekên tevlîkirinê]]". : Ji bo tevlîkirina gotarekî nû krîterên me yên giştî ev in: ''"Di sê berhemên cuda yên danerên ne-anonîm yên cihê de hatiye dîtin. Bikaranîna di van berheman de divê serbixwe bin, ango ne tenê referans an nirxandinên bikaranînên dinê bin. Divê di navbera weşandina her sê çavkaniyan de herî kêm salek derbas bûbe."''. Lê hin istisna hene: 1 - Têgihên folklorî, 2 - Berhemên klasîk, 3 - Nûpeyvên binavûdeng. : Ji bo têgihên folklorî yên di berhemên nivîskî de kêmpeyda ne, reftareke cuda li kar e. Du çavkanî ji bo peyitandina têgihên folklorî bes in. : Heke têgihek di berhemeke klasîk de hatibe dîtin, guncan e ew berhem bi tenê wek çavkanî were tomarkirin. Berhemên berî sedsala 20an nivîsandî wek klasîk tên qebûlkirin. : Têgihên nû sazkirî heta negihîjine pileya peyitandinê, ti carî tevlî rûpelên serbixwe nayên kirin. Lê ji bo peyv û têgihên bala beşdar û rêvebirên Wîkîferhengê kişandine ku roj bi roj bikaranîna wan zêde dibe û di nav civakê de populer dibin, dê lîsteyeke Nûpeyvên Binavûdeng wek pêvekekê were sazkirin. : Kontrola peyvên nû ji aliyê rêvebiran ve tê kirin, ji xeynî vê her bikarhênerekî Wîkîferhengê jî dikare bike. Ger têgiha ku lê zêde bikî peyveke folklorî be ev krîter derbasdar in: "Heke têgihek di berhemeke klasîk de hatibe dîtin, guncan e ew berhem bi tenê wek çavkanî were tomarkirin. Berhemên berî sedsala 20an nivîsandî wek klasîk tên qebûlkirin." Ger peyveke ji berhemên klasîk be ev krîter derbasdar in: "Heke têgihek di berhemeke klasîk de hatibe dîtin, guncan e ew berhem bi tenê wek çavkanî were tomarkirin. Berhemên berî sedsala 20an nivîsandî wek klasîk tên qebûlkirin." Ji bo gotarên din jî ev krîter: ''"Di sê berhemên cuda yên danerên ne-anonîm yên cihê de hatiye dîtin. Bikaranîna di van berheman de divê serbixwe bin, ango ne tenê referans an nirxandinên bikaranînên dinê bin. Divê di navbera weşandina her sê çavkaniyan de herî kêm salek derbas bûbe."''. -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner#top|gotûbêj]]) 23:31, 14 tebax 2020 (UTC) == Alîkariyekê ji bo beşa wergerê == Silav. Min koda {{ş|koda zimanî}} hinek guherand daku alî me bike dema em beşa werger ji en.wikt kopî dikin û şablona {{ş|en-to-kod}} çêkir. Dema navê inglîzî ya zimanekî dinivîsî koda zimanî dide. Mînak: * <code><nowiki>{{en-to-kod|English}}</nowiki></code> → {{en-to-kod|English}} (şablon di rûpelê de dimîne) Dikarî bi vê kodê şablonê jî rakî ji bo ku tenê koda ziman bimîne: * <code><nowiki>{{subst:şablon:en-to-kod|English}}</nowiki></code> → en (şablon di rûpelê de namîne, tenê kod dimîne) Ew çawa kêrî tiştekî tê? Ji ber ku beşa wergerê di en.wikt-ê de wek wisa hatiye amadekirin: <nowiki>*</nowiki> Arabic: <nowiki>*</nowiki> French: <nowiki>*</nowiki> Finnish: Bi rêya bikaranîna Find-Replace, dema beşa wergerê diguherînî dikarî vê kodê û koda <code><nowiki>{{Z|}}</nowiki></code> bi hev re bi kar bînî û karê te hêsantir dibe: Find: <code><nowiki>* </nowiki></code> Replace: <code><nowiki>* {{Z|{{subst:şablon:en-to-kod|</nowiki></code> Dûre dîsa find-replace dikî: Find: <code><nowiki>:</nowiki></code> Replace: <code><nowiki>}}}}:</nowiki></code> Hay ji zimanên bi vî awayî hatine amadekirin hebe. Divê van yek bi yek biguherînî: <nowiki>*</nowiki> Serbo-Croatian: :<nowiki>*:</nowiki> Cyrillic: :<nowiki>*:</nowiki> Roman: Qewet be!:--[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 13:49, 13 îlon 2020 (UTC) :{{r|Balyozxane}} Te zayend û şablonên cihan ji bîr kirîye. Baştir e ev weke bernameyeke derveya Wîkîferhengê werê çêkirin. -- [[Bikarhêner:Guherto|Guherto]] ([[Gotûbêja bikarhêner:Guherto|gotûbêj]]) 14:30, 13 îlon 2020 (UTC) ::{{r|Guherto}} Min ji bîr nekir. Ez nikarim wan biguherînim. Loma yek bi yek diguherînim. Min got qey ew ê fêm bike divê zayend û jimar yek bi yek biguherîne ji ber ku tenê behsa ziman dikim :D Bername jî ji destê min nayê mixabin :/ --[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 14:34, 13 îlon 2020 (UTC) == We sent you an e-mail == Hello {{PAGENAME}}, Really sorry for the inconvenience. This is a gentle note to request that you check your email. We sent you a message titled "The Community Insights survey is coming!". If you have questions, email surveys@wikimedia.org. You can [[:m:Special:Diff/20479077|see my explanation here]]. [[Bikarhêner:MediaWiki message delivery|MediaWiki message delivery]] ([[Gotûbêja bikarhêner:MediaWiki message delivery|gotûbêj]]) 18:52, 25 îlon 2020 (UTC) <!-- Message sent by User:Samuel (WMF)@metawiki using the list at https://meta.wikimedia.org/w/index.php?title=User:Samuel_(WMF)/Community_Insights_survey/other-languages&oldid=20479295 --> == Import == Bira xêra xwe vana bar bike: * [https://ku.wiktionary.org/wiki/Bikarh%C3%AAner:Balyozxane/UpdateLanguageNameAndCode.js] --> [[MediaWiki:UpdateLanguageNameAndCode.js]] * Koda jêr jî li dawiya rûpela [[Mediawiki:Common.js]] kopî bike. <pre> /* == Make it easy to update language name-to-code and code-to-name data modules == */ // This regex will always match. if (['Modul:ziman/ji_kod_li_nav', 'Modul:ziman/navên_zimanan'] .indexOf(mw.config.get('wgPageName').match(/^[^\/]*(?:\/[^\/]+)?/)[0]) !== -1) importScript('MediaWiki:UpdateLanguageNameAndCode.js'); </pre> Spas! --[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 19:27, 23 kanûna paşîn 2021 (UTC) Silav Bikerhêner, tu dizanî kî [https://twitter.com/wikiqisebend vê rûpelê] vekiriye? Ji ber ku bêdestûr hatiye vekirin... Ping: {{r|Balyozxane}}--[[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 19:24, 28 kanûna paşîn 2021 (UTC) : {{r|Ghybu}} Min vekir. -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner#top|gotûbêj]]) 20:01, 28 kanûna paşîn 2021 (UTC) ::Bi min were gertin ji ber ku pirsgirêk derdikevî; bila ew xwe vekin...--[[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 20:12, 28 kanûna paşîn 2021 (UTC) == Import 2 == * [[Bikarhêner:Balyozxane/Gadget-legacy.js]] → [[Mediawiki:Gadget-legacy.js]] * [[Bikarhêner:Balyozxane/Gadget-LegacyScriptsNewNode.js]] → [[Mediawiki:Gadget-LegacyScriptsNewNode.js]] * [[Bikarhêner:Balyozxane/Gadget-StorageUtils.js]] → [[Mediawiki:Gadget-StorageUtils.js]] * [[Bikarhêner:Balyozxane/Gadget-LegacyScripts]] → [[Mediawiki:Gadget-LegacyScripts]] <pre> * LegacyScripts[ResourceLoader|default|dependencies=site,mediawiki.util,mediawiki.cookie,ext.gadget.LegacyScriptsNewNode,ext.gadget.StorageUtils|type=general]|legacy.js * LegacyScriptsNewNode[ResourceLoader|hidden|targets=desktop,mobile]|LegacyScriptsNewNode.js * StorageUtils[ResourceLoader|hidden|dependencies=jquery.cookie,mediawiki.storage]|StorageUtils.js </pre> : → [[MediaWiki:Gadgets-definition]] * Silav bira, xêra xwe dikarî vana bar bikî? --[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 05:49, 18 nîsan 2021 (UTC) :: {{r|Balyozxane}} Merheba bira. Ka kontrol bike rast bûn an? --[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner#top|gotûbêj]]) 15:19, 18 nîsan 2021 (UTC) :::'''[[MediaWiki:Gadget-legacy.js#L-59|Li vir]]''' dibêje "Karber:Balyozxane/newentrywiz.js" wê bike "Bikarhêner:Balyozxane/newentrywiz.js" xêra xwe. [[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 16:36, 18 nîsan 2021 (UTC) == Zêdekirin a peyvan == {{Silav|Bikarhêner}}, ev peyvên deryajin-''denizkızı'' û deryajîn zindî yên deryayê. Mirov van peyvan çawa dikare li vir zêde bike, çavkanî çawa tê dîtin û rêbazên vir çi ye? Li benda bersiva te me, qewet be. [[Bikarhêner:Penaber49|Penaber49]] ([[Gotûbêja bikarhêner:Penaber49|gotûbêj]]) 17:01, 6 tebax 2021 (UTC) : {{r|Penaber49}} Merheba bira. Ji bo tevlîkirina me bi dengdanekê [[Wîkîferheng:Pîvekên tevlîkirinê]] hazir kiribû. Qaîdeyên tevlîkirina gotarên nû li wir dinivîsîn. Li wir dikarî binêrî beşa bi navê "Çavkaniyên dîjîtal". : Li wir ev dinivîsin: "''Tevî herî kêm çavkaniyeke çapkirî du an zêdetir çavkaniyên dijîtal jî dikarin di peyitandina têgihan de werin bikaranîn. Mercên heta niha diyarkirî ji bo wan jî derbasdar in. Herwiha ji bo ne-anonîmbûna danerên van çavkaniyan divê bikarhêner baldar bin. Da ku were misogerkirin ji aliyê kesên cihê ve hatine nivîsandin. Blog, malperên nûçeyan û wd. dikevin ber çavkaniyên dijîtal. Lê malperên medyaya civakî û mîkroblog (wek facebook, twitter û wd.) nikarin bibin çavkanî.''" : Ji bo awayê nivîsînê jî dikarî li vê rûpelê binêrî: "[[Alîkarî:Formata nivîsînê]]". Ev jî rûpela Alîkariyê ye: "[[Alîkarî:Zibare]]". Herwiha dikarî li rûpelên din ên dişibin peyvê ku çêkî binêrî. Mîsalen peyva ku te got "deryajin" navdêr e, zayendmê ye. Dikarî li rûpela "[[jinbira]]" binêrî. Û dikarî li çendîn rûpelên wekî wê binêrî û sîstema vir çêtir tê bigihî. Wekî din ger ji aliyê çavkaniyê ve problem tine be, tu rûpelê çêke, jixwe em kontrol dikin rûpelên nûçêkirî. Qewet be. -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner#top|gotûbêj]]) 19:48, 6 tebax 2021 (UTC) == Rûpela Peyva "Xûn" == Silav , Bira Te Çima Peyva "Xûn" Wek Berîyê Vegerand ? [[Bikarhêner:Zanavano|Zanavano]] ([[Gotûbêja bikarhêner:Zanavano|gotûbêj]]) 13:53, 1 îlon 2021 (UTC) : {{r|Zanavano}} Merheba bira. Bnr. rûpela [[Wîkîferheng:Rêzikên standardkirinê]]. Em li gor wan qaîdeyan hereket dikin. Herwiha bnr. [[Gotûbêj:xwîn]]. -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner#top|gotûbêj]]) 16:17, 1 îlon 2021 (UTC) == How we will see unregistered users == <div lang="en" dir="ltr" class="mw-content-ltr"> <section begin=content/> Hi! You get this message because you are an admin on a Wikimedia wiki. When someone edits a Wikimedia wiki without being logged in today, we show their IP address. As you may already know, we will not be able to do this in the future. This is a decision by the Wikimedia Foundation Legal department, because norms and regulations for privacy online have changed. Instead of the IP we will show a masked identity. You as an admin '''will still be able to access the IP'''. There will also be a new user right for those who need to see the full IPs of unregistered users to fight vandalism, harassment and spam without being admins. Patrollers will also see part of the IP even without this user right. We are also working on [[m:IP Editing: Privacy Enhancement and Abuse Mitigation/Improving tools|better tools]] to help. If you have not seen it before, you can [[m:IP Editing: Privacy Enhancement and Abuse Mitigation|read more on Meta]]. If you want to make sure you don’t miss technical changes on the Wikimedia wikis, you can [[m:Global message delivery/Targets/Tech ambassadors|subscribe]] to [[m:Tech/News|the weekly technical newsletter]]. We have [[m:IP Editing: Privacy Enhancement and Abuse Mitigation#IP Masking Implementation Approaches (FAQ)|two suggested ways]] this identity could work. '''We would appreciate your feedback''' on which way you think would work best for you and your wiki, now and in the future. You can [[m:Talk:IP Editing: Privacy Enhancement and Abuse Mitigation|let us know on the talk page]]. You can write in your language. The suggestions were posted in October and we will decide after 17 January. Thank you. /[[m:User:Johan (WMF)|Johan (WMF)]]<section end=content/> </div> 18:17, 4 kanûna paşîn 2022 (UTC) <!-- Message sent by User:Johan (WMF)@metawiki using the list at https://meta.wikimedia.org/w/index.php?title=User:Johan_(WMF)/Target_lists/Admins2022(5)&oldid=22532651 --> == [[:Kategorî:Gotarên ku bên jêbirin]] == Hi, could you please review the deletion requests in the category above? '''[[User:Rschen7754|Rs]][[User talk:Rschen7754|chen]][[Special:Contributions/Rschen7754|7754]]''' 01:06, 22 îlon 2022 (UTC) == Derbarê du hesaban == Birêz, min xêra babê xwe vê hesabê venekir. Ji ber ku hinek seyên/kûçikên Tirk, Faris û havalbendên wan Inglîz û Awistralî li ser Wîkîpediya Inglîzî min '''BAN''' kirin; min nikarîbû êdî deng di Wîkîferheng de tomar bikira. Min êdî wê hesabê berdaye û bi kar naînim. Ma keda ku min di wê hesabê de daye bê xwedî bimîna? Baş e bila bi yê te be, Êdî ez Ebulfîda tenê me. Ezê wê hesabê rakim. [[Bikarhêner:Ebulfîda|Ebulfîda]] ([[Gotûbêja bikarhêner:Ebulfîda|gotûbêj]]) 21:09, 14 sibat 2023 (UTC) : Merheba. Ev qaîdeyeke giştî ye. Min tenê bi bîra te xist. Wekî rêvebirekî mecbûr im ku bi bîr bixim. Bila hesaba te ya din jî bimîne nexwe. -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner#top|gotûbêj]]) 13:57, 15 sibat 2023 (UTC) ::Birêz, Min ji admînan daxwaz kir ku hesaba mina Key_Mîrza bê rakirin. Bimîne di xweshiyê de. [[Bikarhêner:Ebulfîda|Ebulfîda]] ([[Gotûbêja bikarhêner:Ebulfîda|gotûbêj]]) 20:28, 17 sibat 2023 (UTC) == Need your input on a policy impacting gadgets and UserJS == <div lang="en" dir="ltr" class="mw-content-ltr"> Dear interface administrator, This is Samuel from the Security team and I hope my message finds you well. There is an [[m:Talk:Third-party resources policy|ongoing discussion]] on a proposed policy governing the use of external resources in gadgets and UserJS. The proposed [[m:Special:MyLanguage/Third-party resources policy|Third-party resources policy]] aims at making the UserJS and Gadgets landscape a bit safer by encouraging best practices around external resources. After an initial non-public conversation with a small number of interface admins and staff, we've launched a much larger, public consultation to get a wider pool of feedback for improving the policy proposal. Based on the ideas received so far, the proposed policy now includes some of the risks related to user scripts and gadgets loading third-party resources, best practices for gadgets and UserJS developers, and exemptions requirements such as code transparency and inspectability. As an interface administrator, your feedback and suggestions are warmly welcome until July 17, 2023 on the [[m:Talk:Third-party resources policy|policy talk page]]. Have a great day!</div> <bdi lang="en" dir="ltr">[[m:User:Samuel (WMF)|Samuel (WMF)]], on behalf of the Foundation's Security team</bdi> 12:08, 10 tîrmeh 2023 (UTC) <!-- Message sent by User:Samuel (WMF)@metawiki using the list at https://meta.wikimedia.org/w/index.php?title=User:Samuel_(WMF)/IAdmins_MassMessage_list_2&oldid=25272792 --> : {{r|Ghybu|Balyozxane}} Hevalino, fikra we çi ye li ser vê mijarê? -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner#top|gotûbêj]]) 16:39, 10 tîrmeh 2023 (UTC) == Navguhartin == Silav bira, dikarî li sayfeyên li jêr hemû "Balyozxane" bikî "Wikihez" ji ber ku min navê xwe guhartiye, dibe ku nexebitin. * [[MediaWiki:Gadget-legacy.js]] * [[MediaWiki:Gadget-start.js]] * [[MediaWiki:Gadget-WiktAccFormCreation.js]] * [[MediaWiki:Gadget-aWa.js]] * [[Bikarhêner:Bikarhêner/common.js]] * [[Bikarhêner:Şêr/common.js]] [[Bikarhêner:Wikihez|Wikihez]]<small><sup>'''[[Bikarhêner:Balyozxane|Balyozxane]]''' ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]])</sup></small> 13:16, 14 kanûna paşîn 2025 (UTC) == Qualifiers == Silav bira. Eger wext bibînî, dikarî bikevî [[Modul:labels/data/qualifiers|vê modulê]] û çi tiştên îngilîzî wekî {{code|lua|=labels["including"]}} "including" dibînî, bikî kurdî? Ew di nav şablona {{ş|f}} de tê bikaranîn. Min navê wê jî kiriye {{ş|e}} (kurtkirina etîket) ji ber ku em modela îngilîzî teqîp dikin, ew dibêjin label, bila serê însanan tevlihev nebe. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 20:32, 3 gulan 2025 (UTC) == Alîkarî == Silav û rêz, hêvîdar im ku baş bî. Em dixwazin peyvên Kurdiya Xwarîn li ser Wiktionaryê zêde bikin, lê çima divê tenê bi Kurmancî şiroveyan binivîsin? Û çima tenê li beşa peyvên esasî ku Kurmancî ye Etîmolojî zêde be? Peyvên zaravayên din cuda ne û em dixwazin beşa Kurdiya Xwarîn jî li ser Wiktionaryê kamil û baş be, bi tevahiya înformasyonê û nimûneyan. Ji kerema xwe ji min re bêje çi divê zêde bikin wek Titles ku kamitir be? Wek ku min li ser rûpelên din dîtiye em dikarin zaravayên din zêde bikin, Kurmancî tenê peyva esasî nîne, ev ji bo devokan e ne ji bo zaravayan. {{bêîmze|Amiersoi}} : {{r|Amiersoi}} Ez wisa îzah bikim gotina xwe: Bi min eger etîmolojîya kelîmeyên dîyalektên kurdî (Kurdîya Başûrî / Xwarîn jî daxil) ji yê kurmancî cuda be, bila li ser madeya dîyalektê jî qismê Etîmolojîyê cih bigire. Feqet eger etîmolojîya kelîmeyên dîyalektên kurdî bi ya kurmancî re eynî be, ne hewce ye ku qismê etîmolojîyê li ser madeya kelîmeya dîyalekta kurdî cih bigire. : Hêja {{r|Ghybu}} û {{r|Wikihez}} ji min çêtir dizanin. Em ji wan bipirsin. Ka kîjan qism li ser kelîmeyên dîyalektên kurdî hewce ne, kîjan ne hewce ne? -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner#top|gotûbêj]]) 01:25, 24 tebax 2025 (UTC) :Temam, lê beşa zaravayên din û şirove bi vê zaravayê çima nabe? Divê ku em diyarî bikin bi devokên din çawa tê gotin, belkî kesek bixwaze bizane bi zaravayê Soranî çi dibe, nikare hertim bê beşa Kurmancî li vir bibîne. Loma wek ku min li beşa English peyv zêde kirine pirsgirêkek nabînim. [[Bikarhêner:Amiersoi|Amiersoi]] ([[Gotûbêja bikarhêner:Amiersoi|gotûbêj]]) 08:20, 24 tebax 2025 (UTC) == Nav guhaertin == Merheba ji te re. Gelo mirov dikarê navê xwe biguherîne? @[[Bikarhêner:Bikarhêner|Bikarhêner]] [[Bikarhêner:Rewiye tine|Rewiye tine]] ([[Gotûbêja bikarhêner:Rewiye tine|gotûbêj]]) 10:53, 9 kanûna paşîn 2026 (UTC) :Merheba, belê navguhertin mimkin e. Bnr. [https://meta.wikimedia.org/wiki/Special:GlobalRenameRequest vir] -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner#top|gotûbêj]]) 20:22, 9 kanûna paşîn 2026 (UTC) == Peyva ''dilê'' == Merheba. Min wê rojê hevokek seh kir. Wisa bû . ''Xwezî em baş bûna dilê çayê bû.'' li vir peywira 'dilê'' wekî olmasa da olur a tirkî ye. Gelo em dikarin çawa maneya li wir a ''dilê'' derbasî wîkîferhengî bikin?@[[Bikarhêner:Bikarhêner|Bikarhêner]] [[Bikarhêner:Rewiye tine|Rewiye tine]] ([[Gotûbêja bikarhêner:Rewiye tine|gotûbêj]]) 11:52, 4 sibat 2026 (UTC) :@[[Bikarhêner:Bikarhêner|Bikarhêner]] te çi got? [[Bikarhêner:Rewiye tine|Rewiye tine]] ([[Gotûbêja bikarhêner:Rewiye tine|gotûbêj]]) 15:08, 6 sibat 2026 (UTC) ::Ji bo qeydkirina li ser Wîkîferhengê bi kêmanî (mînîmum) sê çavkanîyên pêbawer lazim e. Ger mirov kelîmeyekê tenê carekê bibihîse, dibe ku mirov şaş seh kiribe. Ev jî rîskek e ji bo rastbûna ferhengê, lewma bi qenaeta min ger mirov ji çend kesan (mîn 3) seh neke, mirov qeyd neke baştir e. -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner#top|gotûbêj]]) 15:32, 6 sibat 2026 (UTC) :::Ev cure bikaranîna ''dil'' li herama botanê ber belav e. Ez dê pirsim. @[[Bikarhêner:Bikarhêner|Bikarhêner]] [[Bikarhêner:Rewiye tine|Rewiye tine]] ([[Gotûbêja bikarhêner:Rewiye tine|gotûbêj]]) 12:13, 8 sibat 2026 (UTC) ::::Min pirs gelek kes kir. Ev bikaranîn heye. Tu jî dikarî pirsî. Wekî din min bikararînek din jî seh kir ev jî wisa ye: 'Dilê xwe de em ê biçûna dibistanê.' Maneya wî bi tirkî '' sözde okula gidecetik'' li vir jî 'dilê xwe de' wekî 'sözde' hatiye bikaranin. [[Bikarhêner:Rewiye tine|Rewiye tine]] ([[Gotûbêja bikarhêner:Rewiye tine|gotûbêj]]) 09:17, 25 adar 2026 (UTC) == You may be an eligible candidate for the U4C election == <div lang="en" dir="ltr" class="mw-content-ltr"> Greetings, The [[m:Special:MyLanguage/Universal_Code_of_Conduct/Coordinating_Committee|Universal Code of Conduct Coordinating Committee (U4C)]] seeks candidates for the 2026 election. The U4C is the global committee responsible for overseeing enforcement of the [[foundation:Special:MyLanguage/Policy:Universal Code of Conduct|Universal Code of Conduct]]. Elections are held annually, if elected a committee member serves for two years. This year the U4C requires candidates to hold administrator rights on at least one wiki, which is why you are being contacted as you appear to hold this right. There are other requirements, such as candidates must be at least 18 years old and may not be employed by the Wikimedia Foundation or other related chapters and affiliates. You can find more information in the [[m:Special:MyLanguage/Universal_Code_of_Conduct/Coordinating_Committee/Election/2026#Call_for_Candidates|call for candidates on Meta-wiki]]. Additionally, the committee's working language is English; some ability to communicate in English is required. The election opens on 18 May, if you are eligible and interested you have until 10 May to submit your candidacy. There will be a week in between for candidates to answer questions from the community. Voting takes place privately in [[m:Special:MyLanguage/SecurePoll|SecurePoll]], successful candidates must receive at least 60% support. More information is available on [[m:Special:MyLanguage/Universal_Code_of_Conduct/Coordinating_Committee/Election/2026|the 2026 Elections page]], including timelines and other candidacy information. If you read over the material and consider yourself qualified, please consider submitting your name to run for the committee. If you think someone else in your community might be interested and qualified, please encourage them to run. In partnership with the U4C -- [[m:User:Keegan (WMF)|Keegan (WMF)]] ([[m:User_talk:Keegan (WMF)|talk]]) 20:06, 28 nîsan 2026 (UTC) </div> <!-- Message sent by User:Keegan (WMF)@metawiki using the list at https://meta.wikimedia.org/w/index.php?title=User:Keegan_(WMF)/test&oldid=30472432 --> == Dermanê mantî == Silav, te li madeyê [[dermanê mantî]] nivîsand ku çavkanî tune ye û dixwaze jê bibe. Ez li çavkaniyan digerim, lê eger hebe yan jî tune be, em bi xwe vê kelîmeyê dibêjin li gundên me. Hêvîdarim ku dîsa jî qebûl dibe, Ji ber ku vê madeyê û madeyên din hişmendiyê çandiya kurdên Berferatî zêde bike. [[Bikarhêner:Kurdanparez|Kurdanparez]] ([[Gotûbêja bikarhêner:Kurdanparez|gotûbêj]]) 13:18, 4 gulan 2026 (UTC) == Paşîgoç == Silav, Ev peyva "paşîgoç"ê li Dêrsimê tê bi kar anîn. Ez bi xwe Dêrsimî me. Li herêmê ma bi taybet li Pêrtagê gava ez ku zarok bûm, me ev peyv pir bi kar dianî. Jixwe ez carcaran dikevim û ferhenga onlayn dixwînim û pir kêfa min jê ra tê. Gegan peyvên ku me zaroktîyê xwe da bi kar dianî, li vir lê digerim, lê nabînim. Min jî xwest, hindik be jî wan peyvên ku li vir qeyd nebûne bidim qeyd kirin. Bimîne di nav xweşiyê da... [[Bikarhêner:Baskîvanî|Baskîvanî]] ([[Gotûbêja bikarhêner:Baskîvanî|gotûbêj]]) 19:07, 2 hezîran 2026 (UTC) :{{merheba|Baskîvanî}}, tu bi xêr hatî Wîkîferhengê! Bo agahdarî, bnr. [[:Kategorî:Peyvên kurmancî ji Dêrsimê]] / {{ş|lîste:hejmar/ku/Dêrsim}}. Li ser Wîkîferhengê em peyvan li gor herêm û devokan jî kategorîzê dikinê: bi [//ku.wiktionary.org/w/index.php?title=pa%C5%9F%C3%AEgo%C3%A7&curid=1357277&diff=6237005&oldid=6236974 '''vî'''] avahî (<code><nowiki>{{f|ku|Dêrsim}}</nowiki></code>) peyv tevlî kategoriya "Peyvên kurmancî ji Dêrsimê" dikevî. [[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 20:29, 2 hezîran 2026 (UTC) ::Merhaba, gelek spas... [[Bikarhêner:Baskîvanî|Baskîvanî]] ([[Gotûbêja bikarhêner:Baskîvanî|gotûbêj]]) 20:37, 25 hezîran 2026 (UTC) == [[zazakînas]] == Merheba @[[Bikarhêner:Bikarhêner|Bikarhêner]], di madeya [[zazakînas]] de çavkanî hewce ye. {{=D}}—[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:16, 15 tîrmeh 2026 (UTC) :Min jî çavkanî peyda nekir, em karin jê bibin :) -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner#top|gotûbêj]]) 22:02, 19 tîrmeh 2026 (UTC) jpj99fuhkshn2uj2lokrn98asjc1ths zazakînas 0 459501 6265690 6250720 2026-07-19T22:06:00Z Wikihez 7344 Requesting speedy deletion (Nehat peyitandin). ([[:m:User:Xiplus/TwinkleGlobal|TwinkleGlobal]]) 6265690 wikitext text/x-wiki {{jêbirin|1=Nehat peyitandin}} {{bêçavkanî}} == {{ziman|ku}} == === Bilêvkirin === * {{ku-kîte}} === Navdêr === {{navdêr|ku|z=mn}} # [[pispor|pispora/ê]] [[zarava|zaravayê]] yan [[ziman|zimanê]] [[zazakî]] ==== Formên alternatîv ==== * [[dimilînas]] * [[kirmanckînas]] ==== Nêzîk ==== * [[kirmanckîaxiv]] * [[kirmanckîpeyiv]] * [[kirmanckîzan]] * [[kirmanckîzar]] * [[kirmanckîzarava]] * [[kirmanckîziman]] * [[dimilîaxiv]] * [[dimilîpeyiv]] * [[dimilîzan]] * [[dimilîzar]] * [[dimilîzarava]] * [[dimilîziman]] * [[zazakîaxiv]] * [[zazakîpeyiv]] * [[zazakîzar]] * [[zazakîzarava]] * [[zazakîziman]] ====Bide ber==== * [[kurdînas]] * [[soranînas]] * [[hewramînas]] * [[kurmancînas]] * [[goranînas]] * [[erebînas]] * [[farisînas]] * [[îngilîzînas]] * [[tirkînas]] ==== Etîmolojî ==== Ji {{qertaf|ku|zazakî|-nas}}. ==== Jê ==== * [[zazakînasî]] nbawny8ykki4qimwsrucu361qyxnpdy Modul:ku-bilêvkirin 828 517780 6265551 6231503 2026-07-19T12:16:57Z Ghybu 1393 kurmancî 6265551 Scribunto text/plain --[[ ================================================================================ Kurdish IPA Pronunciation Module ================================================================================ Description: This module converts Kurdish words to IPA (International Phonetic Alphabet) notation and provides syllabification for Kurdish text. Supported Dialects: - Kurmanji (Northern Kurdish) - Standard Latin alphabet - Sorani (Central Kurdish) - Additional letters: ẍ, ḧ, ʿ, ' - Southern Kurdish (Xwarîn/Feylî) - Additional letters: ł, ň, ř, ü - Arabic loanwords - Emphatic consonants: ṣ, ṭ, ẓ Main Functions: - export.IPA(frame) - Converts words to IPA notation with stress marks - export.kite(frame) - Returns syllabified word with visible breaks Authors: - Bikarhêner:Ghybu - Bikarhêner:Şêr - Bikarhêner: Wikihez Version: 2.0 (Refactored for maintainability) Last Updated: 2026-02-09 ================================================================================ --]] local export = {} local b = require("Modul:bingeh") -- ============================================================================ -- CONSTANTS -- ============================================================================ -- Vowel and consonant definitions local VOWELS = "aeiîuûêoAEÊIÎOUÛ" local CONSONANTS = "bcçdfghjklmnpqrsştvwxyzẍḧłňřüṣṭẓBCÇDFGHJKLMNPQRSŞTVWXYZẌḦŁŇŘÜṢṬẒʿ'" local VOWEL_PATTERN = "[" .. VOWELS .. "]" local CONSONANT_PATTERN = "[" .. CONSONANTS .. "]" local SYLLABLE_PATTERN = "(" .. VOWEL_PATTERN .. ")(" .. CONSONANT_PATTERN .. "?)(" .. CONSONANT_PATTERN .. "?)(" .. VOWEL_PATTERN .. ")" -- Syllabification iterations local MAX_SYLLABIFICATION_ITERATIONS = 2 -- Consonant clusters that need special handling during syllabification local CONSONANT_CLUSTERS = { ["xw"] = "Ꭓ", ["rr"] = "Ꮢ", ["ll"] = "Ꮮ" } -- IPA phoneme mappings for Kurdish (Latin alphabet) local PHONEME_MAP = { -- Basic vowels ["a"] = "ɑː", ["e"] = "ɛ", ["ê"] = "eː", ["i"] = "ɘ", ["î"] = "iː", ["o"] = "oː", ["u"] = "ʊ", ["û"] = "uː", -- Consonants ["b"] = "b", ["c"] = "d͡ʒ", ["ç"] = "t͡ʃ", ["d"] = "d", ["f"] = "f", ["g"] = "ɡ", ["h"] = "h", ["j"] = "ʒ", ["k"] = "k", ["l"] = "l", ["m"] = "m", ["n"] = "n", ["p"] = "p", ["q"] = "q", ["r"] = "ɾ", ["s"] = "s", ["ş"] = "ʃ", ["t"] = "t", ["v"] = "v", ["w"] = "w", ["x"] = "x", ["y"] = "j", ["z"] = "z", -- Special letters (Sorani) ["ẍ"] = "ɣ", -- example: aẍa ["ḧ"] = "ħ", ["ʿ"] = "ʕ", ["'"] = "ʕ", -- Southern Kurdish (Xwarîn) ["ł"] = "ɫ", -- see "ll"; example: bał, diɫ ["ň"] = "ŋ", -- example: maň, seň ["ř"] = "r", -- see 'rr'; example: piř ["ü"] = "yː", -- example: tü -- Non-Kurdish letters (Arabic loanwords) ["ṣ"] = "sˤ", -- ص‎ ["ṭ"] = "tˤ", -- ط ["ẓ"] = "zˤ" } -- ============================================================================ -- HELPER FUNCTIONS -- ============================================================================ --- Wraps text in no-convert tags for MediaWiki -- @param text string The text to wrap -- @return string The wrapped text local function wrapInNoConvert(text) return '-{' .. text .. '}-' end --- Replaces or restores consonant clusters -- @param text string The text to process -- @param reverse boolean If true, restore original clusters; if false, replace with placeholders -- @return string The processed text local function processConsonantClusters(text, reverse) for original, placeholder in pairs(CONSONANT_CLUSTERS) do if reverse then text = mw.ustring.gsub(text, placeholder, original) else text = mw.ustring.gsub(text, original, placeholder) end end return text end --- Adds syllable breaks to a word -- @param word string The word to syllabify -- @return string The syllabified word with dots marking syllable boundaries local function syllabify(word) -- Replace consonant clusters with placeholders word = processConsonantClusters(word, false) -- Replace hyphens between consonants with syllable breaks word = mw.ustring.gsub(word, "%-(" .. CONSONANT_PATTERN .. ")%-(" .. CONSONANT_PATTERN .. ")", "%1.%2") word = string.gsub(word, "%-", ".") -- Add syllable breaks between vowels and consonants for count = 1, MAX_SYLLABIFICATION_ITERATIONS do word = mw.ustring.gsub( word, SYLLABLE_PATTERN, function(a, b, c, d) if c == "" and b ~= "" then c, b = b, "" end return a .. b .. "." .. c .. d end ) end -- Handle consonant clusters within syllables word = mw.ustring.gsub( word, '([' .. VOWELS .. '])([' .. CONSONANTS .. '])([' .. CONSONANTS .. '])([' .. CONSONANTS .. '])', "%1%2%3.%4" ) -- Restore original consonant clusters word = processConsonantClusters(word, true) return word end --- Applies phonological rules to prepare word for IPA conversion -- @param word string The word to process -- @return string The processed word local function applyPhonologicalRules(word) -- Aspirated consonants word = mw.ustring.gsub(word, "k%(h%)", "kʰ") word = mw.ustring.gsub(word, "p%(h%)", "pʰ") word = mw.ustring.gsub(word, "t%(h%)", "tʰ") -- Labialized velars word = mw.ustring.gsub(word, "x%(w%)", "xʷ") word = mw.ustring.gsub(word, 'xw', 'xʷ') -- example: xwarin -- Pharyngealized consonants word = mw.ustring.gsub(word, "%('%)", "ˤ") -- Velar nasal before g and k word = mw.ustring.gsub(word, 'nɡ', 'ŋɡ') -- example: ferheng word = mw.ustring.gsub(word, 'nk', 'ŋk') -- example: bank -- Velarized lateral word = mw.ustring.gsub(word, 'll', 'ɫ') -- example: Sorani gull (گوڵ) vs Kurmanji gul return word end --- Applies post-conversion IPA rules -- @param ipa string The IPA string to process -- @return string The processed IPA string local function applyPostConversionRules(ipa) -- Aspirated affricate ipa = mw.ustring.gsub(ipa, "t͡ʃ%(h%)", "t͡ʃʰ") -- Word-initial r is a trill ipa = mw.ustring.gsub(ipa, '^ɾ', "r") -- example: roj -- Geminate r is a trill ipa = mw.ustring.gsub(ipa, 'ɾɾ', 'r') -- example: pirr -- The letter i standing for the short close front unrounded vowel [i] in front of y ipa = mw.ustring.gsub(ipa, "ɘ%.j", "i.j") -- iy sequences become long i ipa = mw.ustring.gsub(ipa, 'ɪj', 'iː') return ipa end --- Applies stress rules to IPA transcription -- @param ipa string The IPA string -- @return string IPA with stress marks, string Category tag if needed local function applyStressRules(ipa) local category = "" -- Check for manual stress marks and convert them if mw.ustring.find(ipa, "\\ʕ") then category = "[[Kategorî:Giranî (dij rêgezê)]]" end ipa = mw.ustring.gsub(ipa, "\\ʕ", "'") ipa = mw.ustring.gsub(ipa, '"', "'") -- Add stress to final syllable if no manual stress present local words = mw.text.split(ipa, ' ') for k, v in ipairs(words) do local syllables = mw.text.split(v, '%.') if not mw.ustring.find(v, "'") then if #syllables ~= 1 then syllables[#syllables] = "ˈ" .. syllables[#syllables] end end words[k] = table.concat(syllables, '') end ipa = table.concat(words, ' ') -- Add default stress mark if not present if not mw.ustring.find(ipa, "ˈ") then ipa = "ˈ" .. ipa end return ipa, category end --- Converts letters to IPA phonemes, preserving unknown characters -- @param word string The word with letters to convert -- @return string The word with IPA phonemes local function convertLettersToIPA(word) return mw.ustring.gsub(word, '(.)', function(char) return PHONEME_MAP[char] or char end) end --- Converts a Kurdish word to IPA notation -- @param word string The word to convert -- @return table {ipa_string, category_string} local function wordToIPA(word) -- Normalize to lowercase word = mw.ustring.lower(word) -- Apply phonological rules word = applyPhonologicalRules(word) -- Syllabify the word word = syllabify(word) -- Convert letters to IPA phonemes (preserving numbers and other chars) word = convertLettersToIPA(word) -- Apply post-conversion rules word = applyPostConversionRules(word) -- Apply stress rules and get category local ipa, category = applyStressRules(word) return {ipa, category} end -- ============================================================================ -- EXPORTED FUNCTIONS -- ============================================================================ --- Main IPA conversion function for MediaWiki templates -- @param frame table MediaWiki frame object -- @return string Formatted IPA output with pronunciation key function export.IPA(frame) local words = {} -- Collect words from template arguments for _, word in ipairs(frame:getParent().args) do if word and word ~= "" then table.insert(words, word) end end -- If no arguments, use current page title if #words == 0 then local title = mw.title.getCurrentTitle() if title then words = {title.text} else return "[[Kategorî:IPA hatiye şaşkirin]]" end end -- Convert each word to IPA local ipaResults = {} for _, word in ipairs(words) do local result = wordToIPA(word) table.insert(ipaResults, result[1] .. result[2]) end -- Format output local ipaString = table.concat(ipaResults, '/, /') return '[[IPA]]<sup>([[Wîkîferheng:IPA kurmancî|kilîd]])</sup>: <span class="IPA">/' .. wrapInNoConvert(ipaString) .. '/</span>' .. b.bike_kategori_naverok("Bilêvkirina IPAyê bi kurmancî") end --- Returns syllabified version of a word with visible syllable breaks -- @param frame table MediaWiki frame object -- @return string The syllabified word with middle dots function export.kite(frame) local word if frame:getParent().args[1] then word = frame:getParent().args[1] else local title = mw.title.getCurrentTitle() word = title and title.text or "" end -- Remove numbers and other non-letter characters before syllabification word = mw.ustring.gsub(word, '%d', '') -- Remove all digits -- Syllabify and replace dots with middle dots local syllabified = syllabify(word) local result = mw.ustring.gsub(syllabified, '%.', '·') return result end return export qy99tf8x3gxe4b8hoyxcauwihxkuur1 Wîkîferheng:IPA kurmancî 4 518939 6265547 6231481 2026-07-19T12:15:33Z Ghybu 1393 Ghybuî/ê navê [[Wîkîferheng:IPA kurdî]] weke [[Wîkîferheng:IPA kurmancî]] guhart: şaş tê fêm kirin 6231481 wikitext text/x-wiki ;Alfabeya Fonetîk a Navneteweyî (AFN) {| style="background:none;" |- style="vertical-align:top;" | {| class="wikitable" style="margin: 1em" |+ [[bêdeng|Bêdeng]] <small>([[konsonant]])</small> ! IPA !! Deng !! Tîpên latînî !! Tîpên erebî !! Mînak !! Bilêvkirina îngilîzî |- bgcolor="white" | style="text-align: center;" | {{IPAchar|/b/}} | style="text-align: center;" | <phonos file="LL-Q36368 (kur)-Pispor-b.wav">Deng</phonos> | style="text-align: center;" | {{g|ku|B}} {{g|ku|b}} | style="text-align: center;" | {{g|ku|sc=Arab|ب|tr=-}} | '''b'''ira | '''b'''rother |- | style="text-align: center;" | {{IPAchar|/d͡ʒ/}} | style="text-align: center;" | <phonos file="LL-Q36368 (kur)-Pispor-c.wav">Deng</phonos> | style="text-align: center;" | {{g|ku|C}} {{g|ku|c}} | style="text-align: center;" | {{g|ku|sc=Arab|ج|tr=-}} | '''c'''erg | '''j'''oy |- bgcolor="#ffe4c4" | style="text-align: center;" | {{IPAchar|/t͡ʃ/}} | style="text-align: center;" | <phonos file="LL-Q36368 (kur)-Pispor-ç (nerm).wav">Deng</phonos> | style="text-align: center;" | {{g|ku|Ç}} {{g|ku|ç}} (nerm) | style="text-align: center;" | {{g|ku|sc=Arab|چ|tr=-}} | '''ç'''av, '''ç'''îrok | '''ch'''ur'''ch''' |- bgcolor="#ffe4c4" | style="text-align: center;" | {{IPAchar|/t͡ʃʰ/}} | style="text-align: center;" | <phonos file="LL-Q36368 (kur)-Pispor-ç (req).wav">Deng</phonos> | style="text-align: center;" | {{g|ku|Ç}} {{g|ku|ç}} (req) | style="text-align: center;" | {{g|ku|sc=Arab|چ|tr=-}} | '''ç'''adir, '''ç'''end | |- | style="text-align: center;" | {{IPAchar|/d/}} | style="text-align: center;" | <phonos file="LL-Q36368 (kur)-Pispor-d.wav">Deng</phonos> | style="text-align: center;" | {{g|ku|D}} {{g|ku|d}} | style="text-align: center;" | {{g|ku|sc=Arab|د|tr=-}} | '''d'''erga | '''d'''oor |- bgcolor="white" | style="text-align: center;" | {{IPAchar|/f/}} | style="text-align: center;" | <phonos file="LL-Q36368 (kur)-Pispor-f.wav">Deng</phonos> | style="text-align: center;" | {{g|ku|F}} {{g|ku|f}} | style="text-align: center;" | {{g|ku|sc=Arab|ف|tr=-}} | '''f'''irîn | '''f'''amily |- | style="text-align: center;" | {{IPAchar|/ɡ/}} | style="text-align: center;" | <phonos file="LL-Q36368 (kur)-Pispor-g.wav">Deng</phonos> | style="text-align: center;" | {{g|ku|G}} {{g|ku|g}} | style="text-align: center;" | {{g|ku|sc=Arab|گ|tr=-}} | '''g'''und | '''g'''ood |- bgcolor="white" | style="text-align: center;" | {{IPAchar|/h/}} | style="text-align: center;" | <phonos file="LL-Q36368 (kur)-Pispor-h.wav">Deng</phonos> | style="text-align: center;" | {{g|ku|H}} {{g|ku|h}} | style="text-align: center;" | {{g|ku|sc=Arab|ھ‎|tr=-}} | '''h'''eval | '''h'''ouse |- | style="text-align: center;" | {{IPAchar|/ħ/}} | style="text-align: center;" | <phonos file="LL-Q36368 (kur)-Pispor-ḧ.wav">Deng</phonos> | style="text-align: center;" | {{g|ku|Ḧ}} {{g|ku|ḧ}} | style="text-align: center;" | {{g|ku|sc=Arab|ح|tr=-}} | '''ḧ'''erf | ''Ne nameya îngilîzî ye'' |- | style="text-align: center;" | {{IPAchar|/ʒ/}} | style="text-align: center;" | <phonos file="LL-Q36368 (kur)-Pispor-j.wav">Deng</phonos> | style="text-align: center;" | {{g|ku|J}} {{g|ku|j}} | style="text-align: center;" | {{g|ku|sc=Arab|ژ|tr=-}} | '''j'''or | plea'''s'''ure |- bgcolor="#ffe4c4" | style="text-align: center;" | {{IPAchar|/k/}} | style="text-align: center;" | <phonos file="LL-Q36368 (kur)-Pispor-k (nerm).wav">Deng</phonos> | style="text-align: center;" | {{g|ku|K}} {{g|ku|k}} (nerm) | style="text-align: center;" | {{g|ku|sc=Arab|ک|tr=-}} | '''k'''evn, '''k'''êm, çe'''k''', ra'''k'''irin | '''k'''ind |- bgcolor="#ffe4c4" | style="text-align: center;" | {{IPAchar|/kʰ/}} | style="text-align: center;" | <phonos file="LL-Q36368 (kur)-Pispor-k (req).wav">Deng</phonos> | style="text-align: center;" | {{g|ku|K}} {{g|ku|k}} (req) | style="text-align: center;" | {{g|ku|sc=Arab|ک|tr=-}} | '''k'''ar, '''K'''urdistan | '''k'''eep |- | style="text-align: center;" | {{IPAchar|/l/}} | style="text-align: center;" | <phonos file="LL-Q36368 (kur)-Pispor-l (zirav).wav">Deng</phonos> | style="text-align: center;" | {{g|ku|L}} {{g|ku|l}} (zirav) | style="text-align: center;" | {{g|ku|sc=Arab|ل|tr=-}} | '''l'''aw, ma'''l''', '''l'''îmon | '''l'''emon |- bgcolor="white" | style="text-align: center;" | {{IPAchar|/ɫ/}} / {{IPAchar|/lˁ/}}&thinsp;<ref name="ɫ">Peyva-di destpêkê de ne pêk e</ref> | style="text-align: center;" | <phonos file="LL-Q36368 (kur)-Pispor-l (qelew).wav">Deng</phonos> | style="text-align: center;" | {{g|ku|L}} {{g|ku|l}} (qelew) | style="text-align: center;" | {{g|ku|sc=Arab|ڵ|tr=-}} | we'''l'''at, sa'''l''' | bu'''ll''' |- | style="text-align: center;" | {{IPAchar|/m/}} | style="text-align: center;" | <phonos file="LL-Q36368 (kur)-Pispor-m.wav">Deng</phonos> | style="text-align: center;" | {{g|ku|M}} {{g|ku|m}} | style="text-align: center;" | {{g|ku|sc=Arab|م|tr=-}} | '''m'''êr | '''m'''other |- bgcolor="white" | style="text-align: center;" | {{IPAchar|/n/}} | style="text-align: center;" | <phonos file="LL-Q36368 (kur)-Pispor-n.wav">Deng</phonos> | style="text-align: center;" | {{g|ku|N}} {{g|ku|n}} | style="text-align: center;" | {{g|ku|sc=Arab|ن|tr=-}} | '''n'''îsk | '''n'''ode |- bgcolor="#F0FFF0" | style="text-align: center;" | {{IPAchar|/ŋ/}}&thinsp;<ref name="ng">Bikaranîn, li derdora zaravayên ku li Silêmaniyê, Seqiz, Sine û cîhê din de heye. Hinekên din jî mîna normal ew bi lêv [n] bi nameyê [g] di şûna wê fonema [ŋ], e.g. maň/mang.</ref> | style="text-align: center;" | | style="text-align: center;" | {{g|ku|Ň}} {{g|ku|ň}} (ng) | style="text-align: center;" | | ma'''ň''' | lo'''ng''' |- bgcolor="#ffe4c4" | style="text-align: center;" | {{IPAchar|/p/}} | style="text-align: center;" | <phonos file="LL-Q36368 (kur)-Pispor-p (nerm).wav">Deng</phonos> | style="text-align: center;" | {{g|ku|P}} {{g|ku|p}} (nerm) | style="text-align: center;" | {{g|ku|sc=Arab|پ|tr=-}} | '''p'''ênc, '''p'''ayîz | '''p'''olicy |- bgcolor="#ffe4c4" | style="text-align: center;" | {{IPAchar|/pʰ/}} | style="text-align: center;" | <phonos file="LL-Q36368 (kur)-Pispor-p (req).wav">Deng</phonos> | style="text-align: center;" | {{g|ku|P}} {{g|ku|p}} (req) | style="text-align: center;" | {{g|ku|sc=Arab|پ|tr=-}} | '''p'''arastin, '''p'''ere | '''p'''ack |- bgcolor="#ffe4c4" | style="text-align: center;" | {{IPAchar|/pˤ/}} | style="text-align: center;" | <phonos file="LL-Q36163 (kmr)-Ebulfîda-P (Qelew).wav">Deng</phonos> | style="text-align: center;" | {{g|ku|P}} {{g|ku|p}} (stûr/qelew) | style="text-align: center;" | | '''p'''ez, '''p'''iling | |- | style="text-align: center;" | {{IPAchar|/q/}} | style="text-align: center;" | <phonos file="LL-Q36368 (kur)-Pispor-q.wav">Deng</phonos> | style="text-align: center;" | {{g|ku|Q}} {{g|ku|q}} | style="text-align: center;" | {{g|ku|sc=Arab|ق|tr=-}} | '''q'''azî | ''No English equivalent'' |- bgcolor="white" | style="text-align: center;" | {{IPAchar|/ɾ/}}&thinsp;<ref name="r">Peyva-di destpêkê de ne pêk e</ref> | style="text-align: center;" | <phonos file="LL-Q36368 (kur)-Pispor-r (nerm).wav">Deng</phonos> | style="text-align: center;" | {{g|ku|R}} {{g|ku|r}} | style="text-align: center;" | {{g|ku|sc=Arab|ر|tr=-}} | ka'''r'''wan | bette'''r''' in American English |- bgcolor="#F0FFF0" | style="text-align: center;" | {{IPAchar|/r/}}&thinsp;<ref name="rr">Hemû peyva-destpêkê r ya pir kêfxweş in, tu çawa ew hatiye nivîsandin bi.</ref> | style="text-align: center;" | <phonos file="LL-Q36368 (kur)-Pispor-r (qelew).wav">Deng</phonos><br><phonos file="LL-Q36368 (kur)-Pispor-r (zirav).wav">Deng</phonos> | style="text-align: center;" | {{g|ku|Ř}} {{g|ku|ř}} (rr) | style="text-align: center;" | {{g|ku|sc=Arab|ڕ|tr=-}} | pi'''ř''' | ''Ne miqabilê îngilîzî''; trill ''r'' ku Spanî pe'''rr'''o |- bgcolor="white" | style="text-align: center;" | {{IPAchar|/s/}} | style="text-align: center;" | <phonos file="LL-Q36368 (kur)-Pispor-s.wav">Deng</phonos> | style="text-align: center;" | {{g|ku|S}} {{g|ku|s}} | style="text-align: center;" | {{g|ku|sc=Arab|س|tr=-}} | '''s'''ard | '''c'''inema |- | style="text-align: center;" | {{IPAchar|/ʃ/}} | style="text-align: center;" | <phonos file="LL-Q36368 (kur)-Pispor-ş.wav">Deng</phonos> | style="text-align: center;" | {{g|ku|Ş}} {{g|ku|ş}} | style="text-align: center;" | {{g|ku|sc=Arab|ش|tr=-}} | '''ş'''în | '''sh'''eep |- bgcolor="#ffe4c4" | style="text-align: center;" | {{IPAchar|/t/}} | style="text-align: center;" | <phonos file="LL-Q36368 (kur)-Pispor-t (nerm).wav">Deng</phonos> | style="text-align: center;" | {{g|ku|T}} {{g|ku|t}} (nerm) | style="text-align: center;" | {{g|ku|sc=Arab|ت|tr=-}} | '''t'''aze | '''t'''ea |- bgcolor="#ffe4c4" | style="text-align: center;" | {{IPAchar|/tʰ/}} | style="text-align: center;" | <phonos file="LL-Q36368 (kur)-Pispor-t (req).wav">Deng</phonos> | style="text-align: center;" | {{g|ku|T}} {{g|ku|t}} (req) | style="text-align: center;" | {{g|ku|sc=Arab|ت|tr=-}} | '''t'''a ([[sarma]] yan [[germa]]), '''t'''am (hemî, giş), '''t'''ek (bi tenê) | ci'''t'''y (brîtanî) |- bgcolor="#ffe4c4" | style="text-align: center;" | {{IPAchar|/tˤ/}} | style="text-align: center;" | <phonos file="LL-Q36368 (kur)-Pispor-t (qelew).wav">Deng</phonos> | style="text-align: center;" | {{g|ku|T}} {{g|ku|t}} (stûr/qelew) | style="text-align: center;" | {{g|ku|sc=Arab|ت|tr=-}} | '''t'''a ([[çeq]] yan [[şax]]), '''t'''am (çêj), '''t'''eng | bi erebî {{g|ar|طَالِب}} tîpa {{g|ar|ط}} |- | style="text-align: center;" | {{IPAchar|/v/}} | style="text-align: center;" | <phonos file="LL-Q36368 (kur)-Pispor-v.wav">Deng</phonos> | style="text-align: center;" | {{g|ku|V}} {{g|ku|v}} | style="text-align: center;" | {{g|ku|sc=Arab|ڤ|tr=-}} | '''v'''iyan | '''v'''ote |- bgcolor="white" | style="text-align: center;" | {{IPAchar|/w/}} | style="text-align: center;" | <phonos file="LL-Q36368 (kur)-Pispor-w.wav">Deng</phonos> | style="text-align: center;" | {{g|ku|W}} {{g|ku|w}} | style="text-align: center;" | {{g|ku|sc=Arab|و|tr=-}} | '''w'''erz | '''w'''eb |- | style="text-align: center;" | {{IPAchar|/x/}} | style="text-align: center;" | <phonos file="LL-Q36368 (kur)-Pispor-x.wav">Deng</phonos> | style="text-align: center;" | {{g|ku|X}} {{g|ku|x}} | style="text-align: center;" | {{g|ku|sc=Arab|خ|tr=-}} | '''x'''eyall | lo'''ch''' in Scottish English |- | style="text-align: center;" | {{IPAchar|/ɣ/}} | style="text-align: center;" | <phonos file="LL-Q36163 (kmr)-Ebulfîda-Ẍ.wav">Deng</phonos> | style="text-align: center;" | {{g|ku|Ẍ}} {{g|ku|ẍ}} (gh) | style="text-align: center;" | {{g|ku|sc=Arab|غ|tr=-}} | a'''ẍ'''a | ''Ne herfeke îngilîzî ye'' |- bgcolor="white" | style="text-align: center;" | {{IPAchar|/j/}} | style="text-align: center;" | <phonos file="LL-Q36368 (kur)-Pispor-y.wav">Deng</phonos> | style="text-align: center;" | {{g|ku|Y}} {{g|ku|y}} | style="text-align: center;" | {{g|ku|sc=Arab|ی|tr=-}} | '''y'''ar | '''y'''ear |- | style="text-align: center;" | {{IPAchar|/z/}} | style="text-align: center;" | <phonos file="LL-Q36368 (kur)-Pispor-z (zirav).wav">Deng</phonos><br><phonos file="LL-Q36368 (kur)-Pispor-z (qelew).wav">Deng</phonos> | style="text-align: center;" | {{g|ku|Z}} {{g|ku|z}} | style="text-align: center;" | {{g|ku|sc=Arab|ز|tr=-}} | '''z'''îrek | '''z'''oo |- bgcolor="white" | style="text-align: center;" | {{IPAchar|/ʕ/}} | style="text-align: center;" | | style="text-align: center;" | {{g|ku|'}} / {{g|ku|ʿ}} | style="text-align: center;" | {{g|ku|sc=Arab|ع|tr=-}} | '''ʿ'''ezîz | ''Ne herfeke îngilîzî ye'' |} | {| class="wikitable" style="margin: 1em" |+ [[dengdêr|Dengdêr]] <small>([[vokal]])</small> ! IPA !! Deng !! Tîpên latînî !! Tîpên erebî !! Mînak !! Bilêvkirina îngilîzî |- bgcolor="white" | style="text-align: center;" | {{IPAchar|/ɑː/}} | style="text-align: center;" | <phonos file="LL-Q36368 (kur)-Pispor-a.wav">Deng</phonos> | style="text-align: center;" | {{g|ku|A}} {{g|ku|a}} | style="text-align: center;" | {{g|ku|sc=Arab|ا|tr=-}} | m'''a'''sî / '''a'''r | h'''a'''t / l'''a'''va |- | style="text-align: center;" | {{IPAchar|/ɛ/}} | style="text-align: center;" | <phonos file="LL-Q36368 (kur)-Pispor-e.wav">Deng</phonos> | style="text-align: center;" | {{g|ku|E}} {{g|ku|e}} | style="text-align: center;" | {{g|ku|sc=Arab|ە|tr=-}} | b'''e'''rx / '''e'''sp | b'''e'''d / g'''u'''ide |- bgcolor="white" | style="text-align: center;" | {{IPAchar|/eː/}} | style="text-align: center;" | <phonos file="LL-Q36368 (kur)-Pispor-ê.wav">Deng</phonos> | style="text-align: center;" | {{g|ku|Ê}} {{g|ku|ê}} | style="text-align: center;" | {{g|ku|sc=Arab|ێ|tr=-}} | b'''ê'''deng | b'''ea'''r; ''bi fransî '''é'''t'''é''''' |- | style="text-align: center;" | {{IPAchar|/ɘ/}} | style="text-align: center;" | <phonos file="LL-Q36368 (kur)-Pispor-i.wav">Deng</phonos> | style="text-align: center;" | {{g|ku|I}} {{g|ku|i}} | style="text-align: center;" | | Kurd'''i'''stan |- | style="text-align: center;" | {{IPAchar|/i/}} | style="text-align: center;" | <phonos file="LL-Q36368 (kur)-Pispor-a.wav">Deng</phonos> | style="text-align: center;" | {{g|ku|I}} {{g|ku|i}} | style="text-align: center;" | | ç'''i'''ya | |- |- bgcolor="white" | style="text-align: center;" | {{IPAchar|/iː/}} | style="text-align: center;" | <phonos file="LL-Q36368 (kur)-Pispor-î.wav">Deng</phonos> | style="text-align: center;" | {{g|ku|Î}} {{g|ku|î}} | style="text-align: center;" | {{g|ku|sc=Arab|ی|tr=-}} | b'''î'''r | s'''ee''' |- | style="text-align: center;" | {{IPAchar|/oː/}} | style="text-align: center;" | <phonos file="LL-Q36368 (kur)-Pispor-o.wav">Deng</phonos> | style="text-align: center;" | {{g|ku|O}} {{g|ku|o}} | style="text-align: center;" | {{g|ku|sc=Arab|ۆ|tr=-}} | r'''o'''j | '''o'''racle |- bgcolor="#F0FFF0" | style="text-align: center;" | {{IPAchar|/øː/}}&thinsp;<ref name="ö">Bi hebûnên piranî [[Soranî#Zaravayê|Jafi]] bilêvkirin.</ref> | style="text-align: center;" | | style="text-align: center;" | {{g|ku|Ö}} {{g|ku|ö}} | style="text-align: center;" | | x'''ö''' | ''Ne herfeke îngilîzî ye'' |- | style="text-align: center;" | {{IPAchar|/ʊ/}} | style="text-align: center;" | <phonos file="LL-Q36368 (kur)-Pispor-u.wav">Deng</phonos> | style="text-align: center;" | {{g|ku|U}} {{g|ku|u}} | style="text-align: center;" | {{g|ku|sc=Arab|و|tr=-}} | g'''u'''lan | n'''u'''ke |- bgcolor="white" | style="text-align: center;" | {{IPAchar|/uː/}} | style="text-align: center;" | <phonos file="LL-Q36368 (kur)-Pispor-û.wav">Deng</phonos> | style="text-align: center;" | {{g|ku|Û}} {{g|ku|û}} | style="text-align: center;" | {{g|ku|sc=Arab|وو|tr=-}} | s'''û'''r | r'''oo'''t |- bgcolor="#F0FFF0" | style="text-align: center;" | {{IPAchar|/yː/}}&thinsp;<ref name="ü">Bi piranî bilêvkirina [[Başûrê Kurdistanê]].</ref> | style="text-align: center;" | | style="text-align: center;" | {{g|ku|Ü}} {{g|ku|ü}} | style="text-align: center;" | {{g|ku|sc=Arab|ۊ|tr=-}} | k'''ü''' | ch'''oo'''se (li îngilîziya skotyayî) |} :{{legend2|#F0FFF0|border=1px solid #aaa|[[kurdiya başûrî|Kurdiya başûrî]] (<tt>sdh</tt>)}} |} == Mijarên têkildar == * '''[[Pêvek:Dengnasî]]''' * [[Modul:ku-bilêvkirin]] * [[w:Şablon:Dengdarên kurdî]] * [[w:Şablon:Dengdêrên kurdî]] * [[w:Kurmancî#Dengnasiya kurmancî|Dengnasiya kurmancî]] * [[Wîkîferheng:Dîwan/arşîv 2019#Deng bi kurdî]] == Çavkanî == {{çavkanî|2}} == Girêdanên derve == * [//www.kurdishacademy.org/?q=node/3 www.kurdishacademy.org: ''The Kurdish Unified Alphabet''] * Muhamadreza Bahadur: [//www.academia.edu/12911202/Kirma%C5%9Fan%C3%AE_Alphabet_and_Pronunciation_Guide?auto=download ''Kirmaşanî Alphabet and Pronunciation Guide''] __NOTOC__ [[Kategorî:Dengnasî|*]] 3zlyral9xzu61vx2ilh1ob9jk17sweu 6265556 6265547 2026-07-19T12:41:19Z Ghybu 1393 6265556 wikitext text/x-wiki ;Alfabeya Fonetîk a Navneteweyî (AFN) {| style="background:none;" |- style="vertical-align:top;" | {| class="wikitable" style="margin: 1em" |+ [[bêdeng|Bêdeng]] <small>([[konsonant]])</small> ! IPA !! Deng !! Tîpên latînî !! Tîpên erebî !! Mînak !! Bilêvkirina îngilîzî |- bgcolor="white" | style="text-align: center;" | {{IPAchar|/b/}} | style="text-align: center;" | <phonos file="LL-Q36368 (kur)-Pispor-b.wav">Deng</phonos> | style="text-align: center;" | {{g|ku|B}} {{g|ku|b}} | style="text-align: center;" | {{g|ku|sc=Arab|ب|tr=-}} | '''b'''ira | '''b'''rother |- | style="text-align: center;" | {{IPAchar|/d͡ʒ/}} | style="text-align: center;" | <phonos file="LL-Q36368 (kur)-Pispor-c.wav">Deng</phonos> | style="text-align: center;" | {{g|ku|C}} {{g|ku|c}} | style="text-align: center;" | {{g|ku|sc=Arab|ج|tr=-}} | '''c'''erg | '''j'''oy |- bgcolor="#ffe4c4" | style="text-align: center;" | {{IPAchar|/t͡ʃ/}} | style="text-align: center;" | <phonos file="LL-Q36368 (kur)-Pispor-ç (nerm).wav">Deng</phonos> | style="text-align: center;" | {{g|ku|Ç}} {{g|ku|ç}} (nerm) | style="text-align: center;" | {{g|ku|sc=Arab|چ|tr=-}} | '''ç'''av, '''ç'''îrok | '''ch'''ur'''ch''' |- bgcolor="#ffe4c4" | style="text-align: center;" | {{IPAchar|/t͡ʃʰ/}} | style="text-align: center;" | <phonos file="LL-Q36368 (kur)-Pispor-ç (req).wav">Deng</phonos> | style="text-align: center;" | {{g|ku|Ç}} {{g|ku|ç}} (req) | style="text-align: center;" | {{g|ku|sc=Arab|چ|tr=-}} | '''ç'''adir, '''ç'''end | |- | style="text-align: center;" | {{IPAchar|/d/}} | style="text-align: center;" | <phonos file="LL-Q36368 (kur)-Pispor-d.wav">Deng</phonos> | style="text-align: center;" | {{g|ku|D}} {{g|ku|d}} | style="text-align: center;" | {{g|ku|sc=Arab|د|tr=-}} | '''d'''erga | '''d'''oor |- bgcolor="white" | style="text-align: center;" | {{IPAchar|/f/}} | style="text-align: center;" | <phonos file="LL-Q36368 (kur)-Pispor-f.wav">Deng</phonos> | style="text-align: center;" | {{g|ku|F}} {{g|ku|f}} | style="text-align: center;" | {{g|ku|sc=Arab|ف|tr=-}} | '''f'''irîn | '''f'''amily |- | style="text-align: center;" | {{IPAchar|/ɡ/}} | style="text-align: center;" | <phonos file="LL-Q36368 (kur)-Pispor-g.wav">Deng</phonos> | style="text-align: center;" | {{g|ku|G}} {{g|ku|g}} | style="text-align: center;" | {{g|ku|sc=Arab|گ|tr=-}} | '''g'''und | '''g'''ood |- bgcolor="white" | style="text-align: center;" | {{IPAchar|/h/}} | style="text-align: center;" | <phonos file="LL-Q36368 (kur)-Pispor-h.wav">Deng</phonos> | style="text-align: center;" | {{g|ku|H}} {{g|ku|h}} | style="text-align: center;" | {{g|ku|sc=Arab|ھ‎|tr=-}} | '''h'''eval | '''h'''ouse |- | style="text-align: center;" | {{IPAchar|/ħ/}} | style="text-align: center;" | <phonos file="LL-Q36368 (kur)-Pispor-ḧ.wav">Deng</phonos> | style="text-align: center;" | {{g|ku|Ḧ}} {{g|ku|ḧ}} | style="text-align: center;" | {{g|ku|sc=Arab|ح|tr=-}} | '''ḧ'''erf | ''Ne nameya îngilîzî ye'' |- | style="text-align: center;" | {{IPAchar|/ʒ/}} | style="text-align: center;" | <phonos file="LL-Q36368 (kur)-Pispor-j.wav">Deng</phonos> | style="text-align: center;" | {{g|ku|J}} {{g|ku|j}} | style="text-align: center;" | {{g|ku|sc=Arab|ژ|tr=-}} | '''j'''or | plea'''s'''ure |- bgcolor="#ffe4c4" | style="text-align: center;" | {{IPAchar|/k/}} | style="text-align: center;" | <phonos file="LL-Q36368 (kur)-Pispor-k (nerm).wav">Deng</phonos> | style="text-align: center;" | {{g|ku|K}} {{g|ku|k}} (nerm) | style="text-align: center;" | {{g|ku|sc=Arab|ک|tr=-}} | '''k'''evn, '''k'''êm, çe'''k''', ra'''k'''irin | '''k'''ind |- bgcolor="#ffe4c4" | style="text-align: center;" | {{IPAchar|/kʰ/}} | style="text-align: center;" | <phonos file="LL-Q36368 (kur)-Pispor-k (req).wav">Deng</phonos> | style="text-align: center;" | {{g|ku|K}} {{g|ku|k}} (req) | style="text-align: center;" | {{g|ku|sc=Arab|ک|tr=-}} | '''k'''ar, '''K'''urdistan | '''k'''eep |- | style="text-align: center;" | {{IPAchar|/l/}} | style="text-align: center;" | <phonos file="LL-Q36368 (kur)-Pispor-l (zirav).wav">Deng</phonos> | style="text-align: center;" | {{g|ku|L}} {{g|ku|l}} (zirav) | style="text-align: center;" | {{g|ku|sc=Arab|ل|tr=-}} | '''l'''aw, ma'''l''', '''l'''îmon | '''l'''emon |- bgcolor="white" | style="text-align: center;" | {{IPAchar|/ɫ/}} / {{IPAchar|/lˁ/}}&thinsp;<ref name="ɫ">Peyva-di destpêkê de ne pêk e</ref> | style="text-align: center;" | <phonos file="LL-Q36368 (kur)-Pispor-l (qelew).wav">Deng</phonos> | style="text-align: center;" | {{g|ku|L}} {{g|ku|l}} (qelew) | style="text-align: center;" | {{g|ku|sc=Arab|ڵ|tr=-}} | we'''l'''at, sa'''l''' | bu'''ll''' |- | style="text-align: center;" | {{IPAchar|/m/}} | style="text-align: center;" | <phonos file="LL-Q36368 (kur)-Pispor-m.wav">Deng</phonos> | style="text-align: center;" | {{g|ku|M}} {{g|ku|m}} | style="text-align: center;" | {{g|ku|sc=Arab|م|tr=-}} | '''m'''êr | '''m'''other |- bgcolor="white" | style="text-align: center;" | {{IPAchar|/n/}} | style="text-align: center;" | <phonos file="LL-Q36368 (kur)-Pispor-n.wav">Deng</phonos> | style="text-align: center;" | {{g|ku|N}} {{g|ku|n}} | style="text-align: center;" | {{g|ku|sc=Arab|ن|tr=-}} | '''n'''îsk | '''n'''ode |- bgcolor="#F0FFF0" | style="text-align: center;" | {{IPAchar|/ŋ/}}&thinsp;<ref name="ng">Bikaranîn, li derdora zaravayên ku li Silêmaniyê, Seqiz, Sine û cîhê din de heye. Hinekên din jî mîna normal ew bi lêv [n] bi nameyê [g] di şûna wê fonema [ŋ], e.g. maň/mang.</ref> | style="text-align: center;" | | style="text-align: center;" | {{g|ku|Ň}} {{g|ku|ň}} (ng) | style="text-align: center;" | | ma'''ň''' | lo'''ng''' |- bgcolor="#ffe4c4" | style="text-align: center;" | {{IPAchar|/p/}} | style="text-align: center;" | <phonos file="LL-Q36368 (kur)-Pispor-p (nerm).wav">Deng</phonos> | style="text-align: center;" | {{g|ku|P}} {{g|ku|p}} (nerm) | style="text-align: center;" | {{g|ku|sc=Arab|پ|tr=-}} | '''p'''ênc, '''p'''ayîz | '''p'''olicy |- bgcolor="#ffe4c4" | style="text-align: center;" | {{IPAchar|/pʰ/}} | style="text-align: center;" | <phonos file="LL-Q36368 (kur)-Pispor-p (req).wav">Deng</phonos> | style="text-align: center;" | {{g|ku|P}} {{g|ku|p}} (req) | style="text-align: center;" | {{g|ku|sc=Arab|پ|tr=-}} | '''p'''arastin, '''p'''ere | '''p'''ack |- bgcolor="#ffe4c4" | style="text-align: center;" | {{IPAchar|/pˤ/}} | style="text-align: center;" | <phonos file="LL-Q36163 (kmr)-Ebulfîda-P (Qelew).wav">Deng</phonos> | style="text-align: center;" | {{g|ku|P}} {{g|ku|p}} (stûr/qelew) | style="text-align: center;" | | '''p'''ez, '''p'''iling | |- | style="text-align: center;" | {{IPAchar|/q/}} | style="text-align: center;" | <phonos file="LL-Q36368 (kur)-Pispor-q.wav">Deng</phonos> | style="text-align: center;" | {{g|ku|Q}} {{g|ku|q}} | style="text-align: center;" | {{g|ku|sc=Arab|ق|tr=-}} | '''q'''azî | ''No English equivalent'' |- bgcolor="white" | style="text-align: center;" | {{IPAchar|/ɾ/}}&thinsp;<ref name="r">Peyva-di destpêkê de ne pêk e</ref> | style="text-align: center;" | <phonos file="LL-Q36368 (kur)-Pispor-r (nerm).wav">Deng</phonos> | style="text-align: center;" | {{g|ku|R}} {{g|ku|r}} | style="text-align: center;" | {{g|ku|sc=Arab|ر|tr=-}} | ka'''r'''wan | bette'''r''' in American English |- bgcolor="#F0FFF0" | style="text-align: center;" | {{IPAchar|/r/}}&thinsp;<ref name="rr">Hemû peyva-destpêkê r ya pir kêfxweş in, tu çawa ew hatiye nivîsandin bi.</ref> | style="text-align: center;" | <phonos file="LL-Q36368 (kur)-Pispor-r (qelew).wav">Deng</phonos><br><phonos file="LL-Q36368 (kur)-Pispor-r (zirav).wav">Deng</phonos> | style="text-align: center;" | {{g|ku|Ř}} {{g|ku|ř}} (rr) | style="text-align: center;" | {{g|ku|sc=Arab|ڕ|tr=-}} | pi'''ř''' | ''Ne miqabilê îngilîzî''; trill ''r'' ku Spanî pe'''rr'''o |- bgcolor="white" | style="text-align: center;" | {{IPAchar|/s/}} | style="text-align: center;" | <phonos file="LL-Q36368 (kur)-Pispor-s.wav">Deng</phonos> | style="text-align: center;" | {{g|ku|S}} {{g|ku|s}} | style="text-align: center;" | {{g|ku|sc=Arab|س|tr=-}} | '''s'''ard | '''c'''inema |- | style="text-align: center;" | {{IPAchar|/ʃ/}} | style="text-align: center;" | <phonos file="LL-Q36368 (kur)-Pispor-ş.wav">Deng</phonos> | style="text-align: center;" | {{g|ku|Ş}} {{g|ku|ş}} | style="text-align: center;" | {{g|ku|sc=Arab|ش|tr=-}} | '''ş'''în | '''sh'''eep |- bgcolor="#ffe4c4" | style="text-align: center;" | {{IPAchar|/t/}} | style="text-align: center;" | <phonos file="LL-Q36368 (kur)-Pispor-t (nerm).wav">Deng</phonos> | style="text-align: center;" | {{g|ku|T}} {{g|ku|t}} (nerm) | style="text-align: center;" | {{g|ku|sc=Arab|ت|tr=-}} | '''t'''aze | '''t'''ea |- bgcolor="#ffe4c4" | style="text-align: center;" | {{IPAchar|/tʰ/}} | style="text-align: center;" | <phonos file="LL-Q36368 (kur)-Pispor-t (req).wav">Deng</phonos> | style="text-align: center;" | {{g|ku|T}} {{g|ku|t}} (req) | style="text-align: center;" | {{g|ku|sc=Arab|ت|tr=-}} | '''t'''a ([[sarma]] yan [[germa]]), '''t'''am (hemî, giş), '''t'''ek (bi tenê) | ci'''t'''y (brîtanî) |- bgcolor="#ffe4c4" | style="text-align: center;" | {{IPAchar|/tˤ/}} | style="text-align: center;" | <phonos file="LL-Q36368 (kur)-Pispor-t (qelew).wav">Deng</phonos> | style="text-align: center;" | {{g|ku|T}} {{g|ku|t}} (stûr/qelew) | style="text-align: center;" | {{g|ku|sc=Arab|ت|tr=-}} | '''t'''a ([[çeq]] yan [[şax]]), '''t'''am (çêj), '''t'''eng | bi erebî {{g|ar|طَالِب}} tîpa {{g|ar|ط}} |- | style="text-align: center;" | {{IPAchar|/v/}} | style="text-align: center;" | <phonos file="LL-Q36368 (kur)-Pispor-v.wav">Deng</phonos> | style="text-align: center;" | {{g|ku|V}} {{g|ku|v}} | style="text-align: center;" | {{g|ku|sc=Arab|ڤ|tr=-}} | '''v'''iyan | '''v'''ote |- bgcolor="white" | style="text-align: center;" | {{IPAchar|/w/}} | style="text-align: center;" | <phonos file="LL-Q36368 (kur)-Pispor-w.wav">Deng</phonos> | style="text-align: center;" | {{g|ku|W}} {{g|ku|w}} | style="text-align: center;" | {{g|ku|sc=Arab|و|tr=-}} | '''w'''erz | '''w'''eb |- | style="text-align: center;" | {{IPAchar|/x/}} | style="text-align: center;" | <phonos file="LL-Q36368 (kur)-Pispor-x.wav">Deng</phonos> | style="text-align: center;" | {{g|ku|X}} {{g|ku|x}} | style="text-align: center;" | {{g|ku|sc=Arab|خ|tr=-}} | '''x'''eyall | lo'''ch''' in Scottish English |- | style="text-align: center;" | {{IPAchar|/ɣ/}} | style="text-align: center;" | <phonos file="LL-Q36163 (kmr)-Ebulfîda-Ẍ.wav">Deng</phonos> | style="text-align: center;" | {{g|ku|Ẍ}} {{g|ku|ẍ}} (gh) | style="text-align: center;" | {{g|ku|sc=Arab|غ|tr=-}} | a'''ẍ'''a | ''Ne herfeke îngilîzî ye'' |- bgcolor="white" | style="text-align: center;" | {{IPAchar|/j/}} | style="text-align: center;" | <phonos file="LL-Q36368 (kur)-Pispor-y.wav">Deng</phonos> | style="text-align: center;" | {{g|ku|Y}} {{g|ku|y}} | style="text-align: center;" | {{g|ku|sc=Arab|ی|tr=-}} | '''y'''ar | '''y'''ear |- | style="text-align: center;" | {{IPAchar|/z/}} | style="text-align: center;" | <phonos file="LL-Q36368 (kur)-Pispor-z (zirav).wav">Deng</phonos><br><phonos file="LL-Q36368 (kur)-Pispor-z (qelew).wav">Deng</phonos> | style="text-align: center;" | {{g|ku|Z}} {{g|ku|z}} | style="text-align: center;" | {{g|ku|sc=Arab|ز|tr=-}} | '''z'''îrek | '''z'''oo |- bgcolor="white" | style="text-align: center;" | {{IPAchar|/ʕ/}} | style="text-align: center;" | | style="text-align: center;" | {{g|ku|'}} / {{g|ku|ʿ}} | style="text-align: center;" | {{g|ku|sc=Arab|ع|tr=-}} | '''ʿ'''ezîz | ''Ne herfeke îngilîzî ye'' |} | {| class="wikitable" style="margin: 1em" |+ [[dengdêr|Dengdêr]] <small>([[vokal]])</small> ! IPA !! Deng !! Tîpên latînî !! Tîpên erebî !! Mînak !! Bilêvkirina îngilîzî |- bgcolor="white" | style="text-align: center;" | {{IPAchar|/ɑː/}} | style="text-align: center;" | <phonos file="LL-Q36368 (kur)-Pispor-a.wav">Deng</phonos> | style="text-align: center;" | {{g|ku|A}} {{g|ku|a}} | style="text-align: center;" | {{g|ku|sc=Arab|ا|tr=-}} | m'''a'''sî / '''a'''r | h'''a'''t / l'''a'''va |- | style="text-align: center;" | {{IPAchar|/ɛ/}} | style="text-align: center;" | <phonos file="LL-Q36368 (kur)-Pispor-e.wav">Deng</phonos> | style="text-align: center;" | {{g|ku|E}} {{g|ku|e}} | style="text-align: center;" | {{g|ku|sc=Arab|ە|tr=-}} | b'''e'''rx / '''e'''sp | b'''e'''d / g'''u'''ide |- bgcolor="white" | style="text-align: center;" | {{IPAchar|/eː/}} | style="text-align: center;" | <phonos file="LL-Q36368 (kur)-Pispor-ê.wav">Deng</phonos> | style="text-align: center;" | {{g|ku|Ê}} {{g|ku|ê}} | style="text-align: center;" | {{g|ku|sc=Arab|ێ|tr=-}} | b'''ê'''deng | b'''ea'''r; ''bi fransî '''é'''t'''é''''' |- | style="text-align: center;" | {{IPAchar|/ɘ/}} | style="text-align: center;" | <phonos file="LL-Q36368 (kur)-Pispor-i.wav">Deng</phonos> | style="text-align: center;" | {{g|ku|I}} {{g|ku|i}} | style="text-align: center;" | | Kurd'''i'''stan |- | style="text-align: center;" | {{IPAchar|/i/}} | style="text-align: center;" | <phonos file="LL-Q36368 (kur)-Pispor-a.wav">Deng</phonos> | style="text-align: center;" | {{g|ku|I}} {{g|ku|i}} | style="text-align: center;" | | ç'''i'''ya | |- |- bgcolor="white" | style="text-align: center;" | {{IPAchar|/iː/}} | style="text-align: center;" | <phonos file="LL-Q36368 (kur)-Pispor-î.wav">Deng</phonos> | style="text-align: center;" | {{g|ku|Î}} {{g|ku|î}} | style="text-align: center;" | {{g|ku|sc=Arab|ی|tr=-}} | b'''î'''r | s'''ee''' |- | style="text-align: center;" | {{IPAchar|/oː/}} | style="text-align: center;" | <phonos file="LL-Q36368 (kur)-Pispor-o.wav">Deng</phonos> | style="text-align: center;" | {{g|ku|O}} {{g|ku|o}} | style="text-align: center;" | {{g|ku|sc=Arab|ۆ|tr=-}} | r'''o'''j | '''o'''racle |- bgcolor="#F0FFF0" | style="text-align: center;" | {{IPAchar|/øː/}}&thinsp;<ref name="ö">Bi hebûnên piranî [[Soranî#Zaravayê|Jafi]] bilêvkirin.</ref> | style="text-align: center;" | | style="text-align: center;" | {{g|ku|Ö}} {{g|ku|ö}} | style="text-align: center;" | | x'''ö''' | ''Ne herfeke îngilîzî ye'' |- | style="text-align: center;" | {{IPAchar|/ʊ/}} | style="text-align: center;" | <phonos file="LL-Q36368 (kur)-Pispor-u.wav">Deng</phonos> | style="text-align: center;" | {{g|ku|U}} {{g|ku|u}} | style="text-align: center;" | {{g|ku|sc=Arab|و|tr=-}} | g'''u'''lan | n'''u'''ke |- bgcolor="white" | style="text-align: center;" | {{IPAchar|/uː/}} | style="text-align: center;" | <phonos file="LL-Q36368 (kur)-Pispor-û.wav">Deng</phonos> | style="text-align: center;" | {{g|ku|Û}} {{g|ku|û}} | style="text-align: center;" | {{g|ku|sc=Arab|وو|tr=-}} | s'''û'''r | r'''oo'''t |- bgcolor="#F0FFF0" | style="text-align: center;" | {{IPAchar|/yː/}}&thinsp;<ref name="ü">Bi piranî bilêvkirina [[Başûrê Kurdistanê]].</ref> | style="text-align: center;" | | style="text-align: center;" | {{g|ku|Ü}} {{g|ku|ü}} | style="text-align: center;" | {{g|ku|sc=Arab|ۊ|tr=-}} | k'''ü''' | ch'''oo'''se (li îngilîziya skotyayî) |} :{{legend2|#F0FFF0|border=1px solid #aaa|Bi tîpên latînî ya [[kurdiya başûrî]] (<tt>sdh</tt>)}} |} == Mijarên têkildar == * '''[[Pêvek:Dengnasî]]''' * [[Modul:ku-bilêvkirin]] * [[w:Şablon:Dengdarên kurdî]] * [[w:Şablon:Dengdêrên kurdî]] * [[w:Kurmancî#Dengnasiya kurmancî|Dengnasiya kurmancî]] * [[Wîkîferheng:Dîwan/arşîv 2019#Deng bi kurdî]] == Çavkanî == {{çavkanî|2}} == Girêdanên derve == * [//www.kurdishacademy.org/?q=node/3 www.kurdishacademy.org: ''The Kurdish Unified Alphabet''] * Muhamadreza Bahadur: [//www.academia.edu/12911202/Kirma%C5%9Fan%C3%AE_Alphabet_and_Pronunciation_Guide?auto=download ''Kirmaşanî Alphabet and Pronunciation Guide''] __NOTOC__ [[Kategorî:Dengnasî|*]] 7aqsaqdpcqweriqatcft0ngobdsefhy Modul:ku-bilêvkirin/belge 828 518940 6265552 4221218 2026-07-19T12:17:20Z Ghybu 1393 /* Bikaranîn */ 6265552 wikitext text/x-wiki == Bikaranîn == Şablon: * {{ş|ku-IPA}} * {{ş|ku-kîte}} Binêre jî: * [[Wîkîferheng:IPA kurmancî]] 2zf4nfglwu2zd7hdvxelwg1plgk6prq her roj 0 539881 6265651 5675134 2026-07-19T20:15:33Z Wikihez 7344 /* */ bi [[MediaWiki:Gadget-AjaxEdit.js|AjaxEdit]]ê re 6265651 wikitext text/x-wiki == {{ziman|ku}} == === Navdêr === {{navdêr|ku}} # {{guharto|ku|hero}} tsplazgwwhcakvpibyp2s55o0hbqvf6 6265652 6265651 2026-07-19T20:16:10Z Wikihez 7344 /* */ bi [[MediaWiki:Gadget-AjaxEdit.js|AjaxEdit]]ê re 6265652 wikitext text/x-wiki == {{ziman|ku}} == === Hoker === {{hoker|ku}} # {{guharto|ku|hero}} 2nsjvuyfvxwnn0ukwlsos5q73jdwhh0 bejn tît e, mal mescîd e 0 613465 6265591 5674418 2026-07-19T15:10:46Z Wikihez 7344 ([[Mediawiki:Gadget-start.js|WF:NÛ]] v.2.0) +ku:gotineke pêşiyan: 6265591 wikitext text/x-wiki == {{ziman|ku}} == === Gotineke pêşiyan === {{gotineke pêşiyan|ku}} # {{guharto|ku|bejn tît e mal mecît e}} #* {{bênimûne|ku}} dcvrann7g570sxk2p3b84aj58jtkvhv bejin çît, mal mecît 0 622918 6265582 3045908 2026-07-19T15:05:14Z Wikihez 7344 6265582 wikitext text/x-wiki == {{ziman|ku}} == === Gotineke pêşiyan === {{gotineke pêşiyan|ku}} # {{guharto|ku|bejn tît e mal mecît e}} #* {{bênimûne|ku}} dcvrann7g570sxk2p3b84aj58jtkvhv stepping stone 0 640519 6265660 5724751 2026-07-19T20:44:20Z Wikihez 7344 Wikihezî/ê navê [[stepping-stone]] weke [[stepping stone]] guhart 5724751 wikitext text/x-wiki == {{ziman|en}} == === Navdêr === {{navdêr|en}} # [[bazeber]] ro1ezqbe2zu0l2ru9afwezdvhy38sa4 6265664 6265660 2026-07-19T20:46:45Z Wikihez 7344 [[Bikarhêner:Wikihez/templateScript2.js|TS]]: Ji [[en:stepping stone|en.wikt]] 6265664 wikitext text/x-wiki == {{ziman|en}} == === Bilêvkirin === * {{IPA|en|/ˈstɛp.ɪŋ stəʊn/|dever=QY}} * {{IPA|en|/ˈstɛp.ɪŋ stoʊn/|dever=DYA}} * {{IPA|en|/ˈstɛp.ɪŋ stɐʉn/|dever=NûZelanda}} * {{deng|en|En-au-stepping stone.ogg|dever=Awistralya}} * {{deng|en|LL-Q1860 (eng)-Naomi Persephone Amethyst (NaomiAmethyst)-stepping stone.wav|dever=DYA}} === Navdêr === [[Wêne:Stepping Stones, Egton - geograph.org.uk - 570400.jpg|thumb|{{zim|en|Stepping stones, Egton, North Yorkshire}}]] {{en-navdêr}} # [[bazeber]] ==== Formên alternatîv ==== * {{hw|en|stepping-stone}} * {{hw|en|steppingstone}} gf3etwc4j7b9f64sl9ndr0eroaofryo 6265667 6265664 2026-07-19T20:49:38Z Wikihez 7344 [[Bikarhêner:Wikihez/templateScript2.js|TS]]: Ji [[en:stepping stone|en.wikt]] 6265667 wikitext text/x-wiki == {{ziman|en}} == === Bilêvkirin === * {{IPA|en|/ˈstɛp.ɪŋ stəʊn/|dever=QY}} * {{IPA|en|/ˈstɛp.ɪŋ stoʊn/|dever=DYA}} * {{IPA|en|/ˈstɛp.ɪŋ stɐʉn/|dever=NûZelanda}} * {{deng|en|En-au-stepping stone.ogg|dever=Awistralya}} * {{deng|en|LL-Q1860 (eng)-Naomi Persephone Amethyst (NaomiAmethyst)-stepping stone.wav|dever=DYA}} === Navdêr === [[Wêne:Stepping Stones, Egton - geograph.org.uk - 570400.jpg|thumb|{{zim|en|Stepping stones, Egton, North Yorkshire}}]] {{en-navdêr}} # [[bazeber]] ==== Formên alternatîv ==== * {{hw|en|stepping-stone}} * {{hw|en|steppingstone}} ==== Hevmane ==== * {{g|en|means}} * {{g|en|way}} ==== Têkildar ==== * {{g|en|milestone}} ==== Binêre herwiha ==== * {{g|en|building block}} * {{g|en|stumbling block}} 07rspehk1rqbrmripnmroa4i4dv54le 6265681 6265667 2026-07-19T21:38:09Z Ghybu 1393 /* Bilêvkirin */ 6265681 wikitext text/x-wiki == {{ziman|en}} == === Bilêvkirin === * {{IPA|en|/ˈstɛp.ɪŋ stəʊn/|dever=QY}} * {{IPA|en|/ˈstɛp.ɪŋ stoʊn/|dever=DYA}} * {{IPA|en|/ˈstɛp.ɪŋ stɐʉn/|dever=Nû Zelanda}} * {{deng|en|En-au-stepping stone.ogg|dever=Awistralya}} * {{deng|en|LL-Q1860 (eng)-Naomi Persephone Amethyst (NaomiAmethyst)-stepping stone.wav|dever=DYA}} === Navdêr === [[Wêne:Stepping Stones, Egton - geograph.org.uk - 570400.jpg|thumb|{{zim|en|Stepping stones, Egton, North Yorkshire}}]] {{en-navdêr}} # [[bazeber]] ==== Formên alternatîv ==== * {{hw|en|stepping-stone}} * {{hw|en|steppingstone}} ==== Hevmane ==== * {{g|en|means}} * {{g|en|way}} ==== Têkildar ==== * {{g|en|milestone}} ==== Binêre herwiha ==== * {{g|en|building block}} * {{g|en|stumbling block}} gy1n6l8epxp93xjw2jcoltpol3mvmus bejntît e mal mesçît e 0 654445 6265592 5674419 2026-07-19T15:11:15Z Wikihez 7344 /* */ bi [[MediaWiki:Gadget-AjaxEdit.js|AjaxEdit]]ê re 6265592 wikitext text/x-wiki == {{ziman|ku}} == === Gotineke pêşiyan === {{gotineke pêşiyan|ku}} # {{guharto|ku|bejn tît e mal mecît e}} #* {{bênimûne|ku}} dcvrann7g570sxk2p3b84aj58jtkvhv Spielniveau 0 767242 6265738 5845893 2026-07-20T05:47:59Z Wikihez 7344 6265738 wikitext text/x-wiki == {{ziman|de}} == === Navdêr === {{navdêr|de|z=nt}} # [[ast|asta]] [[lîstik|lîstikê]] ==== Etîmolojî ==== Ji {{qertaf|de|Spiel|Niveau}}. iqjqek2nii1kq9t91xdpv9tsge80oy5 ehmer 0 796831 6265742 5840961 2026-07-20T05:59:02Z Wikihez 7344 [[Bikarhêner:Wikihez/templateScript2.js|TS]]: sererastkirin 6265742 wikitext text/x-wiki == {{ziman|ku}} == ==== Bilêvkirin ==== * {{ku-IPA|eḧmer}} * e[[ḧ]]mer === Rengdêr === {{rengdêr|ku}} # {{e|ku|tenê di edebiyata klasîk de}} [[reng|Reng]]ê [[sor]]. #: {{hevmane|ku|sor}} #* {{Jêgirtin/Mela Hisênê Bateyî/Mewlûda Kurdî|jg=''Serfê Mewlûda me '''yek''' derhem fer e</br>Hemberê '''yek''' guhê zêrê [[ehmer]] e''}} ==== Etîmolojî ==== Ji {{ji|ar|ku|أحمر|cuda=أَحْمَر|tr=eḧmer|t=[[sor]]}} ==== Werger ==== {{werger-bnr|sor}} j88lvl71k1oadp05yazomj10jtrkgir çargirekî 0 811837 6265737 4353987 2026-07-20T05:46:54Z Wikihez 7344 /* */ bi [[MediaWiki:Gadget-AjaxEdit.js|AjaxEdit]]ê re 6265737 wikitext text/x-wiki == {{ziman|ku}} == === Formeke navdêrê 1 === {{navdêr|ku|form=erê}} # ''Rewşa [[îzafeyî]] ya nêr a yekjimar a nebinavkirî ya'' '''[[çargir]]'''. === Formeke navdêrê 2 === {{ku-tew-nav|çargir|nêr|çemandî|nebinavkirî}} {{navdêr|ku|form=erê}} # ''Rewşa [[çemandî]] ya nêr a yekjimar a nebinavkirî ya'' '''[[çargir]]'''. jqearx1us8oqhj0i9gbculrce2wur5s Layezal 0 829871 6265769 6194992 2026-07-20T08:00:13Z Wikihez 7344 6265769 wikitext text/x-wiki == {{ziman|ku}} == === Bilêvkirin === * {{ku-kîte}} === Serenav === {{serenav|ku}} # {{i|wek [[zat]] yan [[sifet]]ekî [[Xwedê]]}} [[bêdawî]], [[herheyî]], [[herherî]], [[ebedî]] #* {{jêder|ku|{{Jêgirtin/Mela Hisênê Bateyî/Mewlûda Kurdî}}|jêgirtin=Nîveka dî çêkirin ji çarî çîz</br>'Erş û '''kursî''' û qelem lewhe temîz</br>Hate emrê Padîşahê [[Layezal]]}} ==== Etîmolojî ==== Ji {{ji|ar|ku|لا يزال|tr=la yezal|t=[[bi dawî bûn|bi dawî nabe]], [[dawî lê hatin|dawî lê nayê]], [[qedîn|nadeqe]]}}. Binêre {{anlz|ku|la-|zewal|hûr=1}}. 04qspjg82094ujxb6eukd7a7x1gix96 Şablon:kitêb 10 839507 6265656 6114979 2026-07-19T20:24:52Z Wikihez 7344 6265656 wikitext text/x-wiki {{#if:{{{jêgirtin|}}}|{{#if:{{{sal|}}}|{{j-pêwîst|<b>{{{sal|}}}</b>}},&nbsp;|}}}}<!-- -->{{#if:{{{nivîskar|}}}|{{j-pêwîst|{{{nivîskar|}}}}}{{#if:{{{wergêr}}}|{{#if:{{{nivîskar2}}}|,|}}|,}}&nbsp;|}}<!-- -->{{#if:{{{nivîskar2|}}}|{{j-pêwîst|{{{nivîskar2|}}}}}{{#if:{{{wergêr}}}|{{#if:{{{nivîskar3}}}|,|}}|,}}&nbsp;|}}<!-- -->{{#if:{{{nivîskar3|}}}|{{j-pêwîst|{{{nivîskar3|}}}}}{{#if:{{{wergêr}}}|{{#if:{{{amadekar}}}|,|}}|,}}&nbsp;|}}<!-- -->{{#if:{{{amadekar|}}}|{{j-pêwîst|Amadekar: {{{amadekar|}}}}}{{#if:{{{wergêr}}}||,}}&nbsp;|}}<!-- -->{{#if:{{{terciman|{{{wergêr|}}}}}}|({{j-pêwîst|terciman: {{{terciman|{{{wergêr|}}}}}}}}),&nbsp;|}}<!-- ---->{{#if:{{{sernav|}}}|<i>{{{sernav}}}</i>}}&nbsp;{{#if:{{{url|}}}|<sup>[{{{url|}}}]</sup>}}<!-- -->{{#if:{{{sernavê orjînal|}}}|&nbsp;["{{{sernavê orjînal|}}}"]|}}<!-- -->{{#if:{{{tercimeya sernav|{{{wergera sernav|}}}}}}|&nbsp;["{{{tercimeya sernav|{{{wergera sernav|}}}}}}"]|}}<!-- -->{{#if:{{{weşanxane|}}}|,&nbsp;{{{weşanxane|}}}|}}<!-- -->{{#if:{{{cih|}}}|,&nbsp;{{{cih|}}}|}}<!-- -->{{#if:{{{jêgirtin|}}}||{{#if:{{{sal|}}}|,&nbsp;{{j-pêwîst|{{{sal|}}}}}|}}}}<!-- -->{{#if:{{{sala weşandinê|}}}|,&nbsp;sala weşandinê: {{{sala weşandinê|}}}|}}<!-- -->{{#if:{{{sala orjînal|}}}|&nbsp;["{{{sala orjînal|}}}"]|}}<!-- -->{{#if:{{{çap|}}}|,&nbsp;çapa {{#ifeq:{{{çap|}}}|1|{{{çap|}}}ê|{{{çap|}}}an}}|}}<!-- -->{{#if:{{{cild|}}}|,&nbsp;cild {{{cild|}}}|}}<!-- -->{{#if:{{{rûpel|{{{r|}}}}}}|,&nbsp;r. {{{rûpel|{{{r|}}}}}}|}}<!-- -->{{#if:{{{isbn|}}}|,&nbsp;ISBN {{{isbn|}}}|}}<!-- -->{{#ifeq:{{{nekat|}}}|1||<!-- -->{{#if:{{{ziman|{{{1|}}}}}}|{{kategorî|Jêgirtinên kitêban bi {{nav ziman|{{{ziman|{{{1|}}}}}}}}}}<!-- -->}}<!-- -->}}<!-- --><noinclude> {{belgekirin}} </noinclude> budt17kycmobzormrbo0yy39a9zf2sk Wîkîferheng:Daxwazên jêbirinê 4 843009 6265804 6030641 2026-07-20T08:31:36Z Wikihez 7344 [[Bikarhêner:Wikihez/skrîpt/js/şablon-lêke.js|T]]: Daxwaza jêbirinê: +[[Malik-ul_mulkê_Celîlê_Zulcelal]] 6265804 wikitext text/x-wiki {{/destpêk}} = Daxwazên jêbirinên: {{CURRENTYEAR}} = == [[-înerî]], [[-înertî]], [[-înerîtî]] == {{dengdan|jêbirin|destpêk=06.08.2024|dawî=20.08.2024}} * '''Sedem:''' Xelet in. 1: Ne navdêr in. 2: ne paşgirên rastî ne jî ji ber ku ew "î" ne bi paşgirê lê bi gotinê ve bûye. —[[Bikarhêner:Guherto|Guherto]] ([[Gotûbêja bikarhêner:Guherto|gotûbêj]]) 20:55, 6 tebax 2024 (UTC)<!-- Sedema jêbirinê li şûnda vê nivîsê binivîsin --> <!-- Li jêr dengên xwe li gorî şablona jêr bidin --> * {{jê bibe}} Xelet in. -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 16:44, 7 tebax 2024 (UTC) == herî mezin == {{dengdan|jêbirin|destpêk=15.08.2024|dawî=22.08.2024}} * '''Sedem:''' Neferhengî ye, ji bo "komkirina tercimeyan li cihekî" jî "mezintirîn" heye. — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 17:48, 15 tebax 2024 (UTC) <!-- Sedema jêbirinê li şûnda vê nivîsê binivîsin --> <!-- Li jêr dengên xwe li gorî şablona jêr bidin --> * == tewrî mezin == {{dengdan|jêbirin|destpêk=15.08.2024|dawî=22.08.2024}} * '''Sedem:''' Neferhengî ye, ji bo "komkirina tercimeyan li cihekî" jî "mezintirîn" heye. — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 17:49, 15 tebax 2024 (UTC) <!-- Sedema jêbirinê li şûnda vê nivîsê binivîsin --> <!-- Li jêr dengên xwe li gorî şablona jêr bidin --> * == herî kêm == {{dengdan|jêbirin|destpêk=15.08.2024|dawî=22.08.2024}} * '''Sedem:''' Neferhengî ye, ji bo "komkirina tercimeyan li ba hev" jî "kêmtirîn" heye. — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 18:18, 15 tebax 2024 (UTC)<!-- Sedema jêbirinê li şûnda vê nivîsê binivîsin --> :{{şirove}} @[[Bikarhêner:Bikarhêner|Bikarhêner]] Bi fikrê min çêtir e komkirin li "herî kêm" be û ne li "kêmtirîn", ji ber ko "kêmtirîn" kopiya soranî ye. Di kurmancî de nîne/kêm heye (înternet tiştekî dî). Lê bi rastî ne hewce ye tercime ji bo qiyasên rengdêran hebin jî, ber herdû rûpel werin jêbirin. [[Bikarhêner:Guherto|Guherto]] ([[Gotûbêja bikarhêner:Guherto|gotûbêj]]) 15:30, 20 tebax 2024 (UTC) <!-- Li jêr dengên xwe li gorî şablona jêr bidin --> * == roja bûyînê == {{dengdan|jêbirin|destpêk=09.11.2024|dawî=16.11.2024}} * '''Sedem:''': Ne ferhengî ye. Ji bo komkirina tercimeyan jî kelîmeya "rojbûn"ê heye. — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 20:58, 9 çiriya paşîn 2024 (UTC)<!-- Sedema jêbirinê li şûnda vê nivîsê binivîsin --> <!-- Li jêr dengên xwe li gorî şablona jêr bidin --> * == roja jidayikbûnê == {{dengdan|jêbirin|destpêk=09.11.2024|dawî=16.11.2024}} * '''Sedem:''' Ne ferhengî ye, ji bo komkirina terimceyan jî "rojbûn" heye. — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 20:59, 9 çiriya paşîn 2024 (UTC)<!-- Sedema jêbirinê li şûnda vê nivîsê binivîsin --> <!-- Li jêr dengên xwe li gorî şablona jêr bidin --> * == rêbera cîha == {{dengdan|jêbirin|destpêk=27.12.2024|dawî=31.01.2025}} * '''Sedem:''' Bêçavkanî û neferhengî ye. — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 23:27, 26 kanûna pêşîn 2024 (UTC)<!-- Sedema jêbirinê li şûnda vê nivîsê binivîsin --> <!-- Li jêr dengên xwe li gorî şablona jêr bidin --> * == genetîka guherîbûyayên zindî == {{dengdan|jêbirin|destpêk=27.12.2024|dawî=30.12.2024}} * '''Sedem:''' Bêçavkanî û neferhengî ye. — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 00:07, 27 kanûna pêşîn 2024 (UTC)<!-- Sedema jêbirinê li şûnda vê nivîsê binivîsin --> <!-- Li jêr dengên xwe li gorî şablona jêr bidin --> * == qalika şeytanok == {{dengdan|jêbirin|destpêk=27.12.2024|dawî=30.12.2024}} * '''Sedem:''' Neferhengî ye. — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 00:09, 27 kanûna pêşîn 2024 (UTC)<!-- Sedema jêbirinê li şûnda vê nivîsê binivîsin --> <!-- Li jêr dengên xwe li gorî şablona jêr bidin --> * == kenê kesan == {{dengdan|jêbirin|destpêk=?|dawî=?}} * '''Sedem:''' Divê li madeya "ken" were qeydkirin. — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 00:15, 27 kanûna pêşîn 2024 (UTC)<!-- Sedema jêbirinê li şûnda vê nivîsê binivîsin --> <!-- Li jêr dengên xwe li gorî şablona jêr bidin --> * == [[Malik-ul_mulkê_Celîlê_Zulcelal]] == Eserên klasîk de gelek îfade hene ku nehatine tercimekirin loma xistina hemû li ferhengê nabe. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 08:31, 20 tîrmeh 2026 (UTC) r6h1wzrfvx0q04rz5tlh3439uwlv4p2 6265807 6265804 2026-07-20T08:32:13Z Wikihez 7344 [[MediaWiki:Gadget-aWa.js/belgekirin|aWa]]: Arşîvkirina 1 madeyê li [[Gotûbêj:-înerî]] 6265807 wikitext text/x-wiki {{/destpêk}} = Daxwazên jêbirinên: {{CURRENTYEAR}} = == herî mezin == {{dengdan|jêbirin|destpêk=15.08.2024|dawî=22.08.2024}} * '''Sedem:''' Neferhengî ye, ji bo "komkirina tercimeyan li cihekî" jî "mezintirîn" heye. — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 17:48, 15 tebax 2024 (UTC) <!-- Sedema jêbirinê li şûnda vê nivîsê binivîsin --> <!-- Li jêr dengên xwe li gorî şablona jêr bidin --> * == tewrî mezin == {{dengdan|jêbirin|destpêk=15.08.2024|dawî=22.08.2024}} * '''Sedem:''' Neferhengî ye, ji bo "komkirina tercimeyan li cihekî" jî "mezintirîn" heye. — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 17:49, 15 tebax 2024 (UTC) <!-- Sedema jêbirinê li şûnda vê nivîsê binivîsin --> <!-- Li jêr dengên xwe li gorî şablona jêr bidin --> * == herî kêm == {{dengdan|jêbirin|destpêk=15.08.2024|dawî=22.08.2024}} * '''Sedem:''' Neferhengî ye, ji bo "komkirina tercimeyan li ba hev" jî "kêmtirîn" heye. — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 18:18, 15 tebax 2024 (UTC)<!-- Sedema jêbirinê li şûnda vê nivîsê binivîsin --> :{{şirove}} @[[Bikarhêner:Bikarhêner|Bikarhêner]] Bi fikrê min çêtir e komkirin li "herî kêm" be û ne li "kêmtirîn", ji ber ko "kêmtirîn" kopiya soranî ye. Di kurmancî de nîne/kêm heye (înternet tiştekî dî). Lê bi rastî ne hewce ye tercime ji bo qiyasên rengdêran hebin jî, ber herdû rûpel werin jêbirin. [[Bikarhêner:Guherto|Guherto]] ([[Gotûbêja bikarhêner:Guherto|gotûbêj]]) 15:30, 20 tebax 2024 (UTC) <!-- Li jêr dengên xwe li gorî şablona jêr bidin --> * == roja bûyînê == {{dengdan|jêbirin|destpêk=09.11.2024|dawî=16.11.2024}} * '''Sedem:''': Ne ferhengî ye. Ji bo komkirina tercimeyan jî kelîmeya "rojbûn"ê heye. — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 20:58, 9 çiriya paşîn 2024 (UTC)<!-- Sedema jêbirinê li şûnda vê nivîsê binivîsin --> <!-- Li jêr dengên xwe li gorî şablona jêr bidin --> * == roja jidayikbûnê == {{dengdan|jêbirin|destpêk=09.11.2024|dawî=16.11.2024}} * '''Sedem:''' Ne ferhengî ye, ji bo komkirina terimceyan jî "rojbûn" heye. — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 20:59, 9 çiriya paşîn 2024 (UTC)<!-- Sedema jêbirinê li şûnda vê nivîsê binivîsin --> <!-- Li jêr dengên xwe li gorî şablona jêr bidin --> * == rêbera cîha == {{dengdan|jêbirin|destpêk=27.12.2024|dawî=31.01.2025}} * '''Sedem:''' Bêçavkanî û neferhengî ye. — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 23:27, 26 kanûna pêşîn 2024 (UTC)<!-- Sedema jêbirinê li şûnda vê nivîsê binivîsin --> <!-- Li jêr dengên xwe li gorî şablona jêr bidin --> * == genetîka guherîbûyayên zindî == {{dengdan|jêbirin|destpêk=27.12.2024|dawî=30.12.2024}} * '''Sedem:''' Bêçavkanî û neferhengî ye. — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 00:07, 27 kanûna pêşîn 2024 (UTC)<!-- Sedema jêbirinê li şûnda vê nivîsê binivîsin --> <!-- Li jêr dengên xwe li gorî şablona jêr bidin --> * == qalika şeytanok == {{dengdan|jêbirin|destpêk=27.12.2024|dawî=30.12.2024}} * '''Sedem:''' Neferhengî ye. — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 00:09, 27 kanûna pêşîn 2024 (UTC)<!-- Sedema jêbirinê li şûnda vê nivîsê binivîsin --> <!-- Li jêr dengên xwe li gorî şablona jêr bidin --> * == kenê kesan == {{dengdan|jêbirin|destpêk=?|dawî=?}} * '''Sedem:''' Divê li madeya "ken" were qeydkirin. — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 00:15, 27 kanûna pêşîn 2024 (UTC)<!-- Sedema jêbirinê li şûnda vê nivîsê binivîsin --> <!-- Li jêr dengên xwe li gorî şablona jêr bidin --> * == [[Malik-ul_mulkê_Celîlê_Zulcelal]] == Eserên klasîk de gelek îfade hene ku nehatine tercimekirin loma xistina hemû li ferhengê nabe. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 08:31, 20 tîrmeh 2026 (UTC) kw9qiuqdl7znng8fn9y572kqcqcw4d7 6265811 6265807 2026-07-20T08:34:48Z Wikihez 7344 6265811 wikitext text/x-wiki {{/destpêk}} = Daxwazên jêbirinên: {{CURRENTYEAR}} = == [[herî mezin]] == {{dengdan|jêbirin|destpêk=15.08.2024|dawî=22.08.2024}} * '''Sedem:''' Neferhengî ye, ji bo "komkirina tercimeyan li cihekî" jî "mezintirîn" heye. — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 17:48, 15 tebax 2024 (UTC) <!-- Sedema jêbirinê li şûnda vê nivîsê binivîsin --> <!-- Li jêr dengên xwe li gorî şablona jêr bidin --> * == [[tewrî mezin]] == {{dengdan|jêbirin|destpêk=15.08.2024|dawî=22.08.2024}} * '''Sedem:''' Neferhengî ye, ji bo "komkirina tercimeyan li cihekî" jî "mezintirîn" heye. — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 17:49, 15 tebax 2024 (UTC) <!-- Sedema jêbirinê li şûnda vê nivîsê binivîsin --> <!-- Li jêr dengên xwe li gorî şablona jêr bidin --> * == [[herî kêm]] == {{dengdan|jêbirin|destpêk=15.08.2024|dawî=22.08.2024}} * '''Sedem:''' Neferhengî ye, ji bo "komkirina tercimeyan li ba hev" jî "kêmtirîn" heye. — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 18:18, 15 tebax 2024 (UTC)<!-- Sedema jêbirinê li şûnda vê nivîsê binivîsin --> :{{şirove}} @[[Bikarhêner:Bikarhêner|Bikarhêner]] Bi fikrê min çêtir e komkirin li "herî kêm" be û ne li "kêmtirîn", ji ber ko "kêmtirîn" kopiya soranî ye. Di kurmancî de nîne/kêm heye (înternet tiştekî dî). Lê bi rastî ne hewce ye tercime ji bo qiyasên rengdêran hebin jî, ber herdû rûpel werin jêbirin. [[Bikarhêner:Guherto|Guherto]] ([[Gotûbêja bikarhêner:Guherto|gotûbêj]]) 15:30, 20 tebax 2024 (UTC) <!-- Li jêr dengên xwe li gorî şablona jêr bidin --> * == [[roja bûyînê]] == {{dengdan|jêbirin|destpêk=09.11.2024|dawî=16.11.2024}} * '''Sedem:''': Ne ferhengî ye. Ji bo komkirina tercimeyan jî kelîmeya "rojbûn"ê heye. — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 20:58, 9 çiriya paşîn 2024 (UTC)<!-- Sedema jêbirinê li şûnda vê nivîsê binivîsin --> <!-- Li jêr dengên xwe li gorî şablona jêr bidin --> * == [[roja jidayikbûnê]] == {{dengdan|jêbirin|destpêk=09.11.2024|dawî=16.11.2024}} * '''Sedem:''' Ne ferhengî ye, ji bo komkirina terimceyan jî "rojbûn" heye. — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 20:59, 9 çiriya paşîn 2024 (UTC)<!-- Sedema jêbirinê li şûnda vê nivîsê binivîsin --> <!-- Li jêr dengên xwe li gorî şablona jêr bidin --> * == [[rêbera cîha]] == {{dengdan|jêbirin|destpêk=27.12.2024|dawî=31.01.2025}} * '''Sedem:''' Bêçavkanî û neferhengî ye. — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 23:27, 26 kanûna pêşîn 2024 (UTC)<!-- Sedema jêbirinê li şûnda vê nivîsê binivîsin --> <!-- Li jêr dengên xwe li gorî şablona jêr bidin --> * == [[genetîka guherîbûyayên zindî]] == {{dengdan|jêbirin|destpêk=27.12.2024|dawî=30.12.2024}} * '''Sedem:''' Bêçavkanî û neferhengî ye. — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 00:07, 27 kanûna pêşîn 2024 (UTC)<!-- Sedema jêbirinê li şûnda vê nivîsê binivîsin --> <!-- Li jêr dengên xwe li gorî şablona jêr bidin --> * == [[qalika şeytanok]] == {{dengdan|jêbirin|destpêk=27.12.2024|dawî=30.12.2024}} * '''Sedem:''' Neferhengî ye. — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 00:09, 27 kanûna pêşîn 2024 (UTC)<!-- Sedema jêbirinê li şûnda vê nivîsê binivîsin --> <!-- Li jêr dengên xwe li gorî şablona jêr bidin --> * == [[kenê kesan]] == {{dengdan|jêbirin|destpêk=?|dawî=?}} * '''Sedem:''' Divê li madeya "ken" were qeydkirin. — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 00:15, 27 kanûna pêşîn 2024 (UTC)<!-- Sedema jêbirinê li şûnda vê nivîsê binivîsin --> <!-- Li jêr dengên xwe li gorî şablona jêr bidin --> * == [[Malik-ul mulkê Celîlê Zulcelal]] == Eserên klasîk de gelek îfade hene ku nehatine tercimekirin loma xistina hemû li ferhengê nabe. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 08:31, 20 tîrmeh 2026 (UTC) ifmlu4yujnj1d937hmsgh0ou0vsmzc2 6265812 6265811 2026-07-20T08:35:08Z Wikihez 7344 [[MediaWiki:Gadget-aWa.js/belgekirin|aWa]]: Arşîvkirina 1 madeyê li [[Gotûbêj:herî mezin]] 6265812 wikitext text/x-wiki {{/destpêk}} = Daxwazên jêbirinên: {{CURRENTYEAR}} = == [[tewrî mezin]] == {{dengdan|jêbirin|destpêk=15.08.2024|dawî=22.08.2024}} * '''Sedem:''' Neferhengî ye, ji bo "komkirina tercimeyan li cihekî" jî "mezintirîn" heye. — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 17:49, 15 tebax 2024 (UTC) <!-- Sedema jêbirinê li şûnda vê nivîsê binivîsin --> <!-- Li jêr dengên xwe li gorî şablona jêr bidin --> * == [[herî kêm]] == {{dengdan|jêbirin|destpêk=15.08.2024|dawî=22.08.2024}} * '''Sedem:''' Neferhengî ye, ji bo "komkirina tercimeyan li ba hev" jî "kêmtirîn" heye. — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 18:18, 15 tebax 2024 (UTC)<!-- Sedema jêbirinê li şûnda vê nivîsê binivîsin --> :{{şirove}} @[[Bikarhêner:Bikarhêner|Bikarhêner]] Bi fikrê min çêtir e komkirin li "herî kêm" be û ne li "kêmtirîn", ji ber ko "kêmtirîn" kopiya soranî ye. Di kurmancî de nîne/kêm heye (înternet tiştekî dî). Lê bi rastî ne hewce ye tercime ji bo qiyasên rengdêran hebin jî, ber herdû rûpel werin jêbirin. [[Bikarhêner:Guherto|Guherto]] ([[Gotûbêja bikarhêner:Guherto|gotûbêj]]) 15:30, 20 tebax 2024 (UTC) <!-- Li jêr dengên xwe li gorî şablona jêr bidin --> * == [[roja bûyînê]] == {{dengdan|jêbirin|destpêk=09.11.2024|dawî=16.11.2024}} * '''Sedem:''': Ne ferhengî ye. Ji bo komkirina tercimeyan jî kelîmeya "rojbûn"ê heye. — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 20:58, 9 çiriya paşîn 2024 (UTC)<!-- Sedema jêbirinê li şûnda vê nivîsê binivîsin --> <!-- Li jêr dengên xwe li gorî şablona jêr bidin --> * == [[roja jidayikbûnê]] == {{dengdan|jêbirin|destpêk=09.11.2024|dawî=16.11.2024}} * '''Sedem:''' Ne ferhengî ye, ji bo komkirina terimceyan jî "rojbûn" heye. — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 20:59, 9 çiriya paşîn 2024 (UTC)<!-- Sedema jêbirinê li şûnda vê nivîsê binivîsin --> <!-- Li jêr dengên xwe li gorî şablona jêr bidin --> * == [[rêbera cîha]] == {{dengdan|jêbirin|destpêk=27.12.2024|dawî=31.01.2025}} * '''Sedem:''' Bêçavkanî û neferhengî ye. — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 23:27, 26 kanûna pêşîn 2024 (UTC)<!-- Sedema jêbirinê li şûnda vê nivîsê binivîsin --> <!-- Li jêr dengên xwe li gorî şablona jêr bidin --> * == [[genetîka guherîbûyayên zindî]] == {{dengdan|jêbirin|destpêk=27.12.2024|dawî=30.12.2024}} * '''Sedem:''' Bêçavkanî û neferhengî ye. — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 00:07, 27 kanûna pêşîn 2024 (UTC)<!-- Sedema jêbirinê li şûnda vê nivîsê binivîsin --> <!-- Li jêr dengên xwe li gorî şablona jêr bidin --> * == [[qalika şeytanok]] == {{dengdan|jêbirin|destpêk=27.12.2024|dawî=30.12.2024}} * '''Sedem:''' Neferhengî ye. — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 00:09, 27 kanûna pêşîn 2024 (UTC)<!-- Sedema jêbirinê li şûnda vê nivîsê binivîsin --> <!-- Li jêr dengên xwe li gorî şablona jêr bidin --> * == [[kenê kesan]] == {{dengdan|jêbirin|destpêk=?|dawî=?}} * '''Sedem:''' Divê li madeya "ken" were qeydkirin. — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 00:15, 27 kanûna pêşîn 2024 (UTC)<!-- Sedema jêbirinê li şûnda vê nivîsê binivîsin --> <!-- Li jêr dengên xwe li gorî şablona jêr bidin --> * == [[Malik-ul mulkê Celîlê Zulcelal]] == Eserên klasîk de gelek îfade hene ku nehatine tercimekirin loma xistina hemû li ferhengê nabe. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 08:31, 20 tîrmeh 2026 (UTC) 65zniubt5mxfot2teho46xhj02tohvg 6265814 6265812 2026-07-20T08:35:21Z Wikihez 7344 [[MediaWiki:Gadget-aWa.js/belgekirin|aWa]]: Arşîvkirina 1 madeyê li [[Gotûbêj:tewrî mezin]] 6265814 wikitext text/x-wiki {{/destpêk}} = Daxwazên jêbirinên: {{CURRENTYEAR}} = == [[herî kêm]] == {{dengdan|jêbirin|destpêk=15.08.2024|dawî=22.08.2024}} * '''Sedem:''' Neferhengî ye, ji bo "komkirina tercimeyan li ba hev" jî "kêmtirîn" heye. — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 18:18, 15 tebax 2024 (UTC)<!-- Sedema jêbirinê li şûnda vê nivîsê binivîsin --> :{{şirove}} @[[Bikarhêner:Bikarhêner|Bikarhêner]] Bi fikrê min çêtir e komkirin li "herî kêm" be û ne li "kêmtirîn", ji ber ko "kêmtirîn" kopiya soranî ye. Di kurmancî de nîne/kêm heye (înternet tiştekî dî). Lê bi rastî ne hewce ye tercime ji bo qiyasên rengdêran hebin jî, ber herdû rûpel werin jêbirin. [[Bikarhêner:Guherto|Guherto]] ([[Gotûbêja bikarhêner:Guherto|gotûbêj]]) 15:30, 20 tebax 2024 (UTC) <!-- Li jêr dengên xwe li gorî şablona jêr bidin --> * == [[roja bûyînê]] == {{dengdan|jêbirin|destpêk=09.11.2024|dawî=16.11.2024}} * '''Sedem:''': Ne ferhengî ye. Ji bo komkirina tercimeyan jî kelîmeya "rojbûn"ê heye. — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 20:58, 9 çiriya paşîn 2024 (UTC)<!-- Sedema jêbirinê li şûnda vê nivîsê binivîsin --> <!-- Li jêr dengên xwe li gorî şablona jêr bidin --> * == [[roja jidayikbûnê]] == {{dengdan|jêbirin|destpêk=09.11.2024|dawî=16.11.2024}} * '''Sedem:''' Ne ferhengî ye, ji bo komkirina terimceyan jî "rojbûn" heye. — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 20:59, 9 çiriya paşîn 2024 (UTC)<!-- Sedema jêbirinê li şûnda vê nivîsê binivîsin --> <!-- Li jêr dengên xwe li gorî şablona jêr bidin --> * == [[rêbera cîha]] == {{dengdan|jêbirin|destpêk=27.12.2024|dawî=31.01.2025}} * '''Sedem:''' Bêçavkanî û neferhengî ye. — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 23:27, 26 kanûna pêşîn 2024 (UTC)<!-- Sedema jêbirinê li şûnda vê nivîsê binivîsin --> <!-- Li jêr dengên xwe li gorî şablona jêr bidin --> * == [[genetîka guherîbûyayên zindî]] == {{dengdan|jêbirin|destpêk=27.12.2024|dawî=30.12.2024}} * '''Sedem:''' Bêçavkanî û neferhengî ye. — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 00:07, 27 kanûna pêşîn 2024 (UTC)<!-- Sedema jêbirinê li şûnda vê nivîsê binivîsin --> <!-- Li jêr dengên xwe li gorî şablona jêr bidin --> * == [[qalika şeytanok]] == {{dengdan|jêbirin|destpêk=27.12.2024|dawî=30.12.2024}} * '''Sedem:''' Neferhengî ye. — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 00:09, 27 kanûna pêşîn 2024 (UTC)<!-- Sedema jêbirinê li şûnda vê nivîsê binivîsin --> <!-- Li jêr dengên xwe li gorî şablona jêr bidin --> * == [[kenê kesan]] == {{dengdan|jêbirin|destpêk=?|dawî=?}} * '''Sedem:''' Divê li madeya "ken" were qeydkirin. — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 00:15, 27 kanûna pêşîn 2024 (UTC)<!-- Sedema jêbirinê li şûnda vê nivîsê binivîsin --> <!-- Li jêr dengên xwe li gorî şablona jêr bidin --> * == [[Malik-ul mulkê Celîlê Zulcelal]] == Eserên klasîk de gelek îfade hene ku nehatine tercimekirin loma xistina hemû li ferhengê nabe. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 08:31, 20 tîrmeh 2026 (UTC) 3ujrt17dblarwlssi4i206dak2ki79n Wîkîferheng:Daxwazên peyitandinê 4 843283 6265600 6265438 2026-07-19T15:47:38Z Wikihez 7344 [[Bikarhêner:Wikihez/skrîpt/js/şablon-lêke.js|T]]: Daxwaza peyitandinê: +[[bereyîşk]] 6265600 wikitext text/x-wiki {{/destpêk}} = Hezîran 2020 = == [[romî#Navdêr|romî]] == Li Şingalê maneya polîs? --[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 08:00, 15 hezîran 2020 (UTC) = Tîrmeh 2020 = == [[kêlb#p-mane|kêlb]] == --[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 14:24, 22 tîrmeh 2020 (UTC) == [[ejî#p-mane|ejî]] == --[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 14:24, 22 tîrmeh 2020 (UTC) == [[tutirk#peyitandin|tutirk]] == --[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 22:02, 22 tîrmeh 2020 (UTC) :{{r|Guherto}} Niha çawa ye? Bi ya min çavkaniyên ku min dane têrê me dike. --[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 22:43, 22 tîrmeh 2020 (UTC) ::{{r|Balyozxane}} Nizanim.. li hin deveran wek tutirk hatîye nivîsandin û li hin jî wek tûtirk. Li hin deveran bi wateya tûşêmî (Rubus) ye, hin deveran jî bi wateya tûerd (Fragaria × ananassa) e û carna jî bi wateya tû (ê spî û reş go li ser daran çê dibin) ye. -- [[Bikarhêner:Guherto|Guherto]] ([[Gotûbêja bikarhêner:Guherto|gotûbêj]]) 08:16, 23 tîrmeh 2020 (UTC) == [[erbane#p-mane|erbane]] == Ji bo ''Amûreke tenê tekerekî wê heye ji bo veguhestina tiştan wek: axê, kevir, hwd'' ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]]''--[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 22:42, 31 tîrmeh 2020 (UTC) = Tebax 2020 = == [[cifta berazan]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]]'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 22:57, 9 tebax 2020 (UTC) == [[tê gerîn]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]]'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 22:26, 10 tebax 2020 (UTC) == [[tapor]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]]'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 20:30, 22 tebax 2020 (UTC) :{{r|Mihemed Qers}} -- [[Bikarhêner:Guherto|Guherto]] ([[Gotûbêja bikarhêner:Guherto|gotûbêj]]) 22:16, 22 tebax 2020 (UTC) == [[şimzare]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]]'' —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 19:01, 26 tebax 2020 (UTC) == [[bîrkok]] == Tenê Mehmed Uzun bi kar tîne. Ji bilî kitêbên wî çavkaniyeke din tune. —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 20:38, 28 tebax 2020 (UTC) == [[hunera axaftinê]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]]'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 18:46, 30 tebax 2020 (UTC) == [[derrijîn]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]]'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 07:38, 31 tebax 2020 (UTC) == [[yekal]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]]'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 09:19, 31 tebax 2020 (UTC) == [[av û agir]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]]'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 12:50, 31 tebax 2020 (UTC) : Di çavkaniyeke de wek av û agir kirin derbas dibe û ji wergerandinên inglîzî cuda ye lê nêzîk e.<br> {{jêder-pirtûk|ku|jêgirtin=weke gelek hunermendên ko dû re agir bera berhêm xwe didin Xwedê jî ji bilî maltaba Nûh tevayiyê vê berhema xwe '''av û agir dike''', van melekên xwe yên doxînsist dikişîne asîmanan, li wir wan tawanbar dike, mîna ko bibêje: de biçin û weke xwe bikin, bi derew û tevgerên xwe yên qirêj dijminiya min bikin, Xwedê wan ji asimanan de serjêr davêje xwarê.|nivîskar=Hesenê Metê|sernav=Labîrenta cinan|weşanxane=Nefel|sal=2002|rûpel=132}} --[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 13:37, 31 tebax 2020 (UTC) == [[elm#p-mane-notice|elm]] == Wateya: ''[[ewlebûn]], sihê pê zanîn, baş pê zanîn''. ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 17:31, 31 tebax 2020 (UTC) :{{r|Hakîmo}} Ku çavkanî tunebûn em ê jê bibin. --[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 14:47, 19 îlon 2020 (UTC) ::{{r|Balyozxane}} Mala te neketê... Hingê bixwe here lê bigere. Jixwe ez reşwî me. Ma eve ne çavkanî ye? -- [[Bikarhêner:Hakîmo|Hakîmo]] ([[Gotûbêja bikarhêner:Hakîmo|gotûbêj]]) 14:48, 19 îlon 2020 (UTC) :::{{r|Hakîmo}} Hinek bixwîne [[Wîkîferheng:Pîvekên tevlîkirinê]]. Jixwe dema ti kesan din çavkanî lê zêde nakin, ez lê digerim û zêde dikim. Na tu ne ti çavkanî yî. Çavkaniyên nivîskî hewce ne. --[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 14:51, 19 îlon 2020 (UTC) ::::{{r|Balyozxane}} Erê, lê ku tine bin em çawa bikinî? Em hema jê bibinî? -- [[Bikarhêner:Hakîmo|Hakîmo]] ([[Gotûbêja bikarhêner:Hakîmo|gotûbêj]]) 14:52, 19 îlon 2020 (UTC) :::::{{r|Hakîmo}} Erê em jê dibin. Lê peyvên jê hatine birin em li rûpela [[Pêvek:Bêçavkanî]] zêde dikin. bnr. [[:Kategorî:Pêvek bêçavkanî]]. Dîsa jî ez jî ji vê rewşa me aciz im û bi ya min peyvên devokî divê nayên jêbirin. Lê ji ber ku [[Wîkîferheng:Rêbazname]] dibêje divê werin jêbirin, ez jê dibim. Hevalên {{r|Jiju|Guherto|Ghybu}} [https://ku.wiktionary.org/wiki/Got%C3%BBb%C3%AAj:kejm%C3%BBn], [https://ku.wiktionary.org/wiki/Got%C3%BBb%C3%AAja_p%C3%AAvek%C3%AA:B%C3%AA%C3%A7avkan%C3%AE] jî ji vê rewşê aciz in. Lê ti kes gotûbêj nadin destpêkirin. Ku tu li vir [[Gotûbêja Wîkîferhengê:Pîvekên tevlîkirinê]] gotûbêjek bidî destpêkirin, ez ê piştgirî bidime te. --[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 14:58, 19 îlon 2020 (UTC) ::::::Ji kerema xwe min şaş fêm mekin feqet hemû bikarhêner ku tên vira dilpak nînin. Em çito ew peyvan kotrol bikinê? Mixabin, ji bo konrolkirina peyvan di destên me de tenê xwastina çavkaniyan hene amûrek din tine ye... PS: Herwiha me li ser wîkîferhengê Namespace'yên Nimînok ([[Nimînok:Kurdî/serhedî]]?, [[Nimînok:Kurdî/badînî]]?, ..) û Portal ([[Portal:Kurdî]], [[Portal:Frensî]] (mk. [[:fr:Portail:Français]]), ...) jî çêkiriye...--[[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 15:32, 19 îlon 2020 (UTC) :::::::Nizanim we nivîsa vira xwand, [[Wîkîferheng:Dîwan#Skotî]]. Piraniya peyvên wîkiya skotî çêkirî ne...--[[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 15:47, 19 îlon 2020 (UTC) ::::::::@Ghybu erê min ew xwendibû. Ku em peyvan nepeyitînin, rewşa me jî wek mg.wikt û wikiya skotiyan be. Temam em peyvên devokî jê nebin lê em wan jî nexin werger û rûpelên din heta ku werin peyitandin. Herwiha tu dibêjî amûrek tune ye lê tenê ji bo peyvên devokî û navên heywan/riwekan wisa ye. Gelek caran peyitandin pir hêsan e. Mînak @Hakîmo yan jî hevalên din dikarin blogan binivîsin daku em karibin peyvên wan yên devokî (nepeyitandî) têxin rûpela [[Wîkîferheng:Tomarkirina peyvên ji wêjeya kurdî|Jêgirtinekê tomar bike]] û kengî ew peyv ji hêla nivîskar û blogvanên kurd yên din ve hatine bikaranîn hingê em dikarin li wîkîferhengê jî zêde bikin. --[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 16:05, 19 îlon 2020 (UTC) {{outdent|::::::::}}{{r|Hakîmo|Ghybu}} Xêra dê û bavên we '''[[Gotûbêja_Wîkîferhengê:Pîvekên_tevlîkirinê#Li_ser_peyvên_devokî|li vir]]''' fikrên xwe binivîsin daku kesên din bizanin kesên din jî hene vê fikrê min dipejirînin. --[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 06:48, 3 çiriya pêşîn 2020 (UTC) == [[nîşanbar]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 23:51, 31 tebax 2020 (UTC) = Îlon 2020 = == [[besme]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 11:26, 1 îlon 2020 (UTC) == [[ferengi]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 17:12, 1 îlon 2020 (UTC) == [[çelape]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 17:22, 1 îlon 2020 (UTC) == [[cesasandin]] == Çavkaniyek klasîk heye, yên din heye gelo? —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 09:02, 2 îlon 2020 (UTC) == [[depan]] == Depan guhertoyeke textan an textîn e. Lê li vir çi mane heye min fêm nekir. —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 10:33, 2 îlon 2020 (UTC) == [[li rûyê dinê xweş mayîn]] == Çavkaniyeke klasîk heye —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 20:38, 2 îlon 2020 (UTC) == [[bêsewî]] == klasîk —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 06:34, 4 îlon 2020 (UTC) == [[merkemoş]] == Klasîk —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 06:34, 4 îlon 2020 (UTC) == [[firfiroka bayî]] == {{r|Mamoste Dilovan}} ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 12:57, 6 îlon 2020 (UTC) == [[guhê fîlî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 18:56, 7 îlon 2020 (UTC) : {{r|Bikarhêner}} Min guh li evê peyvê bû ji kesekî ku xudan xwaringehek û baxçeyekî mezin e. : Gelek tişt di berbelav in û xelk dizanin, lê di pertûkan de naye dîtin. {{bêîmze|IbrahimKocher Duhok}} == [[gurovî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 14:41, 14 îlon 2020 (UTC) :{{r|Bikarhêner}} Çavkanîyên peyvên ku min nivîsandin mixabin ne nivîskî ne. Ev peyv min ji hin mezinên malbatê bihîstine û min jî gelek caran dîtîne ku hatine bikaranîn. Ji bo ku ev peyv wûnda nebin min hem li ba xwe û hem jî li wîkîferhengê nivîsand. Ji bo peyvên ku çavkanîyên nivîskî tunin, mixabin gotinên devkî tene weke çavkanî dimînin. Pêşnîyara te ji bo pevên bi vî awayî çi ye gelo? Spas{{bêîmze|Xwende}} ::{{r|Xwende}} Pêşî li ser malpera [https://tirsik.net/xerhati.php] dûre jî li ser arsiv.org qeyd bike ku nikarî çavkanî peyda bikî. Herwiha bnr [[Alîkarî:Îmze]] --[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 16:00, 15 îlon 2020 (UTC) == [[şîloyî]] == {{r|Xwende}} ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 14:44, 14 îlon 2020 (UTC) == [[dever]] == Ji bo wateya ''derence, sêlim û merdîwen'' [[Wîkîferheng:Pîvekên tevlîkirinê|çavkanî hewce ye]]. —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 17:53, 14 îlon 2020 (UTC) == [[kerrnizî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 15:56, 15 îlon 2020 (UTC) == [[li dora (yekê) gerîn]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 18:46, 15 îlon 2020 (UTC) == [[glas]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]]. --[[Bikarhêner:Şêr|Şêr]] ([[Gotûbêja bikarhêner:Şêr|gotûbêj]]) 12:45, 16 îlon 2020 (UTC) == [[kejmûn]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 16:42, 17 îlon 2020 (UTC) == [[lirêgerîn]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 14:20, 18 îlon 2020 (UTC) == [[çavpeqî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 16:23, 23 îlon 2020 (UTC) :http://www.geocities.ws/mehname2004a/63/pexsan5.html -- [[Bikarhêner:Guherto|Guherto]] ([[Gotûbêja bikarhêner:Guherto|gotûbêj]]) 16:58, 23 îlon 2020 (UTC) == [[çavpeqiyayî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 17:14, 23 îlon 2020 (UTC) :{{r|Balyozxane}} Çavpeqî û -iyayî eynî peyv in, heke bo nimûne 2 çavkanî ji bo çavpeqî û 1 ji bo -iyayî werin dîtin ew weke 3 ji bo yek peyv tên jimartin? -- [[Bikarhêner:Guherto|Guherto]] ([[Gotûbêja bikarhêner:Guherto|gotûbêj]]) 17:16, 23 îlon 2020 (UTC) ::{{r|Guherto}}. Na, divê yek ji wan peyitandî be daku em karibin yek ji wan wek guherto nîşan bidin. --[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 17:45, 23 îlon 2020 (UTC) :::Temam naxwe. {{=(}} -- [[Bikarhêner:Guherto|Guherto]] ([[Gotûbêja bikarhêner:Guherto|gotûbêj]]) 17:48, 23 îlon 2020 (UTC) ::::Ecêb e peyva çavpeqîn jî tune ye. Divê çavpeqî/çavpeqiyayî jê hatibe lê qet tune. --[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 17:56, 23 îlon 2020 (UTC) :::::Em çavpeqî ne weke kesekî ku çavê wan peqî ye dibêjin. Siqêfek e. ''Wilo neke, çavpeqî!'' -- [[Bikarhêner:Guherto|Guherto]] ([[Gotûbêja bikarhêner:Guherto|gotûbêj]]) 18:10, 23 îlon 2020 (UTC) == [[olfatûn]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 14:58, 24 îlon 2020 (UTC) :Du çavkanî hatiye dîtin li hêviya ya sisêyan e. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 13:46, 23 sibat 2025 (UTC) == [[hekûke]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 16:00, 28 îlon 2020 (UTC) :Tenê çavkaniyek ji Kovara Kurmancî heye ew jî ji kitêba Gundê Mêrxasan a Eliyê Evdilrehman hatiye girtin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 13:49, 23 sibat 2025 (UTC) == [[dê bêjî kaya di serî de]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 12:58, 29 îlon 2020 (UTC) == [[heçî ne li malekê, nizanit halekê]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 12:58, 29 îlon 2020 (UTC) == [[heta nîva destî reş nebit, tama devî xoş nabit]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 12:58, 29 îlon 2020 (UTC) == [[kirtop]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' Herwiha [[kirtope]]—[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 12:59, 29 îlon 2020 (UTC) : == [[pişkûmişk]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 21:25, 29 îlon 2020 (UTC) = Çiriya pêşîn 2020 = == [[ma te şulê pê ye?]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 13:19, 1 çiriya pêşîn 2020 (UTC) == [[zelam yêt heyn û zelamoşk jî yêt heyn]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 13:28, 1 çiriya pêşîn 2020 (UTC) == [[ezîz î&#59; ji pêrve ne mîzî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 14:15, 1 çiriya pêşîn 2020 (UTC) == [[qelpez]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 08:19, 6 çiriya pêşîn 2020 (UTC) == [[firêzer]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Guherto|Guherto]] ([[Gotûbêja bikarhêner:Guherto|gotûbêj]]) 15:27, 6 çiriya pêşîn 2020 (UTC) == [[kirmişk]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 09:03, 7 çiriya pêşîn 2020 (UTC) == [[orijîn]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Guherto|Guherto]] ([[Gotûbêja bikarhêner:Guherto|gotûbêj]]) 19:03, 7 çiriya pêşîn 2020 (UTC) == [[şequdeq]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 08:50, 9 çiriya pêşîn 2020 (UTC) == [[helizandin]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 11:23, 9 çiriya pêşîn 2020 (UTC) == [[rewastin]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 11:48, 9 çiriya pêşîn 2020 (UTC) == [[xunaftin]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 12:31, 9 çiriya pêşîn 2020 (UTC) == [[itîmad li ser kirin]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Guherto|Guherto]] ([[Gotûbêja bikarhêner:Guherto|gotûbêj]]) 16:32, 15 çiriya pêşîn 2020 (UTC) == [[sengesor]] == {{r|Saberabdollahizad}} ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 22:00, 16 çiriya pêşîn 2020 (UTC) :Navçeya Mirgewerê, Ûrmîye. {{bêîmze|Saberabdollahizad}} == [[zenek]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 22:03, 16 çiriya pêşîn 2020 (UTC) :{{r|Saberabdollahizad}} [[zenek]] jî li Ûrmiyê tê bikaranîn? --[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 19:53, 18 çiriya pêşîn 2020 (UTC) == [[pind#p-mane|pind]] == Min tenê çavkaniyek dît ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 18:48, 17 çiriya pêşîn 2020 (UTC) :Navçeya Mirgewerê, Ûrmîye. {{bêîmze|Saberabdollahizad}} == [[maqezer]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 18:53, 18 çiriya pêşîn 2020 (UTC) :Navçeya Mirgewerê, Ûrmîye. {{bêîmze|Saberabdollahizad}} == [[pezpezok]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 18:55, 18 çiriya pêşîn 2020 (UTC) :Navçeya Mirgewerê, Ûrmîye. {{bêîmze|Saberabdollahizad}} == [[parapet#p-mane|parapet]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 13:53, 31 çiriya pêşîn 2020 (UTC) = Çiriya paşîn 2020 = == [[quloç#p-mane|quloç]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 17:43, 19 çiriya paşîn 2020 (UTC) == [[di ber (yekî) de avêtin]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 16:57, 20 çiriya paşîn 2020 (UTC) :https://tirsik.net/index.php?mijarid=18749&iro=on&rupel=1 —[[Bikarhêner:Mamoste Dilovan|Mamoste Dilovan]] ([[Gotûbêja bikarhêner:Mamoste Dilovan|gotûbêj]]) 17:37, 20 çiriya paşîn 2020 (UTC) :: {{r|Mamoste Dilovan}} [[di ber re avêtin]] heye. lê te wek di ber '''de''' lê zêde kir. Em biguherînin? Gelek çavkanî ji bo di ber re avêtin heye. --[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 17:41, 20 çiriya paşîn 2020 (UTC) == [[hêvastin]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 10:49, 21 çiriya paşîn 2020 (UTC) == [[lamçîn]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 11:28, 22 çiriya paşîn 2020 (UTC) == [[poz#p-mane|poz]] == Ji bo maneya "[[quz]], [[vajîna]]" ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 11:28, 22 çiriya paşîn 2020 (UTC) == [[sihetbexş]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 16:35, 24 çiriya paşîn 2020 (UTC) == [[hevjêhatin ji jêhatîbûnê çêtir e]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 12:14, 25 çiriya paşîn 2020 (UTC) == [[gerriyan#p-mane|gerriyan]] == ''Ji bo wateya cereyan (tevger)''. Qasî ku dibînim tenê Cewerî bi kar aniye —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 18:24, 25 çiriya paşîn 2020 (UTC) == [[derbend]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 12:08, 30 çiriya paşîn 2020 (UTC) = Kanûna paşîn 2021 = == [[desthelgirtin]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 08:48, 6 kanûna paşîn 2021 (UTC) == [[êşewî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 12:52, 7 kanûna paşîn 2021 (UTC) == [[sexorr]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 20:22, 7 kanûna paşîn 2021 (UTC) == [[sapût]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 22:06, 12 kanûna paşîn 2021 (UTC) == <s>[[dimorî]]</s> == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' Maneya navdêrî bêçavkanî ye. — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 15:05, 20 kanûna paşîn 2021 (UTC) :{{nepeyitandî}}--[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 14:18, 26 hezîran 2026 (UTC) :Di Kovara kurmancî hj.67 de "dimor" bi maneya "bêoxir" de derbas dibe. Wekî din ti çavkanî nîne. Merheba @[[Bikarhêner:Gomada|Gomada]] te varyanta "dimhorî" îlawe kiriye. Gelo tu dizanî ev kelîme li kîjan herêman tê bikaranîn? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 14:18, 26 hezîran 2026 (UTC) = Çiriya pêşîn 2022 = == [[paşbingeh]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 07:40, 12 çiriya pêşîn 2022 (UTC) = Kanûna paşîn 2023 = == [[berê beringa]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 21:35, 1 kanûna paşîn 2023 (UTC) == [[mûlûleya xwînê]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 16:36, 6 kanûna paşîn 2023 (UTC) == [[mirovdostî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 05:38, 12 kanûna paşîn 2023 (UTC) == [[derîner]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 23:02, 15 kanûna paşîn 2023 (UTC) == [[neteba]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 00:01, 16 kanûna paşîn 2023 (UTC) :Maneya "uyruksuz" ji ferhenga Farqînî hatiye kopîkirin wekî din bi giştî bi maneya "nakokî" tê bikaranîn. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 14:33, 26 hezîran 2026 (UTC) == [[narkotîkfiroş]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 10:59, 16 kanûna paşîn 2023 (UTC) == [[pirik#p-mane|pirik]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 18:15, 16 kanûna paşîn 2023 (UTC) == [[ramyarî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' Ez dibêjim ev peyv tenê bi maneya "fikrî", wek rengdêr heye. Lê belê di soranî de bi şaşemilandineke wekî "siyasî" bi kar anîne, kurmancên me jî rasterast maneya soranî tevlî çend ferhengên hev-kopîkirî kirine û bi vî awayî belkî hin çavkanî hebin. Lê ez dibêjim divê ew çavkanî jî neyên hesibandin. Hin kes zen dikin ku her tiştê di soranî de ripîrast e. Mesele heqeten eletewş e. Agahiyeke li ser peyvê: "[https://www.welateme.info/kurdi/modules.php?name=News&file=print&sid=686 Welateme.info]" Li vir peyv bi maneya "fikrî" hatiye bikaranîn: "[https://xwebun1.org/ziman-sirhelal-e/ Xwebûn]". Qewet be. — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 22:36, 19 kanûna paşîn 2023 (UTC) == [[dolîwgeh]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 21:08, 22 kanûna paşîn 2023 (UTC) = Sibat 2023 = == [[herebaş]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 15:13, 11 sibat 2023 (UTC) == [[balindeyê korare]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' Tenê çavkaniyekê tê xuyan, ew jî kitêba "Balindeyên Kurdistanê" yê Îsmaîl Taha Şahîn e (Îsmaîl Taha Şahîn (2006). Balindeyên Kurdistanê, 1-4. Spîrêz, Duhok). Ev kitêb ji ser înternetê wek word jî peyda dibe. Xuya ye ku ji Weşanên Spîrez fîzîken jî çap bûye. Lê wekî çavkanî tenê ev tê xuyan. —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 17:10, 14 sibat 2023 (UTC) == [[dîbeyt]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 10:13, 18 sibat 2023 (UTC) == [[çend pat]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 09:35, 24 sibat 2023 (UTC) == [[rabînîn]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' Ji bo kurmancî bêçavkanî ye. Ger ji bo soranî çavkanî hebin jî divê ji bo soranî bi herfên aramî were nivîsîn. An ger halê latînîkirî ya peyveke soranî be, dîsa divê ev hal were eşkerekirin. — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 13:36, 26 sibat 2023 (UTC) = Adar 2023 = == [[qirar#p-mane|qirar]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 09:23, 2 adar 2023 (UTC) == [[pîşpêkirin]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' Tenê di nivîseke online ya Cemal Nebez de derbas dibe. Dibe ku peyveke başûriyan be. Û di wê nivîsa Cemal Nebezê bi forma "pîş bi ... bikin" jî derbas dibe. — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 16:29, 3 adar 2023 (UTC) == [[kûcag]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 01:27, 27 adar 2023 (UTC) == [[destbizavî kirin]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' Xuya ye ku ev peyv tenê di kitêba “''Nameyek Şernexê''” yê Evdirehman Gundikî de derbas bûye. Û ji wir jî Mistefa Aydoganî maneya peyvê di hejmara 61em ya Kovara ''Kurmancî'' de belav kiriye (rûpela 2yem). Lê belê tenê yek çavkaniyekê ne bes e ji bo ku em vê peyvê di vê ferhengê de wekî peyveke çavkanî-temam belav bikin. — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 09:40, 28 adar 2023 (UTC) == [[germav baş]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 18:23, 31 adar 2023 (UTC) == [[germavxweş]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 18:27, 31 adar 2023 (UTC) = Gulan 2023 = == [[kirbend]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 08:34, 5 gulan 2023 (UTC) : Çêkerê rûpelê wek not nivîsiye ku peyv ji herêma Çewlikê ye. -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 06:24, 6 gulan 2023 (UTC) == [[We are off now]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 14:13, 22 gulan 2023 (UTC) == [[baran ji erd û esmana lê diket]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 22:46, 26 gulan 2023 (UTC) == [[sîba]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 15:44, 30 gulan 2023 (UTC) == [[bîrîner]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 17:20, 30 gulan 2023 (UTC) = Hezîran 2023 = == [[bidestmiz]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 16:49, 10 hezîran 2023 (UTC) = Tîrmeh 2023 = == [[parzeng]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 14:01, 15 tîrmeh 2023 (UTC) == [[zerpedest]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 14:05, 15 tîrmeh 2023 (UTC) == [[heta destên mirov nebine gû, devê mirov nabite tû]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 15:27, 19 tîrmeh 2023 (UTC) == [[çemê mezin tê dibore diçe]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 15:38, 19 tîrmeh 2023 (UTC) == [[kevanê nebî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 15:45, 19 tîrmeh 2023 (UTC) == [[teybûr]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' Tenê li malpera yuksekovahaber.com-ê derbas dibe, li wir jî bi maneya "çare, çareserî"yê hatiye emilandin, ne bi vê maneyê. — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 16:00, 19 tîrmeh 2023 (UTC) == [[nikêtî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 16:22, 19 tîrmeh 2023 (UTC) = Tebax 2023 = == [[prêze]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 21:19, 15 tebax 2023 (UTC) == [[qelye]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 15:59, 25 tebax 2023 (UTC) = Îlon 2023 = == [[hetwan]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 20:21, 14 îlon 2023 (UTC) == [[milyonmasî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 14:06, 21 îlon 2023 (UTC) == [[tofana mêjî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 14:20, 21 îlon 2023 (UTC) == [[îshaf]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 10:57, 23 îlon 2023 (UTC) == [[odeya karkirinê]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 10:57, 26 îlon 2023 (UTC) == [[odeya şixulînê]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 11:42, 26 îlon 2023 (UTC) == [[hîter]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 12:08, 26 îlon 2023 (UTC) = Çiriya pêşîn 2023 = == [[vîtamîn waw]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 20:20, 1 çiriya pêşîn 2023 (UTC) == [[berhan]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 14:21, 3 çiriya pêşîn 2023 (UTC) == [[sêlikdêr]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 19:16, 10 çiriya pêşîn 2023 (UTC) == [[qewandêr]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 19:20, 10 çiriya pêşîn 2023 (UTC) == [[darav]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 20:04, 11 çiriya pêşîn 2023 (UTC) = Çiriya paşîn 2023 = == [[kansernasî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 17:54, 14 çiriya paşîn 2023 (UTC) == [[golgir]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 16:06, 15 çiriya paşîn 2023 (UTC) == [[gogpî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 16:19, 15 çiriya paşîn 2023 (UTC) == [[ahardar]] == Tenê Zana Farqînî —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 10:34, 26 çiriya paşîn 2023 (UTC) = Kanûna pêşîn 2023 = == [[Kî mal ezîz bike, can rezîl dike&#59; kî mal rezîl bike, can ezîz dike.]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 13:55, 2 kanûna pêşîn 2023 (UTC) == [[porsing]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 14:22, 2 kanûna pêşîn 2023 (UTC) == [[newelatî kirin]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 16:57, 2 kanûna pêşîn 2023 (UTC) == [[newelatîkirin]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 16:58, 2 kanûna pêşîn 2023 (UTC) == [[alîkar kirin]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Şêr|Şêr]] ([[Gotûbêja bikarhêner:Şêr|gotûbêj]]) 18:42, 3 kanûna pêşîn 2023 (UTC) == [[aramoş kirin]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]]'' -- [[Bikarhêner:Şêr|Şêr]] ([[Gotûbêja bikarhêner:Şêr|gotûbêj]]) 18:48, 3 kanûna pêşîn 2023 (UTC) == [[bêvil kirin]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Şêr|Şêr]] ([[Gotûbêja bikarhêner:Şêr|gotûbêj]]) 18:56, 4 kanûna pêşîn 2023 (UTC) == [[dijberiya naverokî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Şêr|Şêr]] ([[Gotûbêja bikarhêner:Şêr|gotûbêj]]) 22:43, 8 kanûna pêşîn 2023 (UTC) == [[bersivîn]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]]'', û her wiha ne li gorî qayideyên kurdî (kurmancî) ye. —[[Bikarhêner:Şêr|Şêr]] ([[Gotûbêja bikarhêner:Şêr|gotûbêj]]) 22:08, 11 kanûna pêşîn 2023 (UTC) == [[girêbanasî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 20:30, 13 kanûna pêşîn 2023 (UTC) == [[hevalzewac]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 17:25, 18 kanûna pêşîn 2023 (UTC) = Kanûna paşîn 2024 = == [[raperk]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 13:40, 15 kanûna paşîn 2024 (UTC) :Bi wê manê nîne. Bi maneke dî heye. [[Bikarhêner:Guherto|Guherto]] ([[Gotûbêja bikarhêner:Guherto|gotûbêj]]) 19:26, 6 tebax 2024 (UTC) = Sibat 2024 = == [[bi navê lîstin]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 21:02, 3 sibat 2024 (UTC) : Li ser agahdarkirina çêkerê rûpelê me şablona "dever"ê tevlî kir. Peyv ji herêma Qoser, Mêrdînê ye. Me li qismê "Bikaranîn"ê jî vê yekê dîyar kir. Ji xeynî vê me wê peyvê ji rûpelên din jî bir. Bi vî awayî ev made kare were girtin. -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 13:28, 10 nîsan 2024 (UTC) == [[firoşgehkar]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 19:17, 9 sibat 2024 (UTC) == [[preskirin]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 00:43, 11 sibat 2024 (UTC) == [[pres kirin]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 00:43, 11 sibat 2024 (UTC) == [[Xwedê te têr bike]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 22:41, 13 sibat 2024 (UTC) == [[isad]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 22:09, 22 sibat 2024 (UTC) == [[razemendîtî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 18:44, 27 sibat 2024 (UTC) = Adar 2024 = == [[zilhêzî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 23:19, 5 adar 2024 (UTC) == [[hingihîn]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 21:32, 13 adar 2024 (UTC) == [[xore]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 13:30, 15 adar 2024 (UTC) == [[melef]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 13:55, 19 adar 2024 (UTC) == [[uğursuz ayak]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 10:11, 23 adar 2024 (UTC) == [[şepûk]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 10:22, 23 adar 2024 (UTC) == [[agirberdêrî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 00:04, 26 adar 2024 (UTC) == [[kîrquz]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 10:00, 26 adar 2024 (UTC) == [[kîrquzdê]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 10:01, 26 adar 2024 (UTC) == [[quzgêj]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 10:03, 26 adar 2024 (UTC) = Nîsan 2024 = == [[hîkarîkerî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 08:53, 1 nîsan 2024 (UTC) == [[hîkarîker]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 08:54, 1 nîsan 2024 (UTC) == [[hîkarîdarî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 08:55, 1 nîsan 2024 (UTC) == [[hîkarîdar]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 08:56, 1 nîsan 2024 (UTC) == [[bihîkarîtî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 08:57, 1 nîsan 2024 (UTC) == [[bihîkarî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 08:58, 1 nîsan 2024 (UTC) == [[bêhîkarîtî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 08:58, 1 nîsan 2024 (UTC) == [[bêhîkarî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 08:59, 1 nîsan 2024 (UTC) == [[bêhîkarî bûn]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 09:00, 1 nîsan 2024 (UTC) == [[bêhîkarî kirin]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 09:00, 1 nîsan 2024 (UTC) == [[bêhîkarîbûn]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 09:01, 1 nîsan 2024 (UTC) == [[bêhîkarîkirin]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 09:01, 1 nîsan 2024 (UTC) == [[hîkarîkirî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 09:02, 1 nîsan 2024 (UTC) == [[hîkarîkirin]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 09:03, 1 nîsan 2024 (UTC) == [[hîkarî kirin]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 09:07, 1 nîsan 2024 (UTC) == [[rayda]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 09:40, 1 nîsan 2024 (UTC) == [[bêrayda]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 09:42, 1 nîsan 2024 (UTC) == [[bêraydayî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 09:43, 1 nîsan 2024 (UTC) == [[bêraydatî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 09:43, 1 nîsan 2024 (UTC) == [[bêrayda bûn]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 09:43, 1 nîsan 2024 (UTC) == [[bêrayda kirin]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 09:43, 1 nîsan 2024 (UTC) == [[bêraydabûn]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 09:44, 1 nîsan 2024 (UTC) == [[bêraydakirin]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 09:44, 1 nîsan 2024 (UTC) == [[birayda]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 09:44, 1 nîsan 2024 (UTC) == [[biwerêç]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 09:46, 1 nîsan 2024 (UTC) == [[biwerêçî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 09:46, 1 nîsan 2024 (UTC) == [[biwerêçîtî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 09:47, 1 nîsan 2024 (UTC) == [[biwerêçtî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 09:47, 1 nîsan 2024 (UTC) == [[werêç]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 09:49, 1 nîsan 2024 (UTC) == [[werêç kirin]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 09:50, 1 nîsan 2024 (UTC) == [[werêçkirî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 09:50, 1 nîsan 2024 (UTC) == [[werêçkirin]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 09:51, 1 nîsan 2024 (UTC) == [[wişto]] == @[[Bikarhêner:Zerwanda]] Çavkanî ji bo kurmancî tine ye. Zazakî ye? —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 20:19, 1 nîsan 2024 (UTC) :ji devera mûşê, aliyê diya min "wişto/wiştik" digotin. [[Bikarhêner:Zerwanda|Zerwanda]] ([[Gotûbêja bikarhêner:Zerwanda|gotûbêj]]) 20:44, 1 nîsan 2024 (UTC) == [[xewgerî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 10:19, 2 nîsan 2024 (UTC) == [[xewgerokî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 10:28, 2 nîsan 2024 (UTC) == [[nimêh]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 15:51, 2 nîsan 2024 (UTC) == [[فعال]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' [[Bikarhêner:Ghybu|Gyhbu]] di 2021an de li ser rûpela wî tevlî kirîye. Lê ji ber nebûna vê sîstema me tevlî vir nebûye. Lewma min anî ser vir jî. Wê gavê tenê ji bo maneya "kar" ev şablon hatîye tevlîkirin. — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 07:27, 3 nîsan 2024 (UTC) == [[pêjor]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 21:46, 6 nîsan 2024 (UTC) == [[hafil]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 21:48, 6 nîsan 2024 (UTC) == [[micemi]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' Muhtemelem şiklê rast wek "micemî" ye, lê ew jî bêçavkanî ye. — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 11:52, 9 nîsan 2024 (UTC) == [[hesaba xwe]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' Ji xeynî van ev forma wê jî bêçavkanî ne: "[[hisaba xwe]] / [[hesaba xo]] / [[hisaba xo]]". — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 13:25, 9 nîsan 2024 (UTC) == [[leşkerma]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 22:53, 24 nîsan 2024 (UTC) = Gulan 2024 = == [[serîi]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' Wek "serî" belkî li kar be, lê wekî "serîi" çavkanî peyda nabe. — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 16:20, 2 gulan 2024 (UTC) == [[virgu]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' Bêçavkanî tê xuyan. Peyv bi tirkî ye. — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 18:49, 2 gulan 2024 (UTC) == [[xwerre]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 18:57, 20 gulan 2024 (UTC) = Hezîran 2024 = == [[di nav deryaya peyvan de avjenî dikir]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 17:34, 4 hezîran 2024 (UTC) == [[berbixwe]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 09:03, 10 hezîran 2024 (UTC) == [[şipyakî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 09:08, 10 hezîran 2024 (UTC) :"şipêkî" heye [[Bikarhêner:Guherto|Guherto]] ([[Gotûbêja bikarhêner:Guherto|gotûbêj]]) 20:20, 27 tîrmeh 2024 (UTC) == [[wetalane]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 09:18, 10 hezîran 2024 (UTC) == [[wetalî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 09:19, 10 hezîran 2024 (UTC) == [[wetalîtî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 09:20, 10 hezîran 2024 (UTC) == [[wetaltî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 09:20, 10 hezîran 2024 (UTC) == [[se direye karwan dibuhire]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 14:49, 16 hezîran 2024 (UTC) == [[se direwît, karwan bi rêka xo diçît]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' Formeke bêçavkanî ye. — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 14:53, 16 hezîran 2024 (UTC) == [[se direwît, karwan diburît]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' Formeke bêçavkanî ye. — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 14:54, 16 hezîran 2024 (UTC) == [[se direyê karwan dibûrê]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' Formeke bêçavkanî ye. — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 14:55, 16 hezîran 2024 (UTC) == [[se direye karvan li riya xwe diçe]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' Formeke bêçavkanî ye. — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 14:56, 16 hezîran 2024 (UTC) == [[se direye û kerwan dibihure]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' Formeke bêçavkanî ye. — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 15:00, 16 hezîran 2024 (UTC) == [[hingê dinya]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 14:07, 18 hezîran 2024 (UTC) == [[berdanberdan]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 21:22, 24 hezîran 2024 (UTC) == [[nîska mala Barzan]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 08:05, 25 hezîran 2024 (UTC) = Tîrmeh 2024 = == [[avmêwe]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 17:41, 16 tîrmeh 2024 (UTC) == [[nihalok]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 21:53, 24 tîrmeh 2024 (UTC) == [[nihalk]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 21:54, 24 tîrmeh 2024 (UTC) == [[niwalok]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 21:54, 24 tîrmeh 2024 (UTC) == [[niwalk]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 21:55, 24 tîrmeh 2024 (UTC) == [[niwalik]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 21:55, 24 tîrmeh 2024 (UTC) == [[nehalok]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 21:56, 24 tîrmeh 2024 (UTC) == [[nehalk]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 21:56, 24 tîrmeh 2024 (UTC) == [[nehalik]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 21:57, 24 tîrmeh 2024 (UTC) == [[alîkarxwazî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 22:16, 24 tîrmeh 2024 (UTC) == [[nihalik]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 22:19, 24 tîrmeh 2024 (UTC) == [[zêrîb]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' Bi dîtina min, ev form bêçavkanî ye. Dibe ku ji bo forma "zerîb" çavkanî hebe, lê ew form li ser Wîkîferhengê wek made nehatîye çêkirin. Pir kêm be jî ev peyv wek "zerîp" jî li cihekî derbas bûye. — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 22:31, 24 tîrmeh 2024 (UTC) == [[qanat]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' Ev peyv bi maneya "kanal"ê nîne, xelet e. — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 06:59, 25 tîrmeh 2024 (UTC) == [[qenat]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' Ev peyv bi maneya "kanal"ê nîne, xelet e. — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 06:59, 25 tîrmeh 2024 (UTC) :Min 1 çavkanî dît, "Ev kes rojê 6-7 qenatên TV ya diğere û diaxive" https://darkamazi.info/archives/1019704 (bi lêgerana "qenatên", ji ber ko lêgeranên dî tijî tiştên dî derdixin) :Lê mimkun e xelet nivîsîbe. [[Bikarhêner:Guherto|Guherto]] ([[Gotûbêja bikarhêner:Guherto|gotûbêj]]) 20:31, 27 tîrmeh 2024 (UTC) == [[şkaftmend]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 07:08, 25 tîrmeh 2024 (UTC) :3 çavkanî hene. Lê xuya dike jêdera wan hemû ferhenga tirsik.netê e. :* Çavkanî 1: https://tirsik.net/ferheng?query=şkaftmend (berî 2014, lê tarîx nîne) :* Çavkanî 2: https://ku.wikipedia.org/wiki/Deranderî (2011) :* Çavkanî 3: https://x.com/zerdeceno/status/1155331427510247425 (2019) :[[Bikarhêner:Guherto|Guherto]] ([[Gotûbêja bikarhêner:Guherto|gotûbêj]]) 20:28, 27 tîrmeh 2024 (UTC) == [[dan hev#p-mane|dan hev]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' Ev mane li ser çavkanîyan peyda nabe. Tenê çêkerê rûpelê vê maneyê nivîsîye. — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 11:08, 25 tîrmeh 2024 (UTC) == [[baristdar]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 14:47, 25 tîrmeh 2024 (UTC) == [[baristdarî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 14:48, 25 tîrmeh 2024 (UTC) == [[baristdarîtî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 14:49, 25 tîrmeh 2024 (UTC) == [[baristdartî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 14:50, 25 tîrmeh 2024 (UTC) == [[bibaristî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 14:51, 25 tîrmeh 2024 (UTC) == [[bibarist]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 14:52, 25 tîrmeh 2024 (UTC) == [[bibaristîtî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 14:53, 25 tîrmeh 2024 (UTC) == [[bêbaristî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 14:54, 25 tîrmeh 2024 (UTC) == [[bêbarist]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 14:55, 25 tîrmeh 2024 (UTC) == [[peydabûnîtî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Guherto|Guherto]] ([[Gotûbêja bikarhêner:Guherto|gotûbêj]]) 20:52, 27 tîrmeh 2024 (UTC) == [[nexşvan]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Guherto|Guherto]] ([[Gotûbêja bikarhêner:Guherto|gotûbêj]]) 21:05, 27 tîrmeh 2024 (UTC) == [[nexşvanî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Guherto|Guherto]] ([[Gotûbêja bikarhêner:Guherto|gotûbêj]]) 21:05, 27 tîrmeh 2024 (UTC) == [[lêvikî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Guherto|Guherto]] ([[Gotûbêja bikarhêner:Guherto|gotûbêj]]) 21:47, 27 tîrmeh 2024 (UTC) == [[lêvik]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' Min zêde nemeyzand. —[[Bikarhêner:Guherto|Guherto]] ([[Gotûbêja bikarhêner:Guherto|gotûbêj]]) 21:48, 27 tîrmeh 2024 (UTC) == [[şerenîx kirin]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Guherto|Guherto]] ([[Gotûbêja bikarhêner:Guherto|gotûbêj]]) 21:51, 27 tîrmeh 2024 (UTC) == [[sala çîn]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 16:09, 29 tîrmeh 2024 (UTC) == [[berê pêşîn]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 17:57, 30 tîrmeh 2024 (UTC) == [[berê ewilî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 17:57, 30 tîrmeh 2024 (UTC) = Tebax 2024 = == [[xwîndijmin]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 18:02, 4 tebax 2024 (UTC) == [[reîsîtî]]/[[reysîtî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Guherto|Guherto]] ([[Gotûbêja bikarhêner:Guherto|gotûbêj]]) 18:17, 6 tebax 2024 (UTC) == [[soranîaxivî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Guherto|Guherto]] ([[Gotûbêja bikarhêner:Guherto|gotûbêj]]) 18:43, 6 tebax 2024 (UTC) == [[helîna bildo]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' Ji 2020a ve şablon li wir e min tenê li vir zêde kir. —[[Bikarhêner:Guherto|Guherto]] ([[Gotûbêja bikarhêner:Guherto|gotûbêj]]) 19:56, 6 tebax 2024 (UTC) == [[hilbijêrînerî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' "Hilbij" rihê peyvê ye, "-er" jî maneya "kesê dike" dide, qertafa "-îner / -înerî" ya li dawîyê bi eşkereyî xelet e. Û ev peyv bêçavkanî ye. — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 13:45, 7 tebax 2024 (UTC) == [[îqlîmtî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 13:43, 10 tebax 2024 (UTC) == [[jîrbêjî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' Ev peyv ger di soranî de ji bo wê çavkanîyên têr hebe, tenê wek "Nivîsîna bi herfên latînî ya peyva ..." kare were qeydkirin. Lê nabe ku wek kurmancî be, were qeydkirin. Ji bo kurmancî tenê di meqaleyekê de derbas dibe, ew jî ji alî başûrîyekî ve hatîye nivîsîn. — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 19:55, 10 tebax 2024 (UTC) == [[hîgyen]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' Tenê ev form bêçavkanî ye. — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 07:40, 12 tebax 2024 (UTC) == [[kolîner]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 17:45, 12 tebax 2024 (UTC) == [[poşmanî kişîn]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' Tenê di çavkanîyekê de peyda dibe. Ew çavkanîya dayî jî ihtîmal e ku bi tesîra zimanê tirkî ye. — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 08:44, 13 tebax 2024 (UTC) == [[para hevpar a herî mezin]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 16:09, 14 tebax 2024 (UTC) == [[cara hevpar a herî biçûk]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 16:10, 14 tebax 2024 (UTC) == [[regjimar]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 16:16, 14 tebax 2024 (UTC) == [[nîvrengî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Guherto|Guherto]] ([[Gotûbêja bikarhêner:Guherto|gotûbêj]]) 17:33, 18 tebax 2024 (UTC) == [[nîvdûrgeh]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' Wek "guharto" hatiye qeydkirin, lê yek nikare wilo bêje. Ne "guharto" ye, ji ber wê çavkanî hewce ne. —[[Bikarhêner:Guherto|Guherto]] ([[Gotûbêja bikarhêner:Guherto|gotûbêj]]) 17:39, 18 tebax 2024 (UTC) == [[nîvtewlîsî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Guherto|Guherto]] ([[Gotûbêja bikarhêner:Guherto|gotûbêj]]) 17:44, 18 tebax 2024 (UTC) == [[nîvrewa]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Guherto|Guherto]] ([[Gotûbêja bikarhêner:Guherto|gotûbêj]]) 17:44, 18 tebax 2024 (UTC) == [[nîvşehtî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Guherto|Guherto]] ([[Gotûbêja bikarhêner:Guherto|gotûbêj]]) 17:46, 18 tebax 2024 (UTC) == [[nîvfalincî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Guherto|Guherto]] ([[Gotûbêja bikarhêner:Guherto|gotûbêj]]) 17:46, 18 tebax 2024 (UTC) == [[nîvgilkarî]] == Ferhenga Sa.Sa. ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Guherto|Guherto]] ([[Gotûbêja bikarhêner:Guherto|gotûbêj]]) 17:48, 18 tebax 2024 (UTC) == [[kesîkirin]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Guherto|Guherto]] ([[Gotûbêja bikarhêner:Guherto|gotûbêj]]) 20:16, 18 tebax 2024 (UTC) == [[biryarbirin]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 21:38, 24 tebax 2024 (UTC) = Îlon 2024 = == [[qîblename]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Guherto|Guherto]] ([[Gotûbêja bikarhêner:Guherto|gotûbêj]]) 15:15, 1 îlon 2024 (UTC) == [[cihetnima]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' Ji [https://bianet.org/yazi/ferhenga-ser-u-amrazen-ser-ji-kovara-ronahiye-2-196299 vir] hatiye —[[Bikarhêner:Guherto|Guherto]] ([[Gotûbêja bikarhêner:Guherto|gotûbêj]]) 15:27, 1 îlon 2024 (UTC) == [[qûnderîtî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 15:36, 7 îlon 2024 (UTC) == [[hevpîşehî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 17:48, 14 îlon 2024 (UTC) == [[hevpîşeyî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' Wek ''navdêr'' bêçavkanî ye. Wek ''rengdêr'' hebe jî, kêmçavkanî ye. — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 17:50, 14 îlon 2024 (UTC) == [[hempay]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 18:04, 14 îlon 2024 (UTC) == [[nîs]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 19:43, 14 îlon 2024 (UTC) == [[êxbarçî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' Ji bo ''îxbarçî'' çavkanîyekê peyda dibe, lê kêm e. — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 23:06, 14 îlon 2024 (UTC) == [[muxbîrîtî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 23:38, 14 îlon 2024 (UTC) == [[ixbarçî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 23:43, 14 îlon 2024 (UTC) == [[westgeha pasê]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 16:33, 19 îlon 2024 (UTC) == [[avikmadk]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 17:24, 19 îlon 2024 (UTC) == [[ferwerîn]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 09:18, 20 îlon 2024 (UTC) == [[bipayderî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 11:12, 20 îlon 2024 (UTC) == [[bipayderîtî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 11:13, 20 îlon 2024 (UTC) == [[bipaydertî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 11:13, 20 îlon 2024 (UTC) == [[bipedalî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 11:14, 20 îlon 2024 (UTC) == [[bipedalîtî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 11:14, 20 îlon 2024 (UTC) == [[bipedaltî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 11:14, 20 îlon 2024 (UTC) == [[pedaldarî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 11:15, 20 îlon 2024 (UTC) == [[pedaldarîtî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 11:15, 20 îlon 2024 (UTC) == [[pedaldartî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 11:16, 20 îlon 2024 (UTC) == [[ciwên]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 16:11, 22 îlon 2024 (UTC) == [[belgebirin]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 22:31, 23 îlon 2024 (UTC) == [[avsîn]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' Dibe ku ev kelîme biçavkanî be, lê pir bêagahî hatîye qeydkirin. Biçavkanî be jî, ji ber qeydkirina bêagahî (li ser madeyê agahî kêm hatine pêşkêşkirin) em rûpelê jê bibin. — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 22:53, 23 îlon 2024 (UTC) :@[[Bikarhêner:Bikarhêner|Bikarhêner]] Ma ne çêtir e li "Daxwazên zelalkirinê" be naxwe? [[Bikarhêner:Guherto|Guherto]] ([[Gotûbêja bikarhêner:Guherto|gotûbêj]]) 13:40, 10 çiriya paşîn 2024 (UTC) :: {{r|Guherto}} Bi min em karin vê madeyê ji ber bêagahîbûna wî, îlaweyî "Daxwazên jêbirinê" bikin, lê "Daxwazên zelalkirinê" nabe. Wekî din ji ber ku dikeve çarçoveya her du rûpelan jî kîjan be jî dibe, lê madem me li vir da destpêkirin, bila ji vir dewam bike dengdana li ser vê kelîmeyê. -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 21:22, 10 çiriya paşîn 2024 (UTC) == [[kûvank]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' Herçiqas tenê formekê be jî, bêçavkanî ye. — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 21:14, 27 îlon 2024 (UTC) == [[kikark]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' Herçiqas formekê be jî, bêçavkanî dixuye. — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 21:40, 27 îlon 2024 (UTC) == [[kîfkarik]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' Herçiqas tenê formekê be jî, bêçavkanî dixuye. — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 21:45, 27 îlon 2024 (UTC) == [[kuvank]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' Herçiqas formekê be jî, bêçavkanî dixuye. — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 21:53, 27 îlon 2024 (UTC) == [[kûvarik]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' Herçiqas tenê formekê be jî, bêçavkanî dixuye. — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 22:01, 27 îlon 2024 (UTC) = Çiriya pêşîn 2024 = == [[muhil]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' Tenê qismê kurdî bêçavkanî ye, ne ya tirkî. — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 21:00, 9 çiriya pêşîn 2024 (UTC) == [[muhilk]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 21:00, 9 çiriya pêşîn 2024 (UTC) == [[jêrmal]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 21:59, 15 çiriya pêşîn 2024 (UTC) = Çiriya paşîn 2024 = == [[bîrxistiner]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 19:38, 14 çiriya paşîn 2024 (UTC) == [[wisa gotin]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' Ne ferhengî ye. — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 20:13, 15 çiriya paşîn 2024 (UTC) == [[tenzîlatî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 16:12, 16 çiriya paşîn 2024 (UTC) == [[armancparêz]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 13:03, 19 çiriya paşîn 2024 (UTC) == [[şikaftmend]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 13:06, 19 çiriya paşîn 2024 (UTC) == [[derander]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 13:08, 19 çiriya paşîn 2024 (UTC) == [[deranderî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 13:09, 19 çiriya paşîn 2024 (UTC) == [[derxwenîn]] == @[[User:Keyomerd]] ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 22:38, 19 çiriya paşîn 2024 (UTC) == [[kiyû]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 23:53, 22 çiriya paşîn 2024 (UTC) == [[goçavik]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 00:03, 23 çiriya paşîn 2024 (UTC) == [[hûrhesibaner]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 00:19, 23 çiriya paşîn 2024 (UTC) == [[heybera zindî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 18:01, 23 çiriya paşîn 2024 (UTC) == [[misadereker]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 12:51, 24 çiriya paşîn 2024 (UTC) == [[kêmtirkar]] == @[[Bikarhêner:Cyrus the virus|Cyrus the virus]] ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 18:11, 24 çiriya paşîn 2024 (UTC) == [[cudagir]] == @[[Bikarhêner:Cyrus the virus|Cyrus the virus]] ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 18:15, 24 çiriya paşîn 2024 (UTC) == [[qerwaşgir]] == @[[Bikarhêner:Cyrus the virus|Cyrus the virus]] ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 18:42, 24 çiriya paşîn 2024 (UTC) == [[mişkilûr]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 18:45, 24 çiriya paşîn 2024 (UTC) == [[agirbiran]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 18:54, 24 çiriya paşîn 2024 (UTC) == [[alan]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 18:55, 24 çiriya paşîn 2024 (UTC) == [[alêdû]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 18:56, 24 çiriya paşîn 2024 (UTC) == [[henaseker]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 17:37, 25 çiriya paşîn 2024 (UTC) == [[nial]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' Ji xeynî vê, maneya 2yem ya di madeya "nihal" de (navdêr 2) jî bêçavkanî ye. — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 23:46, 27 çiriya paşîn 2024 (UTC) == [[gilçim]] == @[[Bikarhêner:Roj Rewandiz|Roj Rewandiz]] ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 14:28, 29 çiriya paşîn 2024 (UTC) :Ez ji bajarê Kobaniyê me. Min ev peyv ji ser zimanê dê û dapîra xwe girt. Ez gelekî ji vê peyvê bawer im ji ber ku devoka min e. [[Bikarhêner:Roj Rewandiz|Roj Rewandiz]] ([[Gotûbêja bikarhêner:Roj Rewandiz|gotûbêj]]) 19:14, 23 kanûna pêşîn 2024 (UTC) ::@[[Bikarhêner:Roj Rewandiz|Roj Rewandiz]] Mala te ava. Ji ber ku çavkaniyên nivîskî tine ne em ê vê kelîmeyê wek [[Wîkîferheng:Pîvekên_tevlîkirinê#Peyvên_herêmî|herêmî]] nîşan bidin. [[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 12:22, 25 kanûna pêşîn 2024 (UTC) == [[reşeme kirin]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' Li gorî çêkera sayfeyê li Kobaniyê li kar e. Loma dikare wekî herêmî nîşankirin —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 14:35, 29 çiriya paşîn 2024 (UTC) :Li Kobaniyê dibêjin: ‘Tizbiyê min li xwe reş û reşeme kir’ Anko Tizbî bir û venegerand Înkar kir. [[Bikarhêner:Roj Rewandiz|Roj Rewandiz]] ([[Gotûbêja bikarhêner:Roj Rewandiz|gotûbêj]]) 23:48, 7 kanûna paşîn 2025 (UTC) = Kanûna pêşîn 2024 = == <s>[[hemderk]]</s> == @[[Bikarhêner:Ferhengvan|Ferhengvan]] ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 10:02, 1 kanûna pêşîn 2024 (UTC) :{{nepeyitandî}}--[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:30, 17 tîrmeh 2026 (UTC) == <s>[[qefesker]]</s> == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 10:23, 1 kanûna pêşîn 2024 (UTC) :{{nepeyitandî}}--[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:31, 17 tîrmeh 2026 (UTC) == <s>[[sêkunc]]</s> == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 00:17, 27 kanûna pêşîn 2024 (UTC) :Saharnews gelek bi kar tîne feqat nivîskarên wan ne belî ne, tenê ev kitêb [https://kurdistankomunistpartisi.com/wp-content/uploads/2022/03/kurdi2.pdf] derbasdar e. :{{nepeyitandî}}--[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:37, 17 tîrmeh 2026 (UTC) == <s>[[pênckunc]]</s> == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 00:20, 27 kanûna pêşîn 2024 (UTC) :{{nepeyitandî}}--[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:37, 17 tîrmeh 2026 (UTC) == [[çarkunc]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 00:21, 27 kanûna pêşîn 2024 (UTC) == <s>[[şeşkunc]]</s> == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 00:21, 27 kanûna pêşîn 2024 (UTC) :{{nepeyitandî}}--[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:38, 17 tîrmeh 2026 (UTC) = Kanûna paşîn 2025 = == <s>[[oktopod]]</s> == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' Ji bo vê formê ti çavkanî nîne. — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 15:10, 1 kanûna paşîn 2025 (UTC) :{{nepeyitandî}}--[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:41, 17 tîrmeh 2026 (UTC) == [[pevnatî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' Ev kelîme wek kurtkirina ji "bi hev nehatî" hatîye fikirîn, ihtimal e ku wek sunî hatîye çêkirin û bêçavkanî ye. — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 13:43, 6 kanûna paşîn 2025 (UTC) == [[lihevnatîbûn]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' Wek formeke "lihevnehatîbûn"ê hatîye fikirîn, lê bêçavkanî ye. — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 13:49, 6 kanûna paşîn 2025 (UTC) == <s>[[fîzîkîtî]]</s> == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 20:19, 7 kanûna paşîn 2025 (UTC) :{{nepeyitandî}}--[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:42, 17 tîrmeh 2026 (UTC) == <s>[[kobar]]</s> == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 14:59, 21 kanûna paşîn 2025 (UTC) :{{nepeyitandî}}--[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:11, 17 tîrmeh 2026 (UTC) == <s>[[werdanbar]]</s> == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 14:59, 21 kanûna paşîn 2025 (UTC) :{{nepeyitandî}}--[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:10, 17 tîrmeh 2026 (UTC) == [[Binxetê]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' Em zanin ku ji ber sînora Tirkîyeyê ku Cizîrê dike du perçe û ji parçeya binî re Binxet tê gotin ku kurd lê dijîn. Feqet min herêma Binxetê seh nekirîye, û bi tedqîqeke neberfireh jî çavkanî peyda nekir ji bo vê peyvê. Lewma bi min mahîyeta vê madeyê û qeydkirina wek "Binxetê" xelet e. Ger ji bo herêma tarîfkirî çavkanî nîn be, em vê madeyê bikin "'''Binxet'''" û tarîfa wê jî bikin "''Navê Rojavayê Kurdistanê ku li binê xeta Tirkîye - Sûrîyeyê dimîne.''" — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 00:22, 24 kanûna paşîn 2025 (UTC) == [[xirecir çêkirin]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' "''Çê''" bi maneya "''baş''" e, û "''çêkirin''" ji bo tiştên pozîtîv likar e, li nav milet jî ev wisa ye. Lewma ev xelet e. — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 20:00, 24 kanûna paşîn 2025 (UTC) == <s>[[bêonurane]]</s> == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 19:19, 26 kanûna paşîn 2025 (UTC) :{{nepeyitandî}}--[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:09, 17 tîrmeh 2026 (UTC) == <s>[[sabûnsazxane]]</s> == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' Xelet e û bêçavkanî ye. — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 19:24, 26 kanûna paşîn 2025 (UTC) :{{nepeyitandî}}--[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:08, 17 tîrmeh 2026 (UTC) == [[sîrkxane]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 19:30, 26 kanûna paşîn 2025 (UTC) == <s>[[rewanwerziş]]</s> == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 19:33, 26 kanûna paşîn 2025 (UTC) :{{nepeyitandî}}--[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:11, 17 tîrmeh 2026 (UTC) == <s>[[rewanwerzişxane]]</s> == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 19:34, 26 kanûna paşîn 2025 (UTC) :{{nepeyitandî}}--[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:12, 17 tîrmeh 2026 (UTC) == <s>[[qeşaşîrxane]]</s> == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 19:36, 26 kanûna paşîn 2025 (UTC) :{{nepeyitandî}}--[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:14, 17 tîrmeh 2026 (UTC) == <s>[[tiwaletxane]]</s> == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 19:37, 26 kanûna paşîn 2025 (UTC) :{{nepeyitandî}}--[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:14, 17 tîrmeh 2026 (UTC) == [[anînder]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' Di hin çavkanîyan de wek formeke "''der'''''anîn'''"ê hatîye qeydkirin. Lê belê çavkanîyeke eslî (ne ji kitêbên gramerê) peyda nabe ji bo vê kelîmeyê. — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 00:24, 27 kanûna paşîn 2025 (UTC) == <s>[[komherf]]</s> == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Wikihez|Wikihez]]<small><sup>'''[[Bikarhêner:Balyozxane|Balyozxane]]''' ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]])</sup></small> 20:18, 29 kanûna paşîn 2025 (UTC) :{{nepeyitandî}}--[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:16, 17 tîrmeh 2026 (UTC) == <s>[[komtîp]]</s> == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Wikihez|Wikihez]]<small><sup>'''[[Bikarhêner:Balyozxane|Balyozxane]]''' ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]])</sup></small> 20:19, 29 kanûna paşîn 2025 (UTC) :845û* Husein Muhemmed 2016 [https://zimannas.wordpress.com/2016/03/13/kurdizar-ferhenga-sorani-kurmanci-e/] :* Kovara deng [https://www.kovaradeng.com/upload/arsivpdf/Deng%20110.pdf] Mana ne alfabe ye "komtîpên « dj, kh, tch » yê, li cîyê dengên me yên ku bi « c, x, ç » yê hatine dîyarkirin de bikaranîne" :* resadcibrani.blogspot [https://resadcibrani.blogspot.com/p/lekolin.html] tarîx û nivîskar ne belî ye. :Çavkaniyên Instagram, Tiktok, Facebook nayê qebûlkirin loma: :{{nepeyitandî}}--[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:25, 17 tîrmeh 2026 (UTC) == <s>[[tîpgel]]</s> == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Wikihez|Wikihez]]<small><sup>'''[[Bikarhêner:Balyozxane|Balyozxane]]''' ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]])</sup></small> 20:19, 29 kanûna paşîn 2025 (UTC) :{{nepeyitandî}}--[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:26, 17 tîrmeh 2026 (UTC) == [[rastî nîşandan]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 18:14, 30 kanûna paşîn 2025 (UTC) = Sibat 2025 = == <s>[[bêbirî]]</s> == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' Dibe ku xeletîya botê be. — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 18:38, 1 sibat 2025 (UTC) :{{nepeyitandî}}--[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:45, 17 tîrmeh 2026 (UTC) == <s>[[soraxker]]</s> == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 17:24, 2 sibat 2025 (UTC) :{{nepeyitandî}}--[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:46, 17 tîrmeh 2026 (UTC) == <s>[[bîrdozvanî]]</s> == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 19:26, 3 sibat 2025 (UTC) :{{nepeyitandî}}--[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 17:40, 17 tîrmeh 2026 (UTC) == [[pir hindik#p-mane|pir hindik]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 22:31, 3 sibat 2025 (UTC) == <s>[[navçegir]]</s> == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 21:15, 4 sibat 2025 (UTC) : Zana farqînî ji xeynî wî çavkanî nîne, çend xeberên anonîm bi forma navçegirî heye lê ew jî têr nake. {{nepeyitandî}}--[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 17:47, 17 tîrmeh 2026 (UTC) == <s>[[baweranî]]</s> == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' Di ferhenga J. Blau ya "DICTIONNAIRE KURDE/TURC/FRANÇAIS/ANGLAIŞ KURDISH/TURKISH/FRENCH/ENGLISH DICTIONARY" (tercimeya tirkî Fethullah Kakioglu, 1991) der derbas dibe, feqet li cihên din peyda nabe. Wek etîmolojî jî dibe ku ji "bawerîanî" hatibe. — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 22:59, 5 sibat 2025 (UTC) : Ferhenga Baran Rizgar de jî heye lê çavkaniya sisêya nîne loma {{nepeyitandî}}--[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 17:53, 17 tîrmeh 2026 (UTC) == [[anteroz]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 01:19, 15 sibat 2025 (UTC) == [[veşidandin]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 21:43, 15 sibat 2025 (UTC) == [[karîwer kirin]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 02:01, 16 sibat 2025 (UTC) == [[hil girtin]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 21:06, 17 sibat 2025 (UTC) == [[wer girtin]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 21:07, 17 sibat 2025 (UTC) == [[avkûre]] == @[[Bikarhêner:Mohajeer|Mohajeer]] ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 20:36, 18 sibat 2025 (UTC) == [[derdek girtin]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 23:42, 18 sibat 2025 (UTC) == [[vekitandin]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 19:12, 21 sibat 2025 (UTC) == [[dînperist]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 01:32, 22 sibat 2025 (UTC) == [[ayînperist]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 01:33, 22 sibat 2025 (UTC) == [[ayînperistî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 01:33, 22 sibat 2025 (UTC) == [[ayînperistane]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 01:33, 22 sibat 2025 (UTC) == [[piştrastkirinbar]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 01:45, 23 sibat 2025 (UTC) == [[diyarkirinbar]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 02:08, 23 sibat 2025 (UTC) == [[hevhatî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 03:52, 1 adar 2025 (UTC) == [[kerexne]] == @[[Bikarhêner:Rojhilat|Rojhilat]] ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 15:05, 1 adar 2025 (UTC) == [[pawan#p-mane|pawan]] == Ferhenga Hejar soranî ye, ji bo maneya "cihê qedexekirî, cihê inhisarî" ji xeynî wê çavkanî heye gelo —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 20:17, 3 adar 2025 (UTC) == [[taqane]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 02:11, 6 adar 2025 (UTC) == [[gosirmetî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 23:07, 6 adar 2025 (UTC) == [[matîjêker]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 20:08, 14 adar 2025 (UTC) == [[hilewesan]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 21:14, 16 adar 2025 (UTC) == [[peydandin#p-mane|peydandin]] == Ji bo maneya [[dûre]], [[paşî]], [[piştî]] wê / wî ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 20:26, 19 adar 2025 (UTC) == [[peşar]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 20:36, 19 adar 2025 (UTC) == [[nûzaf]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:30, 20 adar 2025 (UTC) == [[deynname]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 22:08, 20 adar 2025 (UTC) == [[girtek]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 22:29, 20 adar 2025 (UTC) == [[bêşxane]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 00:25, 23 adar 2025 (UTC) == [[superleheng]] == @[[Bikarhêner:Avestaboy|Avestaboy]] ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 11:34, 23 adar 2025 (UTC) == [[goranparêz]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 21:54, 27 adar 2025 (UTC) == [[raber#p-mane|raber]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 16:09, 1 nîsan 2025 (UTC) == [[morîvanî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 20:06, 1 nîsan 2025 (UTC) == [[wevde]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 12:17, 3 nîsan 2025 (UTC) == [[şandêr]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 17:31, 3 nîsan 2025 (UTC) == [[giloverî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' Tenê li ser Ferhenga Zaravên Teknîkî û hejmara yekem ya kovara Bernamegehê derbas dibe. —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 09:10, 4 nîsan 2025 (UTC) == [[xêvjimêr]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 00:00, 12 nîsan 2025 (UTC) == [[paşekeft]] == @[[Bikarhêner:Jiyar Hesen|Jiyar Hesen]] ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 11:11, 13 nîsan 2025 (UTC) == [[paşekeft kirin]] == @[[Bikarhêner:Jiyar Hesen|Jiyar Hesen]] ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 11:12, 13 nîsan 2025 (UTC) == [[hawirkanî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 22:36, 20 nîsan 2025 (UTC) == [[hawirkan]] == @[[Bikarhêner:Ferhengvan|Ferhengvan]] ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 22:18, 21 nîsan 2025 (UTC) : Di çavkanîyeke de "''hawrikan''" (ku wek forma vê kelîmeyê hatîye nîşandayîn û wek "hevrêyan" a kurmancî ye) bi maneya "''friends''"a îngilîzî hatîye emilandin. Wekî din ti çavkanî nîne ji bo vê peyvê. Ger ev "hevrik"a kurmancî be, li vir dîsa xelet e. Bi her awayî divê were jêbirin. -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 22:28, 21 nîsan 2025 (UTC) == [[hawirkanî]] == @[[Bikarhêner:Cyrus the virus|Cyrus the virus]] ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 22:18, 21 nîsan 2025 (UTC) == [[hawirkanvanî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 22:18, 21 nîsan 2025 (UTC) == [[riberiz]] == @[[Bikarhêner:Ferhengvan|Ferhengvan]] ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 22:39, 21 nîsan 2025 (UTC) :Ez bawer im ku ev hat peyitandin. Min çavkanî di beşa gotûbêjê de dan û şablona bêçavkanîtiyê rakir. [[Bikarhêner:Ferhengvan|Ferhengvan]] ([[Gotûbêja bikarhêner:Ferhengvan|gotûbêj]]) 06:11, 25 nîsan 2025 (UTC) == [[awam]] == @[[User:Ferhengvan|Ferhengvan]] Min ev kelîme di ferhengên din de nedît. Gelo di kurmancî de tê bikaranîn? —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 21:09, 23 nîsan 2025 (UTC) :@[[Bikarhêner:Zerwanda|Zerwanda]] tu jî forma [[vam]] ya vê kelîmeyê diemilînî, gelo çavkanî ji bo wê jî heye? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 21:11, 23 nîsan 2025 (UTC) ::Min jî li vir peyda kir û dest kar anîn kir, hemin ev li guherrên dengî ên Kurmancî dihat (*ebam > *ewam > *wam > vam; wek *ebaj- > {{q|ku|vajî}}). Min gotibû qey di zarawayê kesekî da hebûye û wî bi ser va kiriye û jixwe nepêkan nîn e ku di zimên da hebe îcar rind e, nê min jî serkanî tine ji bonê. [[Bikarhêner:Zerwanda|Zerwanda]] ([[Gotûbêja bikarhêner:Zerwanda|gotûbêj]]) 21:37, 23 nîsan 2025 (UTC) :::https://bnk.institutkurde.org/images/pdf/4UVB2YMZG3.pdf :::Di vê kitêbê de bi forma wam derbas dibe 1 Wam : qerz, dên. " dîsa jî gereg 3 çavkanî hebe. :::Lê di beşa etîmolojiyê de eger em karibin zimanekî yekgirtî biemilînin, dê baştir be. Wekî din "bi vê enflasyona kelîmeyan" em nikarin ti tiştî bidin fêmkirin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 21:54, 23 nîsan 2025 (UTC) == [[arvanê hûr]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 09:48, 27 nîsan 2025 (UTC) == [[damezrak]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 13:47, 27 nîsan 2025 (UTC) == [[mezrak]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 13:49, 27 nîsan 2025 (UTC) == [[hevhemetî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 15:25, 6 gulan 2025 (UTC) == [[navhemetî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 15:25, 6 gulan 2025 (UTC) == [[entîte]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 15:08, 17 gulan 2025 (UTC) == [[agirvekujêner]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 00:35, 21 gulan 2025 (UTC) == [[progres]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 00:50, 23 gulan 2025 (UTC) == [[bûncî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 22:29, 28 gulan 2025 (UTC) == [[tasît]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 15:36, 31 gulan 2025 (UTC) == [[implîcît]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 15:37, 31 gulan 2025 (UTC) == [[hewedar]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 19:14, 31 gulan 2025 (UTC) == [[destajo]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 22:38, 31 gulan 2025 (UTC) == [[binhimbank]] == @[[Bikarhêner:Ferhengvan|Ferhengvan]] ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 01:23, 1 hezîran 2025 (UTC) == [[şîmane]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 23:31, 2 hezîran 2025 (UTC) == [[materya]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 16:12, 5 hezîran 2025 (UTC) == [[bêtî]] == @[[Bikarhêner:Ferhengvan|Ferhengvan]] ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 13:03, 7 hezîran 2025 (UTC) == [[rîbat]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 17:21, 9 hezîran 2025 (UTC) == [[hevtawan]] == @[[Bikarhêner:Ferhengvan|Ferhengvan]] ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 10:26, 12 hezîran 2025 (UTC) :Pirsek: "Hevwate" kelîmeyên ku maneyan wan hev in. "hevtawan" çawa dibe "şirîkên sûcekê"? Gereg sûcên ku tiştê wan hev bin? Ew tişt çi ye? Çima dibe şirîk? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 10:32, 12 hezîran 2025 (UTC) ::Merheba! ::"Hevtawan" anku "şirîkên heman tawanê, kesên ku heman tawan kiriye/dikin", wek "hevkar = şirîkên heman karî, kesên ku heman karî dikin", "hevjîn = şirîkên heman jiyanê, kesên ku bi hev re dijîn"... [[Bikarhêner:Ferhengvan|Ferhengvan]] ([[Gotûbêja bikarhêner:Ferhengvan|gotûbêj]]) 06:11, 30 hezîran 2025 (UTC) == [[zanîş]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 12:07, 14 hezîran 2025 (UTC) == [[zanîşwer]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 12:07, 14 hezîran 2025 (UTC) == [[zanmend]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 12:09, 14 hezîran 2025 (UTC) == [[zandar]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 21:08, 14 hezîran 2025 (UTC) == [[zayîndar]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 21:12, 14 hezîran 2025 (UTC) == [[zayindar]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 21:12, 14 hezîran 2025 (UTC) == [[akund]] == @[[Bikarhêner:Ferhengvan|Ferhengvan]] ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 01:16, 16 hezîran 2025 (UTC) == [[destbikar]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 07:41, 22 hezîran 2025 (UTC) == [[vekitandin]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:DarkAngel2100|DarkAngel2100]] ([[Gotûbêja bikarhêner:DarkAngel2100|gotûbêj]]) 10:45, 2 tîrmeh 2025 (UTC) Çavkanî: Kurdish-English Dictionary by Baran Rizgar == [[peşarmend]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 17:54, 5 tîrmeh 2025 (UTC) == [[zaîd]] == @[[Bikarhêner:Ferhengvan|Ferhengvan]] ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 06:59, 6 tîrmeh 2025 (UTC) == [[Xrîst]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 07:13, 10 tîrmeh 2025 (UTC) == [[hesibanî kirin]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 09:48, 13 tîrmeh 2025 (UTC) == [[top danîn]] == @[[Bikarhêner:Ferhengvan|Ferhengvan]] ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 10:08, 13 tîrmeh 2025 (UTC) == [[çûkger]] == @[[Bikarhêner:Dûrzan|Dûrzan]] ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:49, 18 tîrmeh 2025 (UTC) == [[dûneçkar]] == @[[Bikarhêner:212.175.166.246|212.175.166.246]] ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 15:38, 10 tebax 2025 (UTC) == [[sermirov]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 15:22, 13 tebax 2025 (UTC) == [[nifira Esed]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 16:00, 19 tebax 2025 (UTC) == [[dilkrîz]] == @[[Bikarhêner:Kurd87612|Kurd87612]] ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 10:44, 23 tebax 2025 (UTC) == [[berxa Xwedê]] == @[[Bikarhêner:Kurd87612|Kurd87612]] ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 14:28, 31 tebax 2025 (UTC) == [[destmatî]] == @[[Bikarhêner:Ferhengvan|Ferhengvan]] ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 17:47, 21 îlon 2025 (UTC) == [[sîbaq]] == @[[Bikarhêner:Ferhengvan|Ferhengvan]] ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 20:33, 27 îlon 2025 (UTC) == [[mirovê daristanê]] == @[[Bikarhêner:Hewarwîkîferheng|Hewarwîkîferheng]] ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 08:09, 18 çiriya pêşîn 2025 (UTC) == [[çavbijîşk]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 18:30, 24 çiriya pêşîn 2025 (UTC) == [[makeşar]] == @[[Bikarhêner:Avestaboy|Avestaboy]] ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 06:46, 14 kanûna pêşîn 2025 (UTC) :Silav @[[Bikarhêner:Bikarhêner|Bikarhêner]] min bi derew peyv çê nekir. Peyva makeşar di sepana O-ferheng û her wiha di ferhenga online ferhengkurdi.org ya '''Enstîtuya Kurdî ya Stenbolê''' tê xwendin. :https://ferhengkurdi.org/tr/kelime/make%C5%9Far-n [[Bikarhêner:Avestaboy|Avestaboy]] ([[Gotûbêja bikarhêner:Avestaboy|gotûbêj]]) 11:07, 18 kanûna pêşîn 2025 (UTC) ::Krîterên me yên tevlîkirina kelîmeyan heye. Ev made rîayeta wan krîteran nake. Lewma min vê kelîmeyê li vir bicih kir. -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 23:28, 18 kanûna pêşîn 2025 (UTC) == [[bihîstinzanî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:30, 23 hezîran 2026 (UTC) == [[hevdilî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 20:28, 24 hezîran 2026 (UTC) == [[kemisandin]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 20:45, 24 hezîran 2026 (UTC) == [[kexme]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 20:53, 24 hezîran 2026 (UTC) == [[lêpirsyarker]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 21:32, 24 hezîran 2026 (UTC) == [[raypirs]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 21:34, 24 hezîran 2026 (UTC) == [[helwestpirs]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 21:34, 24 hezîran 2026 (UTC) == [[kopirî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' xuyaye maneyeke wekî pir jî heye dikare were zêdekirin —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 17:33, 25 hezîran 2026 (UTC) == [[merxeme]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 22:55, 25 hezîran 2026 (UTC) == [[mohl]] == @[[Bikarhêner:Far ati|Far ati]] ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 23:14, 25 hezîran 2026 (UTC) == [[irfandarî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 20:30, 26 hezîran 2026 (UTC) == [[axulme]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 00:20, 30 hezîran 2026 (UTC) == [[şewane]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 14:26, 1 tîrmeh 2026 (UTC) == [[poezî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 14:27, 1 tîrmeh 2026 (UTC) == [[sebaxker]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 22:20, 1 tîrmeh 2026 (UTC) == [[sebaxfiroş]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 22:21, 1 tîrmeh 2026 (UTC) == [[siboxfiroş]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 22:21, 1 tîrmeh 2026 (UTC) == [[diyardenasîtî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 22:26, 1 tîrmeh 2026 (UTC) == [[dawxane]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 10:41, 3 tîrmeh 2026 (UTC) == [[pêşajotî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 17:15, 3 tîrmeh 2026 (UTC) == [[kontînentaltirîn]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 17:35, 3 tîrmeh 2026 (UTC) == [[azmayîşker]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 22:16, 3 tîrmeh 2026 (UTC) == [[ateşparêz]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 05:19, 4 tîrmeh 2026 (UTC) == [[kurtetarîx]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 11:52, 4 tîrmeh 2026 (UTC) == [[besayetî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 17:57, 4 tîrmeh 2026 (UTC) == [[tawbijêr]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 20:45, 4 tîrmeh 2026 (UTC) == [[destbir]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 11:30, 5 tîrmeh 2026 (UTC) == [[nekider]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 22:56, 5 tîrmeh 2026 (UTC) == [[niqar]] == —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 23:39, 5 tîrmeh 2026 (UTC) == [[parêzîn]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' Ev form li ti derê peyda nabe. Berî çendîn salan hatîye çêkirin. Bi qenaeta min şaş e, lewma em jê bibin. — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 10:29, 6 tîrmeh 2026 (UTC) == [[stêrfizîk]] == . —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 20:33, 6 tîrmeh 2026 (UTC) == [[pêçavik]] == . Eger ev kelîmeyeke mehelî be, Jkx şablona {{şx|dever|cihê ku lê tê bikaranîn}} li madeyê zêde bike. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 14:59, 7 tîrmeh 2026 (UTC) == [[qerqef]] == . Eger ev kelîmeyeke mehelî be, Jkx şablona {{şx|dever|cihê ku lê tê bikaranîn}} li madeyê zêde bike. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 15:17, 7 tîrmeh 2026 (UTC) == [[rakar]] == . Eger ev kelîmeyeke mehelî be, Jkx şablona {{şx|dever|cihê ku lê tê bikaranîn}} li madeyê zêde bike. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 15:30, 7 tîrmeh 2026 (UTC) == [[remilîn]] == . Eger ev kelîmeyeke mehelî be, Jkx şablona {{şx|dever|cihê ku lê tê bikaranîn}} li madeyê zêde bike. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 15:36, 7 tîrmeh 2026 (UTC) == [[segurî]] == . —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 15:51, 7 tîrmeh 2026 (UTC) == [[serdev]] == Bnr. [[Wîkîferheng:Pîvekên tevlîkirinê|Krîterên tevlîkirinê]] —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:10, 7 tîrmeh 2026 (UTC) == [[serziman]] == Bnr. [[Wîkîferheng:Pîvekên tevlîkirinê|Krîterên tevlîkirinê]] —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 17:01, 7 tîrmeh 2026 (UTC) == [[tenîsk]] == di Înternetê de gelek netîce derdikevin lê ji bo ku dûre ez kontrol bikim û çavkaniyên sehîh binivîsim li vir îlawe dikim. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 20:53, 7 tîrmeh 2026 (UTC) == [[tertî]] == Bnr. [[Wîkîferheng:Pîvekên tevlîkirinê|Krîterên tevlîkirinê]] —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 20:58, 7 tîrmeh 2026 (UTC) == [[tirut]] == Bnr. [[Wîkîferheng:Pîvekên tevlîkirinê|Krîterên tevlîkirinê]] —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 21:25, 7 tîrmeh 2026 (UTC) == [[tizqa]] == Bnr. [[Wîkîferheng:Pîvekên tevlîkirinê|Krîterên tevlîkirinê]] —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 21:28, 7 tîrmeh 2026 (UTC) == [[têkilîdêr]] == Bnr. [[Wîkîferheng:Pîvekên tevlîkirinê|Krîterên tevlîkirinê]] —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 21:31, 7 tîrmeh 2026 (UTC) == [[tîtalk]] == Bnr. [[Wîkîferheng:Pîvekên tevlîkirinê|Krîterên tevlîkirinê]] —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 21:33, 7 tîrmeh 2026 (UTC) == [[vircoq]] == Bnr. [[Wîkîferheng:Pîvekên tevlîkirinê|Krîterên tevlîkirinê]] —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 21:45, 7 tîrmeh 2026 (UTC) == [[xilêbat]] == Bnr. [[Wîkîferheng:Pîvekên tevlîkirinê|Krîterên tevlîkirinê]]. Li gorî kurteya çêkirina sayfeyê li Qamişlo û Amûdê tê bikaranîn. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 22:14, 7 tîrmeh 2026 (UTC) == [[xin_û_cûc]] == Bnr. [[Wîkîferheng:Pîvekên tevlîkirinê|Krîterên tevlîkirinê]] —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 22:27, 7 tîrmeh 2026 (UTC) == [[çiteba]] == Bnr. [[Wîkîferheng:Pîvekên tevlîkirinê|Krîterên tevlîkirinê]] —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 22:38, 7 tîrmeh 2026 (UTC) == [[desttêl]] == Bnr. [[Wîkîferheng:Pîvekên tevlîkirinê|Krîterên tevlîkirinê]] —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 08:45, 8 tîrmeh 2026 (UTC) == [[Mîmedol]] == Bnr. [[Wîkîferheng:Pîvekên tevlîkirinê|Krîterên tevlîkirinê]] —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 08:51, 8 tîrmeh 2026 (UTC) == [[alaf]] == Bnr. [[Wîkîferheng:Pîvekên tevlîkirinê|Krîterên tevlîkirinê]] —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 14:01, 8 tîrmeh 2026 (UTC) == [[aşirme]] == Bnr. [[Wîkîferheng:Pîvekên tevlîkirinê|Krîterên tevlîkirinê]] —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 10:13, 10 tîrmeh 2026 (UTC) == [[geledîmentî]] == Bnr. [[Wîkîferheng:Pîvekên tevlîkirinê|Krîterên tevlîkirinê]] —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 20:54, 13 tîrmeh 2026 (UTC) == [[çendîmentî]] == Bnr. [[Wîkîferheng:Pîvekên tevlîkirinê|Krîterên tevlîkirinê]] —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 20:54, 13 tîrmeh 2026 (UTC) == [[paşmak]] == Bnr. [[Wîkîferheng:Pîvekên tevlîkirinê|Krîterên tevlîkirinê]] —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:34, 15 tîrmeh 2026 (UTC) == [[zazakînas]] == Bnr. [[Wîkîferheng:Pîvekên tevlîkirinê|Krîterên tevlîkirinê]] —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:16, 15 tîrmeh 2026 (UTC) == [[rojeng]] == Bnr. [[Wîkîferheng:Pîvekên tevlîkirinê|Krîterên tevlîkirinê]] —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 22:41, 18 tîrmeh 2026 (UTC) == [[bereyîşk]] == Bnr. [[Wîkîferheng:Pîvekên tevlîkirinê|Krîterên tevlîkirinê]] —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 15:47, 19 tîrmeh 2026 (UTC) dz1icuuf5nxzz5zfexmqo7g6jss6ev2 6265689 6265600 2026-07-19T22:05:41Z Wikihez 7344 /* zazakînas */ [[Bikarhêner:Wikihez/templateScript2.js|TS]]: +{{[[şablon:nepeyitandî|nepeyitandî]]}} 6265689 wikitext text/x-wiki {{/destpêk}} = Hezîran 2020 = == [[romî#Navdêr|romî]] == Li Şingalê maneya polîs? --[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 08:00, 15 hezîran 2020 (UTC) = Tîrmeh 2020 = == [[kêlb#p-mane|kêlb]] == --[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 14:24, 22 tîrmeh 2020 (UTC) == [[ejî#p-mane|ejî]] == --[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 14:24, 22 tîrmeh 2020 (UTC) == [[tutirk#peyitandin|tutirk]] == --[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 22:02, 22 tîrmeh 2020 (UTC) :{{r|Guherto}} Niha çawa ye? Bi ya min çavkaniyên ku min dane têrê me dike. --[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 22:43, 22 tîrmeh 2020 (UTC) ::{{r|Balyozxane}} Nizanim.. li hin deveran wek tutirk hatîye nivîsandin û li hin jî wek tûtirk. Li hin deveran bi wateya tûşêmî (Rubus) ye, hin deveran jî bi wateya tûerd (Fragaria × ananassa) e û carna jî bi wateya tû (ê spî û reş go li ser daran çê dibin) ye. -- [[Bikarhêner:Guherto|Guherto]] ([[Gotûbêja bikarhêner:Guherto|gotûbêj]]) 08:16, 23 tîrmeh 2020 (UTC) == [[erbane#p-mane|erbane]] == Ji bo ''Amûreke tenê tekerekî wê heye ji bo veguhestina tiştan wek: axê, kevir, hwd'' ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]]''--[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 22:42, 31 tîrmeh 2020 (UTC) = Tebax 2020 = == [[cifta berazan]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]]'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 22:57, 9 tebax 2020 (UTC) == [[tê gerîn]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]]'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 22:26, 10 tebax 2020 (UTC) == [[tapor]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]]'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 20:30, 22 tebax 2020 (UTC) :{{r|Mihemed Qers}} -- [[Bikarhêner:Guherto|Guherto]] ([[Gotûbêja bikarhêner:Guherto|gotûbêj]]) 22:16, 22 tebax 2020 (UTC) == [[şimzare]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]]'' —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 19:01, 26 tebax 2020 (UTC) == [[bîrkok]] == Tenê Mehmed Uzun bi kar tîne. Ji bilî kitêbên wî çavkaniyeke din tune. —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 20:38, 28 tebax 2020 (UTC) == [[hunera axaftinê]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]]'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 18:46, 30 tebax 2020 (UTC) == [[derrijîn]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]]'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 07:38, 31 tebax 2020 (UTC) == [[yekal]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]]'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 09:19, 31 tebax 2020 (UTC) == [[av û agir]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]]'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 12:50, 31 tebax 2020 (UTC) : Di çavkaniyeke de wek av û agir kirin derbas dibe û ji wergerandinên inglîzî cuda ye lê nêzîk e.<br> {{jêder-pirtûk|ku|jêgirtin=weke gelek hunermendên ko dû re agir bera berhêm xwe didin Xwedê jî ji bilî maltaba Nûh tevayiyê vê berhema xwe '''av û agir dike''', van melekên xwe yên doxînsist dikişîne asîmanan, li wir wan tawanbar dike, mîna ko bibêje: de biçin û weke xwe bikin, bi derew û tevgerên xwe yên qirêj dijminiya min bikin, Xwedê wan ji asimanan de serjêr davêje xwarê.|nivîskar=Hesenê Metê|sernav=Labîrenta cinan|weşanxane=Nefel|sal=2002|rûpel=132}} --[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 13:37, 31 tebax 2020 (UTC) == [[elm#p-mane-notice|elm]] == Wateya: ''[[ewlebûn]], sihê pê zanîn, baş pê zanîn''. ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 17:31, 31 tebax 2020 (UTC) :{{r|Hakîmo}} Ku çavkanî tunebûn em ê jê bibin. --[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 14:47, 19 îlon 2020 (UTC) ::{{r|Balyozxane}} Mala te neketê... Hingê bixwe here lê bigere. Jixwe ez reşwî me. Ma eve ne çavkanî ye? -- [[Bikarhêner:Hakîmo|Hakîmo]] ([[Gotûbêja bikarhêner:Hakîmo|gotûbêj]]) 14:48, 19 îlon 2020 (UTC) :::{{r|Hakîmo}} Hinek bixwîne [[Wîkîferheng:Pîvekên tevlîkirinê]]. Jixwe dema ti kesan din çavkanî lê zêde nakin, ez lê digerim û zêde dikim. Na tu ne ti çavkanî yî. Çavkaniyên nivîskî hewce ne. --[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 14:51, 19 îlon 2020 (UTC) ::::{{r|Balyozxane}} Erê, lê ku tine bin em çawa bikinî? Em hema jê bibinî? -- [[Bikarhêner:Hakîmo|Hakîmo]] ([[Gotûbêja bikarhêner:Hakîmo|gotûbêj]]) 14:52, 19 îlon 2020 (UTC) :::::{{r|Hakîmo}} Erê em jê dibin. Lê peyvên jê hatine birin em li rûpela [[Pêvek:Bêçavkanî]] zêde dikin. bnr. [[:Kategorî:Pêvek bêçavkanî]]. Dîsa jî ez jî ji vê rewşa me aciz im û bi ya min peyvên devokî divê nayên jêbirin. Lê ji ber ku [[Wîkîferheng:Rêbazname]] dibêje divê werin jêbirin, ez jê dibim. Hevalên {{r|Jiju|Guherto|Ghybu}} [https://ku.wiktionary.org/wiki/Got%C3%BBb%C3%AAj:kejm%C3%BBn], [https://ku.wiktionary.org/wiki/Got%C3%BBb%C3%AAja_p%C3%AAvek%C3%AA:B%C3%AA%C3%A7avkan%C3%AE] jî ji vê rewşê aciz in. Lê ti kes gotûbêj nadin destpêkirin. Ku tu li vir [[Gotûbêja Wîkîferhengê:Pîvekên tevlîkirinê]] gotûbêjek bidî destpêkirin, ez ê piştgirî bidime te. --[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 14:58, 19 îlon 2020 (UTC) ::::::Ji kerema xwe min şaş fêm mekin feqet hemû bikarhêner ku tên vira dilpak nînin. Em çito ew peyvan kotrol bikinê? Mixabin, ji bo konrolkirina peyvan di destên me de tenê xwastina çavkaniyan hene amûrek din tine ye... PS: Herwiha me li ser wîkîferhengê Namespace'yên Nimînok ([[Nimînok:Kurdî/serhedî]]?, [[Nimînok:Kurdî/badînî]]?, ..) û Portal ([[Portal:Kurdî]], [[Portal:Frensî]] (mk. [[:fr:Portail:Français]]), ...) jî çêkiriye...--[[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 15:32, 19 îlon 2020 (UTC) :::::::Nizanim we nivîsa vira xwand, [[Wîkîferheng:Dîwan#Skotî]]. Piraniya peyvên wîkiya skotî çêkirî ne...--[[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 15:47, 19 îlon 2020 (UTC) ::::::::@Ghybu erê min ew xwendibû. Ku em peyvan nepeyitînin, rewşa me jî wek mg.wikt û wikiya skotiyan be. Temam em peyvên devokî jê nebin lê em wan jî nexin werger û rûpelên din heta ku werin peyitandin. Herwiha tu dibêjî amûrek tune ye lê tenê ji bo peyvên devokî û navên heywan/riwekan wisa ye. Gelek caran peyitandin pir hêsan e. Mînak @Hakîmo yan jî hevalên din dikarin blogan binivîsin daku em karibin peyvên wan yên devokî (nepeyitandî) têxin rûpela [[Wîkîferheng:Tomarkirina peyvên ji wêjeya kurdî|Jêgirtinekê tomar bike]] û kengî ew peyv ji hêla nivîskar û blogvanên kurd yên din ve hatine bikaranîn hingê em dikarin li wîkîferhengê jî zêde bikin. --[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 16:05, 19 îlon 2020 (UTC) {{outdent|::::::::}}{{r|Hakîmo|Ghybu}} Xêra dê û bavên we '''[[Gotûbêja_Wîkîferhengê:Pîvekên_tevlîkirinê#Li_ser_peyvên_devokî|li vir]]''' fikrên xwe binivîsin daku kesên din bizanin kesên din jî hene vê fikrê min dipejirînin. --[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 06:48, 3 çiriya pêşîn 2020 (UTC) == [[nîşanbar]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 23:51, 31 tebax 2020 (UTC) = Îlon 2020 = == [[besme]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 11:26, 1 îlon 2020 (UTC) == [[ferengi]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 17:12, 1 îlon 2020 (UTC) == [[çelape]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 17:22, 1 îlon 2020 (UTC) == [[cesasandin]] == Çavkaniyek klasîk heye, yên din heye gelo? —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 09:02, 2 îlon 2020 (UTC) == [[depan]] == Depan guhertoyeke textan an textîn e. Lê li vir çi mane heye min fêm nekir. —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 10:33, 2 îlon 2020 (UTC) == [[li rûyê dinê xweş mayîn]] == Çavkaniyeke klasîk heye —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 20:38, 2 îlon 2020 (UTC) == [[bêsewî]] == klasîk —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 06:34, 4 îlon 2020 (UTC) == [[merkemoş]] == Klasîk —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 06:34, 4 îlon 2020 (UTC) == [[firfiroka bayî]] == {{r|Mamoste Dilovan}} ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 12:57, 6 îlon 2020 (UTC) == [[guhê fîlî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 18:56, 7 îlon 2020 (UTC) : {{r|Bikarhêner}} Min guh li evê peyvê bû ji kesekî ku xudan xwaringehek û baxçeyekî mezin e. : Gelek tişt di berbelav in û xelk dizanin, lê di pertûkan de naye dîtin. {{bêîmze|IbrahimKocher Duhok}} == [[gurovî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 14:41, 14 îlon 2020 (UTC) :{{r|Bikarhêner}} Çavkanîyên peyvên ku min nivîsandin mixabin ne nivîskî ne. Ev peyv min ji hin mezinên malbatê bihîstine û min jî gelek caran dîtîne ku hatine bikaranîn. Ji bo ku ev peyv wûnda nebin min hem li ba xwe û hem jî li wîkîferhengê nivîsand. Ji bo peyvên ku çavkanîyên nivîskî tunin, mixabin gotinên devkî tene weke çavkanî dimînin. Pêşnîyara te ji bo pevên bi vî awayî çi ye gelo? Spas{{bêîmze|Xwende}} ::{{r|Xwende}} Pêşî li ser malpera [https://tirsik.net/xerhati.php] dûre jî li ser arsiv.org qeyd bike ku nikarî çavkanî peyda bikî. Herwiha bnr [[Alîkarî:Îmze]] --[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 16:00, 15 îlon 2020 (UTC) == [[şîloyî]] == {{r|Xwende}} ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 14:44, 14 îlon 2020 (UTC) == [[dever]] == Ji bo wateya ''derence, sêlim û merdîwen'' [[Wîkîferheng:Pîvekên tevlîkirinê|çavkanî hewce ye]]. —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 17:53, 14 îlon 2020 (UTC) == [[kerrnizî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 15:56, 15 îlon 2020 (UTC) == [[li dora (yekê) gerîn]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 18:46, 15 îlon 2020 (UTC) == [[glas]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]]. --[[Bikarhêner:Şêr|Şêr]] ([[Gotûbêja bikarhêner:Şêr|gotûbêj]]) 12:45, 16 îlon 2020 (UTC) == [[kejmûn]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 16:42, 17 îlon 2020 (UTC) == [[lirêgerîn]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 14:20, 18 îlon 2020 (UTC) == [[çavpeqî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 16:23, 23 îlon 2020 (UTC) :http://www.geocities.ws/mehname2004a/63/pexsan5.html -- [[Bikarhêner:Guherto|Guherto]] ([[Gotûbêja bikarhêner:Guherto|gotûbêj]]) 16:58, 23 îlon 2020 (UTC) == [[çavpeqiyayî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 17:14, 23 îlon 2020 (UTC) :{{r|Balyozxane}} Çavpeqî û -iyayî eynî peyv in, heke bo nimûne 2 çavkanî ji bo çavpeqî û 1 ji bo -iyayî werin dîtin ew weke 3 ji bo yek peyv tên jimartin? -- [[Bikarhêner:Guherto|Guherto]] ([[Gotûbêja bikarhêner:Guherto|gotûbêj]]) 17:16, 23 îlon 2020 (UTC) ::{{r|Guherto}}. Na, divê yek ji wan peyitandî be daku em karibin yek ji wan wek guherto nîşan bidin. --[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 17:45, 23 îlon 2020 (UTC) :::Temam naxwe. {{=(}} -- [[Bikarhêner:Guherto|Guherto]] ([[Gotûbêja bikarhêner:Guherto|gotûbêj]]) 17:48, 23 îlon 2020 (UTC) ::::Ecêb e peyva çavpeqîn jî tune ye. Divê çavpeqî/çavpeqiyayî jê hatibe lê qet tune. --[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 17:56, 23 îlon 2020 (UTC) :::::Em çavpeqî ne weke kesekî ku çavê wan peqî ye dibêjin. Siqêfek e. ''Wilo neke, çavpeqî!'' -- [[Bikarhêner:Guherto|Guherto]] ([[Gotûbêja bikarhêner:Guherto|gotûbêj]]) 18:10, 23 îlon 2020 (UTC) == [[olfatûn]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 14:58, 24 îlon 2020 (UTC) :Du çavkanî hatiye dîtin li hêviya ya sisêyan e. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 13:46, 23 sibat 2025 (UTC) == [[hekûke]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 16:00, 28 îlon 2020 (UTC) :Tenê çavkaniyek ji Kovara Kurmancî heye ew jî ji kitêba Gundê Mêrxasan a Eliyê Evdilrehman hatiye girtin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 13:49, 23 sibat 2025 (UTC) == [[dê bêjî kaya di serî de]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 12:58, 29 îlon 2020 (UTC) == [[heçî ne li malekê, nizanit halekê]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 12:58, 29 îlon 2020 (UTC) == [[heta nîva destî reş nebit, tama devî xoş nabit]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 12:58, 29 îlon 2020 (UTC) == [[kirtop]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' Herwiha [[kirtope]]—[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 12:59, 29 îlon 2020 (UTC) : == [[pişkûmişk]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 21:25, 29 îlon 2020 (UTC) = Çiriya pêşîn 2020 = == [[ma te şulê pê ye?]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 13:19, 1 çiriya pêşîn 2020 (UTC) == [[zelam yêt heyn û zelamoşk jî yêt heyn]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 13:28, 1 çiriya pêşîn 2020 (UTC) == [[ezîz î&#59; ji pêrve ne mîzî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 14:15, 1 çiriya pêşîn 2020 (UTC) == [[qelpez]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 08:19, 6 çiriya pêşîn 2020 (UTC) == [[firêzer]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Guherto|Guherto]] ([[Gotûbêja bikarhêner:Guherto|gotûbêj]]) 15:27, 6 çiriya pêşîn 2020 (UTC) == [[kirmişk]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 09:03, 7 çiriya pêşîn 2020 (UTC) == [[orijîn]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Guherto|Guherto]] ([[Gotûbêja bikarhêner:Guherto|gotûbêj]]) 19:03, 7 çiriya pêşîn 2020 (UTC) == [[şequdeq]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 08:50, 9 çiriya pêşîn 2020 (UTC) == [[helizandin]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 11:23, 9 çiriya pêşîn 2020 (UTC) == [[rewastin]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 11:48, 9 çiriya pêşîn 2020 (UTC) == [[xunaftin]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 12:31, 9 çiriya pêşîn 2020 (UTC) == [[itîmad li ser kirin]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Guherto|Guherto]] ([[Gotûbêja bikarhêner:Guherto|gotûbêj]]) 16:32, 15 çiriya pêşîn 2020 (UTC) == [[sengesor]] == {{r|Saberabdollahizad}} ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 22:00, 16 çiriya pêşîn 2020 (UTC) :Navçeya Mirgewerê, Ûrmîye. {{bêîmze|Saberabdollahizad}} == [[zenek]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 22:03, 16 çiriya pêşîn 2020 (UTC) :{{r|Saberabdollahizad}} [[zenek]] jî li Ûrmiyê tê bikaranîn? --[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 19:53, 18 çiriya pêşîn 2020 (UTC) == [[pind#p-mane|pind]] == Min tenê çavkaniyek dît ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 18:48, 17 çiriya pêşîn 2020 (UTC) :Navçeya Mirgewerê, Ûrmîye. {{bêîmze|Saberabdollahizad}} == [[maqezer]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 18:53, 18 çiriya pêşîn 2020 (UTC) :Navçeya Mirgewerê, Ûrmîye. {{bêîmze|Saberabdollahizad}} == [[pezpezok]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 18:55, 18 çiriya pêşîn 2020 (UTC) :Navçeya Mirgewerê, Ûrmîye. {{bêîmze|Saberabdollahizad}} == [[parapet#p-mane|parapet]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 13:53, 31 çiriya pêşîn 2020 (UTC) = Çiriya paşîn 2020 = == [[quloç#p-mane|quloç]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 17:43, 19 çiriya paşîn 2020 (UTC) == [[di ber (yekî) de avêtin]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 16:57, 20 çiriya paşîn 2020 (UTC) :https://tirsik.net/index.php?mijarid=18749&iro=on&rupel=1 —[[Bikarhêner:Mamoste Dilovan|Mamoste Dilovan]] ([[Gotûbêja bikarhêner:Mamoste Dilovan|gotûbêj]]) 17:37, 20 çiriya paşîn 2020 (UTC) :: {{r|Mamoste Dilovan}} [[di ber re avêtin]] heye. lê te wek di ber '''de''' lê zêde kir. Em biguherînin? Gelek çavkanî ji bo di ber re avêtin heye. --[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 17:41, 20 çiriya paşîn 2020 (UTC) == [[hêvastin]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 10:49, 21 çiriya paşîn 2020 (UTC) == [[lamçîn]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 11:28, 22 çiriya paşîn 2020 (UTC) == [[poz#p-mane|poz]] == Ji bo maneya "[[quz]], [[vajîna]]" ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 11:28, 22 çiriya paşîn 2020 (UTC) == [[sihetbexş]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 16:35, 24 çiriya paşîn 2020 (UTC) == [[hevjêhatin ji jêhatîbûnê çêtir e]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 12:14, 25 çiriya paşîn 2020 (UTC) == [[gerriyan#p-mane|gerriyan]] == ''Ji bo wateya cereyan (tevger)''. Qasî ku dibînim tenê Cewerî bi kar aniye —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 18:24, 25 çiriya paşîn 2020 (UTC) == [[derbend]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 12:08, 30 çiriya paşîn 2020 (UTC) = Kanûna paşîn 2021 = == [[desthelgirtin]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 08:48, 6 kanûna paşîn 2021 (UTC) == [[êşewî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 12:52, 7 kanûna paşîn 2021 (UTC) == [[sexorr]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 20:22, 7 kanûna paşîn 2021 (UTC) == [[sapût]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 22:06, 12 kanûna paşîn 2021 (UTC) == <s>[[dimorî]]</s> == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' Maneya navdêrî bêçavkanî ye. — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 15:05, 20 kanûna paşîn 2021 (UTC) :{{nepeyitandî}}--[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 14:18, 26 hezîran 2026 (UTC) :Di Kovara kurmancî hj.67 de "dimor" bi maneya "bêoxir" de derbas dibe. Wekî din ti çavkanî nîne. Merheba @[[Bikarhêner:Gomada|Gomada]] te varyanta "dimhorî" îlawe kiriye. Gelo tu dizanî ev kelîme li kîjan herêman tê bikaranîn? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 14:18, 26 hezîran 2026 (UTC) = Çiriya pêşîn 2022 = == [[paşbingeh]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 07:40, 12 çiriya pêşîn 2022 (UTC) = Kanûna paşîn 2023 = == [[berê beringa]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 21:35, 1 kanûna paşîn 2023 (UTC) == [[mûlûleya xwînê]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 16:36, 6 kanûna paşîn 2023 (UTC) == [[mirovdostî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 05:38, 12 kanûna paşîn 2023 (UTC) == [[derîner]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 23:02, 15 kanûna paşîn 2023 (UTC) == [[neteba]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 00:01, 16 kanûna paşîn 2023 (UTC) :Maneya "uyruksuz" ji ferhenga Farqînî hatiye kopîkirin wekî din bi giştî bi maneya "nakokî" tê bikaranîn. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 14:33, 26 hezîran 2026 (UTC) == [[narkotîkfiroş]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 10:59, 16 kanûna paşîn 2023 (UTC) == [[pirik#p-mane|pirik]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 18:15, 16 kanûna paşîn 2023 (UTC) == [[ramyarî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' Ez dibêjim ev peyv tenê bi maneya "fikrî", wek rengdêr heye. Lê belê di soranî de bi şaşemilandineke wekî "siyasî" bi kar anîne, kurmancên me jî rasterast maneya soranî tevlî çend ferhengên hev-kopîkirî kirine û bi vî awayî belkî hin çavkanî hebin. Lê ez dibêjim divê ew çavkanî jî neyên hesibandin. Hin kes zen dikin ku her tiştê di soranî de ripîrast e. Mesele heqeten eletewş e. Agahiyeke li ser peyvê: "[https://www.welateme.info/kurdi/modules.php?name=News&file=print&sid=686 Welateme.info]" Li vir peyv bi maneya "fikrî" hatiye bikaranîn: "[https://xwebun1.org/ziman-sirhelal-e/ Xwebûn]". Qewet be. — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 22:36, 19 kanûna paşîn 2023 (UTC) == [[dolîwgeh]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 21:08, 22 kanûna paşîn 2023 (UTC) = Sibat 2023 = == [[herebaş]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 15:13, 11 sibat 2023 (UTC) == [[balindeyê korare]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' Tenê çavkaniyekê tê xuyan, ew jî kitêba "Balindeyên Kurdistanê" yê Îsmaîl Taha Şahîn e (Îsmaîl Taha Şahîn (2006). Balindeyên Kurdistanê, 1-4. Spîrêz, Duhok). Ev kitêb ji ser înternetê wek word jî peyda dibe. Xuya ye ku ji Weşanên Spîrez fîzîken jî çap bûye. Lê wekî çavkanî tenê ev tê xuyan. —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 17:10, 14 sibat 2023 (UTC) == [[dîbeyt]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 10:13, 18 sibat 2023 (UTC) == [[çend pat]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 09:35, 24 sibat 2023 (UTC) == [[rabînîn]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' Ji bo kurmancî bêçavkanî ye. Ger ji bo soranî çavkanî hebin jî divê ji bo soranî bi herfên aramî were nivîsîn. An ger halê latînîkirî ya peyveke soranî be, dîsa divê ev hal were eşkerekirin. — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 13:36, 26 sibat 2023 (UTC) = Adar 2023 = == [[qirar#p-mane|qirar]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 09:23, 2 adar 2023 (UTC) == [[pîşpêkirin]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' Tenê di nivîseke online ya Cemal Nebez de derbas dibe. Dibe ku peyveke başûriyan be. Û di wê nivîsa Cemal Nebezê bi forma "pîş bi ... bikin" jî derbas dibe. — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 16:29, 3 adar 2023 (UTC) == [[kûcag]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 01:27, 27 adar 2023 (UTC) == [[destbizavî kirin]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' Xuya ye ku ev peyv tenê di kitêba “''Nameyek Şernexê''” yê Evdirehman Gundikî de derbas bûye. Û ji wir jî Mistefa Aydoganî maneya peyvê di hejmara 61em ya Kovara ''Kurmancî'' de belav kiriye (rûpela 2yem). Lê belê tenê yek çavkaniyekê ne bes e ji bo ku em vê peyvê di vê ferhengê de wekî peyveke çavkanî-temam belav bikin. — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 09:40, 28 adar 2023 (UTC) == [[germav baş]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 18:23, 31 adar 2023 (UTC) == [[germavxweş]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 18:27, 31 adar 2023 (UTC) = Gulan 2023 = == [[kirbend]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 08:34, 5 gulan 2023 (UTC) : Çêkerê rûpelê wek not nivîsiye ku peyv ji herêma Çewlikê ye. -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 06:24, 6 gulan 2023 (UTC) == [[We are off now]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 14:13, 22 gulan 2023 (UTC) == [[baran ji erd û esmana lê diket]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 22:46, 26 gulan 2023 (UTC) == [[sîba]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 15:44, 30 gulan 2023 (UTC) == [[bîrîner]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 17:20, 30 gulan 2023 (UTC) = Hezîran 2023 = == [[bidestmiz]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 16:49, 10 hezîran 2023 (UTC) = Tîrmeh 2023 = == [[parzeng]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 14:01, 15 tîrmeh 2023 (UTC) == [[zerpedest]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 14:05, 15 tîrmeh 2023 (UTC) == [[heta destên mirov nebine gû, devê mirov nabite tû]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 15:27, 19 tîrmeh 2023 (UTC) == [[çemê mezin tê dibore diçe]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 15:38, 19 tîrmeh 2023 (UTC) == [[kevanê nebî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 15:45, 19 tîrmeh 2023 (UTC) == [[teybûr]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' Tenê li malpera yuksekovahaber.com-ê derbas dibe, li wir jî bi maneya "çare, çareserî"yê hatiye emilandin, ne bi vê maneyê. — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 16:00, 19 tîrmeh 2023 (UTC) == [[nikêtî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 16:22, 19 tîrmeh 2023 (UTC) = Tebax 2023 = == [[prêze]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 21:19, 15 tebax 2023 (UTC) == [[qelye]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 15:59, 25 tebax 2023 (UTC) = Îlon 2023 = == [[hetwan]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 20:21, 14 îlon 2023 (UTC) == [[milyonmasî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 14:06, 21 îlon 2023 (UTC) == [[tofana mêjî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 14:20, 21 îlon 2023 (UTC) == [[îshaf]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 10:57, 23 îlon 2023 (UTC) == [[odeya karkirinê]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 10:57, 26 îlon 2023 (UTC) == [[odeya şixulînê]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 11:42, 26 îlon 2023 (UTC) == [[hîter]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 12:08, 26 îlon 2023 (UTC) = Çiriya pêşîn 2023 = == [[vîtamîn waw]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 20:20, 1 çiriya pêşîn 2023 (UTC) == [[berhan]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 14:21, 3 çiriya pêşîn 2023 (UTC) == [[sêlikdêr]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 19:16, 10 çiriya pêşîn 2023 (UTC) == [[qewandêr]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 19:20, 10 çiriya pêşîn 2023 (UTC) == [[darav]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 20:04, 11 çiriya pêşîn 2023 (UTC) = Çiriya paşîn 2023 = == [[kansernasî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 17:54, 14 çiriya paşîn 2023 (UTC) == [[golgir]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 16:06, 15 çiriya paşîn 2023 (UTC) == [[gogpî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 16:19, 15 çiriya paşîn 2023 (UTC) == [[ahardar]] == Tenê Zana Farqînî —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 10:34, 26 çiriya paşîn 2023 (UTC) = Kanûna pêşîn 2023 = == [[Kî mal ezîz bike, can rezîl dike&#59; kî mal rezîl bike, can ezîz dike.]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 13:55, 2 kanûna pêşîn 2023 (UTC) == [[porsing]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 14:22, 2 kanûna pêşîn 2023 (UTC) == [[newelatî kirin]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 16:57, 2 kanûna pêşîn 2023 (UTC) == [[newelatîkirin]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 16:58, 2 kanûna pêşîn 2023 (UTC) == [[alîkar kirin]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Şêr|Şêr]] ([[Gotûbêja bikarhêner:Şêr|gotûbêj]]) 18:42, 3 kanûna pêşîn 2023 (UTC) == [[aramoş kirin]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]]'' -- [[Bikarhêner:Şêr|Şêr]] ([[Gotûbêja bikarhêner:Şêr|gotûbêj]]) 18:48, 3 kanûna pêşîn 2023 (UTC) == [[bêvil kirin]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Şêr|Şêr]] ([[Gotûbêja bikarhêner:Şêr|gotûbêj]]) 18:56, 4 kanûna pêşîn 2023 (UTC) == [[dijberiya naverokî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Şêr|Şêr]] ([[Gotûbêja bikarhêner:Şêr|gotûbêj]]) 22:43, 8 kanûna pêşîn 2023 (UTC) == [[bersivîn]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]]'', û her wiha ne li gorî qayideyên kurdî (kurmancî) ye. —[[Bikarhêner:Şêr|Şêr]] ([[Gotûbêja bikarhêner:Şêr|gotûbêj]]) 22:08, 11 kanûna pêşîn 2023 (UTC) == [[girêbanasî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 20:30, 13 kanûna pêşîn 2023 (UTC) == [[hevalzewac]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 17:25, 18 kanûna pêşîn 2023 (UTC) = Kanûna paşîn 2024 = == [[raperk]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 13:40, 15 kanûna paşîn 2024 (UTC) :Bi wê manê nîne. Bi maneke dî heye. [[Bikarhêner:Guherto|Guherto]] ([[Gotûbêja bikarhêner:Guherto|gotûbêj]]) 19:26, 6 tebax 2024 (UTC) = Sibat 2024 = == [[bi navê lîstin]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 21:02, 3 sibat 2024 (UTC) : Li ser agahdarkirina çêkerê rûpelê me şablona "dever"ê tevlî kir. Peyv ji herêma Qoser, Mêrdînê ye. Me li qismê "Bikaranîn"ê jî vê yekê dîyar kir. Ji xeynî vê me wê peyvê ji rûpelên din jî bir. Bi vî awayî ev made kare were girtin. -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 13:28, 10 nîsan 2024 (UTC) == [[firoşgehkar]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 19:17, 9 sibat 2024 (UTC) == [[preskirin]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 00:43, 11 sibat 2024 (UTC) == [[pres kirin]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 00:43, 11 sibat 2024 (UTC) == [[Xwedê te têr bike]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 22:41, 13 sibat 2024 (UTC) == [[isad]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 22:09, 22 sibat 2024 (UTC) == [[razemendîtî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 18:44, 27 sibat 2024 (UTC) = Adar 2024 = == [[zilhêzî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 23:19, 5 adar 2024 (UTC) == [[hingihîn]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 21:32, 13 adar 2024 (UTC) == [[xore]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 13:30, 15 adar 2024 (UTC) == [[melef]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 13:55, 19 adar 2024 (UTC) == [[uğursuz ayak]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 10:11, 23 adar 2024 (UTC) == [[şepûk]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 10:22, 23 adar 2024 (UTC) == [[agirberdêrî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 00:04, 26 adar 2024 (UTC) == [[kîrquz]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 10:00, 26 adar 2024 (UTC) == [[kîrquzdê]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 10:01, 26 adar 2024 (UTC) == [[quzgêj]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 10:03, 26 adar 2024 (UTC) = Nîsan 2024 = == [[hîkarîkerî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 08:53, 1 nîsan 2024 (UTC) == [[hîkarîker]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 08:54, 1 nîsan 2024 (UTC) == [[hîkarîdarî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 08:55, 1 nîsan 2024 (UTC) == [[hîkarîdar]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 08:56, 1 nîsan 2024 (UTC) == [[bihîkarîtî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 08:57, 1 nîsan 2024 (UTC) == [[bihîkarî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 08:58, 1 nîsan 2024 (UTC) == [[bêhîkarîtî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 08:58, 1 nîsan 2024 (UTC) == [[bêhîkarî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 08:59, 1 nîsan 2024 (UTC) == [[bêhîkarî bûn]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 09:00, 1 nîsan 2024 (UTC) == [[bêhîkarî kirin]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 09:00, 1 nîsan 2024 (UTC) == [[bêhîkarîbûn]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 09:01, 1 nîsan 2024 (UTC) == [[bêhîkarîkirin]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 09:01, 1 nîsan 2024 (UTC) == [[hîkarîkirî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 09:02, 1 nîsan 2024 (UTC) == [[hîkarîkirin]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 09:03, 1 nîsan 2024 (UTC) == [[hîkarî kirin]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 09:07, 1 nîsan 2024 (UTC) == [[rayda]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 09:40, 1 nîsan 2024 (UTC) == [[bêrayda]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 09:42, 1 nîsan 2024 (UTC) == [[bêraydayî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 09:43, 1 nîsan 2024 (UTC) == [[bêraydatî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 09:43, 1 nîsan 2024 (UTC) == [[bêrayda bûn]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 09:43, 1 nîsan 2024 (UTC) == [[bêrayda kirin]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 09:43, 1 nîsan 2024 (UTC) == [[bêraydabûn]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 09:44, 1 nîsan 2024 (UTC) == [[bêraydakirin]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 09:44, 1 nîsan 2024 (UTC) == [[birayda]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 09:44, 1 nîsan 2024 (UTC) == [[biwerêç]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 09:46, 1 nîsan 2024 (UTC) == [[biwerêçî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 09:46, 1 nîsan 2024 (UTC) == [[biwerêçîtî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 09:47, 1 nîsan 2024 (UTC) == [[biwerêçtî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 09:47, 1 nîsan 2024 (UTC) == [[werêç]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 09:49, 1 nîsan 2024 (UTC) == [[werêç kirin]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 09:50, 1 nîsan 2024 (UTC) == [[werêçkirî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 09:50, 1 nîsan 2024 (UTC) == [[werêçkirin]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 09:51, 1 nîsan 2024 (UTC) == [[wişto]] == @[[Bikarhêner:Zerwanda]] Çavkanî ji bo kurmancî tine ye. Zazakî ye? —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 20:19, 1 nîsan 2024 (UTC) :ji devera mûşê, aliyê diya min "wişto/wiştik" digotin. [[Bikarhêner:Zerwanda|Zerwanda]] ([[Gotûbêja bikarhêner:Zerwanda|gotûbêj]]) 20:44, 1 nîsan 2024 (UTC) == [[xewgerî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 10:19, 2 nîsan 2024 (UTC) == [[xewgerokî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 10:28, 2 nîsan 2024 (UTC) == [[nimêh]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 15:51, 2 nîsan 2024 (UTC) == [[فعال]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' [[Bikarhêner:Ghybu|Gyhbu]] di 2021an de li ser rûpela wî tevlî kirîye. Lê ji ber nebûna vê sîstema me tevlî vir nebûye. Lewma min anî ser vir jî. Wê gavê tenê ji bo maneya "kar" ev şablon hatîye tevlîkirin. — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 07:27, 3 nîsan 2024 (UTC) == [[pêjor]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 21:46, 6 nîsan 2024 (UTC) == [[hafil]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 21:48, 6 nîsan 2024 (UTC) == [[micemi]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' Muhtemelem şiklê rast wek "micemî" ye, lê ew jî bêçavkanî ye. — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 11:52, 9 nîsan 2024 (UTC) == [[hesaba xwe]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' Ji xeynî van ev forma wê jî bêçavkanî ne: "[[hisaba xwe]] / [[hesaba xo]] / [[hisaba xo]]". — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 13:25, 9 nîsan 2024 (UTC) == [[leşkerma]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 22:53, 24 nîsan 2024 (UTC) = Gulan 2024 = == [[serîi]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' Wek "serî" belkî li kar be, lê wekî "serîi" çavkanî peyda nabe. — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 16:20, 2 gulan 2024 (UTC) == [[virgu]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' Bêçavkanî tê xuyan. Peyv bi tirkî ye. — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 18:49, 2 gulan 2024 (UTC) == [[xwerre]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 18:57, 20 gulan 2024 (UTC) = Hezîran 2024 = == [[di nav deryaya peyvan de avjenî dikir]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 17:34, 4 hezîran 2024 (UTC) == [[berbixwe]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 09:03, 10 hezîran 2024 (UTC) == [[şipyakî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 09:08, 10 hezîran 2024 (UTC) :"şipêkî" heye [[Bikarhêner:Guherto|Guherto]] ([[Gotûbêja bikarhêner:Guherto|gotûbêj]]) 20:20, 27 tîrmeh 2024 (UTC) == [[wetalane]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 09:18, 10 hezîran 2024 (UTC) == [[wetalî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 09:19, 10 hezîran 2024 (UTC) == [[wetalîtî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 09:20, 10 hezîran 2024 (UTC) == [[wetaltî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 09:20, 10 hezîran 2024 (UTC) == [[se direye karwan dibuhire]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 14:49, 16 hezîran 2024 (UTC) == [[se direwît, karwan bi rêka xo diçît]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' Formeke bêçavkanî ye. — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 14:53, 16 hezîran 2024 (UTC) == [[se direwît, karwan diburît]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' Formeke bêçavkanî ye. — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 14:54, 16 hezîran 2024 (UTC) == [[se direyê karwan dibûrê]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' Formeke bêçavkanî ye. — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 14:55, 16 hezîran 2024 (UTC) == [[se direye karvan li riya xwe diçe]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' Formeke bêçavkanî ye. — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 14:56, 16 hezîran 2024 (UTC) == [[se direye û kerwan dibihure]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' Formeke bêçavkanî ye. — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 15:00, 16 hezîran 2024 (UTC) == [[hingê dinya]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 14:07, 18 hezîran 2024 (UTC) == [[berdanberdan]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 21:22, 24 hezîran 2024 (UTC) == [[nîska mala Barzan]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 08:05, 25 hezîran 2024 (UTC) = Tîrmeh 2024 = == [[avmêwe]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 17:41, 16 tîrmeh 2024 (UTC) == [[nihalok]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 21:53, 24 tîrmeh 2024 (UTC) == [[nihalk]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 21:54, 24 tîrmeh 2024 (UTC) == [[niwalok]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 21:54, 24 tîrmeh 2024 (UTC) == [[niwalk]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 21:55, 24 tîrmeh 2024 (UTC) == [[niwalik]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 21:55, 24 tîrmeh 2024 (UTC) == [[nehalok]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 21:56, 24 tîrmeh 2024 (UTC) == [[nehalk]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 21:56, 24 tîrmeh 2024 (UTC) == [[nehalik]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 21:57, 24 tîrmeh 2024 (UTC) == [[alîkarxwazî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 22:16, 24 tîrmeh 2024 (UTC) == [[nihalik]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 22:19, 24 tîrmeh 2024 (UTC) == [[zêrîb]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' Bi dîtina min, ev form bêçavkanî ye. Dibe ku ji bo forma "zerîb" çavkanî hebe, lê ew form li ser Wîkîferhengê wek made nehatîye çêkirin. Pir kêm be jî ev peyv wek "zerîp" jî li cihekî derbas bûye. — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 22:31, 24 tîrmeh 2024 (UTC) == [[qanat]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' Ev peyv bi maneya "kanal"ê nîne, xelet e. — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 06:59, 25 tîrmeh 2024 (UTC) == [[qenat]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' Ev peyv bi maneya "kanal"ê nîne, xelet e. — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 06:59, 25 tîrmeh 2024 (UTC) :Min 1 çavkanî dît, "Ev kes rojê 6-7 qenatên TV ya diğere û diaxive" https://darkamazi.info/archives/1019704 (bi lêgerana "qenatên", ji ber ko lêgeranên dî tijî tiştên dî derdixin) :Lê mimkun e xelet nivîsîbe. [[Bikarhêner:Guherto|Guherto]] ([[Gotûbêja bikarhêner:Guherto|gotûbêj]]) 20:31, 27 tîrmeh 2024 (UTC) == [[şkaftmend]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 07:08, 25 tîrmeh 2024 (UTC) :3 çavkanî hene. Lê xuya dike jêdera wan hemû ferhenga tirsik.netê e. :* Çavkanî 1: https://tirsik.net/ferheng?query=şkaftmend (berî 2014, lê tarîx nîne) :* Çavkanî 2: https://ku.wikipedia.org/wiki/Deranderî (2011) :* Çavkanî 3: https://x.com/zerdeceno/status/1155331427510247425 (2019) :[[Bikarhêner:Guherto|Guherto]] ([[Gotûbêja bikarhêner:Guherto|gotûbêj]]) 20:28, 27 tîrmeh 2024 (UTC) == [[dan hev#p-mane|dan hev]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' Ev mane li ser çavkanîyan peyda nabe. Tenê çêkerê rûpelê vê maneyê nivîsîye. — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 11:08, 25 tîrmeh 2024 (UTC) == [[baristdar]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 14:47, 25 tîrmeh 2024 (UTC) == [[baristdarî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 14:48, 25 tîrmeh 2024 (UTC) == [[baristdarîtî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 14:49, 25 tîrmeh 2024 (UTC) == [[baristdartî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 14:50, 25 tîrmeh 2024 (UTC) == [[bibaristî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 14:51, 25 tîrmeh 2024 (UTC) == [[bibarist]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 14:52, 25 tîrmeh 2024 (UTC) == [[bibaristîtî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 14:53, 25 tîrmeh 2024 (UTC) == [[bêbaristî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 14:54, 25 tîrmeh 2024 (UTC) == [[bêbarist]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 14:55, 25 tîrmeh 2024 (UTC) == [[peydabûnîtî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Guherto|Guherto]] ([[Gotûbêja bikarhêner:Guherto|gotûbêj]]) 20:52, 27 tîrmeh 2024 (UTC) == [[nexşvan]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Guherto|Guherto]] ([[Gotûbêja bikarhêner:Guherto|gotûbêj]]) 21:05, 27 tîrmeh 2024 (UTC) == [[nexşvanî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Guherto|Guherto]] ([[Gotûbêja bikarhêner:Guherto|gotûbêj]]) 21:05, 27 tîrmeh 2024 (UTC) == [[lêvikî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Guherto|Guherto]] ([[Gotûbêja bikarhêner:Guherto|gotûbêj]]) 21:47, 27 tîrmeh 2024 (UTC) == [[lêvik]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' Min zêde nemeyzand. —[[Bikarhêner:Guherto|Guherto]] ([[Gotûbêja bikarhêner:Guherto|gotûbêj]]) 21:48, 27 tîrmeh 2024 (UTC) == [[şerenîx kirin]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Guherto|Guherto]] ([[Gotûbêja bikarhêner:Guherto|gotûbêj]]) 21:51, 27 tîrmeh 2024 (UTC) == [[sala çîn]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 16:09, 29 tîrmeh 2024 (UTC) == [[berê pêşîn]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 17:57, 30 tîrmeh 2024 (UTC) == [[berê ewilî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 17:57, 30 tîrmeh 2024 (UTC) = Tebax 2024 = == [[xwîndijmin]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 18:02, 4 tebax 2024 (UTC) == [[reîsîtî]]/[[reysîtî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Guherto|Guherto]] ([[Gotûbêja bikarhêner:Guherto|gotûbêj]]) 18:17, 6 tebax 2024 (UTC) == [[soranîaxivî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Guherto|Guherto]] ([[Gotûbêja bikarhêner:Guherto|gotûbêj]]) 18:43, 6 tebax 2024 (UTC) == [[helîna bildo]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' Ji 2020a ve şablon li wir e min tenê li vir zêde kir. —[[Bikarhêner:Guherto|Guherto]] ([[Gotûbêja bikarhêner:Guherto|gotûbêj]]) 19:56, 6 tebax 2024 (UTC) == [[hilbijêrînerî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' "Hilbij" rihê peyvê ye, "-er" jî maneya "kesê dike" dide, qertafa "-îner / -înerî" ya li dawîyê bi eşkereyî xelet e. Û ev peyv bêçavkanî ye. — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 13:45, 7 tebax 2024 (UTC) == [[îqlîmtî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 13:43, 10 tebax 2024 (UTC) == [[jîrbêjî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' Ev peyv ger di soranî de ji bo wê çavkanîyên têr hebe, tenê wek "Nivîsîna bi herfên latînî ya peyva ..." kare were qeydkirin. Lê nabe ku wek kurmancî be, were qeydkirin. Ji bo kurmancî tenê di meqaleyekê de derbas dibe, ew jî ji alî başûrîyekî ve hatîye nivîsîn. — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 19:55, 10 tebax 2024 (UTC) == [[hîgyen]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' Tenê ev form bêçavkanî ye. — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 07:40, 12 tebax 2024 (UTC) == [[kolîner]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 17:45, 12 tebax 2024 (UTC) == [[poşmanî kişîn]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' Tenê di çavkanîyekê de peyda dibe. Ew çavkanîya dayî jî ihtîmal e ku bi tesîra zimanê tirkî ye. — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 08:44, 13 tebax 2024 (UTC) == [[para hevpar a herî mezin]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 16:09, 14 tebax 2024 (UTC) == [[cara hevpar a herî biçûk]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 16:10, 14 tebax 2024 (UTC) == [[regjimar]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 16:16, 14 tebax 2024 (UTC) == [[nîvrengî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Guherto|Guherto]] ([[Gotûbêja bikarhêner:Guherto|gotûbêj]]) 17:33, 18 tebax 2024 (UTC) == [[nîvdûrgeh]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' Wek "guharto" hatiye qeydkirin, lê yek nikare wilo bêje. Ne "guharto" ye, ji ber wê çavkanî hewce ne. —[[Bikarhêner:Guherto|Guherto]] ([[Gotûbêja bikarhêner:Guherto|gotûbêj]]) 17:39, 18 tebax 2024 (UTC) == [[nîvtewlîsî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Guherto|Guherto]] ([[Gotûbêja bikarhêner:Guherto|gotûbêj]]) 17:44, 18 tebax 2024 (UTC) == [[nîvrewa]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Guherto|Guherto]] ([[Gotûbêja bikarhêner:Guherto|gotûbêj]]) 17:44, 18 tebax 2024 (UTC) == [[nîvşehtî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Guherto|Guherto]] ([[Gotûbêja bikarhêner:Guherto|gotûbêj]]) 17:46, 18 tebax 2024 (UTC) == [[nîvfalincî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Guherto|Guherto]] ([[Gotûbêja bikarhêner:Guherto|gotûbêj]]) 17:46, 18 tebax 2024 (UTC) == [[nîvgilkarî]] == Ferhenga Sa.Sa. ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Guherto|Guherto]] ([[Gotûbêja bikarhêner:Guherto|gotûbêj]]) 17:48, 18 tebax 2024 (UTC) == [[kesîkirin]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Guherto|Guherto]] ([[Gotûbêja bikarhêner:Guherto|gotûbêj]]) 20:16, 18 tebax 2024 (UTC) == [[biryarbirin]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 21:38, 24 tebax 2024 (UTC) = Îlon 2024 = == [[qîblename]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Guherto|Guherto]] ([[Gotûbêja bikarhêner:Guherto|gotûbêj]]) 15:15, 1 îlon 2024 (UTC) == [[cihetnima]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' Ji [https://bianet.org/yazi/ferhenga-ser-u-amrazen-ser-ji-kovara-ronahiye-2-196299 vir] hatiye —[[Bikarhêner:Guherto|Guherto]] ([[Gotûbêja bikarhêner:Guherto|gotûbêj]]) 15:27, 1 îlon 2024 (UTC) == [[qûnderîtî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 15:36, 7 îlon 2024 (UTC) == [[hevpîşehî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 17:48, 14 îlon 2024 (UTC) == [[hevpîşeyî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' Wek ''navdêr'' bêçavkanî ye. Wek ''rengdêr'' hebe jî, kêmçavkanî ye. — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 17:50, 14 îlon 2024 (UTC) == [[hempay]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 18:04, 14 îlon 2024 (UTC) == [[nîs]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 19:43, 14 îlon 2024 (UTC) == [[êxbarçî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' Ji bo ''îxbarçî'' çavkanîyekê peyda dibe, lê kêm e. — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 23:06, 14 îlon 2024 (UTC) == [[muxbîrîtî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 23:38, 14 îlon 2024 (UTC) == [[ixbarçî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 23:43, 14 îlon 2024 (UTC) == [[westgeha pasê]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 16:33, 19 îlon 2024 (UTC) == [[avikmadk]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 17:24, 19 îlon 2024 (UTC) == [[ferwerîn]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 09:18, 20 îlon 2024 (UTC) == [[bipayderî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 11:12, 20 îlon 2024 (UTC) == [[bipayderîtî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 11:13, 20 îlon 2024 (UTC) == [[bipaydertî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 11:13, 20 îlon 2024 (UTC) == [[bipedalî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 11:14, 20 îlon 2024 (UTC) == [[bipedalîtî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 11:14, 20 îlon 2024 (UTC) == [[bipedaltî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 11:14, 20 îlon 2024 (UTC) == [[pedaldarî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 11:15, 20 îlon 2024 (UTC) == [[pedaldarîtî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 11:15, 20 îlon 2024 (UTC) == [[pedaldartî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 11:16, 20 îlon 2024 (UTC) == [[ciwên]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 16:11, 22 îlon 2024 (UTC) == [[belgebirin]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 22:31, 23 îlon 2024 (UTC) == [[avsîn]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' Dibe ku ev kelîme biçavkanî be, lê pir bêagahî hatîye qeydkirin. Biçavkanî be jî, ji ber qeydkirina bêagahî (li ser madeyê agahî kêm hatine pêşkêşkirin) em rûpelê jê bibin. — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 22:53, 23 îlon 2024 (UTC) :@[[Bikarhêner:Bikarhêner|Bikarhêner]] Ma ne çêtir e li "Daxwazên zelalkirinê" be naxwe? [[Bikarhêner:Guherto|Guherto]] ([[Gotûbêja bikarhêner:Guherto|gotûbêj]]) 13:40, 10 çiriya paşîn 2024 (UTC) :: {{r|Guherto}} Bi min em karin vê madeyê ji ber bêagahîbûna wî, îlaweyî "Daxwazên jêbirinê" bikin, lê "Daxwazên zelalkirinê" nabe. Wekî din ji ber ku dikeve çarçoveya her du rûpelan jî kîjan be jî dibe, lê madem me li vir da destpêkirin, bila ji vir dewam bike dengdana li ser vê kelîmeyê. -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 21:22, 10 çiriya paşîn 2024 (UTC) == [[kûvank]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' Herçiqas tenê formekê be jî, bêçavkanî ye. — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 21:14, 27 îlon 2024 (UTC) == [[kikark]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' Herçiqas formekê be jî, bêçavkanî dixuye. — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 21:40, 27 îlon 2024 (UTC) == [[kîfkarik]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' Herçiqas tenê formekê be jî, bêçavkanî dixuye. — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 21:45, 27 îlon 2024 (UTC) == [[kuvank]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' Herçiqas formekê be jî, bêçavkanî dixuye. — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 21:53, 27 îlon 2024 (UTC) == [[kûvarik]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' Herçiqas tenê formekê be jî, bêçavkanî dixuye. — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 22:01, 27 îlon 2024 (UTC) = Çiriya pêşîn 2024 = == [[muhil]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' Tenê qismê kurdî bêçavkanî ye, ne ya tirkî. — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 21:00, 9 çiriya pêşîn 2024 (UTC) == [[muhilk]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 21:00, 9 çiriya pêşîn 2024 (UTC) == [[jêrmal]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 21:59, 15 çiriya pêşîn 2024 (UTC) = Çiriya paşîn 2024 = == [[bîrxistiner]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 19:38, 14 çiriya paşîn 2024 (UTC) == [[wisa gotin]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' Ne ferhengî ye. — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 20:13, 15 çiriya paşîn 2024 (UTC) == [[tenzîlatî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 16:12, 16 çiriya paşîn 2024 (UTC) == [[armancparêz]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 13:03, 19 çiriya paşîn 2024 (UTC) == [[şikaftmend]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 13:06, 19 çiriya paşîn 2024 (UTC) == [[derander]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 13:08, 19 çiriya paşîn 2024 (UTC) == [[deranderî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 13:09, 19 çiriya paşîn 2024 (UTC) == [[derxwenîn]] == @[[User:Keyomerd]] ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 22:38, 19 çiriya paşîn 2024 (UTC) == [[kiyû]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 23:53, 22 çiriya paşîn 2024 (UTC) == [[goçavik]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 00:03, 23 çiriya paşîn 2024 (UTC) == [[hûrhesibaner]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 00:19, 23 çiriya paşîn 2024 (UTC) == [[heybera zindî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 18:01, 23 çiriya paşîn 2024 (UTC) == [[misadereker]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 12:51, 24 çiriya paşîn 2024 (UTC) == [[kêmtirkar]] == @[[Bikarhêner:Cyrus the virus|Cyrus the virus]] ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 18:11, 24 çiriya paşîn 2024 (UTC) == [[cudagir]] == @[[Bikarhêner:Cyrus the virus|Cyrus the virus]] ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 18:15, 24 çiriya paşîn 2024 (UTC) == [[qerwaşgir]] == @[[Bikarhêner:Cyrus the virus|Cyrus the virus]] ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 18:42, 24 çiriya paşîn 2024 (UTC) == [[mişkilûr]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 18:45, 24 çiriya paşîn 2024 (UTC) == [[agirbiran]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 18:54, 24 çiriya paşîn 2024 (UTC) == [[alan]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 18:55, 24 çiriya paşîn 2024 (UTC) == [[alêdû]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 18:56, 24 çiriya paşîn 2024 (UTC) == [[henaseker]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 17:37, 25 çiriya paşîn 2024 (UTC) == [[nial]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' Ji xeynî vê, maneya 2yem ya di madeya "nihal" de (navdêr 2) jî bêçavkanî ye. — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 23:46, 27 çiriya paşîn 2024 (UTC) == [[gilçim]] == @[[Bikarhêner:Roj Rewandiz|Roj Rewandiz]] ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 14:28, 29 çiriya paşîn 2024 (UTC) :Ez ji bajarê Kobaniyê me. Min ev peyv ji ser zimanê dê û dapîra xwe girt. Ez gelekî ji vê peyvê bawer im ji ber ku devoka min e. [[Bikarhêner:Roj Rewandiz|Roj Rewandiz]] ([[Gotûbêja bikarhêner:Roj Rewandiz|gotûbêj]]) 19:14, 23 kanûna pêşîn 2024 (UTC) ::@[[Bikarhêner:Roj Rewandiz|Roj Rewandiz]] Mala te ava. Ji ber ku çavkaniyên nivîskî tine ne em ê vê kelîmeyê wek [[Wîkîferheng:Pîvekên_tevlîkirinê#Peyvên_herêmî|herêmî]] nîşan bidin. [[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 12:22, 25 kanûna pêşîn 2024 (UTC) == [[reşeme kirin]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' Li gorî çêkera sayfeyê li Kobaniyê li kar e. Loma dikare wekî herêmî nîşankirin —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 14:35, 29 çiriya paşîn 2024 (UTC) :Li Kobaniyê dibêjin: ‘Tizbiyê min li xwe reş û reşeme kir’ Anko Tizbî bir û venegerand Înkar kir. [[Bikarhêner:Roj Rewandiz|Roj Rewandiz]] ([[Gotûbêja bikarhêner:Roj Rewandiz|gotûbêj]]) 23:48, 7 kanûna paşîn 2025 (UTC) = Kanûna pêşîn 2024 = == <s>[[hemderk]]</s> == @[[Bikarhêner:Ferhengvan|Ferhengvan]] ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 10:02, 1 kanûna pêşîn 2024 (UTC) :{{nepeyitandî}}--[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:30, 17 tîrmeh 2026 (UTC) == <s>[[qefesker]]</s> == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 10:23, 1 kanûna pêşîn 2024 (UTC) :{{nepeyitandî}}--[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:31, 17 tîrmeh 2026 (UTC) == <s>[[sêkunc]]</s> == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 00:17, 27 kanûna pêşîn 2024 (UTC) :Saharnews gelek bi kar tîne feqat nivîskarên wan ne belî ne, tenê ev kitêb [https://kurdistankomunistpartisi.com/wp-content/uploads/2022/03/kurdi2.pdf] derbasdar e. :{{nepeyitandî}}--[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:37, 17 tîrmeh 2026 (UTC) == <s>[[pênckunc]]</s> == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 00:20, 27 kanûna pêşîn 2024 (UTC) :{{nepeyitandî}}--[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:37, 17 tîrmeh 2026 (UTC) == [[çarkunc]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 00:21, 27 kanûna pêşîn 2024 (UTC) == <s>[[şeşkunc]]</s> == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 00:21, 27 kanûna pêşîn 2024 (UTC) :{{nepeyitandî}}--[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:38, 17 tîrmeh 2026 (UTC) = Kanûna paşîn 2025 = == <s>[[oktopod]]</s> == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' Ji bo vê formê ti çavkanî nîne. — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 15:10, 1 kanûna paşîn 2025 (UTC) :{{nepeyitandî}}--[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:41, 17 tîrmeh 2026 (UTC) == [[pevnatî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' Ev kelîme wek kurtkirina ji "bi hev nehatî" hatîye fikirîn, ihtimal e ku wek sunî hatîye çêkirin û bêçavkanî ye. — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 13:43, 6 kanûna paşîn 2025 (UTC) == [[lihevnatîbûn]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' Wek formeke "lihevnehatîbûn"ê hatîye fikirîn, lê bêçavkanî ye. — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 13:49, 6 kanûna paşîn 2025 (UTC) == <s>[[fîzîkîtî]]</s> == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 20:19, 7 kanûna paşîn 2025 (UTC) :{{nepeyitandî}}--[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:42, 17 tîrmeh 2026 (UTC) == <s>[[kobar]]</s> == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 14:59, 21 kanûna paşîn 2025 (UTC) :{{nepeyitandî}}--[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:11, 17 tîrmeh 2026 (UTC) == <s>[[werdanbar]]</s> == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 14:59, 21 kanûna paşîn 2025 (UTC) :{{nepeyitandî}}--[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:10, 17 tîrmeh 2026 (UTC) == [[Binxetê]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' Em zanin ku ji ber sînora Tirkîyeyê ku Cizîrê dike du perçe û ji parçeya binî re Binxet tê gotin ku kurd lê dijîn. Feqet min herêma Binxetê seh nekirîye, û bi tedqîqeke neberfireh jî çavkanî peyda nekir ji bo vê peyvê. Lewma bi min mahîyeta vê madeyê û qeydkirina wek "Binxetê" xelet e. Ger ji bo herêma tarîfkirî çavkanî nîn be, em vê madeyê bikin "'''Binxet'''" û tarîfa wê jî bikin "''Navê Rojavayê Kurdistanê ku li binê xeta Tirkîye - Sûrîyeyê dimîne.''" — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 00:22, 24 kanûna paşîn 2025 (UTC) == [[xirecir çêkirin]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' "''Çê''" bi maneya "''baş''" e, û "''çêkirin''" ji bo tiştên pozîtîv likar e, li nav milet jî ev wisa ye. Lewma ev xelet e. — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 20:00, 24 kanûna paşîn 2025 (UTC) == <s>[[bêonurane]]</s> == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 19:19, 26 kanûna paşîn 2025 (UTC) :{{nepeyitandî}}--[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:09, 17 tîrmeh 2026 (UTC) == <s>[[sabûnsazxane]]</s> == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' Xelet e û bêçavkanî ye. — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 19:24, 26 kanûna paşîn 2025 (UTC) :{{nepeyitandî}}--[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:08, 17 tîrmeh 2026 (UTC) == [[sîrkxane]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 19:30, 26 kanûna paşîn 2025 (UTC) == <s>[[rewanwerziş]]</s> == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 19:33, 26 kanûna paşîn 2025 (UTC) :{{nepeyitandî}}--[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:11, 17 tîrmeh 2026 (UTC) == <s>[[rewanwerzişxane]]</s> == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 19:34, 26 kanûna paşîn 2025 (UTC) :{{nepeyitandî}}--[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:12, 17 tîrmeh 2026 (UTC) == <s>[[qeşaşîrxane]]</s> == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 19:36, 26 kanûna paşîn 2025 (UTC) :{{nepeyitandî}}--[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:14, 17 tîrmeh 2026 (UTC) == <s>[[tiwaletxane]]</s> == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 19:37, 26 kanûna paşîn 2025 (UTC) :{{nepeyitandî}}--[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:14, 17 tîrmeh 2026 (UTC) == [[anînder]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' Di hin çavkanîyan de wek formeke "''der'''''anîn'''"ê hatîye qeydkirin. Lê belê çavkanîyeke eslî (ne ji kitêbên gramerê) peyda nabe ji bo vê kelîmeyê. — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 00:24, 27 kanûna paşîn 2025 (UTC) == <s>[[komherf]]</s> == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Wikihez|Wikihez]]<small><sup>'''[[Bikarhêner:Balyozxane|Balyozxane]]''' ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]])</sup></small> 20:18, 29 kanûna paşîn 2025 (UTC) :{{nepeyitandî}}--[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:16, 17 tîrmeh 2026 (UTC) == <s>[[komtîp]]</s> == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Wikihez|Wikihez]]<small><sup>'''[[Bikarhêner:Balyozxane|Balyozxane]]''' ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]])</sup></small> 20:19, 29 kanûna paşîn 2025 (UTC) :845û* Husein Muhemmed 2016 [https://zimannas.wordpress.com/2016/03/13/kurdizar-ferhenga-sorani-kurmanci-e/] :* Kovara deng [https://www.kovaradeng.com/upload/arsivpdf/Deng%20110.pdf] Mana ne alfabe ye "komtîpên « dj, kh, tch » yê, li cîyê dengên me yên ku bi « c, x, ç » yê hatine dîyarkirin de bikaranîne" :* resadcibrani.blogspot [https://resadcibrani.blogspot.com/p/lekolin.html] tarîx û nivîskar ne belî ye. :Çavkaniyên Instagram, Tiktok, Facebook nayê qebûlkirin loma: :{{nepeyitandî}}--[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:25, 17 tîrmeh 2026 (UTC) == <s>[[tîpgel]]</s> == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Wikihez|Wikihez]]<small><sup>'''[[Bikarhêner:Balyozxane|Balyozxane]]''' ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]])</sup></small> 20:19, 29 kanûna paşîn 2025 (UTC) :{{nepeyitandî}}--[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:26, 17 tîrmeh 2026 (UTC) == [[rastî nîşandan]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 18:14, 30 kanûna paşîn 2025 (UTC) = Sibat 2025 = == <s>[[bêbirî]]</s> == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' Dibe ku xeletîya botê be. — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 18:38, 1 sibat 2025 (UTC) :{{nepeyitandî}}--[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:45, 17 tîrmeh 2026 (UTC) == <s>[[soraxker]]</s> == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 17:24, 2 sibat 2025 (UTC) :{{nepeyitandî}}--[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:46, 17 tîrmeh 2026 (UTC) == <s>[[bîrdozvanî]]</s> == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 19:26, 3 sibat 2025 (UTC) :{{nepeyitandî}}--[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 17:40, 17 tîrmeh 2026 (UTC) == [[pir hindik#p-mane|pir hindik]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 22:31, 3 sibat 2025 (UTC) == <s>[[navçegir]]</s> == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 21:15, 4 sibat 2025 (UTC) : Zana farqînî ji xeynî wî çavkanî nîne, çend xeberên anonîm bi forma navçegirî heye lê ew jî têr nake. {{nepeyitandî}}--[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 17:47, 17 tîrmeh 2026 (UTC) == <s>[[baweranî]]</s> == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' Di ferhenga J. Blau ya "DICTIONNAIRE KURDE/TURC/FRANÇAIS/ANGLAIŞ KURDISH/TURKISH/FRENCH/ENGLISH DICTIONARY" (tercimeya tirkî Fethullah Kakioglu, 1991) der derbas dibe, feqet li cihên din peyda nabe. Wek etîmolojî jî dibe ku ji "bawerîanî" hatibe. — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 22:59, 5 sibat 2025 (UTC) : Ferhenga Baran Rizgar de jî heye lê çavkaniya sisêya nîne loma {{nepeyitandî}}--[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 17:53, 17 tîrmeh 2026 (UTC) == [[anteroz]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 01:19, 15 sibat 2025 (UTC) == [[veşidandin]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 21:43, 15 sibat 2025 (UTC) == [[karîwer kirin]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 02:01, 16 sibat 2025 (UTC) == [[hil girtin]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 21:06, 17 sibat 2025 (UTC) == [[wer girtin]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 21:07, 17 sibat 2025 (UTC) == [[avkûre]] == @[[Bikarhêner:Mohajeer|Mohajeer]] ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 20:36, 18 sibat 2025 (UTC) == [[derdek girtin]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 23:42, 18 sibat 2025 (UTC) == [[vekitandin]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 19:12, 21 sibat 2025 (UTC) == [[dînperist]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 01:32, 22 sibat 2025 (UTC) == [[ayînperist]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 01:33, 22 sibat 2025 (UTC) == [[ayînperistî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 01:33, 22 sibat 2025 (UTC) == [[ayînperistane]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 01:33, 22 sibat 2025 (UTC) == [[piştrastkirinbar]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 01:45, 23 sibat 2025 (UTC) == [[diyarkirinbar]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 02:08, 23 sibat 2025 (UTC) == [[hevhatî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 03:52, 1 adar 2025 (UTC) == [[kerexne]] == @[[Bikarhêner:Rojhilat|Rojhilat]] ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 15:05, 1 adar 2025 (UTC) == [[pawan#p-mane|pawan]] == Ferhenga Hejar soranî ye, ji bo maneya "cihê qedexekirî, cihê inhisarî" ji xeynî wê çavkanî heye gelo —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 20:17, 3 adar 2025 (UTC) == [[taqane]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 02:11, 6 adar 2025 (UTC) == [[gosirmetî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 23:07, 6 adar 2025 (UTC) == [[matîjêker]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 20:08, 14 adar 2025 (UTC) == [[hilewesan]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 21:14, 16 adar 2025 (UTC) == [[peydandin#p-mane|peydandin]] == Ji bo maneya [[dûre]], [[paşî]], [[piştî]] wê / wî ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 20:26, 19 adar 2025 (UTC) == [[peşar]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 20:36, 19 adar 2025 (UTC) == [[nûzaf]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:30, 20 adar 2025 (UTC) == [[deynname]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 22:08, 20 adar 2025 (UTC) == [[girtek]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 22:29, 20 adar 2025 (UTC) == [[bêşxane]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 00:25, 23 adar 2025 (UTC) == [[superleheng]] == @[[Bikarhêner:Avestaboy|Avestaboy]] ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 11:34, 23 adar 2025 (UTC) == [[goranparêz]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 21:54, 27 adar 2025 (UTC) == [[raber#p-mane|raber]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 16:09, 1 nîsan 2025 (UTC) == [[morîvanî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 20:06, 1 nîsan 2025 (UTC) == [[wevde]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 12:17, 3 nîsan 2025 (UTC) == [[şandêr]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 17:31, 3 nîsan 2025 (UTC) == [[giloverî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' Tenê li ser Ferhenga Zaravên Teknîkî û hejmara yekem ya kovara Bernamegehê derbas dibe. —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 09:10, 4 nîsan 2025 (UTC) == [[xêvjimêr]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 00:00, 12 nîsan 2025 (UTC) == [[paşekeft]] == @[[Bikarhêner:Jiyar Hesen|Jiyar Hesen]] ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 11:11, 13 nîsan 2025 (UTC) == [[paşekeft kirin]] == @[[Bikarhêner:Jiyar Hesen|Jiyar Hesen]] ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 11:12, 13 nîsan 2025 (UTC) == [[hawirkanî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 22:36, 20 nîsan 2025 (UTC) == [[hawirkan]] == @[[Bikarhêner:Ferhengvan|Ferhengvan]] ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 22:18, 21 nîsan 2025 (UTC) : Di çavkanîyeke de "''hawrikan''" (ku wek forma vê kelîmeyê hatîye nîşandayîn û wek "hevrêyan" a kurmancî ye) bi maneya "''friends''"a îngilîzî hatîye emilandin. Wekî din ti çavkanî nîne ji bo vê peyvê. Ger ev "hevrik"a kurmancî be, li vir dîsa xelet e. Bi her awayî divê were jêbirin. -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 22:28, 21 nîsan 2025 (UTC) == [[hawirkanî]] == @[[Bikarhêner:Cyrus the virus|Cyrus the virus]] ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 22:18, 21 nîsan 2025 (UTC) == [[hawirkanvanî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 22:18, 21 nîsan 2025 (UTC) == [[riberiz]] == @[[Bikarhêner:Ferhengvan|Ferhengvan]] ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 22:39, 21 nîsan 2025 (UTC) :Ez bawer im ku ev hat peyitandin. Min çavkanî di beşa gotûbêjê de dan û şablona bêçavkanîtiyê rakir. [[Bikarhêner:Ferhengvan|Ferhengvan]] ([[Gotûbêja bikarhêner:Ferhengvan|gotûbêj]]) 06:11, 25 nîsan 2025 (UTC) == [[awam]] == @[[User:Ferhengvan|Ferhengvan]] Min ev kelîme di ferhengên din de nedît. Gelo di kurmancî de tê bikaranîn? —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 21:09, 23 nîsan 2025 (UTC) :@[[Bikarhêner:Zerwanda|Zerwanda]] tu jî forma [[vam]] ya vê kelîmeyê diemilînî, gelo çavkanî ji bo wê jî heye? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 21:11, 23 nîsan 2025 (UTC) ::Min jî li vir peyda kir û dest kar anîn kir, hemin ev li guherrên dengî ên Kurmancî dihat (*ebam > *ewam > *wam > vam; wek *ebaj- > {{q|ku|vajî}}). Min gotibû qey di zarawayê kesekî da hebûye û wî bi ser va kiriye û jixwe nepêkan nîn e ku di zimên da hebe îcar rind e, nê min jî serkanî tine ji bonê. [[Bikarhêner:Zerwanda|Zerwanda]] ([[Gotûbêja bikarhêner:Zerwanda|gotûbêj]]) 21:37, 23 nîsan 2025 (UTC) :::https://bnk.institutkurde.org/images/pdf/4UVB2YMZG3.pdf :::Di vê kitêbê de bi forma wam derbas dibe 1 Wam : qerz, dên. " dîsa jî gereg 3 çavkanî hebe. :::Lê di beşa etîmolojiyê de eger em karibin zimanekî yekgirtî biemilînin, dê baştir be. Wekî din "bi vê enflasyona kelîmeyan" em nikarin ti tiştî bidin fêmkirin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 21:54, 23 nîsan 2025 (UTC) == [[arvanê hûr]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 09:48, 27 nîsan 2025 (UTC) == [[damezrak]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 13:47, 27 nîsan 2025 (UTC) == [[mezrak]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 13:49, 27 nîsan 2025 (UTC) == [[hevhemetî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 15:25, 6 gulan 2025 (UTC) == [[navhemetî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 15:25, 6 gulan 2025 (UTC) == [[entîte]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 15:08, 17 gulan 2025 (UTC) == [[agirvekujêner]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 00:35, 21 gulan 2025 (UTC) == [[progres]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 00:50, 23 gulan 2025 (UTC) == [[bûncî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 22:29, 28 gulan 2025 (UTC) == [[tasît]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 15:36, 31 gulan 2025 (UTC) == [[implîcît]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 15:37, 31 gulan 2025 (UTC) == [[hewedar]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 19:14, 31 gulan 2025 (UTC) == [[destajo]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 22:38, 31 gulan 2025 (UTC) == [[binhimbank]] == @[[Bikarhêner:Ferhengvan|Ferhengvan]] ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 01:23, 1 hezîran 2025 (UTC) == [[şîmane]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 23:31, 2 hezîran 2025 (UTC) == [[materya]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 16:12, 5 hezîran 2025 (UTC) == [[bêtî]] == @[[Bikarhêner:Ferhengvan|Ferhengvan]] ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 13:03, 7 hezîran 2025 (UTC) == [[rîbat]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 17:21, 9 hezîran 2025 (UTC) == [[hevtawan]] == @[[Bikarhêner:Ferhengvan|Ferhengvan]] ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 10:26, 12 hezîran 2025 (UTC) :Pirsek: "Hevwate" kelîmeyên ku maneyan wan hev in. "hevtawan" çawa dibe "şirîkên sûcekê"? Gereg sûcên ku tiştê wan hev bin? Ew tişt çi ye? Çima dibe şirîk? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 10:32, 12 hezîran 2025 (UTC) ::Merheba! ::"Hevtawan" anku "şirîkên heman tawanê, kesên ku heman tawan kiriye/dikin", wek "hevkar = şirîkên heman karî, kesên ku heman karî dikin", "hevjîn = şirîkên heman jiyanê, kesên ku bi hev re dijîn"... [[Bikarhêner:Ferhengvan|Ferhengvan]] ([[Gotûbêja bikarhêner:Ferhengvan|gotûbêj]]) 06:11, 30 hezîran 2025 (UTC) == [[zanîş]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 12:07, 14 hezîran 2025 (UTC) == [[zanîşwer]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 12:07, 14 hezîran 2025 (UTC) == [[zanmend]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 12:09, 14 hezîran 2025 (UTC) == [[zandar]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 21:08, 14 hezîran 2025 (UTC) == [[zayîndar]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 21:12, 14 hezîran 2025 (UTC) == [[zayindar]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 21:12, 14 hezîran 2025 (UTC) == [[akund]] == @[[Bikarhêner:Ferhengvan|Ferhengvan]] ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 01:16, 16 hezîran 2025 (UTC) == [[destbikar]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 07:41, 22 hezîran 2025 (UTC) == [[vekitandin]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:DarkAngel2100|DarkAngel2100]] ([[Gotûbêja bikarhêner:DarkAngel2100|gotûbêj]]) 10:45, 2 tîrmeh 2025 (UTC) Çavkanî: Kurdish-English Dictionary by Baran Rizgar == [[peşarmend]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 17:54, 5 tîrmeh 2025 (UTC) == [[zaîd]] == @[[Bikarhêner:Ferhengvan|Ferhengvan]] ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 06:59, 6 tîrmeh 2025 (UTC) == [[Xrîst]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 07:13, 10 tîrmeh 2025 (UTC) == [[hesibanî kirin]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 09:48, 13 tîrmeh 2025 (UTC) == [[top danîn]] == @[[Bikarhêner:Ferhengvan|Ferhengvan]] ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 10:08, 13 tîrmeh 2025 (UTC) == [[çûkger]] == @[[Bikarhêner:Dûrzan|Dûrzan]] ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:49, 18 tîrmeh 2025 (UTC) == [[dûneçkar]] == @[[Bikarhêner:212.175.166.246|212.175.166.246]] ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 15:38, 10 tebax 2025 (UTC) == [[sermirov]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 15:22, 13 tebax 2025 (UTC) == [[nifira Esed]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 16:00, 19 tebax 2025 (UTC) == [[dilkrîz]] == @[[Bikarhêner:Kurd87612|Kurd87612]] ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 10:44, 23 tebax 2025 (UTC) == [[berxa Xwedê]] == @[[Bikarhêner:Kurd87612|Kurd87612]] ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 14:28, 31 tebax 2025 (UTC) == [[destmatî]] == @[[Bikarhêner:Ferhengvan|Ferhengvan]] ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 17:47, 21 îlon 2025 (UTC) == [[sîbaq]] == @[[Bikarhêner:Ferhengvan|Ferhengvan]] ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 20:33, 27 îlon 2025 (UTC) == [[mirovê daristanê]] == @[[Bikarhêner:Hewarwîkîferheng|Hewarwîkîferheng]] ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 08:09, 18 çiriya pêşîn 2025 (UTC) == [[çavbijîşk]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 18:30, 24 çiriya pêşîn 2025 (UTC) == [[makeşar]] == @[[Bikarhêner:Avestaboy|Avestaboy]] ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 06:46, 14 kanûna pêşîn 2025 (UTC) :Silav @[[Bikarhêner:Bikarhêner|Bikarhêner]] min bi derew peyv çê nekir. Peyva makeşar di sepana O-ferheng û her wiha di ferhenga online ferhengkurdi.org ya '''Enstîtuya Kurdî ya Stenbolê''' tê xwendin. :https://ferhengkurdi.org/tr/kelime/make%C5%9Far-n [[Bikarhêner:Avestaboy|Avestaboy]] ([[Gotûbêja bikarhêner:Avestaboy|gotûbêj]]) 11:07, 18 kanûna pêşîn 2025 (UTC) ::Krîterên me yên tevlîkirina kelîmeyan heye. Ev made rîayeta wan krîteran nake. Lewma min vê kelîmeyê li vir bicih kir. -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 23:28, 18 kanûna pêşîn 2025 (UTC) == [[bihîstinzanî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:30, 23 hezîran 2026 (UTC) == [[hevdilî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 20:28, 24 hezîran 2026 (UTC) == [[kemisandin]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 20:45, 24 hezîran 2026 (UTC) == [[kexme]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 20:53, 24 hezîran 2026 (UTC) == [[lêpirsyarker]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 21:32, 24 hezîran 2026 (UTC) == [[raypirs]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 21:34, 24 hezîran 2026 (UTC) == [[helwestpirs]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 21:34, 24 hezîran 2026 (UTC) == [[kopirî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' xuyaye maneyeke wekî pir jî heye dikare were zêdekirin —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 17:33, 25 hezîran 2026 (UTC) == [[merxeme]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 22:55, 25 hezîran 2026 (UTC) == [[mohl]] == @[[Bikarhêner:Far ati|Far ati]] ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 23:14, 25 hezîran 2026 (UTC) == [[irfandarî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 20:30, 26 hezîran 2026 (UTC) == [[axulme]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 00:20, 30 hezîran 2026 (UTC) == [[şewane]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 14:26, 1 tîrmeh 2026 (UTC) == [[poezî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 14:27, 1 tîrmeh 2026 (UTC) == [[sebaxker]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 22:20, 1 tîrmeh 2026 (UTC) == [[sebaxfiroş]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 22:21, 1 tîrmeh 2026 (UTC) == [[siboxfiroş]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 22:21, 1 tîrmeh 2026 (UTC) == [[diyardenasîtî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 22:26, 1 tîrmeh 2026 (UTC) == [[dawxane]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 10:41, 3 tîrmeh 2026 (UTC) == [[pêşajotî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 17:15, 3 tîrmeh 2026 (UTC) == [[kontînentaltirîn]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 17:35, 3 tîrmeh 2026 (UTC) == [[azmayîşker]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 22:16, 3 tîrmeh 2026 (UTC) == [[ateşparêz]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 05:19, 4 tîrmeh 2026 (UTC) == [[kurtetarîx]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 11:52, 4 tîrmeh 2026 (UTC) == [[besayetî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 17:57, 4 tîrmeh 2026 (UTC) == [[tawbijêr]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 20:45, 4 tîrmeh 2026 (UTC) == [[destbir]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 11:30, 5 tîrmeh 2026 (UTC) == [[nekider]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 22:56, 5 tîrmeh 2026 (UTC) == [[niqar]] == —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 23:39, 5 tîrmeh 2026 (UTC) == [[parêzîn]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' Ev form li ti derê peyda nabe. Berî çendîn salan hatîye çêkirin. Bi qenaeta min şaş e, lewma em jê bibin. — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 10:29, 6 tîrmeh 2026 (UTC) == [[stêrfizîk]] == . —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 20:33, 6 tîrmeh 2026 (UTC) == [[pêçavik]] == . Eger ev kelîmeyeke mehelî be, Jkx şablona {{şx|dever|cihê ku lê tê bikaranîn}} li madeyê zêde bike. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 14:59, 7 tîrmeh 2026 (UTC) == [[qerqef]] == . Eger ev kelîmeyeke mehelî be, Jkx şablona {{şx|dever|cihê ku lê tê bikaranîn}} li madeyê zêde bike. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 15:17, 7 tîrmeh 2026 (UTC) == [[rakar]] == . Eger ev kelîmeyeke mehelî be, Jkx şablona {{şx|dever|cihê ku lê tê bikaranîn}} li madeyê zêde bike. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 15:30, 7 tîrmeh 2026 (UTC) == [[remilîn]] == . Eger ev kelîmeyeke mehelî be, Jkx şablona {{şx|dever|cihê ku lê tê bikaranîn}} li madeyê zêde bike. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 15:36, 7 tîrmeh 2026 (UTC) == [[segurî]] == . —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 15:51, 7 tîrmeh 2026 (UTC) == [[serdev]] == Bnr. [[Wîkîferheng:Pîvekên tevlîkirinê|Krîterên tevlîkirinê]] —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:10, 7 tîrmeh 2026 (UTC) == [[serziman]] == Bnr. [[Wîkîferheng:Pîvekên tevlîkirinê|Krîterên tevlîkirinê]] —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 17:01, 7 tîrmeh 2026 (UTC) == [[tenîsk]] == di Înternetê de gelek netîce derdikevin lê ji bo ku dûre ez kontrol bikim û çavkaniyên sehîh binivîsim li vir îlawe dikim. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 20:53, 7 tîrmeh 2026 (UTC) == [[tertî]] == Bnr. [[Wîkîferheng:Pîvekên tevlîkirinê|Krîterên tevlîkirinê]] —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 20:58, 7 tîrmeh 2026 (UTC) == [[tirut]] == Bnr. [[Wîkîferheng:Pîvekên tevlîkirinê|Krîterên tevlîkirinê]] —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 21:25, 7 tîrmeh 2026 (UTC) == [[tizqa]] == Bnr. [[Wîkîferheng:Pîvekên tevlîkirinê|Krîterên tevlîkirinê]] —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 21:28, 7 tîrmeh 2026 (UTC) == [[têkilîdêr]] == Bnr. [[Wîkîferheng:Pîvekên tevlîkirinê|Krîterên tevlîkirinê]] —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 21:31, 7 tîrmeh 2026 (UTC) == [[tîtalk]] == Bnr. [[Wîkîferheng:Pîvekên tevlîkirinê|Krîterên tevlîkirinê]] —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 21:33, 7 tîrmeh 2026 (UTC) == [[vircoq]] == Bnr. [[Wîkîferheng:Pîvekên tevlîkirinê|Krîterên tevlîkirinê]] —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 21:45, 7 tîrmeh 2026 (UTC) == [[xilêbat]] == Bnr. [[Wîkîferheng:Pîvekên tevlîkirinê|Krîterên tevlîkirinê]]. Li gorî kurteya çêkirina sayfeyê li Qamişlo û Amûdê tê bikaranîn. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 22:14, 7 tîrmeh 2026 (UTC) == [[xin_û_cûc]] == Bnr. [[Wîkîferheng:Pîvekên tevlîkirinê|Krîterên tevlîkirinê]] —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 22:27, 7 tîrmeh 2026 (UTC) == [[çiteba]] == Bnr. [[Wîkîferheng:Pîvekên tevlîkirinê|Krîterên tevlîkirinê]] —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 22:38, 7 tîrmeh 2026 (UTC) == [[desttêl]] == Bnr. [[Wîkîferheng:Pîvekên tevlîkirinê|Krîterên tevlîkirinê]] —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 08:45, 8 tîrmeh 2026 (UTC) == [[Mîmedol]] == Bnr. [[Wîkîferheng:Pîvekên tevlîkirinê|Krîterên tevlîkirinê]] —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 08:51, 8 tîrmeh 2026 (UTC) == [[alaf]] == Bnr. [[Wîkîferheng:Pîvekên tevlîkirinê|Krîterên tevlîkirinê]] —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 14:01, 8 tîrmeh 2026 (UTC) == [[aşirme]] == Bnr. [[Wîkîferheng:Pîvekên tevlîkirinê|Krîterên tevlîkirinê]] —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 10:13, 10 tîrmeh 2026 (UTC) == [[geledîmentî]] == Bnr. [[Wîkîferheng:Pîvekên tevlîkirinê|Krîterên tevlîkirinê]] —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 20:54, 13 tîrmeh 2026 (UTC) == [[çendîmentî]] == Bnr. [[Wîkîferheng:Pîvekên tevlîkirinê|Krîterên tevlîkirinê]] —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 20:54, 13 tîrmeh 2026 (UTC) == [[paşmak]] == Bnr. [[Wîkîferheng:Pîvekên tevlîkirinê|Krîterên tevlîkirinê]] —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:34, 15 tîrmeh 2026 (UTC) == <s>[[zazakînas]]</s> == Bnr. [[Wîkîferheng:Pîvekên tevlîkirinê|Krîterên tevlîkirinê]] —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:16, 15 tîrmeh 2026 (UTC) :{{nepeyitandî}}--[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 22:05, 19 tîrmeh 2026 (UTC) == [[rojeng]] == Bnr. [[Wîkîferheng:Pîvekên tevlîkirinê|Krîterên tevlîkirinê]] —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 22:41, 18 tîrmeh 2026 (UTC) == [[bereyîşk]] == Bnr. [[Wîkîferheng:Pîvekên tevlîkirinê|Krîterên tevlîkirinê]] —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 15:47, 19 tîrmeh 2026 (UTC) 1vr6dr4by2u9i4jebjg6hdn8v1x4ryq 6265694 6265689 2026-07-19T22:29:28Z Wikihez 7344 [[MediaWiki:Gadget-aWa.js/belgekirin|aWa]]: Arşîvkirina 1 madeyê li [[Gotûbêj:zazakînas]] 6265694 wikitext text/x-wiki {{/destpêk}} = Hezîran 2020 = == [[romî#Navdêr|romî]] == Li Şingalê maneya polîs? --[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 08:00, 15 hezîran 2020 (UTC) = Tîrmeh 2020 = == [[kêlb#p-mane|kêlb]] == --[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 14:24, 22 tîrmeh 2020 (UTC) == [[ejî#p-mane|ejî]] == --[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 14:24, 22 tîrmeh 2020 (UTC) == [[tutirk#peyitandin|tutirk]] == --[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 22:02, 22 tîrmeh 2020 (UTC) :{{r|Guherto}} Niha çawa ye? Bi ya min çavkaniyên ku min dane têrê me dike. --[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 22:43, 22 tîrmeh 2020 (UTC) ::{{r|Balyozxane}} Nizanim.. li hin deveran wek tutirk hatîye nivîsandin û li hin jî wek tûtirk. Li hin deveran bi wateya tûşêmî (Rubus) ye, hin deveran jî bi wateya tûerd (Fragaria × ananassa) e û carna jî bi wateya tû (ê spî û reş go li ser daran çê dibin) ye. -- [[Bikarhêner:Guherto|Guherto]] ([[Gotûbêja bikarhêner:Guherto|gotûbêj]]) 08:16, 23 tîrmeh 2020 (UTC) == [[erbane#p-mane|erbane]] == Ji bo ''Amûreke tenê tekerekî wê heye ji bo veguhestina tiştan wek: axê, kevir, hwd'' ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]]''--[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 22:42, 31 tîrmeh 2020 (UTC) = Tebax 2020 = == [[cifta berazan]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]]'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 22:57, 9 tebax 2020 (UTC) == [[tê gerîn]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]]'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 22:26, 10 tebax 2020 (UTC) == [[tapor]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]]'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 20:30, 22 tebax 2020 (UTC) :{{r|Mihemed Qers}} -- [[Bikarhêner:Guherto|Guherto]] ([[Gotûbêja bikarhêner:Guherto|gotûbêj]]) 22:16, 22 tebax 2020 (UTC) == [[şimzare]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]]'' —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 19:01, 26 tebax 2020 (UTC) == [[bîrkok]] == Tenê Mehmed Uzun bi kar tîne. Ji bilî kitêbên wî çavkaniyeke din tune. —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 20:38, 28 tebax 2020 (UTC) == [[hunera axaftinê]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]]'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 18:46, 30 tebax 2020 (UTC) == [[derrijîn]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]]'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 07:38, 31 tebax 2020 (UTC) == [[yekal]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]]'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 09:19, 31 tebax 2020 (UTC) == [[av û agir]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]]'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 12:50, 31 tebax 2020 (UTC) : Di çavkaniyeke de wek av û agir kirin derbas dibe û ji wergerandinên inglîzî cuda ye lê nêzîk e.<br> {{jêder-pirtûk|ku|jêgirtin=weke gelek hunermendên ko dû re agir bera berhêm xwe didin Xwedê jî ji bilî maltaba Nûh tevayiyê vê berhema xwe '''av û agir dike''', van melekên xwe yên doxînsist dikişîne asîmanan, li wir wan tawanbar dike, mîna ko bibêje: de biçin û weke xwe bikin, bi derew û tevgerên xwe yên qirêj dijminiya min bikin, Xwedê wan ji asimanan de serjêr davêje xwarê.|nivîskar=Hesenê Metê|sernav=Labîrenta cinan|weşanxane=Nefel|sal=2002|rûpel=132}} --[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 13:37, 31 tebax 2020 (UTC) == [[elm#p-mane-notice|elm]] == Wateya: ''[[ewlebûn]], sihê pê zanîn, baş pê zanîn''. ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 17:31, 31 tebax 2020 (UTC) :{{r|Hakîmo}} Ku çavkanî tunebûn em ê jê bibin. --[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 14:47, 19 îlon 2020 (UTC) ::{{r|Balyozxane}} Mala te neketê... Hingê bixwe here lê bigere. Jixwe ez reşwî me. Ma eve ne çavkanî ye? -- [[Bikarhêner:Hakîmo|Hakîmo]] ([[Gotûbêja bikarhêner:Hakîmo|gotûbêj]]) 14:48, 19 îlon 2020 (UTC) :::{{r|Hakîmo}} Hinek bixwîne [[Wîkîferheng:Pîvekên tevlîkirinê]]. Jixwe dema ti kesan din çavkanî lê zêde nakin, ez lê digerim û zêde dikim. Na tu ne ti çavkanî yî. Çavkaniyên nivîskî hewce ne. --[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 14:51, 19 îlon 2020 (UTC) ::::{{r|Balyozxane}} Erê, lê ku tine bin em çawa bikinî? Em hema jê bibinî? -- [[Bikarhêner:Hakîmo|Hakîmo]] ([[Gotûbêja bikarhêner:Hakîmo|gotûbêj]]) 14:52, 19 îlon 2020 (UTC) :::::{{r|Hakîmo}} Erê em jê dibin. Lê peyvên jê hatine birin em li rûpela [[Pêvek:Bêçavkanî]] zêde dikin. bnr. [[:Kategorî:Pêvek bêçavkanî]]. Dîsa jî ez jî ji vê rewşa me aciz im û bi ya min peyvên devokî divê nayên jêbirin. Lê ji ber ku [[Wîkîferheng:Rêbazname]] dibêje divê werin jêbirin, ez jê dibim. Hevalên {{r|Jiju|Guherto|Ghybu}} [https://ku.wiktionary.org/wiki/Got%C3%BBb%C3%AAj:kejm%C3%BBn], [https://ku.wiktionary.org/wiki/Got%C3%BBb%C3%AAja_p%C3%AAvek%C3%AA:B%C3%AA%C3%A7avkan%C3%AE] jî ji vê rewşê aciz in. Lê ti kes gotûbêj nadin destpêkirin. Ku tu li vir [[Gotûbêja Wîkîferhengê:Pîvekên tevlîkirinê]] gotûbêjek bidî destpêkirin, ez ê piştgirî bidime te. --[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 14:58, 19 îlon 2020 (UTC) ::::::Ji kerema xwe min şaş fêm mekin feqet hemû bikarhêner ku tên vira dilpak nînin. Em çito ew peyvan kotrol bikinê? Mixabin, ji bo konrolkirina peyvan di destên me de tenê xwastina çavkaniyan hene amûrek din tine ye... PS: Herwiha me li ser wîkîferhengê Namespace'yên Nimînok ([[Nimînok:Kurdî/serhedî]]?, [[Nimînok:Kurdî/badînî]]?, ..) û Portal ([[Portal:Kurdî]], [[Portal:Frensî]] (mk. [[:fr:Portail:Français]]), ...) jî çêkiriye...--[[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 15:32, 19 îlon 2020 (UTC) :::::::Nizanim we nivîsa vira xwand, [[Wîkîferheng:Dîwan#Skotî]]. Piraniya peyvên wîkiya skotî çêkirî ne...--[[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 15:47, 19 îlon 2020 (UTC) ::::::::@Ghybu erê min ew xwendibû. Ku em peyvan nepeyitînin, rewşa me jî wek mg.wikt û wikiya skotiyan be. Temam em peyvên devokî jê nebin lê em wan jî nexin werger û rûpelên din heta ku werin peyitandin. Herwiha tu dibêjî amûrek tune ye lê tenê ji bo peyvên devokî û navên heywan/riwekan wisa ye. Gelek caran peyitandin pir hêsan e. Mînak @Hakîmo yan jî hevalên din dikarin blogan binivîsin daku em karibin peyvên wan yên devokî (nepeyitandî) têxin rûpela [[Wîkîferheng:Tomarkirina peyvên ji wêjeya kurdî|Jêgirtinekê tomar bike]] û kengî ew peyv ji hêla nivîskar û blogvanên kurd yên din ve hatine bikaranîn hingê em dikarin li wîkîferhengê jî zêde bikin. --[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 16:05, 19 îlon 2020 (UTC) {{outdent|::::::::}}{{r|Hakîmo|Ghybu}} Xêra dê û bavên we '''[[Gotûbêja_Wîkîferhengê:Pîvekên_tevlîkirinê#Li_ser_peyvên_devokî|li vir]]''' fikrên xwe binivîsin daku kesên din bizanin kesên din jî hene vê fikrê min dipejirînin. --[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 06:48, 3 çiriya pêşîn 2020 (UTC) == [[nîşanbar]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 23:51, 31 tebax 2020 (UTC) = Îlon 2020 = == [[besme]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 11:26, 1 îlon 2020 (UTC) == [[ferengi]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 17:12, 1 îlon 2020 (UTC) == [[çelape]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 17:22, 1 îlon 2020 (UTC) == [[cesasandin]] == Çavkaniyek klasîk heye, yên din heye gelo? —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 09:02, 2 îlon 2020 (UTC) == [[depan]] == Depan guhertoyeke textan an textîn e. Lê li vir çi mane heye min fêm nekir. —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 10:33, 2 îlon 2020 (UTC) == [[li rûyê dinê xweş mayîn]] == Çavkaniyeke klasîk heye —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 20:38, 2 îlon 2020 (UTC) == [[bêsewî]] == klasîk —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 06:34, 4 îlon 2020 (UTC) == [[merkemoş]] == Klasîk —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 06:34, 4 îlon 2020 (UTC) == [[firfiroka bayî]] == {{r|Mamoste Dilovan}} ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 12:57, 6 îlon 2020 (UTC) == [[guhê fîlî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 18:56, 7 îlon 2020 (UTC) : {{r|Bikarhêner}} Min guh li evê peyvê bû ji kesekî ku xudan xwaringehek û baxçeyekî mezin e. : Gelek tişt di berbelav in û xelk dizanin, lê di pertûkan de naye dîtin. {{bêîmze|IbrahimKocher Duhok}} == [[gurovî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 14:41, 14 îlon 2020 (UTC) :{{r|Bikarhêner}} Çavkanîyên peyvên ku min nivîsandin mixabin ne nivîskî ne. Ev peyv min ji hin mezinên malbatê bihîstine û min jî gelek caran dîtîne ku hatine bikaranîn. Ji bo ku ev peyv wûnda nebin min hem li ba xwe û hem jî li wîkîferhengê nivîsand. Ji bo peyvên ku çavkanîyên nivîskî tunin, mixabin gotinên devkî tene weke çavkanî dimînin. Pêşnîyara te ji bo pevên bi vî awayî çi ye gelo? Spas{{bêîmze|Xwende}} ::{{r|Xwende}} Pêşî li ser malpera [https://tirsik.net/xerhati.php] dûre jî li ser arsiv.org qeyd bike ku nikarî çavkanî peyda bikî. Herwiha bnr [[Alîkarî:Îmze]] --[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 16:00, 15 îlon 2020 (UTC) == [[şîloyî]] == {{r|Xwende}} ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 14:44, 14 îlon 2020 (UTC) == [[dever]] == Ji bo wateya ''derence, sêlim û merdîwen'' [[Wîkîferheng:Pîvekên tevlîkirinê|çavkanî hewce ye]]. —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 17:53, 14 îlon 2020 (UTC) == [[kerrnizî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 15:56, 15 îlon 2020 (UTC) == [[li dora (yekê) gerîn]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 18:46, 15 îlon 2020 (UTC) == [[glas]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]]. --[[Bikarhêner:Şêr|Şêr]] ([[Gotûbêja bikarhêner:Şêr|gotûbêj]]) 12:45, 16 îlon 2020 (UTC) == [[kejmûn]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 16:42, 17 îlon 2020 (UTC) == [[lirêgerîn]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 14:20, 18 îlon 2020 (UTC) == [[çavpeqî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 16:23, 23 îlon 2020 (UTC) :http://www.geocities.ws/mehname2004a/63/pexsan5.html -- [[Bikarhêner:Guherto|Guherto]] ([[Gotûbêja bikarhêner:Guherto|gotûbêj]]) 16:58, 23 îlon 2020 (UTC) == [[çavpeqiyayî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 17:14, 23 îlon 2020 (UTC) :{{r|Balyozxane}} Çavpeqî û -iyayî eynî peyv in, heke bo nimûne 2 çavkanî ji bo çavpeqî û 1 ji bo -iyayî werin dîtin ew weke 3 ji bo yek peyv tên jimartin? -- [[Bikarhêner:Guherto|Guherto]] ([[Gotûbêja bikarhêner:Guherto|gotûbêj]]) 17:16, 23 îlon 2020 (UTC) ::{{r|Guherto}}. Na, divê yek ji wan peyitandî be daku em karibin yek ji wan wek guherto nîşan bidin. --[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 17:45, 23 îlon 2020 (UTC) :::Temam naxwe. {{=(}} -- [[Bikarhêner:Guherto|Guherto]] ([[Gotûbêja bikarhêner:Guherto|gotûbêj]]) 17:48, 23 îlon 2020 (UTC) ::::Ecêb e peyva çavpeqîn jî tune ye. Divê çavpeqî/çavpeqiyayî jê hatibe lê qet tune. --[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 17:56, 23 îlon 2020 (UTC) :::::Em çavpeqî ne weke kesekî ku çavê wan peqî ye dibêjin. Siqêfek e. ''Wilo neke, çavpeqî!'' -- [[Bikarhêner:Guherto|Guherto]] ([[Gotûbêja bikarhêner:Guherto|gotûbêj]]) 18:10, 23 îlon 2020 (UTC) == [[olfatûn]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 14:58, 24 îlon 2020 (UTC) :Du çavkanî hatiye dîtin li hêviya ya sisêyan e. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 13:46, 23 sibat 2025 (UTC) == [[hekûke]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 16:00, 28 îlon 2020 (UTC) :Tenê çavkaniyek ji Kovara Kurmancî heye ew jî ji kitêba Gundê Mêrxasan a Eliyê Evdilrehman hatiye girtin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 13:49, 23 sibat 2025 (UTC) == [[dê bêjî kaya di serî de]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 12:58, 29 îlon 2020 (UTC) == [[heçî ne li malekê, nizanit halekê]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 12:58, 29 îlon 2020 (UTC) == [[heta nîva destî reş nebit, tama devî xoş nabit]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 12:58, 29 îlon 2020 (UTC) == [[kirtop]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' Herwiha [[kirtope]]—[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 12:59, 29 îlon 2020 (UTC) : == [[pişkûmişk]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 21:25, 29 îlon 2020 (UTC) = Çiriya pêşîn 2020 = == [[ma te şulê pê ye?]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 13:19, 1 çiriya pêşîn 2020 (UTC) == [[zelam yêt heyn û zelamoşk jî yêt heyn]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 13:28, 1 çiriya pêşîn 2020 (UTC) == [[ezîz î&#59; ji pêrve ne mîzî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 14:15, 1 çiriya pêşîn 2020 (UTC) == [[qelpez]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 08:19, 6 çiriya pêşîn 2020 (UTC) == [[firêzer]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Guherto|Guherto]] ([[Gotûbêja bikarhêner:Guherto|gotûbêj]]) 15:27, 6 çiriya pêşîn 2020 (UTC) == [[kirmişk]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 09:03, 7 çiriya pêşîn 2020 (UTC) == [[orijîn]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Guherto|Guherto]] ([[Gotûbêja bikarhêner:Guherto|gotûbêj]]) 19:03, 7 çiriya pêşîn 2020 (UTC) == [[şequdeq]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 08:50, 9 çiriya pêşîn 2020 (UTC) == [[helizandin]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 11:23, 9 çiriya pêşîn 2020 (UTC) == [[rewastin]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 11:48, 9 çiriya pêşîn 2020 (UTC) == [[xunaftin]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 12:31, 9 çiriya pêşîn 2020 (UTC) == [[itîmad li ser kirin]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Guherto|Guherto]] ([[Gotûbêja bikarhêner:Guherto|gotûbêj]]) 16:32, 15 çiriya pêşîn 2020 (UTC) == [[sengesor]] == {{r|Saberabdollahizad}} ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 22:00, 16 çiriya pêşîn 2020 (UTC) :Navçeya Mirgewerê, Ûrmîye. {{bêîmze|Saberabdollahizad}} == [[zenek]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 22:03, 16 çiriya pêşîn 2020 (UTC) :{{r|Saberabdollahizad}} [[zenek]] jî li Ûrmiyê tê bikaranîn? --[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 19:53, 18 çiriya pêşîn 2020 (UTC) == [[pind#p-mane|pind]] == Min tenê çavkaniyek dît ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 18:48, 17 çiriya pêşîn 2020 (UTC) :Navçeya Mirgewerê, Ûrmîye. {{bêîmze|Saberabdollahizad}} == [[maqezer]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 18:53, 18 çiriya pêşîn 2020 (UTC) :Navçeya Mirgewerê, Ûrmîye. {{bêîmze|Saberabdollahizad}} == [[pezpezok]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 18:55, 18 çiriya pêşîn 2020 (UTC) :Navçeya Mirgewerê, Ûrmîye. {{bêîmze|Saberabdollahizad}} == [[parapet#p-mane|parapet]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 13:53, 31 çiriya pêşîn 2020 (UTC) = Çiriya paşîn 2020 = == [[quloç#p-mane|quloç]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 17:43, 19 çiriya paşîn 2020 (UTC) == [[di ber (yekî) de avêtin]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 16:57, 20 çiriya paşîn 2020 (UTC) :https://tirsik.net/index.php?mijarid=18749&iro=on&rupel=1 —[[Bikarhêner:Mamoste Dilovan|Mamoste Dilovan]] ([[Gotûbêja bikarhêner:Mamoste Dilovan|gotûbêj]]) 17:37, 20 çiriya paşîn 2020 (UTC) :: {{r|Mamoste Dilovan}} [[di ber re avêtin]] heye. lê te wek di ber '''de''' lê zêde kir. Em biguherînin? Gelek çavkanî ji bo di ber re avêtin heye. --[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 17:41, 20 çiriya paşîn 2020 (UTC) == [[hêvastin]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 10:49, 21 çiriya paşîn 2020 (UTC) == [[lamçîn]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 11:28, 22 çiriya paşîn 2020 (UTC) == [[poz#p-mane|poz]] == Ji bo maneya "[[quz]], [[vajîna]]" ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 11:28, 22 çiriya paşîn 2020 (UTC) == [[sihetbexş]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 16:35, 24 çiriya paşîn 2020 (UTC) == [[hevjêhatin ji jêhatîbûnê çêtir e]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 12:14, 25 çiriya paşîn 2020 (UTC) == [[gerriyan#p-mane|gerriyan]] == ''Ji bo wateya cereyan (tevger)''. Qasî ku dibînim tenê Cewerî bi kar aniye —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 18:24, 25 çiriya paşîn 2020 (UTC) == [[derbend]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 12:08, 30 çiriya paşîn 2020 (UTC) = Kanûna paşîn 2021 = == [[desthelgirtin]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 08:48, 6 kanûna paşîn 2021 (UTC) == [[êşewî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 12:52, 7 kanûna paşîn 2021 (UTC) == [[sexorr]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 20:22, 7 kanûna paşîn 2021 (UTC) == [[sapût]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 22:06, 12 kanûna paşîn 2021 (UTC) == <s>[[dimorî]]</s> == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' Maneya navdêrî bêçavkanî ye. — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 15:05, 20 kanûna paşîn 2021 (UTC) :{{nepeyitandî}}--[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 14:18, 26 hezîran 2026 (UTC) :Di Kovara kurmancî hj.67 de "dimor" bi maneya "bêoxir" de derbas dibe. Wekî din ti çavkanî nîne. Merheba @[[Bikarhêner:Gomada|Gomada]] te varyanta "dimhorî" îlawe kiriye. Gelo tu dizanî ev kelîme li kîjan herêman tê bikaranîn? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 14:18, 26 hezîran 2026 (UTC) = Çiriya pêşîn 2022 = == [[paşbingeh]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 07:40, 12 çiriya pêşîn 2022 (UTC) = Kanûna paşîn 2023 = == [[berê beringa]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 21:35, 1 kanûna paşîn 2023 (UTC) == [[mûlûleya xwînê]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 16:36, 6 kanûna paşîn 2023 (UTC) == [[mirovdostî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 05:38, 12 kanûna paşîn 2023 (UTC) == [[derîner]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 23:02, 15 kanûna paşîn 2023 (UTC) == [[neteba]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 00:01, 16 kanûna paşîn 2023 (UTC) :Maneya "uyruksuz" ji ferhenga Farqînî hatiye kopîkirin wekî din bi giştî bi maneya "nakokî" tê bikaranîn. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 14:33, 26 hezîran 2026 (UTC) == [[narkotîkfiroş]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 10:59, 16 kanûna paşîn 2023 (UTC) == [[pirik#p-mane|pirik]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 18:15, 16 kanûna paşîn 2023 (UTC) == [[ramyarî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' Ez dibêjim ev peyv tenê bi maneya "fikrî", wek rengdêr heye. Lê belê di soranî de bi şaşemilandineke wekî "siyasî" bi kar anîne, kurmancên me jî rasterast maneya soranî tevlî çend ferhengên hev-kopîkirî kirine û bi vî awayî belkî hin çavkanî hebin. Lê ez dibêjim divê ew çavkanî jî neyên hesibandin. Hin kes zen dikin ku her tiştê di soranî de ripîrast e. Mesele heqeten eletewş e. Agahiyeke li ser peyvê: "[https://www.welateme.info/kurdi/modules.php?name=News&file=print&sid=686 Welateme.info]" Li vir peyv bi maneya "fikrî" hatiye bikaranîn: "[https://xwebun1.org/ziman-sirhelal-e/ Xwebûn]". Qewet be. — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 22:36, 19 kanûna paşîn 2023 (UTC) == [[dolîwgeh]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 21:08, 22 kanûna paşîn 2023 (UTC) = Sibat 2023 = == [[herebaş]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 15:13, 11 sibat 2023 (UTC) == [[balindeyê korare]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' Tenê çavkaniyekê tê xuyan, ew jî kitêba "Balindeyên Kurdistanê" yê Îsmaîl Taha Şahîn e (Îsmaîl Taha Şahîn (2006). Balindeyên Kurdistanê, 1-4. Spîrêz, Duhok). Ev kitêb ji ser înternetê wek word jî peyda dibe. Xuya ye ku ji Weşanên Spîrez fîzîken jî çap bûye. Lê wekî çavkanî tenê ev tê xuyan. —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 17:10, 14 sibat 2023 (UTC) == [[dîbeyt]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 10:13, 18 sibat 2023 (UTC) == [[çend pat]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 09:35, 24 sibat 2023 (UTC) == [[rabînîn]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' Ji bo kurmancî bêçavkanî ye. Ger ji bo soranî çavkanî hebin jî divê ji bo soranî bi herfên aramî were nivîsîn. An ger halê latînîkirî ya peyveke soranî be, dîsa divê ev hal were eşkerekirin. — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 13:36, 26 sibat 2023 (UTC) = Adar 2023 = == [[qirar#p-mane|qirar]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 09:23, 2 adar 2023 (UTC) == [[pîşpêkirin]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' Tenê di nivîseke online ya Cemal Nebez de derbas dibe. Dibe ku peyveke başûriyan be. Û di wê nivîsa Cemal Nebezê bi forma "pîş bi ... bikin" jî derbas dibe. — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 16:29, 3 adar 2023 (UTC) == [[kûcag]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 01:27, 27 adar 2023 (UTC) == [[destbizavî kirin]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' Xuya ye ku ev peyv tenê di kitêba “''Nameyek Şernexê''” yê Evdirehman Gundikî de derbas bûye. Û ji wir jî Mistefa Aydoganî maneya peyvê di hejmara 61em ya Kovara ''Kurmancî'' de belav kiriye (rûpela 2yem). Lê belê tenê yek çavkaniyekê ne bes e ji bo ku em vê peyvê di vê ferhengê de wekî peyveke çavkanî-temam belav bikin. — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 09:40, 28 adar 2023 (UTC) == [[germav baş]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 18:23, 31 adar 2023 (UTC) == [[germavxweş]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 18:27, 31 adar 2023 (UTC) = Gulan 2023 = == [[kirbend]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 08:34, 5 gulan 2023 (UTC) : Çêkerê rûpelê wek not nivîsiye ku peyv ji herêma Çewlikê ye. -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 06:24, 6 gulan 2023 (UTC) == [[We are off now]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 14:13, 22 gulan 2023 (UTC) == [[baran ji erd û esmana lê diket]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 22:46, 26 gulan 2023 (UTC) == [[sîba]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 15:44, 30 gulan 2023 (UTC) == [[bîrîner]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 17:20, 30 gulan 2023 (UTC) = Hezîran 2023 = == [[bidestmiz]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 16:49, 10 hezîran 2023 (UTC) = Tîrmeh 2023 = == [[parzeng]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 14:01, 15 tîrmeh 2023 (UTC) == [[zerpedest]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 14:05, 15 tîrmeh 2023 (UTC) == [[heta destên mirov nebine gû, devê mirov nabite tû]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 15:27, 19 tîrmeh 2023 (UTC) == [[çemê mezin tê dibore diçe]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 15:38, 19 tîrmeh 2023 (UTC) == [[kevanê nebî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 15:45, 19 tîrmeh 2023 (UTC) == [[teybûr]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' Tenê li malpera yuksekovahaber.com-ê derbas dibe, li wir jî bi maneya "çare, çareserî"yê hatiye emilandin, ne bi vê maneyê. — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 16:00, 19 tîrmeh 2023 (UTC) == [[nikêtî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 16:22, 19 tîrmeh 2023 (UTC) = Tebax 2023 = == [[prêze]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 21:19, 15 tebax 2023 (UTC) == [[qelye]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 15:59, 25 tebax 2023 (UTC) = Îlon 2023 = == [[hetwan]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 20:21, 14 îlon 2023 (UTC) == [[milyonmasî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 14:06, 21 îlon 2023 (UTC) == [[tofana mêjî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 14:20, 21 îlon 2023 (UTC) == [[îshaf]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 10:57, 23 îlon 2023 (UTC) == [[odeya karkirinê]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 10:57, 26 îlon 2023 (UTC) == [[odeya şixulînê]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 11:42, 26 îlon 2023 (UTC) == [[hîter]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 12:08, 26 îlon 2023 (UTC) = Çiriya pêşîn 2023 = == [[vîtamîn waw]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 20:20, 1 çiriya pêşîn 2023 (UTC) == [[berhan]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 14:21, 3 çiriya pêşîn 2023 (UTC) == [[sêlikdêr]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 19:16, 10 çiriya pêşîn 2023 (UTC) == [[qewandêr]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 19:20, 10 çiriya pêşîn 2023 (UTC) == [[darav]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 20:04, 11 çiriya pêşîn 2023 (UTC) = Çiriya paşîn 2023 = == [[kansernasî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 17:54, 14 çiriya paşîn 2023 (UTC) == [[golgir]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 16:06, 15 çiriya paşîn 2023 (UTC) == [[gogpî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 16:19, 15 çiriya paşîn 2023 (UTC) == [[ahardar]] == Tenê Zana Farqînî —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 10:34, 26 çiriya paşîn 2023 (UTC) = Kanûna pêşîn 2023 = == [[Kî mal ezîz bike, can rezîl dike&#59; kî mal rezîl bike, can ezîz dike.]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 13:55, 2 kanûna pêşîn 2023 (UTC) == [[porsing]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 14:22, 2 kanûna pêşîn 2023 (UTC) == [[newelatî kirin]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 16:57, 2 kanûna pêşîn 2023 (UTC) == [[newelatîkirin]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 16:58, 2 kanûna pêşîn 2023 (UTC) == [[alîkar kirin]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Şêr|Şêr]] ([[Gotûbêja bikarhêner:Şêr|gotûbêj]]) 18:42, 3 kanûna pêşîn 2023 (UTC) == [[aramoş kirin]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]]'' -- [[Bikarhêner:Şêr|Şêr]] ([[Gotûbêja bikarhêner:Şêr|gotûbêj]]) 18:48, 3 kanûna pêşîn 2023 (UTC) == [[bêvil kirin]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Şêr|Şêr]] ([[Gotûbêja bikarhêner:Şêr|gotûbêj]]) 18:56, 4 kanûna pêşîn 2023 (UTC) == [[dijberiya naverokî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Şêr|Şêr]] ([[Gotûbêja bikarhêner:Şêr|gotûbêj]]) 22:43, 8 kanûna pêşîn 2023 (UTC) == [[bersivîn]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]]'', û her wiha ne li gorî qayideyên kurdî (kurmancî) ye. —[[Bikarhêner:Şêr|Şêr]] ([[Gotûbêja bikarhêner:Şêr|gotûbêj]]) 22:08, 11 kanûna pêşîn 2023 (UTC) == [[girêbanasî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 20:30, 13 kanûna pêşîn 2023 (UTC) == [[hevalzewac]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 17:25, 18 kanûna pêşîn 2023 (UTC) = Kanûna paşîn 2024 = == [[raperk]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 13:40, 15 kanûna paşîn 2024 (UTC) :Bi wê manê nîne. Bi maneke dî heye. [[Bikarhêner:Guherto|Guherto]] ([[Gotûbêja bikarhêner:Guherto|gotûbêj]]) 19:26, 6 tebax 2024 (UTC) = Sibat 2024 = == [[bi navê lîstin]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 21:02, 3 sibat 2024 (UTC) : Li ser agahdarkirina çêkerê rûpelê me şablona "dever"ê tevlî kir. Peyv ji herêma Qoser, Mêrdînê ye. Me li qismê "Bikaranîn"ê jî vê yekê dîyar kir. Ji xeynî vê me wê peyvê ji rûpelên din jî bir. Bi vî awayî ev made kare were girtin. -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 13:28, 10 nîsan 2024 (UTC) == [[firoşgehkar]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 19:17, 9 sibat 2024 (UTC) == [[preskirin]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 00:43, 11 sibat 2024 (UTC) == [[pres kirin]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 00:43, 11 sibat 2024 (UTC) == [[Xwedê te têr bike]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 22:41, 13 sibat 2024 (UTC) == [[isad]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 22:09, 22 sibat 2024 (UTC) == [[razemendîtî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 18:44, 27 sibat 2024 (UTC) = Adar 2024 = == [[zilhêzî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 23:19, 5 adar 2024 (UTC) == [[hingihîn]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 21:32, 13 adar 2024 (UTC) == [[xore]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 13:30, 15 adar 2024 (UTC) == [[melef]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 13:55, 19 adar 2024 (UTC) == [[uğursuz ayak]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 10:11, 23 adar 2024 (UTC) == [[şepûk]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 10:22, 23 adar 2024 (UTC) == [[agirberdêrî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 00:04, 26 adar 2024 (UTC) == [[kîrquz]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 10:00, 26 adar 2024 (UTC) == [[kîrquzdê]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 10:01, 26 adar 2024 (UTC) == [[quzgêj]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 10:03, 26 adar 2024 (UTC) = Nîsan 2024 = == [[hîkarîkerî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 08:53, 1 nîsan 2024 (UTC) == [[hîkarîker]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 08:54, 1 nîsan 2024 (UTC) == [[hîkarîdarî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 08:55, 1 nîsan 2024 (UTC) == [[hîkarîdar]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 08:56, 1 nîsan 2024 (UTC) == [[bihîkarîtî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 08:57, 1 nîsan 2024 (UTC) == [[bihîkarî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 08:58, 1 nîsan 2024 (UTC) == [[bêhîkarîtî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 08:58, 1 nîsan 2024 (UTC) == [[bêhîkarî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 08:59, 1 nîsan 2024 (UTC) == [[bêhîkarî bûn]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 09:00, 1 nîsan 2024 (UTC) == [[bêhîkarî kirin]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 09:00, 1 nîsan 2024 (UTC) == [[bêhîkarîbûn]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 09:01, 1 nîsan 2024 (UTC) == [[bêhîkarîkirin]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 09:01, 1 nîsan 2024 (UTC) == [[hîkarîkirî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 09:02, 1 nîsan 2024 (UTC) == [[hîkarîkirin]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 09:03, 1 nîsan 2024 (UTC) == [[hîkarî kirin]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 09:07, 1 nîsan 2024 (UTC) == [[rayda]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 09:40, 1 nîsan 2024 (UTC) == [[bêrayda]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 09:42, 1 nîsan 2024 (UTC) == [[bêraydayî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 09:43, 1 nîsan 2024 (UTC) == [[bêraydatî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 09:43, 1 nîsan 2024 (UTC) == [[bêrayda bûn]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 09:43, 1 nîsan 2024 (UTC) == [[bêrayda kirin]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 09:43, 1 nîsan 2024 (UTC) == [[bêraydabûn]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 09:44, 1 nîsan 2024 (UTC) == [[bêraydakirin]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 09:44, 1 nîsan 2024 (UTC) == [[birayda]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 09:44, 1 nîsan 2024 (UTC) == [[biwerêç]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 09:46, 1 nîsan 2024 (UTC) == [[biwerêçî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 09:46, 1 nîsan 2024 (UTC) == [[biwerêçîtî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 09:47, 1 nîsan 2024 (UTC) == [[biwerêçtî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 09:47, 1 nîsan 2024 (UTC) == [[werêç]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 09:49, 1 nîsan 2024 (UTC) == [[werêç kirin]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 09:50, 1 nîsan 2024 (UTC) == [[werêçkirî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 09:50, 1 nîsan 2024 (UTC) == [[werêçkirin]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 09:51, 1 nîsan 2024 (UTC) == [[wişto]] == @[[Bikarhêner:Zerwanda]] Çavkanî ji bo kurmancî tine ye. Zazakî ye? —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 20:19, 1 nîsan 2024 (UTC) :ji devera mûşê, aliyê diya min "wişto/wiştik" digotin. [[Bikarhêner:Zerwanda|Zerwanda]] ([[Gotûbêja bikarhêner:Zerwanda|gotûbêj]]) 20:44, 1 nîsan 2024 (UTC) == [[xewgerî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 10:19, 2 nîsan 2024 (UTC) == [[xewgerokî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 10:28, 2 nîsan 2024 (UTC) == [[nimêh]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 15:51, 2 nîsan 2024 (UTC) == [[فعال]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' [[Bikarhêner:Ghybu|Gyhbu]] di 2021an de li ser rûpela wî tevlî kirîye. Lê ji ber nebûna vê sîstema me tevlî vir nebûye. Lewma min anî ser vir jî. Wê gavê tenê ji bo maneya "kar" ev şablon hatîye tevlîkirin. — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 07:27, 3 nîsan 2024 (UTC) == [[pêjor]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 21:46, 6 nîsan 2024 (UTC) == [[hafil]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 21:48, 6 nîsan 2024 (UTC) == [[micemi]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' Muhtemelem şiklê rast wek "micemî" ye, lê ew jî bêçavkanî ye. — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 11:52, 9 nîsan 2024 (UTC) == [[hesaba xwe]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' Ji xeynî van ev forma wê jî bêçavkanî ne: "[[hisaba xwe]] / [[hesaba xo]] / [[hisaba xo]]". — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 13:25, 9 nîsan 2024 (UTC) == [[leşkerma]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 22:53, 24 nîsan 2024 (UTC) = Gulan 2024 = == [[serîi]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' Wek "serî" belkî li kar be, lê wekî "serîi" çavkanî peyda nabe. — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 16:20, 2 gulan 2024 (UTC) == [[virgu]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' Bêçavkanî tê xuyan. Peyv bi tirkî ye. — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 18:49, 2 gulan 2024 (UTC) == [[xwerre]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 18:57, 20 gulan 2024 (UTC) = Hezîran 2024 = == [[di nav deryaya peyvan de avjenî dikir]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 17:34, 4 hezîran 2024 (UTC) == [[berbixwe]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 09:03, 10 hezîran 2024 (UTC) == [[şipyakî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 09:08, 10 hezîran 2024 (UTC) :"şipêkî" heye [[Bikarhêner:Guherto|Guherto]] ([[Gotûbêja bikarhêner:Guherto|gotûbêj]]) 20:20, 27 tîrmeh 2024 (UTC) == [[wetalane]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 09:18, 10 hezîran 2024 (UTC) == [[wetalî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 09:19, 10 hezîran 2024 (UTC) == [[wetalîtî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 09:20, 10 hezîran 2024 (UTC) == [[wetaltî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 09:20, 10 hezîran 2024 (UTC) == [[se direye karwan dibuhire]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 14:49, 16 hezîran 2024 (UTC) == [[se direwît, karwan bi rêka xo diçît]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' Formeke bêçavkanî ye. — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 14:53, 16 hezîran 2024 (UTC) == [[se direwît, karwan diburît]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' Formeke bêçavkanî ye. — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 14:54, 16 hezîran 2024 (UTC) == [[se direyê karwan dibûrê]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' Formeke bêçavkanî ye. — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 14:55, 16 hezîran 2024 (UTC) == [[se direye karvan li riya xwe diçe]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' Formeke bêçavkanî ye. — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 14:56, 16 hezîran 2024 (UTC) == [[se direye û kerwan dibihure]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' Formeke bêçavkanî ye. — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 15:00, 16 hezîran 2024 (UTC) == [[hingê dinya]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 14:07, 18 hezîran 2024 (UTC) == [[berdanberdan]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 21:22, 24 hezîran 2024 (UTC) == [[nîska mala Barzan]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 08:05, 25 hezîran 2024 (UTC) = Tîrmeh 2024 = == [[avmêwe]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 17:41, 16 tîrmeh 2024 (UTC) == [[nihalok]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 21:53, 24 tîrmeh 2024 (UTC) == [[nihalk]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 21:54, 24 tîrmeh 2024 (UTC) == [[niwalok]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 21:54, 24 tîrmeh 2024 (UTC) == [[niwalk]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 21:55, 24 tîrmeh 2024 (UTC) == [[niwalik]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 21:55, 24 tîrmeh 2024 (UTC) == [[nehalok]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 21:56, 24 tîrmeh 2024 (UTC) == [[nehalk]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 21:56, 24 tîrmeh 2024 (UTC) == [[nehalik]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 21:57, 24 tîrmeh 2024 (UTC) == [[alîkarxwazî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 22:16, 24 tîrmeh 2024 (UTC) == [[nihalik]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 22:19, 24 tîrmeh 2024 (UTC) == [[zêrîb]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' Bi dîtina min, ev form bêçavkanî ye. Dibe ku ji bo forma "zerîb" çavkanî hebe, lê ew form li ser Wîkîferhengê wek made nehatîye çêkirin. Pir kêm be jî ev peyv wek "zerîp" jî li cihekî derbas bûye. — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 22:31, 24 tîrmeh 2024 (UTC) == [[qanat]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' Ev peyv bi maneya "kanal"ê nîne, xelet e. — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 06:59, 25 tîrmeh 2024 (UTC) == [[qenat]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' Ev peyv bi maneya "kanal"ê nîne, xelet e. — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 06:59, 25 tîrmeh 2024 (UTC) :Min 1 çavkanî dît, "Ev kes rojê 6-7 qenatên TV ya diğere û diaxive" https://darkamazi.info/archives/1019704 (bi lêgerana "qenatên", ji ber ko lêgeranên dî tijî tiştên dî derdixin) :Lê mimkun e xelet nivîsîbe. [[Bikarhêner:Guherto|Guherto]] ([[Gotûbêja bikarhêner:Guherto|gotûbêj]]) 20:31, 27 tîrmeh 2024 (UTC) == [[şkaftmend]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 07:08, 25 tîrmeh 2024 (UTC) :3 çavkanî hene. Lê xuya dike jêdera wan hemû ferhenga tirsik.netê e. :* Çavkanî 1: https://tirsik.net/ferheng?query=şkaftmend (berî 2014, lê tarîx nîne) :* Çavkanî 2: https://ku.wikipedia.org/wiki/Deranderî (2011) :* Çavkanî 3: https://x.com/zerdeceno/status/1155331427510247425 (2019) :[[Bikarhêner:Guherto|Guherto]] ([[Gotûbêja bikarhêner:Guherto|gotûbêj]]) 20:28, 27 tîrmeh 2024 (UTC) == [[dan hev#p-mane|dan hev]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' Ev mane li ser çavkanîyan peyda nabe. Tenê çêkerê rûpelê vê maneyê nivîsîye. — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 11:08, 25 tîrmeh 2024 (UTC) == [[baristdar]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 14:47, 25 tîrmeh 2024 (UTC) == [[baristdarî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 14:48, 25 tîrmeh 2024 (UTC) == [[baristdarîtî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 14:49, 25 tîrmeh 2024 (UTC) == [[baristdartî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 14:50, 25 tîrmeh 2024 (UTC) == [[bibaristî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 14:51, 25 tîrmeh 2024 (UTC) == [[bibarist]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 14:52, 25 tîrmeh 2024 (UTC) == [[bibaristîtî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 14:53, 25 tîrmeh 2024 (UTC) == [[bêbaristî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 14:54, 25 tîrmeh 2024 (UTC) == [[bêbarist]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 14:55, 25 tîrmeh 2024 (UTC) == [[peydabûnîtî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Guherto|Guherto]] ([[Gotûbêja bikarhêner:Guherto|gotûbêj]]) 20:52, 27 tîrmeh 2024 (UTC) == [[nexşvan]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Guherto|Guherto]] ([[Gotûbêja bikarhêner:Guherto|gotûbêj]]) 21:05, 27 tîrmeh 2024 (UTC) == [[nexşvanî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Guherto|Guherto]] ([[Gotûbêja bikarhêner:Guherto|gotûbêj]]) 21:05, 27 tîrmeh 2024 (UTC) == [[lêvikî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Guherto|Guherto]] ([[Gotûbêja bikarhêner:Guherto|gotûbêj]]) 21:47, 27 tîrmeh 2024 (UTC) == [[lêvik]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' Min zêde nemeyzand. —[[Bikarhêner:Guherto|Guherto]] ([[Gotûbêja bikarhêner:Guherto|gotûbêj]]) 21:48, 27 tîrmeh 2024 (UTC) == [[şerenîx kirin]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Guherto|Guherto]] ([[Gotûbêja bikarhêner:Guherto|gotûbêj]]) 21:51, 27 tîrmeh 2024 (UTC) == [[sala çîn]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 16:09, 29 tîrmeh 2024 (UTC) == [[berê pêşîn]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 17:57, 30 tîrmeh 2024 (UTC) == [[berê ewilî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 17:57, 30 tîrmeh 2024 (UTC) = Tebax 2024 = == [[xwîndijmin]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 18:02, 4 tebax 2024 (UTC) == [[reîsîtî]]/[[reysîtî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Guherto|Guherto]] ([[Gotûbêja bikarhêner:Guherto|gotûbêj]]) 18:17, 6 tebax 2024 (UTC) == [[soranîaxivî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Guherto|Guherto]] ([[Gotûbêja bikarhêner:Guherto|gotûbêj]]) 18:43, 6 tebax 2024 (UTC) == [[helîna bildo]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' Ji 2020a ve şablon li wir e min tenê li vir zêde kir. —[[Bikarhêner:Guherto|Guherto]] ([[Gotûbêja bikarhêner:Guherto|gotûbêj]]) 19:56, 6 tebax 2024 (UTC) == [[hilbijêrînerî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' "Hilbij" rihê peyvê ye, "-er" jî maneya "kesê dike" dide, qertafa "-îner / -înerî" ya li dawîyê bi eşkereyî xelet e. Û ev peyv bêçavkanî ye. — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 13:45, 7 tebax 2024 (UTC) == [[îqlîmtî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 13:43, 10 tebax 2024 (UTC) == [[jîrbêjî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' Ev peyv ger di soranî de ji bo wê çavkanîyên têr hebe, tenê wek "Nivîsîna bi herfên latînî ya peyva ..." kare were qeydkirin. Lê nabe ku wek kurmancî be, were qeydkirin. Ji bo kurmancî tenê di meqaleyekê de derbas dibe, ew jî ji alî başûrîyekî ve hatîye nivîsîn. — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 19:55, 10 tebax 2024 (UTC) == [[hîgyen]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' Tenê ev form bêçavkanî ye. — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 07:40, 12 tebax 2024 (UTC) == [[kolîner]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 17:45, 12 tebax 2024 (UTC) == [[poşmanî kişîn]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' Tenê di çavkanîyekê de peyda dibe. Ew çavkanîya dayî jî ihtîmal e ku bi tesîra zimanê tirkî ye. — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 08:44, 13 tebax 2024 (UTC) == [[para hevpar a herî mezin]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 16:09, 14 tebax 2024 (UTC) == [[cara hevpar a herî biçûk]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 16:10, 14 tebax 2024 (UTC) == [[regjimar]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 16:16, 14 tebax 2024 (UTC) == [[nîvrengî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Guherto|Guherto]] ([[Gotûbêja bikarhêner:Guherto|gotûbêj]]) 17:33, 18 tebax 2024 (UTC) == [[nîvdûrgeh]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' Wek "guharto" hatiye qeydkirin, lê yek nikare wilo bêje. Ne "guharto" ye, ji ber wê çavkanî hewce ne. —[[Bikarhêner:Guherto|Guherto]] ([[Gotûbêja bikarhêner:Guherto|gotûbêj]]) 17:39, 18 tebax 2024 (UTC) == [[nîvtewlîsî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Guherto|Guherto]] ([[Gotûbêja bikarhêner:Guherto|gotûbêj]]) 17:44, 18 tebax 2024 (UTC) == [[nîvrewa]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Guherto|Guherto]] ([[Gotûbêja bikarhêner:Guherto|gotûbêj]]) 17:44, 18 tebax 2024 (UTC) == [[nîvşehtî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Guherto|Guherto]] ([[Gotûbêja bikarhêner:Guherto|gotûbêj]]) 17:46, 18 tebax 2024 (UTC) == [[nîvfalincî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Guherto|Guherto]] ([[Gotûbêja bikarhêner:Guherto|gotûbêj]]) 17:46, 18 tebax 2024 (UTC) == [[nîvgilkarî]] == Ferhenga Sa.Sa. ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Guherto|Guherto]] ([[Gotûbêja bikarhêner:Guherto|gotûbêj]]) 17:48, 18 tebax 2024 (UTC) == [[kesîkirin]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Guherto|Guherto]] ([[Gotûbêja bikarhêner:Guherto|gotûbêj]]) 20:16, 18 tebax 2024 (UTC) == [[biryarbirin]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 21:38, 24 tebax 2024 (UTC) = Îlon 2024 = == [[qîblename]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Guherto|Guherto]] ([[Gotûbêja bikarhêner:Guherto|gotûbêj]]) 15:15, 1 îlon 2024 (UTC) == [[cihetnima]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' Ji [https://bianet.org/yazi/ferhenga-ser-u-amrazen-ser-ji-kovara-ronahiye-2-196299 vir] hatiye —[[Bikarhêner:Guherto|Guherto]] ([[Gotûbêja bikarhêner:Guherto|gotûbêj]]) 15:27, 1 îlon 2024 (UTC) == [[qûnderîtî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 15:36, 7 îlon 2024 (UTC) == [[hevpîşehî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 17:48, 14 îlon 2024 (UTC) == [[hevpîşeyî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' Wek ''navdêr'' bêçavkanî ye. Wek ''rengdêr'' hebe jî, kêmçavkanî ye. — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 17:50, 14 îlon 2024 (UTC) == [[hempay]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 18:04, 14 îlon 2024 (UTC) == [[nîs]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 19:43, 14 îlon 2024 (UTC) == [[êxbarçî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' Ji bo ''îxbarçî'' çavkanîyekê peyda dibe, lê kêm e. — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 23:06, 14 îlon 2024 (UTC) == [[muxbîrîtî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 23:38, 14 îlon 2024 (UTC) == [[ixbarçî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 23:43, 14 îlon 2024 (UTC) == [[westgeha pasê]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 16:33, 19 îlon 2024 (UTC) == [[avikmadk]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 17:24, 19 îlon 2024 (UTC) == [[ferwerîn]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 09:18, 20 îlon 2024 (UTC) == [[bipayderî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 11:12, 20 îlon 2024 (UTC) == [[bipayderîtî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 11:13, 20 îlon 2024 (UTC) == [[bipaydertî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 11:13, 20 îlon 2024 (UTC) == [[bipedalî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 11:14, 20 îlon 2024 (UTC) == [[bipedalîtî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 11:14, 20 îlon 2024 (UTC) == [[bipedaltî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 11:14, 20 îlon 2024 (UTC) == [[pedaldarî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 11:15, 20 îlon 2024 (UTC) == [[pedaldarîtî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 11:15, 20 îlon 2024 (UTC) == [[pedaldartî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 11:16, 20 îlon 2024 (UTC) == [[ciwên]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 16:11, 22 îlon 2024 (UTC) == [[belgebirin]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 22:31, 23 îlon 2024 (UTC) == [[avsîn]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' Dibe ku ev kelîme biçavkanî be, lê pir bêagahî hatîye qeydkirin. Biçavkanî be jî, ji ber qeydkirina bêagahî (li ser madeyê agahî kêm hatine pêşkêşkirin) em rûpelê jê bibin. — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 22:53, 23 îlon 2024 (UTC) :@[[Bikarhêner:Bikarhêner|Bikarhêner]] Ma ne çêtir e li "Daxwazên zelalkirinê" be naxwe? [[Bikarhêner:Guherto|Guherto]] ([[Gotûbêja bikarhêner:Guherto|gotûbêj]]) 13:40, 10 çiriya paşîn 2024 (UTC) :: {{r|Guherto}} Bi min em karin vê madeyê ji ber bêagahîbûna wî, îlaweyî "Daxwazên jêbirinê" bikin, lê "Daxwazên zelalkirinê" nabe. Wekî din ji ber ku dikeve çarçoveya her du rûpelan jî kîjan be jî dibe, lê madem me li vir da destpêkirin, bila ji vir dewam bike dengdana li ser vê kelîmeyê. -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 21:22, 10 çiriya paşîn 2024 (UTC) == [[kûvank]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' Herçiqas tenê formekê be jî, bêçavkanî ye. — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 21:14, 27 îlon 2024 (UTC) == [[kikark]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' Herçiqas formekê be jî, bêçavkanî dixuye. — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 21:40, 27 îlon 2024 (UTC) == [[kîfkarik]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' Herçiqas tenê formekê be jî, bêçavkanî dixuye. — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 21:45, 27 îlon 2024 (UTC) == [[kuvank]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' Herçiqas formekê be jî, bêçavkanî dixuye. — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 21:53, 27 îlon 2024 (UTC) == [[kûvarik]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' Herçiqas tenê formekê be jî, bêçavkanî dixuye. — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 22:01, 27 îlon 2024 (UTC) = Çiriya pêşîn 2024 = == [[muhil]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' Tenê qismê kurdî bêçavkanî ye, ne ya tirkî. — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 21:00, 9 çiriya pêşîn 2024 (UTC) == [[muhilk]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 21:00, 9 çiriya pêşîn 2024 (UTC) == [[jêrmal]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 21:59, 15 çiriya pêşîn 2024 (UTC) = Çiriya paşîn 2024 = == [[bîrxistiner]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 19:38, 14 çiriya paşîn 2024 (UTC) == [[wisa gotin]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' Ne ferhengî ye. — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 20:13, 15 çiriya paşîn 2024 (UTC) == [[tenzîlatî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 16:12, 16 çiriya paşîn 2024 (UTC) == [[armancparêz]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 13:03, 19 çiriya paşîn 2024 (UTC) == [[şikaftmend]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 13:06, 19 çiriya paşîn 2024 (UTC) == [[derander]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 13:08, 19 çiriya paşîn 2024 (UTC) == [[deranderî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 13:09, 19 çiriya paşîn 2024 (UTC) == [[derxwenîn]] == @[[User:Keyomerd]] ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 22:38, 19 çiriya paşîn 2024 (UTC) == [[kiyû]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 23:53, 22 çiriya paşîn 2024 (UTC) == [[goçavik]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 00:03, 23 çiriya paşîn 2024 (UTC) == [[hûrhesibaner]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 00:19, 23 çiriya paşîn 2024 (UTC) == [[heybera zindî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 18:01, 23 çiriya paşîn 2024 (UTC) == [[misadereker]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 12:51, 24 çiriya paşîn 2024 (UTC) == [[kêmtirkar]] == @[[Bikarhêner:Cyrus the virus|Cyrus the virus]] ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 18:11, 24 çiriya paşîn 2024 (UTC) == [[cudagir]] == @[[Bikarhêner:Cyrus the virus|Cyrus the virus]] ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 18:15, 24 çiriya paşîn 2024 (UTC) == [[qerwaşgir]] == @[[Bikarhêner:Cyrus the virus|Cyrus the virus]] ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 18:42, 24 çiriya paşîn 2024 (UTC) == [[mişkilûr]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 18:45, 24 çiriya paşîn 2024 (UTC) == [[agirbiran]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 18:54, 24 çiriya paşîn 2024 (UTC) == [[alan]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 18:55, 24 çiriya paşîn 2024 (UTC) == [[alêdû]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 18:56, 24 çiriya paşîn 2024 (UTC) == [[henaseker]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 17:37, 25 çiriya paşîn 2024 (UTC) == [[nial]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' Ji xeynî vê, maneya 2yem ya di madeya "nihal" de (navdêr 2) jî bêçavkanî ye. — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 23:46, 27 çiriya paşîn 2024 (UTC) == [[gilçim]] == @[[Bikarhêner:Roj Rewandiz|Roj Rewandiz]] ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 14:28, 29 çiriya paşîn 2024 (UTC) :Ez ji bajarê Kobaniyê me. Min ev peyv ji ser zimanê dê û dapîra xwe girt. Ez gelekî ji vê peyvê bawer im ji ber ku devoka min e. [[Bikarhêner:Roj Rewandiz|Roj Rewandiz]] ([[Gotûbêja bikarhêner:Roj Rewandiz|gotûbêj]]) 19:14, 23 kanûna pêşîn 2024 (UTC) ::@[[Bikarhêner:Roj Rewandiz|Roj Rewandiz]] Mala te ava. Ji ber ku çavkaniyên nivîskî tine ne em ê vê kelîmeyê wek [[Wîkîferheng:Pîvekên_tevlîkirinê#Peyvên_herêmî|herêmî]] nîşan bidin. [[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 12:22, 25 kanûna pêşîn 2024 (UTC) == [[reşeme kirin]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' Li gorî çêkera sayfeyê li Kobaniyê li kar e. Loma dikare wekî herêmî nîşankirin —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 14:35, 29 çiriya paşîn 2024 (UTC) :Li Kobaniyê dibêjin: ‘Tizbiyê min li xwe reş û reşeme kir’ Anko Tizbî bir û venegerand Înkar kir. [[Bikarhêner:Roj Rewandiz|Roj Rewandiz]] ([[Gotûbêja bikarhêner:Roj Rewandiz|gotûbêj]]) 23:48, 7 kanûna paşîn 2025 (UTC) = Kanûna pêşîn 2024 = == <s>[[hemderk]]</s> == @[[Bikarhêner:Ferhengvan|Ferhengvan]] ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 10:02, 1 kanûna pêşîn 2024 (UTC) :{{nepeyitandî}}--[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:30, 17 tîrmeh 2026 (UTC) == <s>[[qefesker]]</s> == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 10:23, 1 kanûna pêşîn 2024 (UTC) :{{nepeyitandî}}--[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:31, 17 tîrmeh 2026 (UTC) == <s>[[sêkunc]]</s> == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 00:17, 27 kanûna pêşîn 2024 (UTC) :Saharnews gelek bi kar tîne feqat nivîskarên wan ne belî ne, tenê ev kitêb [https://kurdistankomunistpartisi.com/wp-content/uploads/2022/03/kurdi2.pdf] derbasdar e. :{{nepeyitandî}}--[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:37, 17 tîrmeh 2026 (UTC) == <s>[[pênckunc]]</s> == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 00:20, 27 kanûna pêşîn 2024 (UTC) :{{nepeyitandî}}--[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:37, 17 tîrmeh 2026 (UTC) == [[çarkunc]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 00:21, 27 kanûna pêşîn 2024 (UTC) == <s>[[şeşkunc]]</s> == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 00:21, 27 kanûna pêşîn 2024 (UTC) :{{nepeyitandî}}--[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:38, 17 tîrmeh 2026 (UTC) = Kanûna paşîn 2025 = == <s>[[oktopod]]</s> == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' Ji bo vê formê ti çavkanî nîne. — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 15:10, 1 kanûna paşîn 2025 (UTC) :{{nepeyitandî}}--[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:41, 17 tîrmeh 2026 (UTC) == [[pevnatî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' Ev kelîme wek kurtkirina ji "bi hev nehatî" hatîye fikirîn, ihtimal e ku wek sunî hatîye çêkirin û bêçavkanî ye. — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 13:43, 6 kanûna paşîn 2025 (UTC) == [[lihevnatîbûn]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' Wek formeke "lihevnehatîbûn"ê hatîye fikirîn, lê bêçavkanî ye. — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 13:49, 6 kanûna paşîn 2025 (UTC) == <s>[[fîzîkîtî]]</s> == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 20:19, 7 kanûna paşîn 2025 (UTC) :{{nepeyitandî}}--[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:42, 17 tîrmeh 2026 (UTC) == <s>[[kobar]]</s> == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 14:59, 21 kanûna paşîn 2025 (UTC) :{{nepeyitandî}}--[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:11, 17 tîrmeh 2026 (UTC) == <s>[[werdanbar]]</s> == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 14:59, 21 kanûna paşîn 2025 (UTC) :{{nepeyitandî}}--[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:10, 17 tîrmeh 2026 (UTC) == [[Binxetê]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' Em zanin ku ji ber sînora Tirkîyeyê ku Cizîrê dike du perçe û ji parçeya binî re Binxet tê gotin ku kurd lê dijîn. Feqet min herêma Binxetê seh nekirîye, û bi tedqîqeke neberfireh jî çavkanî peyda nekir ji bo vê peyvê. Lewma bi min mahîyeta vê madeyê û qeydkirina wek "Binxetê" xelet e. Ger ji bo herêma tarîfkirî çavkanî nîn be, em vê madeyê bikin "'''Binxet'''" û tarîfa wê jî bikin "''Navê Rojavayê Kurdistanê ku li binê xeta Tirkîye - Sûrîyeyê dimîne.''" — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 00:22, 24 kanûna paşîn 2025 (UTC) == [[xirecir çêkirin]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' "''Çê''" bi maneya "''baş''" e, û "''çêkirin''" ji bo tiştên pozîtîv likar e, li nav milet jî ev wisa ye. Lewma ev xelet e. — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 20:00, 24 kanûna paşîn 2025 (UTC) == <s>[[bêonurane]]</s> == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 19:19, 26 kanûna paşîn 2025 (UTC) :{{nepeyitandî}}--[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:09, 17 tîrmeh 2026 (UTC) == <s>[[sabûnsazxane]]</s> == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' Xelet e û bêçavkanî ye. — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 19:24, 26 kanûna paşîn 2025 (UTC) :{{nepeyitandî}}--[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:08, 17 tîrmeh 2026 (UTC) == [[sîrkxane]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 19:30, 26 kanûna paşîn 2025 (UTC) == <s>[[rewanwerziş]]</s> == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 19:33, 26 kanûna paşîn 2025 (UTC) :{{nepeyitandî}}--[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:11, 17 tîrmeh 2026 (UTC) == <s>[[rewanwerzişxane]]</s> == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 19:34, 26 kanûna paşîn 2025 (UTC) :{{nepeyitandî}}--[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:12, 17 tîrmeh 2026 (UTC) == <s>[[qeşaşîrxane]]</s> == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 19:36, 26 kanûna paşîn 2025 (UTC) :{{nepeyitandî}}--[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:14, 17 tîrmeh 2026 (UTC) == <s>[[tiwaletxane]]</s> == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 19:37, 26 kanûna paşîn 2025 (UTC) :{{nepeyitandî}}--[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:14, 17 tîrmeh 2026 (UTC) == [[anînder]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' Di hin çavkanîyan de wek formeke "''der'''''anîn'''"ê hatîye qeydkirin. Lê belê çavkanîyeke eslî (ne ji kitêbên gramerê) peyda nabe ji bo vê kelîmeyê. — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 00:24, 27 kanûna paşîn 2025 (UTC) == <s>[[komherf]]</s> == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Wikihez|Wikihez]]<small><sup>'''[[Bikarhêner:Balyozxane|Balyozxane]]''' ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]])</sup></small> 20:18, 29 kanûna paşîn 2025 (UTC) :{{nepeyitandî}}--[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:16, 17 tîrmeh 2026 (UTC) == <s>[[komtîp]]</s> == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Wikihez|Wikihez]]<small><sup>'''[[Bikarhêner:Balyozxane|Balyozxane]]''' ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]])</sup></small> 20:19, 29 kanûna paşîn 2025 (UTC) :845û* Husein Muhemmed 2016 [https://zimannas.wordpress.com/2016/03/13/kurdizar-ferhenga-sorani-kurmanci-e/] :* Kovara deng [https://www.kovaradeng.com/upload/arsivpdf/Deng%20110.pdf] Mana ne alfabe ye "komtîpên « dj, kh, tch » yê, li cîyê dengên me yên ku bi « c, x, ç » yê hatine dîyarkirin de bikaranîne" :* resadcibrani.blogspot [https://resadcibrani.blogspot.com/p/lekolin.html] tarîx û nivîskar ne belî ye. :Çavkaniyên Instagram, Tiktok, Facebook nayê qebûlkirin loma: :{{nepeyitandî}}--[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:25, 17 tîrmeh 2026 (UTC) == <s>[[tîpgel]]</s> == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Wikihez|Wikihez]]<small><sup>'''[[Bikarhêner:Balyozxane|Balyozxane]]''' ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]])</sup></small> 20:19, 29 kanûna paşîn 2025 (UTC) :{{nepeyitandî}}--[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:26, 17 tîrmeh 2026 (UTC) == [[rastî nîşandan]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 18:14, 30 kanûna paşîn 2025 (UTC) = Sibat 2025 = == <s>[[bêbirî]]</s> == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' Dibe ku xeletîya botê be. — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 18:38, 1 sibat 2025 (UTC) :{{nepeyitandî}}--[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:45, 17 tîrmeh 2026 (UTC) == <s>[[soraxker]]</s> == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 17:24, 2 sibat 2025 (UTC) :{{nepeyitandî}}--[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:46, 17 tîrmeh 2026 (UTC) == <s>[[bîrdozvanî]]</s> == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 19:26, 3 sibat 2025 (UTC) :{{nepeyitandî}}--[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 17:40, 17 tîrmeh 2026 (UTC) == [[pir hindik#p-mane|pir hindik]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 22:31, 3 sibat 2025 (UTC) == <s>[[navçegir]]</s> == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 21:15, 4 sibat 2025 (UTC) : Zana farqînî ji xeynî wî çavkanî nîne, çend xeberên anonîm bi forma navçegirî heye lê ew jî têr nake. {{nepeyitandî}}--[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 17:47, 17 tîrmeh 2026 (UTC) == <s>[[baweranî]]</s> == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' Di ferhenga J. Blau ya "DICTIONNAIRE KURDE/TURC/FRANÇAIS/ANGLAIŞ KURDISH/TURKISH/FRENCH/ENGLISH DICTIONARY" (tercimeya tirkî Fethullah Kakioglu, 1991) der derbas dibe, feqet li cihên din peyda nabe. Wek etîmolojî jî dibe ku ji "bawerîanî" hatibe. — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 22:59, 5 sibat 2025 (UTC) : Ferhenga Baran Rizgar de jî heye lê çavkaniya sisêya nîne loma {{nepeyitandî}}--[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 17:53, 17 tîrmeh 2026 (UTC) == [[anteroz]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 01:19, 15 sibat 2025 (UTC) == [[veşidandin]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 21:43, 15 sibat 2025 (UTC) == [[karîwer kirin]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 02:01, 16 sibat 2025 (UTC) == [[hil girtin]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 21:06, 17 sibat 2025 (UTC) == [[wer girtin]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 21:07, 17 sibat 2025 (UTC) == [[avkûre]] == @[[Bikarhêner:Mohajeer|Mohajeer]] ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 20:36, 18 sibat 2025 (UTC) == [[derdek girtin]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 23:42, 18 sibat 2025 (UTC) == [[vekitandin]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 19:12, 21 sibat 2025 (UTC) == [[dînperist]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 01:32, 22 sibat 2025 (UTC) == [[ayînperist]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 01:33, 22 sibat 2025 (UTC) == [[ayînperistî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 01:33, 22 sibat 2025 (UTC) == [[ayînperistane]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 01:33, 22 sibat 2025 (UTC) == [[piştrastkirinbar]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 01:45, 23 sibat 2025 (UTC) == [[diyarkirinbar]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 02:08, 23 sibat 2025 (UTC) == [[hevhatî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 03:52, 1 adar 2025 (UTC) == [[kerexne]] == @[[Bikarhêner:Rojhilat|Rojhilat]] ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 15:05, 1 adar 2025 (UTC) == [[pawan#p-mane|pawan]] == Ferhenga Hejar soranî ye, ji bo maneya "cihê qedexekirî, cihê inhisarî" ji xeynî wê çavkanî heye gelo —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 20:17, 3 adar 2025 (UTC) == [[taqane]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 02:11, 6 adar 2025 (UTC) == [[gosirmetî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 23:07, 6 adar 2025 (UTC) == [[matîjêker]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 20:08, 14 adar 2025 (UTC) == [[hilewesan]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 21:14, 16 adar 2025 (UTC) == [[peydandin#p-mane|peydandin]] == Ji bo maneya [[dûre]], [[paşî]], [[piştî]] wê / wî ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 20:26, 19 adar 2025 (UTC) == [[peşar]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 20:36, 19 adar 2025 (UTC) == [[nûzaf]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:30, 20 adar 2025 (UTC) == [[deynname]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 22:08, 20 adar 2025 (UTC) == [[girtek]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 22:29, 20 adar 2025 (UTC) == [[bêşxane]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 00:25, 23 adar 2025 (UTC) == [[superleheng]] == @[[Bikarhêner:Avestaboy|Avestaboy]] ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 11:34, 23 adar 2025 (UTC) == [[goranparêz]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 21:54, 27 adar 2025 (UTC) == [[raber#p-mane|raber]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 16:09, 1 nîsan 2025 (UTC) == [[morîvanî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 20:06, 1 nîsan 2025 (UTC) == [[wevde]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 12:17, 3 nîsan 2025 (UTC) == [[şandêr]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 17:31, 3 nîsan 2025 (UTC) == [[giloverî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' Tenê li ser Ferhenga Zaravên Teknîkî û hejmara yekem ya kovara Bernamegehê derbas dibe. —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 09:10, 4 nîsan 2025 (UTC) == [[xêvjimêr]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 00:00, 12 nîsan 2025 (UTC) == [[paşekeft]] == @[[Bikarhêner:Jiyar Hesen|Jiyar Hesen]] ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 11:11, 13 nîsan 2025 (UTC) == [[paşekeft kirin]] == @[[Bikarhêner:Jiyar Hesen|Jiyar Hesen]] ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 11:12, 13 nîsan 2025 (UTC) == [[hawirkanî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 22:36, 20 nîsan 2025 (UTC) == [[hawirkan]] == @[[Bikarhêner:Ferhengvan|Ferhengvan]] ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 22:18, 21 nîsan 2025 (UTC) : Di çavkanîyeke de "''hawrikan''" (ku wek forma vê kelîmeyê hatîye nîşandayîn û wek "hevrêyan" a kurmancî ye) bi maneya "''friends''"a îngilîzî hatîye emilandin. Wekî din ti çavkanî nîne ji bo vê peyvê. Ger ev "hevrik"a kurmancî be, li vir dîsa xelet e. Bi her awayî divê were jêbirin. -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 22:28, 21 nîsan 2025 (UTC) == [[hawirkanî]] == @[[Bikarhêner:Cyrus the virus|Cyrus the virus]] ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 22:18, 21 nîsan 2025 (UTC) == [[hawirkanvanî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 22:18, 21 nîsan 2025 (UTC) == [[riberiz]] == @[[Bikarhêner:Ferhengvan|Ferhengvan]] ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 22:39, 21 nîsan 2025 (UTC) :Ez bawer im ku ev hat peyitandin. Min çavkanî di beşa gotûbêjê de dan û şablona bêçavkanîtiyê rakir. [[Bikarhêner:Ferhengvan|Ferhengvan]] ([[Gotûbêja bikarhêner:Ferhengvan|gotûbêj]]) 06:11, 25 nîsan 2025 (UTC) == [[awam]] == @[[User:Ferhengvan|Ferhengvan]] Min ev kelîme di ferhengên din de nedît. Gelo di kurmancî de tê bikaranîn? —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 21:09, 23 nîsan 2025 (UTC) :@[[Bikarhêner:Zerwanda|Zerwanda]] tu jî forma [[vam]] ya vê kelîmeyê diemilînî, gelo çavkanî ji bo wê jî heye? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 21:11, 23 nîsan 2025 (UTC) ::Min jî li vir peyda kir û dest kar anîn kir, hemin ev li guherrên dengî ên Kurmancî dihat (*ebam > *ewam > *wam > vam; wek *ebaj- > {{q|ku|vajî}}). Min gotibû qey di zarawayê kesekî da hebûye û wî bi ser va kiriye û jixwe nepêkan nîn e ku di zimên da hebe îcar rind e, nê min jî serkanî tine ji bonê. [[Bikarhêner:Zerwanda|Zerwanda]] ([[Gotûbêja bikarhêner:Zerwanda|gotûbêj]]) 21:37, 23 nîsan 2025 (UTC) :::https://bnk.institutkurde.org/images/pdf/4UVB2YMZG3.pdf :::Di vê kitêbê de bi forma wam derbas dibe 1 Wam : qerz, dên. " dîsa jî gereg 3 çavkanî hebe. :::Lê di beşa etîmolojiyê de eger em karibin zimanekî yekgirtî biemilînin, dê baştir be. Wekî din "bi vê enflasyona kelîmeyan" em nikarin ti tiştî bidin fêmkirin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 21:54, 23 nîsan 2025 (UTC) == [[arvanê hûr]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 09:48, 27 nîsan 2025 (UTC) == [[damezrak]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 13:47, 27 nîsan 2025 (UTC) == [[mezrak]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 13:49, 27 nîsan 2025 (UTC) == [[hevhemetî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 15:25, 6 gulan 2025 (UTC) == [[navhemetî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 15:25, 6 gulan 2025 (UTC) == [[entîte]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 15:08, 17 gulan 2025 (UTC) == [[agirvekujêner]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 00:35, 21 gulan 2025 (UTC) == [[progres]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 00:50, 23 gulan 2025 (UTC) == [[bûncî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 22:29, 28 gulan 2025 (UTC) == [[tasît]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 15:36, 31 gulan 2025 (UTC) == [[implîcît]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 15:37, 31 gulan 2025 (UTC) == [[hewedar]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 19:14, 31 gulan 2025 (UTC) == [[destajo]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 22:38, 31 gulan 2025 (UTC) == [[binhimbank]] == @[[Bikarhêner:Ferhengvan|Ferhengvan]] ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 01:23, 1 hezîran 2025 (UTC) == [[şîmane]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 23:31, 2 hezîran 2025 (UTC) == [[materya]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 16:12, 5 hezîran 2025 (UTC) == [[bêtî]] == @[[Bikarhêner:Ferhengvan|Ferhengvan]] ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 13:03, 7 hezîran 2025 (UTC) == [[rîbat]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 17:21, 9 hezîran 2025 (UTC) == [[hevtawan]] == @[[Bikarhêner:Ferhengvan|Ferhengvan]] ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 10:26, 12 hezîran 2025 (UTC) :Pirsek: "Hevwate" kelîmeyên ku maneyan wan hev in. "hevtawan" çawa dibe "şirîkên sûcekê"? Gereg sûcên ku tiştê wan hev bin? Ew tişt çi ye? Çima dibe şirîk? [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 10:32, 12 hezîran 2025 (UTC) ::Merheba! ::"Hevtawan" anku "şirîkên heman tawanê, kesên ku heman tawan kiriye/dikin", wek "hevkar = şirîkên heman karî, kesên ku heman karî dikin", "hevjîn = şirîkên heman jiyanê, kesên ku bi hev re dijîn"... [[Bikarhêner:Ferhengvan|Ferhengvan]] ([[Gotûbêja bikarhêner:Ferhengvan|gotûbêj]]) 06:11, 30 hezîran 2025 (UTC) == [[zanîş]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 12:07, 14 hezîran 2025 (UTC) == [[zanîşwer]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 12:07, 14 hezîran 2025 (UTC) == [[zanmend]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 12:09, 14 hezîran 2025 (UTC) == [[zandar]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 21:08, 14 hezîran 2025 (UTC) == [[zayîndar]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 21:12, 14 hezîran 2025 (UTC) == [[zayindar]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 21:12, 14 hezîran 2025 (UTC) == [[akund]] == @[[Bikarhêner:Ferhengvan|Ferhengvan]] ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 01:16, 16 hezîran 2025 (UTC) == [[destbikar]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 07:41, 22 hezîran 2025 (UTC) == [[vekitandin]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:DarkAngel2100|DarkAngel2100]] ([[Gotûbêja bikarhêner:DarkAngel2100|gotûbêj]]) 10:45, 2 tîrmeh 2025 (UTC) Çavkanî: Kurdish-English Dictionary by Baran Rizgar == [[peşarmend]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 17:54, 5 tîrmeh 2025 (UTC) == [[zaîd]] == @[[Bikarhêner:Ferhengvan|Ferhengvan]] ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 06:59, 6 tîrmeh 2025 (UTC) == [[Xrîst]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 07:13, 10 tîrmeh 2025 (UTC) == [[hesibanî kirin]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 09:48, 13 tîrmeh 2025 (UTC) == [[top danîn]] == @[[Bikarhêner:Ferhengvan|Ferhengvan]] ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 10:08, 13 tîrmeh 2025 (UTC) == [[çûkger]] == @[[Bikarhêner:Dûrzan|Dûrzan]] ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:49, 18 tîrmeh 2025 (UTC) == [[dûneçkar]] == @[[Bikarhêner:212.175.166.246|212.175.166.246]] ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 15:38, 10 tebax 2025 (UTC) == [[sermirov]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 15:22, 13 tebax 2025 (UTC) == [[nifira Esed]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 16:00, 19 tebax 2025 (UTC) == [[dilkrîz]] == @[[Bikarhêner:Kurd87612|Kurd87612]] ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 10:44, 23 tebax 2025 (UTC) == [[berxa Xwedê]] == @[[Bikarhêner:Kurd87612|Kurd87612]] ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 14:28, 31 tebax 2025 (UTC) == [[destmatî]] == @[[Bikarhêner:Ferhengvan|Ferhengvan]] ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 17:47, 21 îlon 2025 (UTC) == [[sîbaq]] == @[[Bikarhêner:Ferhengvan|Ferhengvan]] ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 20:33, 27 îlon 2025 (UTC) == [[mirovê daristanê]] == @[[Bikarhêner:Hewarwîkîferheng|Hewarwîkîferheng]] ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 08:09, 18 çiriya pêşîn 2025 (UTC) == [[çavbijîşk]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 18:30, 24 çiriya pêşîn 2025 (UTC) == [[makeşar]] == @[[Bikarhêner:Avestaboy|Avestaboy]] ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 06:46, 14 kanûna pêşîn 2025 (UTC) :Silav @[[Bikarhêner:Bikarhêner|Bikarhêner]] min bi derew peyv çê nekir. Peyva makeşar di sepana O-ferheng û her wiha di ferhenga online ferhengkurdi.org ya '''Enstîtuya Kurdî ya Stenbolê''' tê xwendin. :https://ferhengkurdi.org/tr/kelime/make%C5%9Far-n [[Bikarhêner:Avestaboy|Avestaboy]] ([[Gotûbêja bikarhêner:Avestaboy|gotûbêj]]) 11:07, 18 kanûna pêşîn 2025 (UTC) ::Krîterên me yên tevlîkirina kelîmeyan heye. Ev made rîayeta wan krîteran nake. Lewma min vê kelîmeyê li vir bicih kir. -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 23:28, 18 kanûna pêşîn 2025 (UTC) == [[bihîstinzanî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:30, 23 hezîran 2026 (UTC) == [[hevdilî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 20:28, 24 hezîran 2026 (UTC) == [[kemisandin]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 20:45, 24 hezîran 2026 (UTC) == [[kexme]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 20:53, 24 hezîran 2026 (UTC) == [[lêpirsyarker]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 21:32, 24 hezîran 2026 (UTC) == [[raypirs]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 21:34, 24 hezîran 2026 (UTC) == [[helwestpirs]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 21:34, 24 hezîran 2026 (UTC) == [[kopirî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' xuyaye maneyeke wekî pir jî heye dikare were zêdekirin —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 17:33, 25 hezîran 2026 (UTC) == [[merxeme]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 22:55, 25 hezîran 2026 (UTC) == [[mohl]] == @[[Bikarhêner:Far ati|Far ati]] ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 23:14, 25 hezîran 2026 (UTC) == [[irfandarî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 20:30, 26 hezîran 2026 (UTC) == [[axulme]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 00:20, 30 hezîran 2026 (UTC) == [[şewane]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 14:26, 1 tîrmeh 2026 (UTC) == [[poezî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 14:27, 1 tîrmeh 2026 (UTC) == [[sebaxker]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 22:20, 1 tîrmeh 2026 (UTC) == [[sebaxfiroş]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 22:21, 1 tîrmeh 2026 (UTC) == [[siboxfiroş]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 22:21, 1 tîrmeh 2026 (UTC) == [[diyardenasîtî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 22:26, 1 tîrmeh 2026 (UTC) == [[dawxane]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 10:41, 3 tîrmeh 2026 (UTC) == [[pêşajotî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 17:15, 3 tîrmeh 2026 (UTC) == [[kontînentaltirîn]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 17:35, 3 tîrmeh 2026 (UTC) == [[azmayîşker]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 22:16, 3 tîrmeh 2026 (UTC) == [[ateşparêz]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 05:19, 4 tîrmeh 2026 (UTC) == [[kurtetarîx]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 11:52, 4 tîrmeh 2026 (UTC) == [[besayetî]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 17:57, 4 tîrmeh 2026 (UTC) == [[tawbijêr]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 20:45, 4 tîrmeh 2026 (UTC) == [[destbir]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 11:30, 5 tîrmeh 2026 (UTC) == [[nekider]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 22:56, 5 tîrmeh 2026 (UTC) == [[niqar]] == —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 23:39, 5 tîrmeh 2026 (UTC) == [[parêzîn]] == ''[[Wîkîferheng:Pîvekên tevlîkirinê|Çavkanî hewce ye]].'' Ev form li ti derê peyda nabe. Berî çendîn salan hatîye çêkirin. Bi qenaeta min şaş e, lewma em jê bibin. — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 10:29, 6 tîrmeh 2026 (UTC) == [[stêrfizîk]] == . —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 20:33, 6 tîrmeh 2026 (UTC) == [[pêçavik]] == . Eger ev kelîmeyeke mehelî be, Jkx şablona {{şx|dever|cihê ku lê tê bikaranîn}} li madeyê zêde bike. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 14:59, 7 tîrmeh 2026 (UTC) == [[qerqef]] == . Eger ev kelîmeyeke mehelî be, Jkx şablona {{şx|dever|cihê ku lê tê bikaranîn}} li madeyê zêde bike. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 15:17, 7 tîrmeh 2026 (UTC) == [[rakar]] == . Eger ev kelîmeyeke mehelî be, Jkx şablona {{şx|dever|cihê ku lê tê bikaranîn}} li madeyê zêde bike. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 15:30, 7 tîrmeh 2026 (UTC) == [[remilîn]] == . Eger ev kelîmeyeke mehelî be, Jkx şablona {{şx|dever|cihê ku lê tê bikaranîn}} li madeyê zêde bike. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 15:36, 7 tîrmeh 2026 (UTC) == [[segurî]] == . —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 15:51, 7 tîrmeh 2026 (UTC) == [[serdev]] == Bnr. [[Wîkîferheng:Pîvekên tevlîkirinê|Krîterên tevlîkirinê]] —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:10, 7 tîrmeh 2026 (UTC) == [[serziman]] == Bnr. [[Wîkîferheng:Pîvekên tevlîkirinê|Krîterên tevlîkirinê]] —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 17:01, 7 tîrmeh 2026 (UTC) == [[tenîsk]] == di Înternetê de gelek netîce derdikevin lê ji bo ku dûre ez kontrol bikim û çavkaniyên sehîh binivîsim li vir îlawe dikim. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 20:53, 7 tîrmeh 2026 (UTC) == [[tertî]] == Bnr. [[Wîkîferheng:Pîvekên tevlîkirinê|Krîterên tevlîkirinê]] —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 20:58, 7 tîrmeh 2026 (UTC) == [[tirut]] == Bnr. [[Wîkîferheng:Pîvekên tevlîkirinê|Krîterên tevlîkirinê]] —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 21:25, 7 tîrmeh 2026 (UTC) == [[tizqa]] == Bnr. [[Wîkîferheng:Pîvekên tevlîkirinê|Krîterên tevlîkirinê]] —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 21:28, 7 tîrmeh 2026 (UTC) == [[têkilîdêr]] == Bnr. [[Wîkîferheng:Pîvekên tevlîkirinê|Krîterên tevlîkirinê]] —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 21:31, 7 tîrmeh 2026 (UTC) == [[tîtalk]] == Bnr. [[Wîkîferheng:Pîvekên tevlîkirinê|Krîterên tevlîkirinê]] —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 21:33, 7 tîrmeh 2026 (UTC) == [[vircoq]] == Bnr. [[Wîkîferheng:Pîvekên tevlîkirinê|Krîterên tevlîkirinê]] —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 21:45, 7 tîrmeh 2026 (UTC) == [[xilêbat]] == Bnr. [[Wîkîferheng:Pîvekên tevlîkirinê|Krîterên tevlîkirinê]]. Li gorî kurteya çêkirina sayfeyê li Qamişlo û Amûdê tê bikaranîn. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 22:14, 7 tîrmeh 2026 (UTC) == [[xin_û_cûc]] == Bnr. [[Wîkîferheng:Pîvekên tevlîkirinê|Krîterên tevlîkirinê]] —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 22:27, 7 tîrmeh 2026 (UTC) == [[çiteba]] == Bnr. [[Wîkîferheng:Pîvekên tevlîkirinê|Krîterên tevlîkirinê]] —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 22:38, 7 tîrmeh 2026 (UTC) == [[desttêl]] == Bnr. [[Wîkîferheng:Pîvekên tevlîkirinê|Krîterên tevlîkirinê]] —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 08:45, 8 tîrmeh 2026 (UTC) == [[Mîmedol]] == Bnr. [[Wîkîferheng:Pîvekên tevlîkirinê|Krîterên tevlîkirinê]] —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 08:51, 8 tîrmeh 2026 (UTC) == [[alaf]] == Bnr. [[Wîkîferheng:Pîvekên tevlîkirinê|Krîterên tevlîkirinê]] —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 14:01, 8 tîrmeh 2026 (UTC) == [[aşirme]] == Bnr. [[Wîkîferheng:Pîvekên tevlîkirinê|Krîterên tevlîkirinê]] —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 10:13, 10 tîrmeh 2026 (UTC) == [[geledîmentî]] == Bnr. [[Wîkîferheng:Pîvekên tevlîkirinê|Krîterên tevlîkirinê]] —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 20:54, 13 tîrmeh 2026 (UTC) == [[çendîmentî]] == Bnr. [[Wîkîferheng:Pîvekên tevlîkirinê|Krîterên tevlîkirinê]] —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 20:54, 13 tîrmeh 2026 (UTC) == [[paşmak]] == Bnr. [[Wîkîferheng:Pîvekên tevlîkirinê|Krîterên tevlîkirinê]] —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:34, 15 tîrmeh 2026 (UTC) == [[rojeng]] == Bnr. [[Wîkîferheng:Pîvekên tevlîkirinê|Krîterên tevlîkirinê]] —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 22:41, 18 tîrmeh 2026 (UTC) == [[bereyîşk]] == Bnr. [[Wîkîferheng:Pîvekên tevlîkirinê|Krîterên tevlîkirinê]] —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 15:47, 19 tîrmeh 2026 (UTC) ivvps9wpd6moflsjd056gx890zby36t Şablon:ceribandin2 10 843332 6265629 6067019 2026-07-19T19:00:00Z Wikihez 7344 6265629 wikitext text/x-wiki <span class="manelazim"><span style="color:var( --color-subtle, rgb(119, 119, 119) );><i>Maneya vê madeyê hê nehatiye nivîsîn. Heke hûn maneya wê bizanin kerem bikin binivîsin.</i>&nbsp;</span><span class="plainlinks stubedit">[{{SERVER}}{{localurl:{{PAGENAME}}|action=edit}} <span style="color:var( --color-subtle, rgb(119, 119, 119 ) ); font-size:x-small;">[&nbsp;biguhêre&nbsp;<nowiki>]</nowiki></span>]</span><!-- --><bdi lang="{{{1|}}}" style="display: none"><!-- Balise de marquage pour le gadget [[MediaWiki:Gadget-wikt.add-examples]], ne pas retirer ! --></bdi></span><noinclude>[[Kategorî:Şablonên hişyarde]]{{belgekirin}}</noinclude> 8fx6orhdga2ixjhrhhlsb3gw6ne6rms Wîkîferheng:Daxwazên standardkirinê 4 845699 6265701 6265371 2026-07-19T23:14:20Z Bikarhêner 3719 /* dûkel */ beşeke nû 6265701 wikitext text/x-wiki {{/destpêk}} = Daxwazên standardkirinê: 2020 = == [[mizhar]] == mizhar / miz'ar / mizar --[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 19:31, 10 tebax 2020 (UTC) ===Gotûbêj=== {{şîrove}} Min gelek ferhangan nêrî lê min kelîmeyek wisa nedît. Divê ev kelîme were peyitandin. Wexta em kelîmeyek bo standartkirinê hilbijêrin divê hinek ser bisekinin. Ka kelîme hêjaye an na. Kelîmeyê zêde tên bikaranîn divê were hilbijêrîn.--[[Bikarhêner:Rewiye tine|Rewiye tine]] ([[Gotûbêja bikarhêner:Rewiye tine|gotûbêj]]) 20:54, 3 çiriya paşîn 2020 (UTC) <!-- === Dengdan === {{dengdan/nû|destpêk=?|dawî=?}} piştî dengdan dest pê kir vê şablonê {{dengdan|destpêk=|dawî=}}, û kengî xilas bû vê şablonê {{dengdan/borî|destpêk=|dawî=}} bi kar bînin. --> == [[kîte]] / [[kite]] == [[kîte]] / [[kite]] Divê werin standardkirin. -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 20:11, 13 tebax 2020 (UTC) {{rfk||}} Di vê ferhengê de "kîte / kite" nîne, lê wek lêker cih dane "kîte kirin"ê. Jê tê famkirin ku halê standard wek "'''kîte'''" dibînin. -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 20:31, 28 nîsan 2025 (UTC) === Gotûbêj === <!--Li jêr fikrên xwe binivîsin. {{şîrove}} --> {{şîrove}} Ji bo '''''[[kit]]''''' ez dibêjim '''''[[kit]]'''''; nabêjim '''''[[kît]]'''''. Ma '''''[[kîte]]''''' ('''''[[kît]]''''') li kû derê li kar e? -- [[Bikarhêner:Hakîmo|Hakîmo]] ([[Gotûbêja bikarhêner:Hakîmo|gotûbêj]]) 15:13, 5 îlon 2020 (UTC) <!-- === Dengdan === {{dengdan/nû|destpêk=?|dawî=?}} piştî dengdan dest pê kir vê şablonê {{dengdan|destpêk=|dawî=}}, û kengî xilas bû vê şablonê {{dengdan/borî|destpêk=|dawî=}} bi kar bînin. --> == [[hêvişandin]] == [[hêvişandin]] / [[êvişandin]] / [[hewişandin]]--[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 21:50, 15 tebax 2020 (UTC) '''Gotûbêj:''' <!--Li jêr fikrên xwe binivîsin. {{şîrove}} --> {{şîrove}} <!-- === Dengdan === {{dengdan/nû|destpêk=?|dawî=?}} piştî dengdan dest pê kir vê şablonê {{dengdan|destpêk=|dawî=}}, û kengî xilas bû vê şablonê {{dengdan/borî|destpêk=|dawî=}} bi kar bînin. --> == [[hindirandin]] == --[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 09:09, 16 tebax 2020 (UTC) '''Gotûbêj:''' <!--Li jêr fikrên xwe binivîsin. {{şîrove}} --> {{şîrove}} *Bi ya min divê forma ''hundirandin'' bibe standard. Li herêma Behdînan gelek caran '''u''' dibe '''i''', '''û''' jî dibe '''î'''. Loma [[hindir]] weke rûpela sereke hatiye çêkirin.—<small>[[Bikarhêner:Gomada|<span style="background:Yellow">'''''<span style="font-family:Verdana;color:red">Gom<span style="color:#006400">ada</span></span></span>''''']]<sup>[[Gotûbêja bikarhêner:Gomada|peyam]]</sup></small> 15:40, 21 kanûna paşîn 2021 (UTC) ** {{silav|Gomada}}. Bnr. [[WF:Rêzikên standardkirinê]]--[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 15:42, 21 kanûna paşîn 2021 (UTC) == [[zingar]] == Eynî rûpel li [[zeng]] û [[jeng]] heye. Ez awayê rast wek [[zingar]] dibînim. -- [[Bikarhêner:Guherto|Guherto]] ([[Gotûbêja bikarhêner:Guherto|gotûbêj]]) 12:34, 18 tebax 2020 (UTC) '''Gotûbêj:''' <!--Li jêr fikrên xwe binivîsin. {{şîrove}} --> {{şîrove}} <!-- === Dengdan === {{dengdan/nû|destpêk=?|dawî=?}} piştî dengdan dest pê kir vê şablonê {{dengdan|destpêk=|dawî=}}, û kengî xilas bû vê şablonê {{dengdan/borî|destpêk=|dawî=}} bi kar bînin. --> == [[axaftin]] == [[axaftin]] / [[axivtin]] / [[axiftin]] / [[axivîn]]--[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 12:23, 19 tebax 2020 (UTC) '''Gotûbêj:''' <!--Li jêr fikrên xwe binivîsin. {{şîrove}} --> {{şîrove}} Axiftin û axivîn ne eynî tişt in. -- [[Bikarhêner:Guherto|Guherto]] ([[Gotûbêja bikarhêner:Guherto|gotûbêj]]) 09:05, 22 tebax 2020 (UTC) <!-- === Dengdan === {{dengdan/nû|destpêk=?|dawî=?}} piştî dengdan dest pê kir vê şablonê {{dengdan|destpêk=|dawî=}}, û kengî xilas bû vê şablonê {{dengdan/borî|destpêk=|dawî=}} bi kar bînin. --> == [[jêbirk]] == [[jêbir]]--[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 15:41, 19 tebax 2020 (UTC) '''Gotûbêj:''' <!--Li jêr fikrên xwe binivîsin. {{şîrove}} --> {{şîrove}} Xuya dike paşgira -k (bi vê maneyê) gelekî nayê bikaranîn. Agirkuj bi dêla agirkuj-k tê bikaranîn, min tenê "jêbir" bihîstîye, "xwêdan-k" bêçavkanî ye, "demjimêr-k" kêm peyda dibê (bêhtir di spam de heye) ... -- [[Bikarhêner:Guherto|Guherto]] ([[Gotûbêja bikarhêner:Guherto|gotûbêj]]) 09:39, 22 tebax 2020 (UTC) <!-- === Dengdan === {{dengdan/nû|destpêk=?|dawî=?}} piştî dengdan dest pê kir vê şablonê {{dengdan|destpêk=|dawî=}}, û kengî xilas bû vê şablonê {{dengdan/borî|destpêk=|dawî=}} bi kar bînin. --> == [[bager]] == [[bager]] / [[bagêr]]--[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 21:16, 19 tebax 2020 (UTC) '''Gotûbêj:''' <!--Li jêr fikrên xwe binivîsin. {{şîrove}} --> {{şîrove}} <!-- === Dengdan === {{dengdan/nû|destpêk=?|dawî=?}} piştî dengdan dest pê kir vê şablonê {{dengdan|destpêk=|dawî=}}, û kengî xilas bû vê şablonê {{dengdan/borî|destpêk=|dawî=}} bi kar bînin. --> == [[çikilandin]] == --[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 10:52, 20 tebax 2020 (UTC) '''Gotûbêj:''' <!--Li jêr fikrên xwe binivîsin. {{şîrove}} --> {{şîrove}} <!-- === Dengdan === {{dengdan/nû|destpêk=?|dawî=?}} piştî dengdan dest pê kir vê şablonê {{dengdan|destpêk=|dawî=}}, û kengî xilas bû vê şablonê {{dengdan/borî|destpêk=|dawî=}} bi kar bînin. --> == [[evraz]] == [[evraz]] / [[hevraz]] / [[evrazî]] / [[hevrazî]]--[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 15:03, 20 tebax 2020 (UTC) :ervaz [[Taybet:Beşdarî/&#126;2026-16469-22|&#126;2026-16469-22]] ([[Gotûbêja bikarhêner:&#126;2026-16469-22|talk]]) 19:30, 15 adar 2026 (UTC) '''Gotûbêj:''' <!--Li jêr fikrên xwe binivîsin. {{şîrove}} --> {{şîrove}} <!-- === Dengdan === {{dengdan/nû|destpêk=?|dawî=?}} piştî dengdan dest pê kir vê şablonê {{dengdan|destpêk=|dawî=}}, û kengî xilas bû vê şablonê {{dengdan/borî|destpêk=|dawî=}} bi kar bînin. --> == [[xwişk]] == [[xwişk]] / [[xweng]] / [[xwek]] / [[xuşk]]--[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 15:33, 21 tebax 2020 (UTC) {{rfk|xwişk, xweng, xweh|r=524 (xweng, xweh), 526 (xwişk)}} Di ferhengê de "xwişk (r. 526), xweng (r. 524), xweh (r.524)" tev jî bi maneya "''kız kardeş''" hatine qeydkirin. "xwek" û "xuşk" jî tê de nîne. -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 10:04, 2 hezîran 2025 (UTC) === Gotûbêj === <!--Li jêr fikrên xwe binivîsin. {{şîrove}} --> {{şîrove}} ''[[xuşk]]'' u ''[[xweh]]'' ji ber ku di devoka min da herdu jî têne bikaranîn, wek ''[[xuçik]]'' u ''[[xweng]]''. ''[[xwek]]'' devokî ye u bipiranî li rojavayê tê bikaranîn. -- [[Bikarhêner:Hakîmo|Hakîmo]] ([[Gotûbêja bikarhêner:Hakîmo|gotûbêj]]) 15:49, 21 tebax 2020 (UTC) : {{silav|Hakîmo}} Kengî dengdana li ser [[Wîkîferheng:Rêzikên standardkirinê|Rêzikên standardkirinê]] xilas bû, em ê dest bi standardkirinê bikin. Tu jî dikarî fikrên xwe li vir bibêjî '''[[Wîkîferheng:Dengdan/Rêzik/Rêzikên standardkirinê]]'''. ::Di devoka min de xwîşk, xuh û xwak hene. Di wextên cuda de tên bikaranîn. -- [[Bikarhêner:Guherto|Guherto]] ([[Gotûbêja bikarhêner:Guherto|gotûbêj]]) 16:06, 21 tebax 2020 (UTC) Ez awayê rast ya xwîşk/xwişk weke "xwîşk" dibînim, û di înternetê de bêhtir encam hene (hejmara rûpelan binêrin, hejmara encaman şaş e.) -- [[Bikarhêner:Guherto|Guherto]] ([[Gotûbêja bikarhêner:Guherto|gotûbêj]]) 15:27, 25 tebax 2020 (UTC) <!-- === Dengdan === {{dengdan/nû|destpêk=?|dawî=?}} piştî dengdan dest pê kir vê şablonê {{dengdan|destpêk=|dawî=}}, û kengî xilas bû vê şablonê {{dengdan/borî|destpêk=|dawî=}} bi kar bînin. {{erê}}: [[xuşk]] u [[xweh]] (belkî [[xuçik]] jî, lê niha [[xuşk]] ancax têr dikê)--> == [[xwendevan]] == [[xwendevan]] / [[xwandevan]] / [[xwêndkarî]] / [[xwîndkarî]] --[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 22:50, 21 tebax 2020 (UTC) {{rfk|xwendevan, xwendekar|r=524}} Di ferhengê de bi maneyên cuda her du peyv jî derbas dibin. "xwendekar" bi maneya "öğrenci, talebe"; "xwendevan" bi maneya "okuyucu, okur" hatîye qeydkirin. Lewma divê her du jî hebin. "''xwêndkarî''" û "''xwîndkarî''" jî formên "xwendekarî"yê ne, lewma divê wek "xwendekarî" werin standardkirin. -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 09:52, 2 hezîran 2025 (UTC) === Gotûbêj === <!--Li jêr fikrên xwe binivîsin. {{şîrove}} --> {{şîrove}} Xwendevan û xwendekar bi eynî maneyî ne lê ne eynî peyv in, nikarin weke yek werin standardkirin. Ji ber ku xwendin/xwandin weke xwendin hatîye standardkirin divê xwendevan jî wilo bibê. -- [[Bikarhêner:Guherto|Guherto]] ([[Gotûbêja bikarhêner:Guherto|gotûbêj]]) 14:05, 4 îlon 2020 (UTC) <!-- === Dengdan === {{dengdan/nû|destpêk=?|dawî=?}} piştî dengdan dest pê kir vê şablonê {{dengdan|destpêk=|dawî=}}, û kengî xilas bû vê şablonê {{dengdan/borî|destpêk=|dawî=}} bi kar bînin. --> == [[sefhe]] == [[sefhe]] / [[seyfe]] / [[sayfe]] -- [[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 13:34, 22 tebax 2020 (UTC) {{rfk||}} -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 23:06, 1 hezîran 2025 (UTC) === Gotûbêj === <!--Li jêr fikrên xwe binivîsin. {{şîrove}} --> {{şîrove}} Bi min ya standard "sehîfe" ye. Forma "sefhe" di şiîrên Ehmedê Xanî de derbas dibe, lê îro ev peyv bi forma "sehîfe" tê zanîn. Lewma bi min divê em awayê standard wek "'''sehîfe'''" nîşan bidin. -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 23:06, 1 hezîran 2025 (UTC) <!-- === Dengdan === {{dengdan/nû|destpêk=?|dawî=?}} piştî dengdan dest pê kir vê şablonê {{dengdan|destpêk=|dawî=}}, û kengî xilas bû vê şablonê {{dengdan/borî|destpêk=|dawî=}} bi kar bînin. --> == [[pergala xebatê]] == [[pergala xebatê]] / [[pergala xebitandinê]] -- [[Bikarhêner:Guherto|Guherto]] ([[Gotûbêja bikarhêner:Guherto|gotûbêj]]) 15:29, 26 tebax 2020 (UTC) {{rfk||}} -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 22:49, 1 hezîran 2025 (UTC) === Gotûbêj === <!--Li jêr fikrên xwe binivîsin. {{şîrove}} --> {{şîrove}} Ya rast ev ne pirseke li ser standardkirinê ye. Lewma li vir neyê minaqeşekirin baştir e. Lê dîsa fikrê xwe bêjim. Îngilîzîya wî "''operating system''" e, ew jî bi kurdî him dibe "''sîstema xebitandinê''" him jî "''sîstema xebitînê''", ji ber ku lêkera "operate" him transîtîv e him jî întransîtîv. Bi min "pergala xebatê" jî ne xelet e. -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 22:49, 1 hezîran 2025 (UTC) <!-- === Dengdan === {{dengdan/nû|destpêk=?|dawî=?}} piştî dengdan dest pê kir vê şablonê {{dengdan|destpêk=|dawî=}}, û kengî xilas bû vê şablonê {{dengdan/borî|destpêk=|dawî=}} bi kar bînin. --> == [[qet]] == Navdêra qet/qed (bi maneya parçe). Ji erebî hatîye û ya erebî "qet" e (bi t-ya qalin weke '''t'''ewandin). Ya kurdî bi t-ya normal e. -- [[Bikarhêner:Guherto|Guherto]] ([[Gotûbêja bikarhêner:Guherto|gotûbêj]]) 18:24, 28 tebax 2020 (UTC) {{rfk||}} -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 20:02, 28 nîsan 2025 (UTC) Di ''Ji bo Rastnivîsînê Ferhenga Kurdî (Kurmancî)-Tirkî ya Nû'' de 'qed' derbas nabe, qet bi maneya 'hîç' derbas dibe, halê standard ya 'qet'a bi maneya 'parçe'yê wekî 'qut' nîşan dane. -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 20:07, 28 nîsan 2025 (UTC) === Gotûbêj === <!--Li jêr fikrên xwe binivîsin. {{şîrove}} --> {{şîrove}} * Hiii, min got yanî ya hoker bû. -- [[Bikarhêner:Hakîmo|Hakîmo]] ([[Gotûbêja bikarhêner:Hakîmo|gotûbêj]]) 14:03, 29 tebax 2020 (UTC) :{{r|Hakîmo}} Min şablonê li navdêrê danîbû lê baştir e ez binivîsim ku li ser navdêrê ye. (Min vêce nivîsî). -- [[Bikarhêner:Guherto|Guherto]] ([[Gotûbêja bikarhêner:Guherto|gotûbêj]]) 14:30, 29 tebax 2020 (UTC) {{şîrove}} Wek min li jor nivîsî, ev peyv di ferhenga ''Ji bo Rastnivîsînê Ferhenga Kurdî (Kurmancî)-Tirkî ya Nû'' de tine ye, feqet bi min divê forma "'''qet'''" wek ya standard were qebûlkirin. Wek notek biçûk vê jî bêjim, ji "qet"a bi maneya "parçe" lêkera "qet kirin"ê jî çêbûye û lêkera "qut kirin"ê ku tê maneya "du tiştan ji hev qet kirin" û lêkera "qet kirin"ê bi eynî maneyê ne. -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 20:02, 28 nîsan 2025 (UTC) {{şîrove}} Li ser meseleya 'qet' û 'qut'ê jî, her du jî pir berbelav in, lewma bi min divê her du jî bimînin. Wekî din hin ferq jî hene di navbera wan de, wek nimûne, halê navdêrî ya "qet"ê berbelav e, lê halê navdêrî ya "qut"ê neberbelav e. -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 20:07, 28 nîsan 2025 (UTC) <!-- === Dengdan === {{dengdan/nû|destpêk=?|dawî=?}} piştî dengdan dest pê kir vê şablonê {{dengdan|destpêk=|dawî=}}, û kengî xilas bû vê şablonê {{dengdan/borî|destpêk=|dawî=}} bi kar bînin. --> == [[darberû]] / [[darberî]] == [[darberû]] / [[darberî]]--[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 21:36, 30 tebax 2020 (UTC) {{rfk|berû|r=73}} Peyva "darberû" nîne, lê "berû" heye. Jixwe peyda "dar" standard e, nelihevî li ser qismê "berû" û "berî"yê ye. -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 22:24, 27 nîsan 2025 (UTC) {{ds-kirî|darberû}} --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 23:06, 1 hezîran 2025 (UTC) == [[diran]] / [[didan]] == [[diran]] --[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 08:52, 31 tebax 2020 (UTC) {{rfk|diran|r=136}} -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 22:20, 27 nîsan 2025 (UTC) === Gotûbêj === <!--Li jêr fikrên xwe binivîsin. {{şîrove}} --> {{şîrove}} '''''[[didan]]''''' awayê standard e ji ber ku '''''[[diran]]''''' ji wê hatiye: '''''didan''''' > '''''diran''''' * Li Qonyayê herdu li kar in (ez '''''[[didan]]''''' bi kar tînim); li rojhilatê '''''[[didan]]''''' pirtir li kar e; Ehmedê Xanî di ''Nûbihara Biçûkan'' da '''''[[didan]]''''' bi kar anîbû. -- [[Bikarhêner:Hakîmo|Hakîmo]] ([[Gotûbêja bikarhêner:Hakîmo|gotûbêj]]) 08:29, 1 îlon 2020 (UTC) * {{erê}} [[didan]] -- [[Bikarhêner:Hakîmo|Hakîmo]] ([[Gotûbêja bikarhêner:Hakîmo|gotûbêj]]) 08:29, 1 îlon 2020 (UTC) Em dibêjin diran û dinan. "Didan" formeke lêkerê ye jî ("ew xwarin ''didan'' xelkê"), baştir e ne weke hev bin. Diran (înternetê bigere "diranê" û "diranên") gelekî bêhtir ji "didan" ("didanê", "didanên") tê bikaranîn. Fikirên [[Bikarhêner:Ferhengvan|Ferhengvan]] (23ê îlonê 2019) li vir hene: [[Gotûbêja pêvekê:fînî-kurdî]]. -- [[Bikarhêner:Guherto|Guherto]] ([[Gotûbêja bikarhêner:Guherto|gotûbêj]]) 19:02, 1 îlon 2020 (UTC) {{şîrove}} {{r|Guherto|Hakîmo}} Hevalno hûn tim behsa bilêvkirinê dikim lê hûn ti carî behsa çavkaniyan nakin. Binêrin [[Wîkîferheng:Dengdan/Rêzik/Rêzikên standardkirinê]] dibêje ''Derbarê awayê peyvekê de çiqas zêde çavkaniyên kitêb an ferhengên rastnivîsînê, ferheng û kovarên zimannasiyê hebin, ew awa wek awayê standard tên pejirandin.'' Yanî bilêvkirina xelkê ne xema me ye. Heta niha 4 kes gotine erê, ku hûn naxwazin em bi ya çavkaniyan bikin hingê dengê xwe bidin, bibêjin na daku ew rêzik nayên pêjirandin û em dîsa gotûbêj çêkin, rêzikên din hilbijêrin. --[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 19:11, 1 îlon 2020 (UTC) ::{{r|Balyozxane}} Min gotibû ''Diran (înternetê bigere "diranê" û "diranên") gelekî bêhtir ji "didan" ("didanê", "didanên") tê bikaranîn.''. Ew li ser çavkanîya ne. -- [[Bikarhêner:Guherto|Guherto]] ([[Gotûbêja bikarhêner:Guherto|gotûbêj]]) 19:26, 1 îlon 2020 (UTC) :::{{r|Guherto}} Hingê çima dengê xwe nadî? --[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 19:27, 1 îlon 2020 (UTC) ::::{{r|Balyozxane}} Min hin sanîye berî ku tu vê peyama xwe ya talî şand dengê xwe da :) -- [[Bikarhêner:Guherto|Guherto]] ([[Gotûbêja bikarhêner:Guherto|gotûbêj]]) 19:28, 1 îlon 2020 (UTC) :::::{{r|Guherto}} Mala te ava! :) --[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 19:30, 1 îlon 2020 (UTC) ::::::{{r|Balyozxane}} Merheba. Min berê jî gotibû: ''rewşa kurmancên me gelek xirab e, u ji ber hindê pir kurmancên me bi xwendin u nivîsîna zimanê xwe nizanin''. Çavkaniyên niha bipiranî ji devokên navendî tên, hinên rojhilatê jî bi herfên erebî ne. Zimanê standard bi çavkaniyan çênabit, divêt li gorî zimanê hemî kurmancan çêbit. -- [[Bikarhêner:Hakîmo|Hakîmo]] ([[Gotûbêja bikarhêner:Hakîmo|gotûbêj]]) 16:19, 2 îlon 2020 (UTC) ::::::{{r|Balyozxane}} Herwiha '''''[[didan]]''''' helbet dikarit wek '''''[[diran]]''''' bi lêv bibit, lê berevajî nabit. -- [[Bikarhêner:Hakîmo|Hakîmo]] ([[Gotûbêja bikarhêner:Hakîmo|gotûbêj]]) 16:22, 2 îlon 2020 (UTC) :::::::{{r|Hakîmo}} Merheba, fikirên xwe li dengdanê çima nadê? -- [[Bikarhêner:Guherto|Guherto]] ([[Gotûbêja bikarhêner:Guherto|gotûbêj]]) 16:44, 2 îlon 2020 (UTC) ::::::::{{r|Guherto}} Ne min dayê... -- [[Bikarhêner:Hakîmo|Hakîmo]] ([[Gotûbêja bikarhêner:Hakîmo|gotûbêj]]) 12:53, 3 îlon 2020 (UTC) Ez dibêjim ku "dinan" formêka rasttirin bi kurdî ye (bi kelhûrî bikar tînin). Em berhevdin: Farsî: duzd, nazdīk, gandum, gand, dandān, xand-īd-an Kurdî: diz, nezîk, genim, genî, dinan, ken-î-n Zazayî: dızd, nezdi, genım*, gende, dından, (hûwaene) Bi kurmancî, soranî u kelhûrî ZD u ND dibin Z u N, D dikeve. Ev qeyde gelêk kevin e. *ji kurmancî, bi taliş qender: gāndım [[Bikarhêner:Umut Akkoç|Umut Akkoç]] ([[Gotûbêja bikarhêner:Umut Akkoç|gotûbêj]]) 14:14, 18 gulan 2021 (UTC) {{ds-kirî|diran}} --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 23:07, 1 hezîran 2025 (UTC) == [[dur]] == [[dur]] û [[dir]] --[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 19:41, 31 tebax 2020 (UTC) '''Gotûbêj:''' <!--Li jêr fikrên xwe binivîsin. {{şîrove}} --> {{şîrove}} <!-- === Dengdan === {{dengdan/nû|destpêk=?|dawî=?}} piştî dengdan dest pê kir vê şablonê {{dengdan|destpêk=|dawî=}}, û kengî xilas bû vê şablonê {{dengdan/borî|destpêk=|dawî=}} bi kar bînin. --> == [[nanoziko]] == [[nanoziko]] / [[nanzikî]] / [[nano ziko]]--[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 06:57, 4 îlon 2020 (UTC) {{rfk|nanozikî|r=324}} -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 19:27, 27 nîsan 2025 (UTC) {{ds-kirî|nanozikî}} --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 23:07, 1 hezîran 2025 (UTC) == [[sînor]] / [[sinor]] == sînor / sinor -- [[Bikarhêner:Guherto|Guherto]] ([[Gotûbêja bikarhêner:Guherto|gotûbêj]]) 21:15, 4 îlon 2020 (UTC) {{rfk|sînor|r=446}} -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 19:25, 27 nîsan 2025 (UTC) {{ds-kirî|sînor}} --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 23:08, 1 hezîran 2025 (UTC) == [[ard]] == ard / ar -- [[Bikarhêner:Guherto|Guherto]] ([[Gotûbêja bikarhêner:Guherto|gotûbêj]]) 14:10, 6 îlon 2020 (UTC) {{rfk||}} -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 09:52, 27 nîsan 2025 (UTC) === Gotûbêj === <!--Li jêr fikrên xwe binivîsin. {{şîrove}} --> {{şîrove}} ard rasttir dibînim -- [[Bikarhêner:Guherto|Guherto]] ([[Gotûbêja bikarhêner:Guherto|gotûbêj]]) 14:10, 6 îlon 2020 (UTC) {{şîrove}} "ar" tê maneya "agir"ê jî. "Erd" (rûyê zemînê) û "ard" jî wek telafûz nêzî hev in. Di peyva "arvan"ê de jî wek "ar" derbas dibe. Bi min wek "'''ar'''" baştir e. -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 09:52, 27 nîsan 2025 (UTC) <!-- === Dengdan === {{dengdan/nû|destpêk=?|dawî=?}} piştî dengdan dest pê kir vê şablonê {{dengdan|destpêk=|dawî=}}, û kengî xilas bû vê şablonê {{dengdan/borî|destpêk=|dawî=}} bi kar bînin. --> == [[ajne]] /[[avjenî]]/[[ajnî]] == [[ajnî]]--[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 19:05, 6 îlon 2020 (UTC) * {{rfk|ajne, avjenî|r=42, 50}} Di vê rêbera rastnivîsînê de her du formên wek "ajne" û "avjenî" wek standard hatine qeydkirin. Lewma formên peyva ''ajne'' yên wek "ajnê", "ajnî", "aşnê" divê li madeya "ajne"yê werin alîkirin, lê "avjenî" bi serê xwe cih bigire. -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 09:39, 21 îlon 2024 (UTC) {{ds-kirî|[[avjenî]], [[ajne]]}} --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 23:09, 1 hezîran 2025 (UTC) == [[gurî]] == [[gurî]] / [[gurîtî]] / [[gurriyatî]]--[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 20:53, 6 îlon 2020 (UTC) '''Gotûbêj:''' <!--Li jêr fikrên xwe binivîsin. {{şîrove}} --> {{şîrove}} <!-- === Dengdan === {{dengdan/nû|destpêk=?|dawî=?}} piştî dengdan dest pê kir vê şablonê {{dengdan|destpêk=|dawî=}}, û kengî xilas bû vê şablonê {{dengdan/borî|destpêk=|dawî=}} bi kar bînin. --> == [[parsî]] == [[partî]]--[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 23:09, 7 îlon 2020 (UTC) '''Gotûbêj:''' <!--Li jêr fikrên xwe binivîsin. {{şîrove}} --> {{şîrove}} <!-- === Dengdan === {{dengdan/nû|destpêk=?|dawî=?}} piştî dengdan dest pê kir vê şablonê {{dengdan|destpêk=|dawî=}}, û kengî xilas bû vê şablonê {{dengdan/borî|destpêk=|dawî=}} bi kar bînin. --> == [[xwestin]] == xwestin / xwastin xwestin rasttir dibînim. -- [[Bikarhêner:Guherto|Guherto]] ([[Gotûbêja bikarhêner:Guherto|gotûbêj]]) 18:09, 9 îlon 2020 (UTC) {{rfk|xwastin|r=523}} -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 13:48, 6 adar 2025 (UTC) === Gotûbêj === <!--Li jêr fikrên xwe binivîsin. {{şîrove}} --> {{şîrove}} Ez jî '''''[[xwestin]]''''' rasttir dibînim; jixwe '''''[[xwastin]]''''' bi min giran têt, o '''''[[xwestin]]''''' di hemî lehceyên kirmancî da heye. -- [[Bikarhêner:Hakîmo|Hakîmo]] ([[Gotûbêja bikarhêner:Hakîmo|gotûbêj]]) 08:21, 19 îlon 2020 (UTC) <!-- === Dengdan === {{dengdan/nû|destpêk=?|dawî=?}} piştî dengdan dest pê kir vê şablonê {{dengdan|destpêk=|dawî=}}, û kengî xilas bû vê şablonê {{dengdan/borî|destpêk=|dawî=}} bi kar bînin. --> == [[îrrasyonel]] == [[îrrasyonal]]--[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 22:44, 9 îlon 2020 (UTC) {{rfk||}} Ev peyv derbas nabe, feqet peyva "rasyonel" wek standard cih girtîye (r. 403). Lewma ev jî dibe "'''îrrasyonel'''". -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 13:46, 6 adar 2025 (UTC) === Gotûbêj === <!--Li jêr fikrên xwe binivîsin. {{şîrove}} --> {{şîrove}} <!-- === Dengdan === {{dengdan/nû|destpêk=?|dawî=?}} piştî dengdan dest pê kir vê şablonê {{dengdan|destpêk=|dawî=}}, û kengî xilas bû vê şablonê {{dengdan/borî|destpêk=|dawî=}} bi kar bînin. --> == [[ajel]]/[[ajal]] == ajel / ajal Em dibêjin heywan :) -- [[Bikarhêner:Guherto|Guherto]] ([[Gotûbêja bikarhêner:Guherto|gotûbêj]]) 19:11, 10 îlon 2020 (UTC) * {{rfk|ajel|r=42}} --[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 19:34, 22 îlon 2023 (UTC) === Gotûbêj === <!--Li jêr fikrên xwe binivîsin. {{şîrove}} --> {{şîrove}} Peyva ajel ji peyva sewal a kurmancî hatiye standin (s>J) sewal anku ajel ew canewerên çarpayî yên kedîkirî ne. Wekî pez, bizin, çêlek.{{bêîmze|46.161.196.225}} {{ds-kirî|ajel}} --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 23:11, 1 hezîran 2025 (UTC) == [[pîrebok]]/[[pîrhebok]] == {{rfk|pîrebok|r=365}} -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 13:44, 6 adar 2025 (UTC) === Gotûbêj === <!--Li jêr fikrên xwe binivîsin. {{şîrove}} --> {{şîrove}} Ji bo Rastnivîsnê Ferhanga Kurdî; di pera 365 wek ''pîrebok'' hatiye standardîzekirin. Di ferhengê de herweha ev form jî hene: pîraboçk, pîrabok, pîraboşk, pîrabotîk, pîravok, pîravtong, pîreboşk, pîrebotk. Wîkîferhengê herwiha forma pîrhebok heye[[Bikarhêner:Rewiye tine|Rewiye tine]] ([[Gotûbêja bikarhêner:Rewiye tine|gotûbêj]]) 21:15, 10 îlon 2020 (UTC) {{ds-kirî|pîrebok}} --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 23:11, 1 hezîran 2025 (UTC) == [[şirove]] / [[şîrove]] == [[şirove]] / [[şîrove]] --[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 00:50, 11 îlon 2020 (UTC) {{rfk|şirove|r=466}} -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 13:41, 6 adar 2025 (UTC) {{ds-kirî|şirove}}--[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 08:48, 5 tîrmeh 2026 (UTC) == [[pezkûvî]]/[[pezkovî]] == [[pezkovî]]--[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 08:59, 11 îlon 2020 (UTC) {{rfk|pezkûvî|r=354}} -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 13:41, 6 adar 2025 (UTC) === Gotûbêj === <!--Li jêr fikrên xwe binivîsin. {{şîrove}} --> {{şîrove}} {{r|Balyozxane}} Yek hatîye jêbirin. -- [[Bikarhêner:Guherto|Guherto]] ([[Gotûbêja bikarhêner:Guherto|gotûbêj]]) 19:22, 23 çiriya pêşîn 2020 (UTC) {{ds-kirî|pezkûvî}} --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 23:13, 1 hezîran 2025 (UTC) == [[dibistana seretayî]]/[[dibistana seratayî]] == [[dibistana seratayî]]--[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 19:22, 12 îlon 2020 (UTC) {{rfk||}} -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 13:39, 6 adar 2025 (UTC) === Gotûbêj === <!--Li jêr fikrên xwe binivîsin. {{şîrove}} --> {{şîrove}} Bi min eşkere ye ku awayê standard "sereta" ye, lewma ya standard dibe "''[[dibistana seretayî]]''". -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 13:39, 6 adar 2025 (UTC) {{ds-kirî|dibistana seretayî}} --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 23:13, 1 hezîran 2025 (UTC) == [[sêzdeh]]/ [[sêzde]] == / sêzde. sêzdeh rasttir dibînim, sê + z + deh. Ti sedem nîne ji bo jêbirina "h" -- [[Bikarhêner:Guherto|Guherto]] ([[Gotûbêja bikarhêner:Guherto|gotûbêj]]) 09:34, 13 îlon 2020 (UTC) {{rfk|sêzdeh|r=441}} -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 13:37, 6 adar 2025 (UTC) === Gotûbêj === <!--Li jêr fikrên xwe binivîsin. {{şîrove}} --> {{şîrove}} Ferhenga Michael L. Chyet (2003) sêzde ber alî dike sêzdeh. -- [[Bikarhêner:Guherto|Guherto]] ([[Gotûbêja bikarhêner:Guherto|gotûbêj]]) 09:34, 13 îlon 2020 (UTC) : yazdeh/yazde (beralîkirin), çardeh/çarde (dubare), pazdeh/pazde (beralîkirin), şazdeh/şazde (beralîkirin), hevdeh/hevde (beralîkirin), hejdeh/hejde (beralîkirin), nozdeh/nozde (beralîkirin) -- [[Bikarhêner:Guherto|Guherto]] ([[Gotûbêja bikarhêner:Guherto|gotûbêj]]) 09:37, 13 îlon 2020 (UTC) {{ds-kirî|sêzdeh}} --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 23:14, 1 hezîran 2025 (UTC) == [[çirûsk]]/[[çirîsk]] == çirîsk/çirûsk çirûsk(m):1.kıvılcım, çıngı çirîsk(m): binêre(çirûsk)(per 116,117)[[Bikarhêner:Rewiye tine|Rewiye tine]] ([[Gotûbêja bikarhêner:Rewiye tine|gotûbêj]]) 22:46, 13 îlon 2020 (UTC) {{rfk|çirûsk|r=116}} -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 13:36, 6 adar 2025 (UTC) {{ds-kirî|çirûsk}} --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 23:15, 1 hezîran 2025 (UTC) == [[êriş]]/[[êrîş]] == [[êriş]]--[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 17:11, 15 îlon 2020 (UTC) * {{rfk|êriş|r=157}} --[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 19:36, 22 îlon 2023 (UTC) {{ds-kirî|êriş}} --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 23:15, 1 hezîran 2025 (UTC) == [[mûmin]] == [[momîn]]--[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 18:22, 16 îlon 2020 (UTC) {{rfk||}} -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 23:00, 5 sibat 2025 (UTC) === Gotûbêj === <!--Li jêr fikrên xwe binivîsin. {{şîrove}} --> {{şîrove}} Bi min ya standard "'''mumin'''" e. Bi apostrof baştir be jî, ji ber nestandardbûna emilandina apostrofan, ji bo halê standard bêapostrof baştir e. -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 23:00, 5 sibat 2025 (UTC) <!-- === Dengdan === {{dengdan/nû|destpêk=?|dawî=?}} piştî dengdan dest pê kir vê şablonê {{dengdan|destpêk=|dawî=}}, û kengî xilas bû vê şablonê {{dengdan/borî|destpêk=|dawî=}} bi kar bînin. --> == [[xwarza]] == [[xwarza]] / [[xwarzî]] / [[xuharzî]]--[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 15:14, 17 îlon 2020 (UTC) {{rfk|xwarza, xwarzî|r=523}} Her du peyv jî bi eynî maneyê di ferhengê de cih girtine. -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 22:34, 5 sibat 2025 (UTC) === Gotûbêj === <!--Li jêr fikrên xwe binivîsin. {{şîrove}} --> {{şîrove}} <!-- === Dengdan === {{dengdan/nû|destpêk=?|dawî=?}} piştî dengdan dest pê kir vê şablonê {{dengdan|destpêk=|dawî=}}, û kengî xilas bû vê şablonê {{dengdan/borî|destpêk=|dawî=}} bi kar bînin. --> == [[lênêrîn]] == [[nerîn]] / [[nêrîn]] / [[lênêrîn]] / [[lê nerîn]]--[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 21:19, 17 îlon 2020 (UTC) {{rfk|nêrîn|r=333}} -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 21:04, 5 sibat 2025 (UTC) === Gotûbêj === <!--Li jêr fikrên xwe binivîsin. {{şîrove}} --> {{şîrove}} "Lênêrîn" jixwe wek navdêr "''nêrîna li tiştekî''" ye, û "lê nêrîn" jî wek lêker "''li tiştekî nêrîn''" e, lê belê di her dukan de jî lêker/navdêr "nêrîn" e. "li"ya pêşî ji bo maneya "nêrîn"ê bêtesîr e/tesîreke wê lê nîne. Feqet ger were gotin ku "nêrîn" (bi îngilîzî "looking") wek forma "lênêrîn" xwedî maneyeke din e (ku divê ev yek jî bi çavkanîyan were îsbatkirin) wê gavê mirov kare wê peyvê cardin binirxîne. -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 21:04, 5 sibat 2025 (UTC) <!-- === Dengdan === {{dengdan/nû|destpêk=?|dawî=?}} piştî dengdan dest pê kir vê şablonê {{dengdan|destpêk=|dawî=}}, û kengî xilas bû vê şablonê {{dengdan/borî|destpêk=|dawî=}} bi kar bînin. --> == [[hewar]] == [[hewar]]/[[hawar]] --[[Bikarhêner:Şêr|Şêr]] ([[Gotûbêja bikarhêner:Şêr|gotûbêj]]) 10:07, 19 îlon 2020 (UTC) {{rfk|hawar|r=190}} -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 20:35, 5 sibat 2025 (UTC) === Gotûbêj === <!--Li jêr fikrên xwe binivîsin. {{şîrove}} --> {{şîrove}} <!-- === Dengdan === {{dengdan/nû|destpêk=?|dawî=?}} piştî dengdan dest pê kir vê şablonê {{dengdan|destpêk=|dawî=}}, û kengî xilas bû vê şablonê {{dengdan/borî|destpêk=|dawî=}} bi kar bînin. --> == [[muhakeme]] == [[muhakeme]] / [[mihakeme]]--[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 11:59, 19 îlon 2020 (UTC) {{rfk|mihakeme|r=309}} -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 20:34, 5 sibat 2025 (UTC) === Gotûbêj === <!--Li jêr fikrên xwe binivîsin. {{şîrove}} --> {{şîrove}} <!-- === Dengdan === {{dengdan/nû|destpêk=?|dawî=?}} piştî dengdan dest pê kir vê şablonê {{dengdan|destpêk=|dawî=}}, û kengî xilas bû vê şablonê {{dengdan/borî|destpêk=|dawî=}} bi kar bînin. --> == [[tevabûn]] == [[tewabûn]]--[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 18:22, 19 îlon 2020 (UTC) {{rfk|temambûn|r=477}} -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 20:32, 5 sibat 2025 (UTC) === Gotûbêj === <!--Li jêr fikrên xwe binivîsin. {{şîrove}} --> {{şîrove}} Tev jî formên "''temambûn''"ê ne. -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 20:32, 5 sibat 2025 (UTC) <!-- === Dengdan === {{dengdan/nû|destpêk=?|dawî=?}} piştî dengdan dest pê kir vê şablonê {{dengdan|destpêk=|dawî=}}, û kengî xilas bû vê şablonê {{dengdan/borî|destpêk=|dawî=}} bi kar bînin. --> == [[fiêl]] == [[fiêl]] / [[fîil]] / [[fîîl]] Standardkirin lazim e. -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 20:12, 19 îlon 2020 (UTC) {{rfk|fêl|r=164}} -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 20:21, 5 sibat 2025 (UTC) === Gotûbêj === <!--Li jêr fikrên xwe binivîsin. {{şîrove}} --> {{şîrove}} <!-- === Dengdan === {{dengdan/nû|destpêk=?|dawî=?}} piştî dengdan dest pê kir vê şablonê {{dengdan|destpêk=|dawî=}}, û kengî xilas bû vê şablonê {{dengdan/borî|destpêk=|dawî=}} bi kar bînin. --> == [[pêşniyazkirî]] == [[pêşniyarkirî]], [[pêşniyar]] beralî dike [[pêşniyaz]]--[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 22:24, 19 îlon 2020 (UTC) '''Eynî mijar li jêr hatîye vekirin. Ji bo standardkirinê binêrin ya jêr.''' -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 20:18, 5 sibat 2025 (UTC) '''Gotûbêj:''' <!--Li jêr fikrên xwe binivîsin. {{şîrove}} --> {{şîrove}} == [[xwehr]] == [[xwehr]] / [[xwar]] Standardkirin hewce ye. -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 07:43, 20 îlon 2020 (UTC) '''Gotûbêj:''' <!--Li jêr fikrên xwe binivîsin. {{şîrove}} --> {{şîrove}} {{r|Bikarhêner}} Kîjan mane? Jixwe ya xwehr (îng crooked) standardkirî bû lê te xwehr kopî kir xwar. Çima? -- [[Bikarhêner:Guherto|Guherto]] ([[Gotûbêja bikarhêner:Guherto|gotûbêj]]) 09:07, 20 îlon 2020 (UTC) : {{r|Guherto}} Merheba bira. Li ser rûpela "[[xwar]]" maneya rengdêrî ya "ne rast, tewandî" tinebû. Tenê maneyeke wek "çewt, xelet" ''(bi cureyê rengdêrî)'' hebû. Ji ber ku mane kêm û şaş hatibû dayîn min ji rûpela "[[xwehr]]" mane û beşên din kopî kir û bi rûpela "[[xwar]]" ve kir. Û ji ber ku ji bo tenê maneyekê du awayên nivîsê yê wek "[[xwar]]" û "[[xwehr]]" wek standard cih digirtin, min şablona standardkirinê tevlî wan her du rûpelan jî kir, û ji bo ku em awayê standard bibijêrin li vir beşekê nû vekir. -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 09:25, 20 îlon 2020 (UTC) ::Tu dikarîbû bnr-ek lê zêde bikê, ne hewce ye kopîkirin. -- [[Bikarhêner:Guherto|Guherto]] ([[Gotûbêja bikarhêner:Guherto|gotûbêj]]) 09:48, 20 îlon 2020 (UTC) ::: {{r|Guherto}} Ji ber ku ez awayê standard wek "[[xwar]]" dibînim min rûpelê wek standard hazir kir. Awayê bnr-yî ne awayê wek standard e. -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 10:07, 20 îlon 2020 (UTC) ::::Temam. Lê hêjî kopîkirin ne hewce ye, bnr min çawa kir li [[#girover]] ji ber ku ez wê standard didîtim (dibînim). -- [[Bikarhêner:Guherto|Guherto]] ([[Gotûbêja bikarhêner:Guherto|gotûbêj]]) 10:11, 20 îlon 2020 (UTC) ::::: {{r|Guherto}} Baş e, di yên din de êdî ez ê wisa bikim. -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 14:35, 20 îlon 2020 (UTC) xwehr = ne rast (tirkî:eğik) û xwar = jêr (tirkî:aşağı).—<small>[[Bikarhêner:Gomada|<span style="background:Yellow">'''''<span style="font-family:Verdana;color:red">Gom<span style="color:#006400">ada</span></span></span>''''']]<sup>[[Gotûbêja bikarhêner:Gomada|peyam]]</sup></small> 15:34, 21 kanûna paşîn 2021 (UTC) {{şirove}} Birêzan; li herêma me ev peyv wek ''xar'' tê bilêv kirin û li serhedê heta Sêwaz û ji wir hata Rojavayê Kurdistan bi vî awayîye.Min xwehr heya niha ji devê kesî nebihîstibû. Bi ya min xwar rasttire. Ji ber ku li devê meda di nav gellek peyvanda tîpa ''w'' nîne. Lê îjar jî bi peyva ''xwarin'' û ''xwarê''(berjêr) tevlihevî çêdibe.Dema ku standardizasyon çêdibe divê hemî peyvên watecûda bi wekhev neyê nivîsandin. Wek mînak niha peyvên kêr(alav,feyde,pozdewixî), ker(ajal,parçe,koma pez,nebihîz) 3-4 peyven ku xwendinên wan cûdane bi heman awayî tê nivîsin,ev zimanê me zortir dike û dibe sedema xeletîyan.Divê ziman standardîze be, lê ne bi vî awayî. {{bêîmze|Mihemed Qers}} == [[dirist]] == [[dirist]] / [[dirust]] -- [[Bikarhêner:Guherto|Guherto]] ([[Gotûbêja bikarhêner:Guherto|gotûbêj]]) 13:44, 20 îlon 2020 (UTC) {{rfk|dirust|r=137}} -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 20:15, 5 sibat 2025 (UTC) === Gotûbêj === <!--Li jêr fikrên xwe binivîsin. {{şîrove}} --> {{şîrove}} == [[neynok]] == [[neynok]] / [[neynûk]] / [[nînok]] / [[nênûk]] / [[nenîk]] Awayê ku herî kêm tê bikaranîn (nînok) weke standard hatîye neqandin, ez vê şaş dibînim. -- [[Bikarhêner:Guherto|Guherto]] ([[Gotûbêja bikarhêner:Guherto|gotûbêj]]) 20:43, 20 îlon 2020 (UTC) Eynî rûpel li nînok û nênûk hene. -- [[Bikarhêner:Guherto|Guherto]] ([[Gotûbêja bikarhêner:Guherto|gotûbêj]]) 20:45, 20 îlon 2020 (UTC) {{rfk|nenûk|r=328}} -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 20:10, 5 sibat 2025 (UTC) === Gotûbêj === <!--Li jêr fikrên xwe binivîsin. {{şîrove}} --> {{şîrove}} Bi qenaeta min divê halê standard "neynûk" be. -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 20:10, 5 sibat 2025 (UTC) == [[neynokbir]] == neynokbir/neynûkbir/nenîkbir Divê li gora encama [[#neynok]] werê standardkirin. -- [[Bikarhêner:Guherto|Guherto]] ([[Gotûbêja bikarhêner:Guherto|gotûbêj]]) 20:39, 20 îlon 2020 (UTC) {{rfk|nenûk|r=328}} Di vê ferhengê de ''nenûkbir'' nîne, lê ji bo peyva "neynûk"ê awayê standard wek "nenûk" hatîye nîşandayîn. -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 20:12, 5 sibat 2025 (UTC) === Gotûbêj === <!--Li jêr fikrên xwe binivîsin. {{şîrove}} --> {{şîrove}} Bi min wek halê standard forma "neynûk" baştir e. Lewma ev jî dibe "''neynûkbir''". -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 20:12, 5 sibat 2025 (UTC) == [[xwijok]] == [[xişok]]--[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 02:46, 21 îlon 2020 (UTC) {{rfk||}} -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 19:44, 5 sibat 2025 (UTC) === Gotûbêj === <!--Li jêr fikrên xwe binivîsin. {{şîrove}} --> {{şîrove}} Bi min ji ber ku halê wê yê lêker wek "''xişîn''" e, ya standard "'''xişok'''" e. -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 19:44, 5 sibat 2025 (UTC) == [[pirhindik]] == [[pir hindik]]--[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 20:34, 22 îlon 2020 (UTC) {{rfk||}} -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 22:30, 3 sibat 2025 (UTC) === Gotûbêj === <!--Li jêr fikrên xwe binivîsin. {{şîrove}} --> {{şîrove}} Formeke wek "pirhindik" bi min bêçavkanî ye. Lewma ya standard divê wek "pir hindik" be. Feqet peyva "pir hindik" jî bi maneya "teqrîben, nêzîkî" nîne. Divê ew qism jî were rastkirin. -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 22:30, 3 sibat 2025 (UTC) :Min maneya wê fam kir, feqet nizanim, emilandineke wisa heye an tine. -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 13:26, 6 adar 2025 (UTC) == [[qireqir]] == [[qîreqîr]]--[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 17:22, 23 îlon 2020 (UTC) {{rfk|qîreqîr|r=390}} -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 22:11, 3 sibat 2025 (UTC) === Gotûbêj === <!--Li jêr fikrên xwe binivîsin. {{şîrove}} --> {{şîrove}} == [[pênivîs]] == [[pênivîs]] / [[pênûs]] / [[pênivîsk]]. Pênivîs bêhtir tê bikaranîn. Ev û pênûs eynî peyv in, lê pênûs li gora "nûsîn"a soranî û pênivîs li gora "nivîsîn"a kurmancî hatîye çêkirin. Em wan bikin yek? -- [[Bikarhêner:Guherto|Guherto]] ([[Gotûbêja bikarhêner:Guherto|gotûbêj]]) 14:58, 24 îlon 2020 (UTC) {{rfk||}} -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 21:34, 3 sibat 2025 (UTC) === Gotûbêj === <!--Li jêr fikrên xwe binivîsin. {{şîrove}} --> {{şîrove}} # pênivîs - Ferhenga Birûskî Michael L. Chyet # pênivîs - Ferhenga Destî çap 2 Umîd Demîrhan # pênivîs - Ferhenga Kurdî ( Kurmancî ) - Farsî. Koma Kurdîya Kurmancî. Azad MAKÛYÎ,Haşim MEHMÛDÎ,Şehnaz OMERZADE, Nasir ECEMÎ,Mohsin QULÎZADE,Kejal PADAŞ,Efsûn YÛSIFÎ # pênivîsk - Rehnas Husein Muhammed {{şîrove}} Qertafa "-k"yê di çêkirina navdêran de li kar e. Lewma ji alîyê xisûsîyeta navderbûnê ve "''pênivîsk''", ji alîyê pratîkbûnê ve ''"pênivîs"'' baştir e. Lê eger krîtera girêdayîmayîna bi eslê peyvê ve were esasgirtin, wê gavê jî ''"pênûs"'' baştir e. Biqenaeta min "'''pênivîsk'''". : Ji xeynî vê qismeke ji [https://zimannas.wordpress.com/2015/12/21/em-cima-kurdi-li-ber-xwe-dikin-ciyayeki-ase/ nivîsa malpera Zimannasê]: : ''[Peyva ”qelem” ji aliyê hemû kurdan ve û ji hêla miletên misilman ve ji Indonezyayê heta Mexribê tê fehmkirin û bikaranîn. Lê nivîskarên me qîma xwe bi wê naînin ji ber ku bi xeletî bawer dikin ku eslê wê erebî ye. Lê eslê wê jî yûnaniya kevn e: κάλαμος (kálamos). Li cihê wê nivîskarên me xwe dispêrin peyvên çêkirok yên wek ”pênivîs(k)” yan jî ”pênûs” ya ji soranî wergirtî. Lê ”pênivîs(k)” yan ”pênûs” her tişt e ku mirov pê dinivîse, ne tenê qelem e: li vê serdemê mirov zêdetir ne bi qeleman lê bi kompûterê, bi telefona mobîl yan bi hin makîneyên din dinivîse. Amûrên nivîsînê yên serekî niha ne qelem in lê kompûter, laptop, tablet û telefon in. Li gor vê rêbazê be, divê mirov ji kompûteran, ji laptopan re, ji tabletan re û ji telefonan re jî bibêje ”pênivîsk/pênûs”, ne tenê ji qeleman re!]'' -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 21:34, 3 sibat 2025 (UTC) == [[behs]] == / [[bas]]. Em dibêjin beḧs. -- [[Bikarhêner:Guherto|Guherto]] ([[Gotûbêja bikarhêner:Guherto|gotûbêj]]) 17:49, 24 îlon 2020 (UTC) {{rfk|behs|r=64}} -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 14:42, 1 sibat 2025 (UTC) === Gotûbêj === <!--Li jêr fikrên xwe binivîsin. {{şîrove}} --> {{şîrove}} == [[dîmender]] == [[dîmender]] / [[dîmendêr]]. -- [[Bikarhêner:Guherto|Guherto]] ([[Gotûbêja bikarhêner:Guherto|gotûbêj]]) 21:43, 25 îlon 2020 (UTC) {{rfk||}} -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 18:45, 27 kanûna paşîn 2025 (UTC) === Gotûbêj === <!--Li jêr fikrên xwe binivîsin. {{şîrove}} --> {{şîrove}} Paşgira "der" / "dêr"ê li şûna hev hatine emilandin. Lê ji nimûneyên jêrîn ên ji ferhenga ''Ji bo Rastnivîsînê Ferhenga Kurdî (Kurmancî)-Tirkî ya Nû'' tê dîtin ku qerareke li ser zelalkirina halê standard nehatîye dayîn di wê ferhengê de. Bnr. [[agahîder]] (Ji bo Rastnivîsînê Ferhenga Kurdî (Kurmancî)-Tirkî ya Nû r. 41), [[hander]] (Ji bo Rastnivîsînê Ferhenga Kurdî (Kurmancî)-Tirkî ya Nû r. 189), [[kêfder]] (Ji bo Rastnivîsînê Ferhenga Kurdî (Kurmancî)-Tirkî ya Nû r. 253), [[avdêr]] (Ji bo Rastnivîsînê Ferhenga Kurdî (Kurmancî)-Tirkî ya Nû wek "avdêr" nîne, lê wek "''avdêrî''" r. 50), [[bangdêr]] (Ji bo Rastnivîsînê Ferhenga Kurdî (Kurmancî)-Tirkî ya Nû r. 58), [[dengdêr]] ''-ne zelal e, nimûneyên din fahmbartir in-'' (Ji bo Rastnivîsînê Ferhenga Kurdî (Kurmancî)-Tirkî ya Nû r. 127), [[kardêr]] (Ji bo Rastnivîsînê Ferhenga Kurdî (Kurmancî)-Tirkî ya Nû r. 239), [[saloxdêr]] (Ji bo Rastnivîsînê Ferhenga Kurdî (Kurmancî)-Tirkî ya Nû r. 425), [[serîhildêr]] (Ji bo Rastnivîsînê Ferhenga Kurdî (Kurmancî)-Tirkî ya Nû r. 435), [[xwepêşander]] (Di ''Ji bo Rastnivîsînê Ferhenga Kurdî (Kurmancî)-Tirkî ya Nû'' de nîne), [[dersder]] (Di ''Ji bo Rastnivîsînê Ferhenga Kurdî (Kurmancî)-Tirkî ya Nû'' de nîne), [[fermandêr]] (Di ''Ji bo Rastnivîsînê Ferhenga Kurdî (Kurmancî)-Tirkî ya Nû'' de ev form nîne, wek "''fermande''" qeyd kirine), [[deynder]] (Di ''Ji bo Rastnivîsînê Ferhenga Kurdî (Kurmancî)-Tirkî ya Nû'' de nîne), [[girêdêr]] (Di ''Ji bo Rastnivîsînê Ferhenga Kurdî (Kurmancî)-Tirkî ya Nû'' de nîne), [[mizgînder]] (Di ''Ji bo Rastnivîsînê Ferhenga Kurdî (Kurmancî)-Tirkî ya Nû'' de nîne). Bi min divê em li balê bidin ser ku paşgirên "der" / "dêr"ê eynî maneyê didin an na. Bi min paşgira "der"ê qismen nêzî paşgira "-dar"ê ye ku ew jî maneya xwedîbûna tiştekî dide. Lewma bi min ji bo peyvên bi maneya "kesê tiştekî dide" emilandina paşgira "-dêr"ê wê baştir be, lê ger em ji alîyê rehetîya telafûzê bifikirin jî paşgira "-der"ê baştir e ji bo awayê standard. Wek netîce bi min ji bo halê standard (ji bo peyvên bi maneya "kesê tiştekî dide") paşgira "-dêr"ê başttir e. -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 18:45, 27 kanûna paşîn 2025 (UTC) == [[Rojavayê Kurdistanê]] == /Rojavaya Kurdistanê. -- [[Bikarhêner:Guherto|Guherto]] ([[Gotûbêja bikarhêner:Guherto|gotûbêj]]) 12:16, 26 îlon 2020 (UTC) [[Rojavayê Kurdistanê]]-- [[Bikarhêner:Mihemed Qers|Mihemed Qers]] ([[Gotûbêja bikarhêner:Mihemed Qers|gotûbêj]]) 21:12, 9 adar 2021 (UTC) {{rfk|"rojava" wek nêr derbas dibe|r=416}} Peyva "rojava" wek nêr qeyd kirine. -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 21:13, 26 kanûna paşîn 2025 (UTC) === Gotûbêj === <!--Li jêr fikrên xwe binivîsin. {{şîrove}} --> {{şîrove}} ''{{g|ku|rojava}}'' navdêreke mê ye, li gori rêzimana kurdi nivîsa rast "Rojava'''ya''' ''(îzafe)'' Kurdistan'''ê''' ''(çemandî)''" ye. Feqet "Rojavayê Kurdistanê" jî pirr tê bikaranîn.. --[[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 21:27, 9 adar 2021 (UTC) {{şîrove}} Slav @[[Bikarhêner:Ghybu|Ghybu]], gelle me û mezinên me dema ku peyvan bilêv dikin nêr/mê bûna peyvan çîye nizanin,peyv û hevokên ku hezaran salanda terkîb bûne û derketine holê bi xwezayî ji devên wan dertê, heta eger ku ji wanra nêr/mê bûna peyvan qal bikin yê li me xerîb binêrin,lê wan bi hezaran saland a bê qest û bi xwezayî vî zimanî qasê ku meriva şaş bihêle bi duzen ava kirine. Ne tenê herêma me, min ji gellê çi bihîstîye wê dinivîsim. Lê ji bilî gellê meyê hin herêmên Mêrdînê min tu cîyek nebihîstye ku mînak şûna ″porê min″ ″pora min″,yan jî şûna ″Rojavayê Kurdistanê″ ″Rojavaya Kurdistanê″ bêjin. Lê bi ya min em nikarin bêjin jiber ku peyva ″roj″ mê ye divê ″rojava″ jî mê be. Rast e rojava ji roj tê lê edî rojava peyveke cûda ye. [[Bikarhêner:Mihemed Qers|Mihemed Qers]] ([[Gotûbêja bikarhêner:Mihemed Qers|gotûbêj]]) 23:09, 9 adar 2021 (UTC) {{şîrove}} Di Rêbera Rastnivîsînê ya Komxebata Kurmancîyê de (r.40) jî wek alî (wek hêl, ne parçe) "'''rojavayê''' Kurdistanê" derbas kirine. Ji ber ku eynî peyv e, em dibînin ku li wir jî wek "nêr" qebûl kirine. -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 21:13, 26 kanûna paşîn 2025 (UTC) == [[diz]] == [[diz]] / [[dizîker]] / [[dizîkar]]. -- [[Bikarhêner:Guherto|Guherto]] ([[Gotûbêja bikarhêner:Guherto|gotûbêj]]) 12:37, 27 îlon 2020 (UTC) {{rfk|diz, dizek|r=138}} -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 21:06, 26 kanûna paşîn 2025 (UTC) === Gotûbêj === <!--Li jêr fikrên xwe binivîsin. {{şîrove}} --> {{şîrove}} ″diz″ ji xwe kesek e ″dizî″ jî karesata wî/ê ye lewma ″dizîker/dizîkar″ xeletin.[[Bikarhêner:Mihemed Qers|Mihemed Qers]] ([[Gotûbêja bikarhêner:Mihemed Qers|gotûbêj]]) 20:38, 9 adar 2021 (UTC) :Kes nabêje "dizîker,/dizîkar", kurd dibêjin : dizek . [[Taybet:Beşdarî/83.252.83.100|83.252.83.100]] 19:25, 3 gulan 2023 (UTC) {{şîrove}} Şiroveyên hatî yên berê ji bo min jî rast dixuyin. -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 21:06, 26 kanûna paşîn 2025 (UTC) == [[rêkxistin]] == [[rêxistin]] --[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 22:03, 27 îlon 2020 (UTC) *{{rfk|rêxistin}}--[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 11:27, 23 îlon 2023 (UTC) === Gotûbêj === <!--Li jêr fikrên xwe binivîsin. {{şîrove}} --> {{şîrove}} [[rêxistin]] -- [[Bikarhêner:Mihemed Qers|Mihemed Qers]] ([[Gotûbêja bikarhêner:Mihemed Qers|gotûbêj]]) 20:39, 9 adar 2021 (UTC) == [[cihêl]] == [[cihêl]] / [[cehêl]] standardkirin lazim e. -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 14:38, 29 îlon 2020 (UTC) {{rfk|cahil|r=94}} Forma standard wek "'''cahil'''" hatîye nîşandan, ji bo kelîmeya "cihêl". -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 00:10, 4 çiriya paşîn 2024 (UTC) === Gotûbêj === <!--Li jêr fikrên xwe binivîsin. {{şîrove}} --> {{şîrove}} == [[tihn]] == [[tên]] --[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 20:41, 30 îlon 2020 (UTC) {{rfk|tîn|r=488}} -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 21:01, 26 kanûna paşîn 2025 (UTC) === Gotûbêj === <!--Li jêr fikrên xwe binivîsin. {{şîrove}} --> {{şîrove}} == [[gişt]] == [[gişt]] / [[giş]] / [[gî]] / [[gîh]] --[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 22:25, 30 îlon 2020 (UTC) {{rfk|gişt|r=179}} -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 20:55, 26 kanûna paşîn 2025 (UTC) === Gotûbêj === <!--Li jêr fikrên xwe binivîsin. {{şîrove}} --> {{şîrove}} == [[tal]] == [[tehl]]--[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 00:35, 1 çiriya pêşîn 2020 (UTC) {{rfk|tahl|r=472}} -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 20:51, 26 kanûna paşîn 2025 (UTC) === Gotûbêj === <!--Li jêr fikrên xwe binivîsin. {{şîrove}} --> {{şîrove}} Birêzan pirranîya gellê me vê peyvê wek ″تعال″ bilêv dike lê alfabeya me da tîpa ″ع″ tune.Divê em jibo vê tîpê standartekî çêkin, wek şûna ″ع″ ″a yan jî eh″ bikarbînin wê demê pirsgirêk yê jibo peyvên din jî çareser be. -- [[Bikarhêner:Mihemed Qers|Mihemed Qers]] ([[Gotûbêja bikarhêner:Mihemed Qers|gotûbêj]]) 21:31, 9 adar 2021 (UTC) == [[şuxl]] == [[şol]]--[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 02:56, 2 çiriya pêşîn 2020 (UTC) [[şuxil]]--[[Bikarhêner:Mihemed Qers|Mihemed Qers]] ([[Gotûbêja bikarhêner:Mihemed Qers|gotûbêj]]) 21:41, 9 adar 2021 (UTC) {{rfk|şixul|r=466}} -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 20:50, 26 kanûna paşîn 2025 (UTC) === Gotûbêj === <!--Li jêr fikrên xwe binivîsin. {{şîrove}} --> {{şîrove}} == [[gilîz]] == [[girêz]] / [[gilîz]] / [[gilêz]] -- [[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 12:25, 5 çiriya pêşîn 2020 (UTC) :girêz [[Taybet:Beşdarî/&#126;2026-20662-33|&#126;2026-20662-33]] ([[Gotûbêja bikarhêner:&#126;2026-20662-33|talk]]) 19:33, 3 nîsan 2026 (UTC) {{rfk|gilêz|r=176}} -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 20:46, 26 kanûna paşîn 2025 (UTC) === Gotûbêj === <!--Li jêr fikrên xwe binivîsin. {{şîrove}} --> {{şîrove}} Çi wê ê standardkirin? -- [[Bikarhêner:Guherto|Guherto]] ([[Gotûbêja bikarhêner:Guherto|gotûbêj]]) 17:27, 14 çiriya paşîn 2020 (UTC) {{şîrove}} [[girêz]] -- [[Bikarhêner:Mihemed Qers|Mihemed Qers]] ([[Gotûbêja bikarhêner:Mihemed Qers|gotûbêj]]) 20:42, 9 adar 2021 (UTC) == [[waris]] == / [[wêris]] -- [[Bikarhêner:Guherto|Guherto]] ([[Gotûbêja bikarhêner:Guherto|gotûbêj]]) 17:03, 6 çiriya pêşîn 2020 (UTC) {{rfk|waris|r=504}} -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 16:00, 26 kanûna paşîn 2025 (UTC) === Gotûbêj === <!--Li jêr fikrên xwe binivîsin. {{şîrove}} --> {{şîrove}} == [[rêveber]] == /birêveber. Ber alî dike "birêveber" lê bahwer im "rêveber" bêhtir tê bikaranîn. -- [[Bikarhêner:Guherto|Guherto]] ([[Gotûbêja bikarhêner:Guherto|gotûbêj]]) 19:50, 12 çiriya pêşîn 2020 (UTC) {{rfk|birêveber|r=86}} -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 15:15, 26 kanûna paşîn 2025 (UTC) === Gotûbêj === <!--Li jêr fikrên xwe binivîsin. {{şîrove}} --> {{şîrove}} Bi min her çiqas lêker "''bi rê ve birin''" be jî halê standard wek "''rêveber''" be baştir e. -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 15:15, 26 kanûna paşîn 2025 (UTC) == [[jêk cuda bûn]] == /jê cuda bûn. -- [[Bikarhêner:Guherto|Guherto]] ([[Gotûbêja bikarhêner:Guherto|gotûbêj]]) 15:15, 15 çiriya pêşîn 2020 (UTC) {{rfk|ji hev cihê bûn, ji hev cuda bûn|r=230}} Forma "jêk" (ji yek) di vê ferhengê de derbas nabe. -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 15:13, 26 kanûna paşîn 2025 (UTC) === Gotûbêj === <!--Li jêr fikrên xwe binivîsin. {{şîrove}} --> {{şîrove}} [[jê cuda bûn]]--[[Bikarhêner:Mihemed Qers|Mihemed Qers]] ([[Gotûbêja bikarhêner:Mihemed Qers|gotûbêj]]) 18:18, 7 adar 2021 (UTC) {{şîrove}} Di "Cuda bûn" / "cihê bûn"ê de jixwe du tişt ji hev cuda dibin, lewma bi min madeyeke wek "''jê cuda bûn''" / "''jê cihê bûn''" (ji tiştekî cuda bûn / ji tiştekî cihê bûn) nehewce (neferhengî) ye. Forma "''jêk''" ''(ji yek)'' di ferhenga 'Ji bo Rastnivîsînê Ferhenga Kurdî (Kurmancî)-Tirkî ya Nû' de derbas nabe. Lewma bi dîtina min her du formên mewcûd jî nestandard in, lê belê ya standard "'''''ji hev cuda bûn'''''" e. -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 15:13, 26 kanûna paşîn 2025 (UTC) == [[pakêt]] == /paket. -- [[Bikarhêner:Guherto|Guherto]] ([[Gotûbêja bikarhêner:Guherto|gotûbêj]]) 19:04, 24 çiriya pêşîn 2020 (UTC) {{rfk||}} -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 14:56, 26 kanûna paşîn 2025 (UTC) === Gotûbêj === <!--Li jêr fikrên xwe binivîsin. {{şîrove}} --> {{şîrove}} Di Ji bo Rastnivîsînê Ferhenga Kurdî (Kurmancî)-Tirkî ya Nû de (r. 346) ji bo halê standard yê kelîmeya "''parsêl''"ê "''parsel''" nîşan dane. Ev jî wekî wî ye, '''lewma halê standard "''paket''" e''', lê ne "''pakêt''". Ji ber ku telafûza "''pakêt''"ê jî li gor yê din zehmettir e. -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 14:56, 26 kanûna paşîn 2025 (UTC) == [[hevaltî]] == / [[hevalî]]. Hevaltî rasttir e û bêhtir tê bikaranîn. -- [[Bikarhêner:Guherto|Guherto]] ([[Gotûbêja bikarhêner:Guherto|gotûbêj]]) 21:32, 31 çiriya pêşîn 2020 (UTC) {{rfk|hevalî, hevaltî|r=200}} Di vê ferhengê de her du formên wek "''hevaltî''" û "''hevalî''" jî wek standard hatine qebûlkirin. -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 14:52, 26 kanûna paşîn 2025 (UTC) === Gotûbêj === <!--Li jêr fikrên xwe binivîsin. {{şîrove}} --> {{şîrove}} Bi min divê em tenê yekî ji wan wek ya standard bibijêrin. Ew jî divê '''''hevaltî''''' be. -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 14:52, 26 kanûna paşîn 2025 (UTC) == [[êzidî]] == [[êzîdî]]/[[êzdî]] - -[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 19:04, 11 çiriya paşîn 2020 (UTC) {{rfk|êzidî|r=158}} û wek kelîmeya jêçêbûyî: "êzidîtî". -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 14:48, 26 kanûna paşîn 2025 (UTC) === Gotûbêj === <!--Li jêr fikrên xwe binivîsin. {{şîrove}} --> {{şîrove}} [[êzdî]]--[[Bikarhêner:Mihemed Qers|Mihemed Qers]] ([[Gotûbêja bikarhêner:Mihemed Qers|gotûbêj]]) 18:16, 7 adar 2021 (UTC) == [[potîn]] == [[putîn]]--[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 18:04, 14 çiriya paşîn 2020 (UTC) {{rfk||}} -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 19:59, 19 adar 2025 (UTC) === Gotûbêj === <!--Li jêr fikrên xwe binivîsin. {{şîrove}} --> {{şîrove}} Di pir cihan de wek "potîn" derbas bûye, lê min li ti derê forma "putîn" nedît. Lewma bi min eşkere ye ku halê standard wek "'''potîn'''" e. Û ger forma din bi temamî bêçavkanî be, em wê formê jî jê bibin. -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 19:59, 19 adar 2025 (UTC) == [[diwazdeh]] == [[diwazdeh]] / [[dazde]] {{rfk|duwazdeh|r=142}} -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 00:19, 4 çiriya paşîn 2024 (UTC) === Gotûbêj === <!--Li jêr fikrên xwe binivîsin. {{şîrove}} --> {{şîrove}} == [[xwende]] == [[xwenda]]--[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 18:47, 25 çiriya paşîn 2020 (UTC) {{rfk|xwende|r=524}} -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 00:17, 4 çiriya paşîn 2024 (UTC) === Gotûbêj === <!--Li jêr fikrên xwe binivîsin. {{şîrove}} --> {{şîrove}} Bi min ji bo kelîmeya "'''xwende'''" divê forma standard "xwende" be, ne ku "xwendî". Maneya kesê perwerdegirtî û kesê du-kelîme-xwendî divê ne eynî be. Lewma ez kelîmeya "xwende" pêşnîyar dikim ji bo awayê standard. -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 00:17, 4 çiriya paşîn 2024 (UTC) == [[pêşniyaz]] == [[pêşniyaz]] / [[pêşniyar]] / [[pêşniyaz kirin]] / [[pêşniyar kirin]]--[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 19:06, 25 çiriya paşîn 2020 (UTC) {{rfk|pêşnîyaz|r=359}} Kelîmeyên jêçêbûyî ên "pêşnîyaz kirin", "pêşnîyazî", "pêşnîyazkirin" jî wek standard hatine nîşandan. -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 00:12, 4 çiriya paşîn 2024 (UTC) :Dibe ku ev peyv pêşniyaz be ne pêşn(î)yaz. Ev peyv hîn bêtir nêzî hizir e. Lewra niyaz wateya daxwazê dide lê niyar wateya neyartiyê dide. Divê ev peyv pêşniyaz be. [[Bikarhêner:Mûhemmed Seîd|Mûhemmed Seîd]] ([[Gotûbêja bikarhêner:Mûhemmed Seîd|gotûbêj]]) 21:03, 28 tebax 2025 (UTC) === Gotûbêj === <!--Li jêr fikrên xwe binivîsin. {{şîrove}} --> {{şîrove}} {{r|Balyozxane}} Wê çi ê standardkirin? Yan ti dixwazê ya standard werê guhertin? -- [[Bikarhêner:Guherto|Guherto]] ([[Gotûbêja bikarhêner:Guherto|gotûbêj]]) 20:06, 25 çiriya paşîn 2020 (UTC) :{{r|Guherto}} Nabînî pêşniyar dibêje pêşniyaz rast e pêşniyaz kirin dibêje pêşniyar kirin rast e. Kîjan rast e? --[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 20:21, 25 çiriya paşîn 2020 (UTC) ::Qusûrê ne mêzêne, mi tenê rûpela pêşniyaz vekir û dît ku dibêjê pêşniyaz / pêşniyar. -- [[Bikarhêner:Guherto|Guherto]] ([[Gotûbêja bikarhêner:Guherto|gotûbêj]]) 20:56, 25 çiriya paşîn 2020 (UTC) == [[kamil]] == [[kamil]], [[kamîl]], [[kamul]]--[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 20:02, 29 çiriya paşîn 2020 (UTC) {{rfk||}} -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 21:49, 3 çiriya paşîn 2024 (UTC) === Gotûbêj === <!--Li jêr fikrên xwe binivîsin. {{şîrove}} --> {{şîrove}} Ev peyveke Erebîye, lê dema ku Kurd wê bilêv dikin ″kamil″ dibêjin.Lewma ″kamil″ rasttire, ″kamîl û kamul″ bilêvkirinên tirk û hindîyane. [[Bikarhêner:Mihemed Qers|Mihemed Qers]] ([[Gotûbêja bikarhêner:Mihemed Qers|gotûbêj]]) 17:26, 7 adar 2021 (UTC) {{şîrove}} Ya standard bi eşkereyî "kamil" e. -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 21:49, 3 çiriya paşîn 2024 (UTC) : Lê di Ji bo Rastnivîsînê Ferhenga Kurdî (Kurmancî) - Tirkî ya Nû ya M. Malmîsanij û yên din de cih dane madeya "tekamil" û formên wê yên nestandard ên wek ''tekamîl'', ''tekamul''. Lewma ya standard li gor vê ferhengê dide "'''kamil'''". -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 21:54, 3 çiriya paşîn 2024 (UTC) = Daxwazên standardkirinê: 2021 = == [[fêrgeh]] == [[fêrgeh]] / [[fêrge]]--[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 16:58, 5 kanûna paşîn 2021 (UTC) {{rfk||}} -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 21:36, 3 çiriya paşîn 2024 (UTC) === Gotûbêj === <!--Li jêr fikrên xwe binivîsin. {{şîrove}} --> {{şîrove}} [[fêrgeh]] bê guman rasttire, ev tîpa ″h″ di gellek peyvanda li hin herêman nayê bilêvkirin.Lê ev nayê manê ku ″h″ tunne. {{şîrove}} Herçend ev kelîme di Ferhenga Kurdî ya Rastnivîsînê ya M. Malmîsanij û yên din de derbas nabe jî, ji madeyên "azmûngeh" (r. 54), "dadgeh" (r. 120), "dangeh" (r. 122) û yên din tê famkirin ku ji bo paşgira "-geh"ê (formên din: "-ge") ya standard "-geh" e. Lewma em karin bêjin ku ji bo vê kelîmeyê divê ya standard bibe "fêrgeh". -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 21:36, 3 çiriya paşîn 2024 (UTC) == [[bêhêwî]] == [[bêhewî]] Standardkirin hewce ye. -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 18:52, 23 kanûna paşîn 2021 (UTC) {{rfk|hewî|r=202}} Ji bo maneya "kuma" awayê standard wekî "hewî" hatiye nîşandan. -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 21:25, 3 îlon 2023 (UTC) === Gotûbêj === <!--Li jêr fikrên xwe binivîsin. {{şîrove}} --> {{şîrove}} Peyvên "hewî" û "hêwî" her du jî xweyî çendîn maneyan in. Lewma ger beralîkirin were danîn divê maneya ku jê tê beralîkirin jî were nivîsîn. -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 21:25, 3 îlon 2023 (UTC) == [[pêşnûma]] == [[pêşnima]] Divê bên standardkirin. Bi îxtîmalekî mezin ya standard "pêşnima" ye. -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 21:20, 12 sibat 2021 (UTC) '''Eynî mijar li jêr hatîye vekirin. Ji bo standardkirinê binêrin ya jêr.''' -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 21:15, 3 çiriya paşîn 2024 (UTC) '''Gotûbêj:''' <!--Li jêr fikrên xwe binivîsin. {{şîrove}} --> {{şîrove}} [[pêşnima]]--[[Bikarhêner:Mihemed Qers|Mihemed Qers]] ([[Gotûbêja bikarhêner:Mihemed Qers|gotûbêj]]) 18:13, 7 adar 2021 (UTC) == [[jenosîd]] == [[jînoside]] --[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 14:39, 13 sibat 2021 (UTC) {{rfk||}} -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 21:13, 3 çiriya paşîn 2024 (UTC) === Gotûbêj === <!--Li jêr fikrên xwe binivîsin. {{şîrove}} --> {{şîrove}} "jînoside" an "jînosid" ? Min nivîsandinên formên "jînosideyê" an "jînosideya" pirr nedîtiye...--[[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 14:48, 13 sibat 2021 (UTC) {{şîrove}} Bi min ya standard "[[jenosîd]]" e. Halên din ên "cenosîd", "jînosîd", "jînosid" kêm-li-kar in. -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 21:13, 3 çiriya paşîn 2024 (UTC) == [[kesaxtin]] == - [[kezaxtin]] Standardkirin hewce ye. Bi ya min ya rast "kesaxtin" e, yê din xelet e. -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 12:57, 14 sibat 2021 (UTC) {{rfk|kesaxtin|r=250}} -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 21:07, 3 çiriya paşîn 2024 (UTC) === Gotûbêj === <!--Li jêr fikrên xwe binivîsin. {{şîrove}} --> {{şîrove}} == [[derazîng]] == / [[derazînk]] Standardkirin lazim e. -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 22:54, 19 sibat 2021 (UTC) {{rfk|derazînk|r=127}} -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 19:53, 30 çiriya pêşîn 2024 (UTC) === Gotûbêj === <!--Li jêr fikrên xwe binivîsin. {{şîrove}} --> {{şîrove}} {{r|Bikarhêner}} bira navê sernavî neguherîne. Parametreya yekem ya şablona {{ş|ds}} divê sernavê vê gotûbêjê be.--[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 23:51, 19 sibat 2021 (UTC) == [[rovî]] == [[rûvî]]/[[rîvî]]. Bi ya min ji bo maneya "guhandarek" rovî zêdetir tê bikaranîn. Bi maneya "hinav" jî du rûpel ([[rûvî]]/[[rîvî]]) hene.--[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 21:19, 19 adar 2021 (UTC) {{rfk|rûvî|r=423}} Bi maneya "ince bağırsak". -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 18:40, 30 çiriya pêşîn 2024 (UTC) {{rfk|rovî|r=419}} Bi maneya "tilkî". -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 18:41, 30 çiriya pêşîn 2024 (UTC) === Gotûbêj === <!--Li jêr fikrên xwe binivîsin. {{şîrove}} --> {{şîrove}} == [[esman]] == [[esman]] | [[asman]] | [[ezman]] --[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 18:00, 24 adar 2021 (UTC) {{rfk|esman|r=152}} -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 18:38, 30 çiriya pêşîn 2024 (UTC) === Gotûbêj === <!--Li jêr fikrên xwe binivîsin. {{şîrove}} --> {{şîrove}} Ji ber ku ji didu peyvan pêk tê wek [[asê]]+[[man]]. Ezê peyva [[asman]] pêşniyar bikim. [[Bikarhêner:Key Mîrza|Key Mîrza]] ([[Gotûbêja bikarhêner:Key Mîrza|gotûbêj]]) 16:30, 10 gulan 2021 (UTC) == [[niha]] == [[niha]] / [[niho]]--[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 21:22, 25 adar 2021 (UTC) {{rfk|niha|r=333}} -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 18:35, 30 çiriya pêşîn 2024 (UTC) === Gotûbêj === <!--Li jêr fikrên xwe binivîsin. {{şîrove}} --> {{şîrove}} == [[sûper]] == Standardkirinê teleb dikim. -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 11:55, 26 adar 2021 (UTC) {{rfk||}} -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 21:27, 3 îlon 2023 (UTC) === Gotûbêj === <!--Li jêr fikrên xwe binivîsin. {{şîrove}} --> {{şîrove}} Li gorî telefûzê ya standard "super" e, kes halê dirêjkirî nabêje, bi qasî zanîna min. -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 17:48, 30 çiriya pêşîn 2024 (UTC) == [[sûperlatîv]] == Standardkirinê teleb dikim. -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 11:57, 26 adar 2021 (UTC) {{rfk||}} -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 21:28, 3 îlon 2023 (UTC) === Gotûbêj === <!--Li jêr fikrên xwe binivîsin. {{şîrove}} --> {{şîrove}} Bi ya min ya rast "super" û "superlatîv" e, ji ber ku gava em bi lêv dikin em wek "superlatîv" bi lêv dikin, ne wek "sûperlatîv". -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 11:57, 26 adar 2021 (UTC) == [[radîkalîzm]] == /[[radikalîzm]]--[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 16:21, 30 nîsan 2021 (UTC) {{rfk|}} -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 17:46, 30 çiriya pêşîn 2024 (UTC) === Gotûbêj === <!--Li jêr fikrên xwe binivîsin. {{şîrove}} --> {{şîrove}} {{r|Balyozxane}} Bi min peyveke wekî "radikalîzm" tine ye û bi xeletî wisa hatiye qeydkirin. -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 10:16, 17 tebax 2022 (UTC) == [[texdîr]] == [[teqdîr]] standardkirin hewce ye. Bi min "teqdîr" standardtir e. -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 10:52, 18 gulan 2021 (UTC) {{rfk|}} -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 17:45, 30 çiriya pêşîn 2024 (UTC) === Gotûbêj === <!--Li jêr fikrên xwe binivîsin. {{şîrove}} --> {{şîrove}} Pir eşkere ye ku ya standard "'''teqdîr'''" e. -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 17:45, 30 çiriya pêşîn 2024 (UTC) == [[tayîn]] == [[teyîn]] / [[tayîn]] / [[teîn]] / [[tayin]]. Standardkirin hewce ye. -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 09:30, 9 tîrmeh 2021 (UTC) {{rfk|}} -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 23:55, 29 çiriya pêşîn 2024 (UTC) === Gotûbêj === <!--Li jêr fikrên xwe binivîsin. {{şîrove}} --> {{şîrove}} Mirov di navbera "tayîn" û "tayin" de bêqerar dimîne. Lê bi min divê wek halê standard "'''tayîn'''" were dîyarkirin. Ji ber ku zêdetir li kar e (di lêgera Google Searche de jî zêdetir "tayîn" derdikeve, ''formata lêgerînê: wek "tayîna xwe" / "tayina xwe"''). -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 23:55, 29 çiriya pêşîn 2024 (UTC) == [[nod]] == * [[not]] Ev made li vir heye: [[Wîkîferheng:Daxwazên_standardkirinê#not,_nod]] Bi şaşî tekraren hatîye tevlîkirin. Ji bo agahîyan lê binêrin. -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 23:00, 29 çiriya pêşîn 2024 (UTC) '''Gotûbêj:''' <!--Li jêr fikrên xwe binivîsin. {{şîrove}} --> {{şîrove}} {{r|Zanavano}}. Bnr. [[WF:Rêzikên standardkirinê]]--[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 17:28, 1 çiriya pêşîn 2021 (UTC) = Daxwazên standardkirinê: 2022 = == [[xizar]] == [[xizar]], [[xîzar]]. Standardkirin hewce ye.{{bêîmze|Bikarhêner}} {{rfk|}} -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 23:46, 29 çiriya pêşîn 2024 (UTC) === Gotûbêj === <!--Li jêr fikrên xwe binivîsin. {{şîrove}} --> {{şîrove}} Forma xizar hema bêje li ti derê tine ye. Lewma halê standard divê "xîzar" be. -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 23:46, 29 çiriya pêşîn 2024 (UTC) == [[Nû Zelenda]] == [[Zelandaya Nû]] zêdetir tê bikaranîn.[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 23:18, 9 kanûna pêşîn 2022 (UTC) {{rfk|}} -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 23:39, 29 çiriya pêşîn 2024 (UTC) === Gotûbêj === <!--Li jêr fikrên xwe binivîsin. {{şîrove}} --> {{şîrove}} Di '''Rêbera Rastnivîsînê''' ya Komxebata Kurmancîyê de (r. 37) wek "Zelandaya Nû" hatîye qeydkirin. Di kitêba '''Rastnuştişê''' ya Gruba Xebatê ya Vateyî de jî ev peyv wek "Zelandaya Newîye" (r. 67) hatîye qeydkirin. Lewma bi min divê halê standard bibe "Zelandaya Nû." -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 23:39, 29 çiriya pêşîn 2024 (UTC) = Daxwazên standardkirinê: 2023 = == [[pirzik]] == [[pizik]] --[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 23:37, 15 kanûna paşîn 2023 (UTC) * {{rfk|pizrik}} --[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 23:37, 15 kanûna paşîn 2023 (UTC) === Gotûbêj === <!--Li jêr fikrên xwe binivîsin. {{şîrove}} --> {{şîrove}} Bi min forma wek "{{g|ku|pizrik}}" jî heye û divê ew jî were standardkirin. -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 19:53, 31 tebax 2023 (UTC) == [[bûro]] == {{g|ku|bûro}} / {{g|ku|buro}} / {{g|ku|buriyo}} standardkirin hewce ye. --- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 21:06, 22 kanûna paşîn 2023 (UTC) {{rfk|}} -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 19:58, 31 tebax 2023 (UTC) === Gotûbêj === <!--Li jêr fikrên xwe binivîsin. {{şîrove}} --> {{şîrove}} Di ''Rêbera Rastnivîsînê'' ya Komxebata Kurmancî de di rûpela 139em de nimûneyeke wek "'''buroya wî'''" hatiye dayîn. Ji vê nimûneyê mirov dikare bêje ku ji bo vê peyvê awayê standard wekî "buro" dibînin. -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 14:53, 3 îlon 2023 (UTC) == [[fezîlet]] == [[fazîlet]]--[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 11:47, 26 kanûna paşîn 2023 (UTC) === Gotûbêj === <!--Li jêr fikrên xwe binivîsin. {{şîrove}} --> {{şîrove}} Ev peyv jî ji erebî tê. Herçiqas di hin peyvên reh-erebî de (wek nimûne "edalet") ji bo eyna erebî "e" hatibe tercîhkirin jî bi min ji bo em li vir nêzî telafûza di pratîkê de bibin, forma bi "e"yê neyê tercîhkirin jî dibe. Lewma ez "fazîlet"ê pêşnîyar dikim. -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 22:57, 29 çiriya pêşîn 2024 (UTC) == [[Uman]] == {{g|ku|Uman}}, {{g|ku|Oman}}, {{g|ku|Iman}}, {{g|ku|'Iman}}, {{g|ku|'Uman}}, {{g|ku|Umman}} Standardkirin hewce ye. {{rfk|}} === Gotûbêj === <!--Li jêr fikrên xwe binivîsin. {{şîrove}} --> {{şîrove}} Di '''''Rêbera Rastnivîsînê''''' ya Komxebata Kurmancîyê de awayê "'''Uman'''" wekî standard hatiye nîşandan. -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 01:34, 3 nîsan 2023 (UTC) == [[hejî]] == {{g|ku|hejî}}, {{g|ku|hêja}} Standardkirin hewce ye. {{rfk|}} === Gotûbêj === <!--Li jêr fikrên xwe binivîsin. {{şîrove}} --> {{şîrove}} {{r|Ferhengvan}} Bi min ev herdu, wekî formên eynî peyvê dixuyin. Lewma standardkirinê teleb dikim. Her çiqas berçav be ku awayê stadard "hêja" ye jî, li vir teleb dikim. Lê ger ne formên eynî peyvê bin, xêra xwe li vir binivîsin. -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 01:52, 7 nîsan 2023 (UTC) ::{{Silav|Bikarhêner}} Rast dibêjî, "hejî" formeke devokî (behdînî) ya peyva "hêja" ye. --[[Bikarhêner:Ferhengvan|Ferhengvan]] ([[Gotûbêja bikarhêner:Ferhengvan|gotûbêj]]) 20:31, 7 nîsan 2023 (UTC) == [[sererast]] == {{q|ku|sererast}}, {{q|ku|serrast}} Standardkirin hewce ye. Bi min xuya ye ku forma standard "sererast" e. -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 10:02, 25 nîsan 2023 (UTC) {{rfk|serrast, serrast kirin|r=437}} -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 19:41, 31 tebax 2023 (UTC) === Gotûbêj === <!--Li jêr fikrên xwe binivîsin. {{şîrove}} --> {{şîrove}} Bila piştî gihîştina netîceyê, standardkirina formên din ên wekî "sererastkirin" / "serrastkirin", "sererast kirin" / "serrast kirin" jî neyê jibîrkirin. Bi min divê forma standard bibe "sererast". -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 19:41, 31 tebax 2023 (UTC) == [[fiqih]] == {{g|ku|fiqh}} / {{g|ku|fiqih}} Standardkirin hewce ye. -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 21:16, 30 nîsan 2023 (UTC) {{rfk|}} -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 21:16, 30 nîsan 2023 (UTC) === Gotûbêj === <!--Li jêr fikrên xwe binivîsin. {{şîrove}} --> {{şîrove}} Di ''Rêbera Rastnivîsînê'' ya Komxebata Kurmanciyê de (r.52, 53) behsa vê mijarê kirine: Bi sernavê "'''Nivîsîna hin bêjeyên bîyanî yên yekkîteyî ku di kurmancîyê da dibin dukîteyî'''", wek nimûne jî "'''aqil ✓''', '''aql ✗'''", "fikir ✓, fikr ✗", "qebir ✓, qebr ✗", "qebiz ✓, qebz ✗", "qedir ✓, qedr ✗", "qehir ✓, qehr ✗"... Li binî jÎ dibêjin divê li gel îzafeyê [i] bê parastin, wekî "aqilê min ✓, aqlê min ✗", "fikira min ✓, fikra min ✗", "qebira min ✓, qebra min ✗"... Lewma bi dîtina min, li gor vê rêberê divê wekî "fiqih" bibe ya standard. -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 19:38, 31 tebax 2023 (UTC) == [[îqaz]] == {{g|ku|îqaz}} - {{g|ku|îkaz}}. Standardkirin hewce ye. Piştî qerardana li ser forma standard, divê peyvên girêdayî wan jî yên wek "îqazker", "îqaz kirin" hwd jî bên guherandin. -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 23:14, 19 gulan 2023 (UTC) {{rfk|}} -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 23:14, 19 gulan 2023 (UTC) === Gotûbêj === <!--Li jêr fikrên xwe binivîsin. {{şîrove}} --> {{şîrove}} Di ''Rêbera Rastnivîsînê'' ya Komxebata Kurmanciyê de (r. 80) dibêjin "'''[q]ya bêjeyên biyanî neke [k]'''". "k"ya vê peyvê jî bi eslê xwe "[q]" ye, û lewma divê awayê standard bibe "îqaz". -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 19:22, 31 tebax 2023 (UTC) == [[hundirîn]] == {{g|ku|hindirîn}}, {{g|ku|hundirîn}} standardkirin hewce ye. -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 17:41, 27 gulan 2023 (UTC) {{rfk|hundir|r=217}} Ji ber ku awayê "hundir" wek standard hatiye bijartin, li gor vê "hundirîn" jî dibe awayê standard. -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 21:40, 29 tebax 2023 (UTC) === Gotûbêj === <!--Li jêr fikrên xwe binivîsin. {{şîrove}} --> {{şîrove}} == [[wasita]] == {{g|ku|wasita}}, {{g|ku|wesite}}, {{g|ku|wasîte}}, {{g|ku|wasta}}, {{g|ku|wesita}}, {{g|en|wesita}}, {{g|en|wesîte}}, {{g|en|wasite}} standardkirin hewce ye. -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 09:06, 21 hezîran 2023 (UTC) {{rfk|wasîte|r=504}} === Gotûbêj === <!--Li jêr fikrên xwe binivîsin. {{şîrove}} --> {{şîrove}} == [[qebe]] == {{g|ku|qebe}} / {{g|ku|qeba}} Standardkirin hewce ye. -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 20:10, 27 tebax 2023 (UTC) {{rfk|}} --[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 21:35, 29 tebax 2023 (UTC) === Gotûbêj === <!--Li jêr fikrên xwe binivîsin. {{şîrove}} --> {{şîrove}} Bi min forma "qeba" baştir e ji bo halê standard. Helbet gava dîyarkirina halê standand divê em halên emilandinê û peyvên jêçêbûyî jî bifikirin. Ji bo vê peyvê wek "qebetî" / "qebatî". -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 22:26, 29 çiriya pêşîn 2024 (UTC) == [[sewgûr]] == {{g|ku|sewgur}} / {{g|en|sewgûr}} / {{g|en|sewgir}} / {{g|en|sewgor}} Standardkirin hewce ye. -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 21:33, 29 tebax 2023 (UTC) {{rfk|sewgurî, sewgura sibê|r=439}} Di ferhengê de wek "sewgurî" û wek "sewgura sibê" hatiye qeydkirin. -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 21:33, 29 tebax 2023 (UTC) === Gotûbêj === <!--Li jêr fikrên xwe binivîsin. {{şîrove}} --> {{şîrove}} == [[Danmarka]] == [[Danîmarka]] zêdetir tê bikaranîn--[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 19:54, 3 îlon 2023 (UTC) {{rfk|}} Di vê ferhengê de peyvên "danîmarkî" û "danîmarqî" ber bi rûpela "danmarkî" ve yê hatine alîkirin. Lewma mirov fam dike ku navê vî welatî li gorî vê ferhengê "'''Danmarka'''" ye. -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 20:12, 3 îlon 2023 (UTC) :@[[Bikarhêner:Bikarhêner|Bikarhêner]] Bi min ew mantiqeke şaş e. Loma em li ferhengên din jî binêrin baştir be. Ez fêm nakim çawa ferhengeke rastnivîsînê navên welatan qeyd nekirine. [[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 20:27, 3 îlon 2023 (UTC) === Gotûbêj === <!--Li jêr fikrên xwe binivîsin. {{şîrove}} --> {{şîrove}} Bi ya ''Rêbera Rastnivîsînê'' ya Komxebata Kurmancî jî awayê standard "'''Danîmarka'''" ye (r. 31). Ez bixwe jî ji bo awayê standard "Danîmarka"yê pêşniyar dikim. -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 20:55, 3 îlon 2023 (UTC) == [[dijmîn]] == {{g|ku|dijmîn}}, {{g|ku|dijûn}} Standardkirin lazim e. -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 16:57, 12 îlon 2023 (UTC) {{rfk|dijûn|r=135}} -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 22:04, 18 hezîran 2024 (UTC) === Gotûbêj === <!--Li jêr fikrên xwe binivîsin. {{şîrove}} --> {{şîrove}} == [[fîlmografî]] == [[filmografî]] :--[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 12:38, 20 îlon 2023 (UTC) {{rfk|fîlm|r=166}} Şiklê standard ji bo peyva "film / fîlm / fîlim" wek "fîlm" hatîye nîşandan. Lewma li gor vê awayê standard dibe "'''fîlmografî'''". -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 22:07, 18 hezîran 2024 (UTC) === Gotûbêj === <!--Li jêr fikrên xwe binivîsin. {{şîrove}} --> {{şîrove}} == [[not]], [[nod]] == [[not]], [[nod]]--[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 20:23, 11 çiriya pêşîn 2023 (UTC) {{rfk|nod|r=338}} -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 22:09, 18 hezîran 2024 (UTC) === Gotûbêj === <!--Li jêr fikrên xwe binivîsin. {{şîrove}} --> {{şîrove}} == [[afrîkî]] == [[afrîkî]] / [[afrîkayî]] ?--[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 18:06, 9 çiriya paşîn 2023 (UTC) {{rfk|afrîkayî|r=41}} -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 22:11, 18 hezîran 2024 (UTC) === Gotûbêj === <!--Li jêr fikrên xwe binivîsin. {{şîrove}} --> {{şîrove}} == [[eware]] == [[eware]]/[[aware]] :Bi maneya ''avare/aylak/serseri'' {{rfk|153}} :Ji bo maneya ''penaber'' di vê ferhengê de standardek tine ye. Loma divê du rûpel hebe ji bo kelîmeya kurmancî ya eware û yekî din ji bo maneya penaber. --[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 12:14, 8 sibat 2024 (UTC) === Gotûbêj === <!--Li jêr fikrên xwe binivîsin. {{şîrove}} --> {{şîrove}} Di ferhenga ''Ji bo Rastnivîsînê Ferhenga Kurdî (Kurmancî)-Tirkî ya Nû'' de jixwe standarda ji bo vê peyvê heye. Ji bo maneya penaber jî hebûna vê maneyê bi min bişibhe ye, wekî din ''ger hebe jî'' ji ber ku ji berhirefkirina maneya "''yê derbeder û bê cih û mal''" hatîye çêkirin, dîsa girêdayî wê maneya eslî ya derbiderîyê ye, lewma divê li ser rûpelekî werin standardkirin û ew rûpel jî pêşnîyara di kitêba nav-zikirkirî de be baştir e. -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 22:22, 18 hezîran 2024 (UTC) == [[wesetî]] == [[wasatî]] / [[wesetî]] standardkirin hewce ye. -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 10:48, 29 adar 2024 (UTC) {{rfk|wesetî|r=506}} -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 22:27, 18 hezîran 2024 (UTC) === Gotûbêj === <!--Li jêr fikrên xwe binivîsin. {{şîrove}} --> {{şîrove}} == [[se direwît, karwan bi rêka xwe diçît]] == {{g|ku|se direwît, karwan bi rêka xwe diçît}} / {{g|ku|se direwin, karwan diborin}} / {{g|ku|seh direye kerwan dibihore}} Divê ev her sê form werin standardkirin. -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 14:51, 16 hezîran 2024 (UTC) {{rfk|}} -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 08:26, 7 tîrmeh 2024 (UTC) === Gotûbêj === <!--Li jêr fikrên xwe binivîsin. {{şîrove}} --> {{şîrove}} Bi min ya standardtir "'''seg direye karwan dibihure'''" ye ("seg", ''Ji Bo Rastnivîsînê Ferhenga Kurdî (Kurmancî) - Tirkî ya Nû'', r. 429; "reyîn", r. 410; "karwan", r. 240; "bihurîn", r. 83). Wekî form (di qismê "Herwiha" de) em "'''bi ewtîna seyan, ji rê namîne karwan'''" jî nîşan bidin. Lê ji alîyê xwedîçavkanîbûnê ve jî divê werin kontrolkirin. Min ji bo "''bi ewtîna seyan, ji rê namîne karwan''" çavkanî peyda nekir, min ji bo "''seg direye karwan dibihure''" jî tenê çavkanîyekê peyda kir ([https://www.tirejafrin.com/pdf/Pend%20.pdf ''Pend û Peng''], Bîlal Hesen, di kitêbê de wek "seh direye kerwan dibihore" derbas dibe). -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 08:26, 7 tîrmeh 2024 (UTC) == [[serobino bûn]] == {{g|ku|serobino bûn}} / {{g|ku|serûbin bûn}} Standardkirin hewce ye. -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 16:21, 14 tebax 2024 (UTC) {{rfk|serûbin|r=438}} "serûbin bûn, serûbin kirin, serûbinbûn, serûbinkirin, serûbinkirî" wek peyvên jêçêbûyî hatine nîşandayîn. -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 12:19, 29 çiriya pêşîn 2024 (UTC) === Gotûbêj === <!--Li jêr fikrên xwe binivîsin. {{şîrove}} --> {{şîrove}} == [[sanî]] == [[sanî]] / [[saniye]] {{rfk|}} -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 13:45, 29 çiriya pêşîn 2024 (UTC) === Gotûbêj === <!--Li jêr fikrên xwe binivîsin. {{şîrove}} --> {{şîrove}} Ez dibêjim ber saniye be. [[Bikarhêner:Guherto|Guherto]] ([[Gotûbêja bikarhêner:Guherto|gotûbêj]]) 15:22, 1 îlon 2024 (UTC) {{şîrove}} Ez dibêjim bila "sanîye" be. Em wek sanîye telafûz dikin. -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 13:45, 29 çiriya pêşîn 2024 (UTC) :@[[Bikarhêner:Bikarhêner|Bikarhêner]] "Sanîye" çênabe. Li vir em "îy" nanivîsînin. [[Bikarhêner:Guherto|Guherto]] ([[Gotûbêja bikarhêner:Guherto|gotûbêj]]) 13:34, 10 çiriya paşîn 2024 (UTC) == [[pêşnûma]] == [[pêşnûma]] / [[pêşnima]] Standardkirin lazim e. -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 18:00, 29 çiriya pêşîn 2024 (UTC) {{rfk|}} -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 18:00, 29 çiriya pêşîn 2024 (UTC) === Gotûbêj === <!--Li jêr fikrên xwe binivîsin. {{şîrove}} --> {{şîrove}} Bi min divê "pêşnima" be. Formên bi "u"yê zahfê caran nayên emilandin. -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 18:00, 29 çiriya pêşîn 2024 (UTC) == [[payîz]] == [[payîz]] / [[payiz]] Standardkirin hewce ye. -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 22:12, 29 çiriya pêşîn 2024 (UTC) {{rfk|payîz|347}} -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 22:12, 29 çiriya pêşîn 2024 (UTC) === Gotûbêj === <!--Li jêr fikrên xwe binivîsin. {{şîrove}} --> {{şîrove}} == [[behîv]] == {{g|ku|behîv}} / {{g|ku|bahîv}} Standardkirin hewce ye. -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 11:41, 26 kanûna paşîn 2025 (UTC) {{rfk|behîv|63}} -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 14:38, 26 kanûna paşîn 2025 (UTC) === Gotûbêj === <!--Li jêr fikrên xwe binivîsin. {{şîrove}} --> {{şîrove}} == [[mitîng]] == [[mitîng]] / [[mîtîng]] Standardkirin hewce ye. -- --[[Bikarhêner:Şêr|Şêr]] ([[Gotûbêja bikarhêner:Şêr|gotûbêj]]) 21:47, 27 kanûna paşîn 2025 (UTC) {{rfk|mîtîng|r=316}} -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 22:43, 1 hezîran 2025 (UTC) === Gotûbêj === <!--Li jêr fikrên xwe binivîsin. {{şîrove}} --> {{şîrove}} == [[rûtîn]] == [[rûtîn]], [[rutîn]] Standardkirin hewce ye. — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 23:47, 18 sibat 2025 (UTC) {{rfk||}} -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 22:42, 1 hezîran 2025 (UTC) === Gotûbêj === <!--Li jêr fikrên xwe binivîsin. {{şirove}} --> {{şirove}} Bi min eşkere ye ku ya standard "'''rutîn'''" e. Peyvên telafûza wan dirêj be, bi "û"yê tên gotin, lê li vir dirêj nayê gotin. Lewma bi "u"ya bêkumik çêtir e. -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 22:42, 1 hezîran 2025 (UTC) == [[parleman]] == [[parleman]] / [[perleman]] / [[parlament]]/[[parlemento]] / [[perlemen]], Standardkirin hewce ye.--[[Bikarhêner:Şêr|Şêr]] ([[Gotûbêja bikarhêner:Şêr|gotûbêj]]) 00:53, 22 sibat 2025 (UTC) {{rfk|parlamento|r=345}} -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 22:39, 1 hezîran 2025 (UTC) === Gotûbêj === {{şîrove}} Di ferhenga "Ji bo Rastnivîsînê Ferhenga Kurdî (Kurmancî)-Tirkî ya Nû" da bi maneya ''meclis''ê wek "parlamento" hatîye qeydkirin, bi maneya ''azayê meclisê'' wek "parlamenter" hatîye qeydkirin. -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 22:39, 1 hezîran 2025 (UTC) == [[sond]] == [[sond]], [[sûnd]]—[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 20:41, 21 adar 2025 (UTC) {{rfk|sond|r=447}} -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 22:35, 1 hezîran 2025 (UTC) === Gotûbêj === <!--Li jêr fikrên xwe binivîsin. {{şirove}} --> {{şirove}} == [[sifet]] / [[sîfet]] == {{rfk|}}--[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 13:41, 1 gulan 2025 (UTC) === Gotûbêj === <!--Li jêr fikrên xwe binivîsin. {{şîrove}} --> {{şîrove}} Bi dîtina min wek "sifet" zêdetir li kar e. (Ger rast transkrîbe kiribin) Di eserên berê yên kurdî de wek "sîfet" hatine gotin. -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 06:29, 31 gulan 2025 (UTC) == [[mane]] == [[mane]], [[mana]]—[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 10:13, 30 gulan 2025 (UTC) {{rfk|mane|r=297}} -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 06:20, 31 gulan 2025 (UTC) === Gotûbêj === {{şirove}} {{r|Bikarhêner}} [https://ferheng.wmezopotamyaye.org/ weqfa mezopotamyaye] dibêje forma standard "mana" ye. Dikarî ji ferhenga rastnivîsînê binêrî? --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 10:18, 30 gulan 2025 (UTC) : {{r|Wikihez}} Di Ferhenga Rastnivîsînê de wek "mane" (jê "mane dan", "manedan", "manedar", "manedarî") hatîye qeydkirin. -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 06:20, 31 gulan 2025 (UTC) == [[memnû]] == {{g|ku|memnû}} {{g|ku|memnûh}} Standardkirin lazim e. -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 22:34, 1 hezîran 2025 (UTC) {{rfk||}} -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 22:34, 1 hezîran 2025 (UTC) === Gotûbêj=== <!--Li jêr fikrên xwe binivîsin. {{şîrove}} --> {{şîrove}} Eşkere ye ku ya standard "'''memnû'''" ye. Forma "memnûh" ne li kar e. -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 22:34, 1 hezîran 2025 (UTC) == [[niha]] == === Gotûbêj === <!--Li jêr fikrên xwe binivîsin. {{şîrove}} --> {{şîrove}} {{rfk|niha|r=333}} [[Bikarhêner:Rewiye tine|Rewiye tine]] ([[Gotûbêja bikarhêner:Rewiye tine|gotûbêj]]) 11:22, 16 sibat 2026 (UTC) == [[gîya]] == === Gotûbêj === <!--Li jêr fikrên xwe binivîsin. {{şîrove}} --> {{şîrove}} {{rfk|gîya|r=180}} [[Bikarhêner:Rewiye tine|Rewiye tine]] ([[Gotûbêja bikarhêner:Rewiye tine|gotûbêj]]) 11:24, 16 sibat 2026 (UTC) Kelîmeya jêçêbûyî: {{g|ku|gîyagezk}} (mê, mane "''ısırgan otu''") -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 19:11, 5 tîrmeh 2026 (UTC) :@[[Bikarhêner:Bikarhêner|Bikarhêner]], @[[Bikarhêner:Rewiye tine|Rewiye tine]] Bi ya min, ev ne meseleya standardkirinê ye lê ya îmlayê ye çûnkî ev problema îy - iy zêde tevlihev e. Dengdanek hewce ye ku bibêje konsensusek heye li ser bikaranîna -îy û ne -iy. Lê dengdanek wisa dê têk biçe ji ber ku hejmara kesên -îy tercih dikin kêmtir e li ser Wikiferhengê. Loma divê ev gotûbêj wek çênebû were tayînkirin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 21:04, 5 tîrmeh 2026 (UTC) ::Bi qenaeta min jî "'''îy'''" rasttir e. Divê em di demên pêş da wî meseleyê hel bikin. Feqet wekî ku te jî got, ji ber ku vê gavê li ser vê qerar nehatîye dayîn, em karin wek xwe bihêlin. -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 07:45, 6 tîrmeh 2026 (UTC) == [[hincet]] == === Gotûbêj === <!--Li jêr fikrên xwe binivîsin. {{şîrove}} --> {{şîrove}} {{rfk|hincet|r=210}} [[Bikarhêner:Rewiye tine|Rewiye tine]] ([[Gotûbêja bikarhêner:Rewiye tine|gotûbêj]]) 11:18, 16 sibat 2026 (UTC) == [[kurmî]] == === Gotûbêj === <!--Li jêr fikrên xwe binivîsin. {{şîrove}} --> {{şîrove}} {{rfk|kurm (navdêr), kurmî (rengdêr)|r=269}} [[Bikarhêner:Rewiye tine|Rewiye tine]] ([[Gotûbêja bikarhêner:Rewiye tine|gotûbêj]]) 08:55, 23 adar 2026 (UTC) :kurmî berbelav e hem jî standardîze bûye bi min. Hem em dibêjin kurm bi gelemperî kirm kêm e. [[Bikarhêner:Bibliophile|Bibliophile]] ([[Gotûbêja bikarhêner:Bibliophile|gotûbêj]]) 10:55, 23 adar 2026 (UTC) ::Lê balkêş e ku rehê xwe yê qedîm zêdetir wekî [[kirm]] xuya dike. Lê etîmolojî nikare bikeve pêşberî bikaranîna giştî peyvekê ji aliyê xelkê ve. Helbet ev fikra min a şexsî ye. Ji bo selameta ferhengê kurdî ev yek gerek e bête çareserkirin. [[Bikarhêner:Bibliophile|Bibliophile]] ([[Gotûbêja bikarhêner:Bibliophile|gotûbêj]]) 11:01, 23 adar 2026 (UTC) == [[tihn]] == [[tihn]], [[tîn]], [[tên]] {{rfk|tîn (mê, mane: ''ısı; hararet, sıcaklık'')|r=488}} -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 19:18, 5 tîrmeh 2026 (UTC) === Gotûbêj === <!--Li jêr fikrên xwe binivîsin. {{şîrove}} --> {{şîrove}} Ez bawer dikim ku ''tîn'' zêdetir tê bikaranîn. == [[nehwirandin]] == [[nehwirandin]], [[norandin]] bnr [[Gotûbêj:norandin]] —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 11:52, 3 tîrmeh 2026 (UTC) {{rfk|nehwirandin|r=328}} -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 19:05, 5 tîrmeh 2026 (UTC) === Gotûbêj === == [[rus]], [[rûsî]] == [[rus]], [[rûs]], [[rûsî]], [[rusî]] bnr. [[Gotûbêja kategoriyê:Rusî]] —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 07:11, 5 tîrmeh 2026 (UTC) {{rfk|rûs, rûsî|r=422}} "rûs" wek navê miletê, "rûsî" wek navê zimanê hatîye qeydkirin. -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 18:57, 5 tîrmeh 2026 (UTC) === Gotûbêj === == [[dûkel]] == {{g|ku|dûkel}} / {{g|ku|dûkêl}} Standardkirin hewce ye. -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 23:14, 19 tîrmeh 2026 (UTC) '''Gotûbêj:''' <!--Li jêr fikrên xwe binivîsin. {{şîrove}} --> {{şîrove}} rlfya063zmv2lxndz9h2l3uvmolgs2y 6265702 6265701 2026-07-19T23:16:39Z Bikarhêner 3719 /* dûkel */ 6265702 wikitext text/x-wiki {{/destpêk}} = Daxwazên standardkirinê: 2020 = == [[mizhar]] == mizhar / miz'ar / mizar --[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 19:31, 10 tebax 2020 (UTC) ===Gotûbêj=== {{şîrove}} Min gelek ferhangan nêrî lê min kelîmeyek wisa nedît. Divê ev kelîme were peyitandin. Wexta em kelîmeyek bo standartkirinê hilbijêrin divê hinek ser bisekinin. Ka kelîme hêjaye an na. Kelîmeyê zêde tên bikaranîn divê were hilbijêrîn.--[[Bikarhêner:Rewiye tine|Rewiye tine]] ([[Gotûbêja bikarhêner:Rewiye tine|gotûbêj]]) 20:54, 3 çiriya paşîn 2020 (UTC) <!-- === Dengdan === {{dengdan/nû|destpêk=?|dawî=?}} piştî dengdan dest pê kir vê şablonê {{dengdan|destpêk=|dawî=}}, û kengî xilas bû vê şablonê {{dengdan/borî|destpêk=|dawî=}} bi kar bînin. --> == [[kîte]] / [[kite]] == [[kîte]] / [[kite]] Divê werin standardkirin. -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 20:11, 13 tebax 2020 (UTC) {{rfk||}} Di vê ferhengê de "kîte / kite" nîne, lê wek lêker cih dane "kîte kirin"ê. Jê tê famkirin ku halê standard wek "'''kîte'''" dibînin. -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 20:31, 28 nîsan 2025 (UTC) === Gotûbêj === <!--Li jêr fikrên xwe binivîsin. {{şîrove}} --> {{şîrove}} Ji bo '''''[[kit]]''''' ez dibêjim '''''[[kit]]'''''; nabêjim '''''[[kît]]'''''. Ma '''''[[kîte]]''''' ('''''[[kît]]''''') li kû derê li kar e? -- [[Bikarhêner:Hakîmo|Hakîmo]] ([[Gotûbêja bikarhêner:Hakîmo|gotûbêj]]) 15:13, 5 îlon 2020 (UTC) <!-- === Dengdan === {{dengdan/nû|destpêk=?|dawî=?}} piştî dengdan dest pê kir vê şablonê {{dengdan|destpêk=|dawî=}}, û kengî xilas bû vê şablonê {{dengdan/borî|destpêk=|dawî=}} bi kar bînin. --> == [[hêvişandin]] == [[hêvişandin]] / [[êvişandin]] / [[hewişandin]]--[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 21:50, 15 tebax 2020 (UTC) '''Gotûbêj:''' <!--Li jêr fikrên xwe binivîsin. {{şîrove}} --> {{şîrove}} <!-- === Dengdan === {{dengdan/nû|destpêk=?|dawî=?}} piştî dengdan dest pê kir vê şablonê {{dengdan|destpêk=|dawî=}}, û kengî xilas bû vê şablonê {{dengdan/borî|destpêk=|dawî=}} bi kar bînin. --> == [[hindirandin]] == --[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 09:09, 16 tebax 2020 (UTC) '''Gotûbêj:''' <!--Li jêr fikrên xwe binivîsin. {{şîrove}} --> {{şîrove}} *Bi ya min divê forma ''hundirandin'' bibe standard. Li herêma Behdînan gelek caran '''u''' dibe '''i''', '''û''' jî dibe '''î'''. Loma [[hindir]] weke rûpela sereke hatiye çêkirin.—<small>[[Bikarhêner:Gomada|<span style="background:Yellow">'''''<span style="font-family:Verdana;color:red">Gom<span style="color:#006400">ada</span></span></span>''''']]<sup>[[Gotûbêja bikarhêner:Gomada|peyam]]</sup></small> 15:40, 21 kanûna paşîn 2021 (UTC) ** {{silav|Gomada}}. Bnr. [[WF:Rêzikên standardkirinê]]--[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 15:42, 21 kanûna paşîn 2021 (UTC) == [[zingar]] == Eynî rûpel li [[zeng]] û [[jeng]] heye. Ez awayê rast wek [[zingar]] dibînim. -- [[Bikarhêner:Guherto|Guherto]] ([[Gotûbêja bikarhêner:Guherto|gotûbêj]]) 12:34, 18 tebax 2020 (UTC) '''Gotûbêj:''' <!--Li jêr fikrên xwe binivîsin. {{şîrove}} --> {{şîrove}} <!-- === Dengdan === {{dengdan/nû|destpêk=?|dawî=?}} piştî dengdan dest pê kir vê şablonê {{dengdan|destpêk=|dawî=}}, û kengî xilas bû vê şablonê {{dengdan/borî|destpêk=|dawî=}} bi kar bînin. --> == [[axaftin]] == [[axaftin]] / [[axivtin]] / [[axiftin]] / [[axivîn]]--[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 12:23, 19 tebax 2020 (UTC) '''Gotûbêj:''' <!--Li jêr fikrên xwe binivîsin. {{şîrove}} --> {{şîrove}} Axiftin û axivîn ne eynî tişt in. -- [[Bikarhêner:Guherto|Guherto]] ([[Gotûbêja bikarhêner:Guherto|gotûbêj]]) 09:05, 22 tebax 2020 (UTC) <!-- === Dengdan === {{dengdan/nû|destpêk=?|dawî=?}} piştî dengdan dest pê kir vê şablonê {{dengdan|destpêk=|dawî=}}, û kengî xilas bû vê şablonê {{dengdan/borî|destpêk=|dawî=}} bi kar bînin. --> == [[jêbirk]] == [[jêbir]]--[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 15:41, 19 tebax 2020 (UTC) '''Gotûbêj:''' <!--Li jêr fikrên xwe binivîsin. {{şîrove}} --> {{şîrove}} Xuya dike paşgira -k (bi vê maneyê) gelekî nayê bikaranîn. Agirkuj bi dêla agirkuj-k tê bikaranîn, min tenê "jêbir" bihîstîye, "xwêdan-k" bêçavkanî ye, "demjimêr-k" kêm peyda dibê (bêhtir di spam de heye) ... -- [[Bikarhêner:Guherto|Guherto]] ([[Gotûbêja bikarhêner:Guherto|gotûbêj]]) 09:39, 22 tebax 2020 (UTC) <!-- === Dengdan === {{dengdan/nû|destpêk=?|dawî=?}} piştî dengdan dest pê kir vê şablonê {{dengdan|destpêk=|dawî=}}, û kengî xilas bû vê şablonê {{dengdan/borî|destpêk=|dawî=}} bi kar bînin. --> == [[bager]] == [[bager]] / [[bagêr]]--[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 21:16, 19 tebax 2020 (UTC) '''Gotûbêj:''' <!--Li jêr fikrên xwe binivîsin. {{şîrove}} --> {{şîrove}} <!-- === Dengdan === {{dengdan/nû|destpêk=?|dawî=?}} piştî dengdan dest pê kir vê şablonê {{dengdan|destpêk=|dawî=}}, û kengî xilas bû vê şablonê {{dengdan/borî|destpêk=|dawî=}} bi kar bînin. --> == [[çikilandin]] == --[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 10:52, 20 tebax 2020 (UTC) '''Gotûbêj:''' <!--Li jêr fikrên xwe binivîsin. {{şîrove}} --> {{şîrove}} <!-- === Dengdan === {{dengdan/nû|destpêk=?|dawî=?}} piştî dengdan dest pê kir vê şablonê {{dengdan|destpêk=|dawî=}}, û kengî xilas bû vê şablonê {{dengdan/borî|destpêk=|dawî=}} bi kar bînin. --> == [[evraz]] == [[evraz]] / [[hevraz]] / [[evrazî]] / [[hevrazî]]--[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 15:03, 20 tebax 2020 (UTC) :ervaz [[Taybet:Beşdarî/&#126;2026-16469-22|&#126;2026-16469-22]] ([[Gotûbêja bikarhêner:&#126;2026-16469-22|talk]]) 19:30, 15 adar 2026 (UTC) '''Gotûbêj:''' <!--Li jêr fikrên xwe binivîsin. {{şîrove}} --> {{şîrove}} <!-- === Dengdan === {{dengdan/nû|destpêk=?|dawî=?}} piştî dengdan dest pê kir vê şablonê {{dengdan|destpêk=|dawî=}}, û kengî xilas bû vê şablonê {{dengdan/borî|destpêk=|dawî=}} bi kar bînin. --> == [[xwişk]] == [[xwişk]] / [[xweng]] / [[xwek]] / [[xuşk]]--[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 15:33, 21 tebax 2020 (UTC) {{rfk|xwişk, xweng, xweh|r=524 (xweng, xweh), 526 (xwişk)}} Di ferhengê de "xwişk (r. 526), xweng (r. 524), xweh (r.524)" tev jî bi maneya "''kız kardeş''" hatine qeydkirin. "xwek" û "xuşk" jî tê de nîne. -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 10:04, 2 hezîran 2025 (UTC) === Gotûbêj === <!--Li jêr fikrên xwe binivîsin. {{şîrove}} --> {{şîrove}} ''[[xuşk]]'' u ''[[xweh]]'' ji ber ku di devoka min da herdu jî têne bikaranîn, wek ''[[xuçik]]'' u ''[[xweng]]''. ''[[xwek]]'' devokî ye u bipiranî li rojavayê tê bikaranîn. -- [[Bikarhêner:Hakîmo|Hakîmo]] ([[Gotûbêja bikarhêner:Hakîmo|gotûbêj]]) 15:49, 21 tebax 2020 (UTC) : {{silav|Hakîmo}} Kengî dengdana li ser [[Wîkîferheng:Rêzikên standardkirinê|Rêzikên standardkirinê]] xilas bû, em ê dest bi standardkirinê bikin. Tu jî dikarî fikrên xwe li vir bibêjî '''[[Wîkîferheng:Dengdan/Rêzik/Rêzikên standardkirinê]]'''. ::Di devoka min de xwîşk, xuh û xwak hene. Di wextên cuda de tên bikaranîn. -- [[Bikarhêner:Guherto|Guherto]] ([[Gotûbêja bikarhêner:Guherto|gotûbêj]]) 16:06, 21 tebax 2020 (UTC) Ez awayê rast ya xwîşk/xwişk weke "xwîşk" dibînim, û di înternetê de bêhtir encam hene (hejmara rûpelan binêrin, hejmara encaman şaş e.) -- [[Bikarhêner:Guherto|Guherto]] ([[Gotûbêja bikarhêner:Guherto|gotûbêj]]) 15:27, 25 tebax 2020 (UTC) <!-- === Dengdan === {{dengdan/nû|destpêk=?|dawî=?}} piştî dengdan dest pê kir vê şablonê {{dengdan|destpêk=|dawî=}}, û kengî xilas bû vê şablonê {{dengdan/borî|destpêk=|dawî=}} bi kar bînin. {{erê}}: [[xuşk]] u [[xweh]] (belkî [[xuçik]] jî, lê niha [[xuşk]] ancax têr dikê)--> == [[xwendevan]] == [[xwendevan]] / [[xwandevan]] / [[xwêndkarî]] / [[xwîndkarî]] --[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 22:50, 21 tebax 2020 (UTC) {{rfk|xwendevan, xwendekar|r=524}} Di ferhengê de bi maneyên cuda her du peyv jî derbas dibin. "xwendekar" bi maneya "öğrenci, talebe"; "xwendevan" bi maneya "okuyucu, okur" hatîye qeydkirin. Lewma divê her du jî hebin. "''xwêndkarî''" û "''xwîndkarî''" jî formên "xwendekarî"yê ne, lewma divê wek "xwendekarî" werin standardkirin. -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 09:52, 2 hezîran 2025 (UTC) === Gotûbêj === <!--Li jêr fikrên xwe binivîsin. {{şîrove}} --> {{şîrove}} Xwendevan û xwendekar bi eynî maneyî ne lê ne eynî peyv in, nikarin weke yek werin standardkirin. Ji ber ku xwendin/xwandin weke xwendin hatîye standardkirin divê xwendevan jî wilo bibê. -- [[Bikarhêner:Guherto|Guherto]] ([[Gotûbêja bikarhêner:Guherto|gotûbêj]]) 14:05, 4 îlon 2020 (UTC) <!-- === Dengdan === {{dengdan/nû|destpêk=?|dawî=?}} piştî dengdan dest pê kir vê şablonê {{dengdan|destpêk=|dawî=}}, û kengî xilas bû vê şablonê {{dengdan/borî|destpêk=|dawî=}} bi kar bînin. --> == [[sefhe]] == [[sefhe]] / [[seyfe]] / [[sayfe]] -- [[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 13:34, 22 tebax 2020 (UTC) {{rfk||}} -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 23:06, 1 hezîran 2025 (UTC) === Gotûbêj === <!--Li jêr fikrên xwe binivîsin. {{şîrove}} --> {{şîrove}} Bi min ya standard "sehîfe" ye. Forma "sefhe" di şiîrên Ehmedê Xanî de derbas dibe, lê îro ev peyv bi forma "sehîfe" tê zanîn. Lewma bi min divê em awayê standard wek "'''sehîfe'''" nîşan bidin. -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 23:06, 1 hezîran 2025 (UTC) <!-- === Dengdan === {{dengdan/nû|destpêk=?|dawî=?}} piştî dengdan dest pê kir vê şablonê {{dengdan|destpêk=|dawî=}}, û kengî xilas bû vê şablonê {{dengdan/borî|destpêk=|dawî=}} bi kar bînin. --> == [[pergala xebatê]] == [[pergala xebatê]] / [[pergala xebitandinê]] -- [[Bikarhêner:Guherto|Guherto]] ([[Gotûbêja bikarhêner:Guherto|gotûbêj]]) 15:29, 26 tebax 2020 (UTC) {{rfk||}} -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 22:49, 1 hezîran 2025 (UTC) === Gotûbêj === <!--Li jêr fikrên xwe binivîsin. {{şîrove}} --> {{şîrove}} Ya rast ev ne pirseke li ser standardkirinê ye. Lewma li vir neyê minaqeşekirin baştir e. Lê dîsa fikrê xwe bêjim. Îngilîzîya wî "''operating system''" e, ew jî bi kurdî him dibe "''sîstema xebitandinê''" him jî "''sîstema xebitînê''", ji ber ku lêkera "operate" him transîtîv e him jî întransîtîv. Bi min "pergala xebatê" jî ne xelet e. -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 22:49, 1 hezîran 2025 (UTC) <!-- === Dengdan === {{dengdan/nû|destpêk=?|dawî=?}} piştî dengdan dest pê kir vê şablonê {{dengdan|destpêk=|dawî=}}, û kengî xilas bû vê şablonê {{dengdan/borî|destpêk=|dawî=}} bi kar bînin. --> == [[qet]] == Navdêra qet/qed (bi maneya parçe). Ji erebî hatîye û ya erebî "qet" e (bi t-ya qalin weke '''t'''ewandin). Ya kurdî bi t-ya normal e. -- [[Bikarhêner:Guherto|Guherto]] ([[Gotûbêja bikarhêner:Guherto|gotûbêj]]) 18:24, 28 tebax 2020 (UTC) {{rfk||}} -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 20:02, 28 nîsan 2025 (UTC) Di ''Ji bo Rastnivîsînê Ferhenga Kurdî (Kurmancî)-Tirkî ya Nû'' de 'qed' derbas nabe, qet bi maneya 'hîç' derbas dibe, halê standard ya 'qet'a bi maneya 'parçe'yê wekî 'qut' nîşan dane. -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 20:07, 28 nîsan 2025 (UTC) === Gotûbêj === <!--Li jêr fikrên xwe binivîsin. {{şîrove}} --> {{şîrove}} * Hiii, min got yanî ya hoker bû. -- [[Bikarhêner:Hakîmo|Hakîmo]] ([[Gotûbêja bikarhêner:Hakîmo|gotûbêj]]) 14:03, 29 tebax 2020 (UTC) :{{r|Hakîmo}} Min şablonê li navdêrê danîbû lê baştir e ez binivîsim ku li ser navdêrê ye. (Min vêce nivîsî). -- [[Bikarhêner:Guherto|Guherto]] ([[Gotûbêja bikarhêner:Guherto|gotûbêj]]) 14:30, 29 tebax 2020 (UTC) {{şîrove}} Wek min li jor nivîsî, ev peyv di ferhenga ''Ji bo Rastnivîsînê Ferhenga Kurdî (Kurmancî)-Tirkî ya Nû'' de tine ye, feqet bi min divê forma "'''qet'''" wek ya standard were qebûlkirin. Wek notek biçûk vê jî bêjim, ji "qet"a bi maneya "parçe" lêkera "qet kirin"ê jî çêbûye û lêkera "qut kirin"ê ku tê maneya "du tiştan ji hev qet kirin" û lêkera "qet kirin"ê bi eynî maneyê ne. -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 20:02, 28 nîsan 2025 (UTC) {{şîrove}} Li ser meseleya 'qet' û 'qut'ê jî, her du jî pir berbelav in, lewma bi min divê her du jî bimînin. Wekî din hin ferq jî hene di navbera wan de, wek nimûne, halê navdêrî ya "qet"ê berbelav e, lê halê navdêrî ya "qut"ê neberbelav e. -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 20:07, 28 nîsan 2025 (UTC) <!-- === Dengdan === {{dengdan/nû|destpêk=?|dawî=?}} piştî dengdan dest pê kir vê şablonê {{dengdan|destpêk=|dawî=}}, û kengî xilas bû vê şablonê {{dengdan/borî|destpêk=|dawî=}} bi kar bînin. --> == [[darberû]] / [[darberî]] == [[darberû]] / [[darberî]]--[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 21:36, 30 tebax 2020 (UTC) {{rfk|berû|r=73}} Peyva "darberû" nîne, lê "berû" heye. Jixwe peyda "dar" standard e, nelihevî li ser qismê "berû" û "berî"yê ye. -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 22:24, 27 nîsan 2025 (UTC) {{ds-kirî|darberû}} --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 23:06, 1 hezîran 2025 (UTC) == [[diran]] / [[didan]] == [[diran]] --[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 08:52, 31 tebax 2020 (UTC) {{rfk|diran|r=136}} -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 22:20, 27 nîsan 2025 (UTC) === Gotûbêj === <!--Li jêr fikrên xwe binivîsin. {{şîrove}} --> {{şîrove}} '''''[[didan]]''''' awayê standard e ji ber ku '''''[[diran]]''''' ji wê hatiye: '''''didan''''' > '''''diran''''' * Li Qonyayê herdu li kar in (ez '''''[[didan]]''''' bi kar tînim); li rojhilatê '''''[[didan]]''''' pirtir li kar e; Ehmedê Xanî di ''Nûbihara Biçûkan'' da '''''[[didan]]''''' bi kar anîbû. -- [[Bikarhêner:Hakîmo|Hakîmo]] ([[Gotûbêja bikarhêner:Hakîmo|gotûbêj]]) 08:29, 1 îlon 2020 (UTC) * {{erê}} [[didan]] -- [[Bikarhêner:Hakîmo|Hakîmo]] ([[Gotûbêja bikarhêner:Hakîmo|gotûbêj]]) 08:29, 1 îlon 2020 (UTC) Em dibêjin diran û dinan. "Didan" formeke lêkerê ye jî ("ew xwarin ''didan'' xelkê"), baştir e ne weke hev bin. Diran (înternetê bigere "diranê" û "diranên") gelekî bêhtir ji "didan" ("didanê", "didanên") tê bikaranîn. Fikirên [[Bikarhêner:Ferhengvan|Ferhengvan]] (23ê îlonê 2019) li vir hene: [[Gotûbêja pêvekê:fînî-kurdî]]. -- [[Bikarhêner:Guherto|Guherto]] ([[Gotûbêja bikarhêner:Guherto|gotûbêj]]) 19:02, 1 îlon 2020 (UTC) {{şîrove}} {{r|Guherto|Hakîmo}} Hevalno hûn tim behsa bilêvkirinê dikim lê hûn ti carî behsa çavkaniyan nakin. Binêrin [[Wîkîferheng:Dengdan/Rêzik/Rêzikên standardkirinê]] dibêje ''Derbarê awayê peyvekê de çiqas zêde çavkaniyên kitêb an ferhengên rastnivîsînê, ferheng û kovarên zimannasiyê hebin, ew awa wek awayê standard tên pejirandin.'' Yanî bilêvkirina xelkê ne xema me ye. Heta niha 4 kes gotine erê, ku hûn naxwazin em bi ya çavkaniyan bikin hingê dengê xwe bidin, bibêjin na daku ew rêzik nayên pêjirandin û em dîsa gotûbêj çêkin, rêzikên din hilbijêrin. --[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 19:11, 1 îlon 2020 (UTC) ::{{r|Balyozxane}} Min gotibû ''Diran (înternetê bigere "diranê" û "diranên") gelekî bêhtir ji "didan" ("didanê", "didanên") tê bikaranîn.''. Ew li ser çavkanîya ne. -- [[Bikarhêner:Guherto|Guherto]] ([[Gotûbêja bikarhêner:Guherto|gotûbêj]]) 19:26, 1 îlon 2020 (UTC) :::{{r|Guherto}} Hingê çima dengê xwe nadî? --[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 19:27, 1 îlon 2020 (UTC) ::::{{r|Balyozxane}} Min hin sanîye berî ku tu vê peyama xwe ya talî şand dengê xwe da :) -- [[Bikarhêner:Guherto|Guherto]] ([[Gotûbêja bikarhêner:Guherto|gotûbêj]]) 19:28, 1 îlon 2020 (UTC) :::::{{r|Guherto}} Mala te ava! :) --[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 19:30, 1 îlon 2020 (UTC) ::::::{{r|Balyozxane}} Merheba. Min berê jî gotibû: ''rewşa kurmancên me gelek xirab e, u ji ber hindê pir kurmancên me bi xwendin u nivîsîna zimanê xwe nizanin''. Çavkaniyên niha bipiranî ji devokên navendî tên, hinên rojhilatê jî bi herfên erebî ne. Zimanê standard bi çavkaniyan çênabit, divêt li gorî zimanê hemî kurmancan çêbit. -- [[Bikarhêner:Hakîmo|Hakîmo]] ([[Gotûbêja bikarhêner:Hakîmo|gotûbêj]]) 16:19, 2 îlon 2020 (UTC) ::::::{{r|Balyozxane}} Herwiha '''''[[didan]]''''' helbet dikarit wek '''''[[diran]]''''' bi lêv bibit, lê berevajî nabit. -- [[Bikarhêner:Hakîmo|Hakîmo]] ([[Gotûbêja bikarhêner:Hakîmo|gotûbêj]]) 16:22, 2 îlon 2020 (UTC) :::::::{{r|Hakîmo}} Merheba, fikirên xwe li dengdanê çima nadê? -- [[Bikarhêner:Guherto|Guherto]] ([[Gotûbêja bikarhêner:Guherto|gotûbêj]]) 16:44, 2 îlon 2020 (UTC) ::::::::{{r|Guherto}} Ne min dayê... -- [[Bikarhêner:Hakîmo|Hakîmo]] ([[Gotûbêja bikarhêner:Hakîmo|gotûbêj]]) 12:53, 3 îlon 2020 (UTC) Ez dibêjim ku "dinan" formêka rasttirin bi kurdî ye (bi kelhûrî bikar tînin). Em berhevdin: Farsî: duzd, nazdīk, gandum, gand, dandān, xand-īd-an Kurdî: diz, nezîk, genim, genî, dinan, ken-î-n Zazayî: dızd, nezdi, genım*, gende, dından, (hûwaene) Bi kurmancî, soranî u kelhûrî ZD u ND dibin Z u N, D dikeve. Ev qeyde gelêk kevin e. *ji kurmancî, bi taliş qender: gāndım [[Bikarhêner:Umut Akkoç|Umut Akkoç]] ([[Gotûbêja bikarhêner:Umut Akkoç|gotûbêj]]) 14:14, 18 gulan 2021 (UTC) {{ds-kirî|diran}} --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 23:07, 1 hezîran 2025 (UTC) == [[dur]] == [[dur]] û [[dir]] --[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 19:41, 31 tebax 2020 (UTC) '''Gotûbêj:''' <!--Li jêr fikrên xwe binivîsin. {{şîrove}} --> {{şîrove}} <!-- === Dengdan === {{dengdan/nû|destpêk=?|dawî=?}} piştî dengdan dest pê kir vê şablonê {{dengdan|destpêk=|dawî=}}, û kengî xilas bû vê şablonê {{dengdan/borî|destpêk=|dawî=}} bi kar bînin. --> == [[nanoziko]] == [[nanoziko]] / [[nanzikî]] / [[nano ziko]]--[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 06:57, 4 îlon 2020 (UTC) {{rfk|nanozikî|r=324}} -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 19:27, 27 nîsan 2025 (UTC) {{ds-kirî|nanozikî}} --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 23:07, 1 hezîran 2025 (UTC) == [[sînor]] / [[sinor]] == sînor / sinor -- [[Bikarhêner:Guherto|Guherto]] ([[Gotûbêja bikarhêner:Guherto|gotûbêj]]) 21:15, 4 îlon 2020 (UTC) {{rfk|sînor|r=446}} -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 19:25, 27 nîsan 2025 (UTC) {{ds-kirî|sînor}} --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 23:08, 1 hezîran 2025 (UTC) == [[ard]] == ard / ar -- [[Bikarhêner:Guherto|Guherto]] ([[Gotûbêja bikarhêner:Guherto|gotûbêj]]) 14:10, 6 îlon 2020 (UTC) {{rfk||}} -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 09:52, 27 nîsan 2025 (UTC) === Gotûbêj === <!--Li jêr fikrên xwe binivîsin. {{şîrove}} --> {{şîrove}} ard rasttir dibînim -- [[Bikarhêner:Guherto|Guherto]] ([[Gotûbêja bikarhêner:Guherto|gotûbêj]]) 14:10, 6 îlon 2020 (UTC) {{şîrove}} "ar" tê maneya "agir"ê jî. "Erd" (rûyê zemînê) û "ard" jî wek telafûz nêzî hev in. Di peyva "arvan"ê de jî wek "ar" derbas dibe. Bi min wek "'''ar'''" baştir e. -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 09:52, 27 nîsan 2025 (UTC) <!-- === Dengdan === {{dengdan/nû|destpêk=?|dawî=?}} piştî dengdan dest pê kir vê şablonê {{dengdan|destpêk=|dawî=}}, û kengî xilas bû vê şablonê {{dengdan/borî|destpêk=|dawî=}} bi kar bînin. --> == [[ajne]] /[[avjenî]]/[[ajnî]] == [[ajnî]]--[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 19:05, 6 îlon 2020 (UTC) * {{rfk|ajne, avjenî|r=42, 50}} Di vê rêbera rastnivîsînê de her du formên wek "ajne" û "avjenî" wek standard hatine qeydkirin. Lewma formên peyva ''ajne'' yên wek "ajnê", "ajnî", "aşnê" divê li madeya "ajne"yê werin alîkirin, lê "avjenî" bi serê xwe cih bigire. -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 09:39, 21 îlon 2024 (UTC) {{ds-kirî|[[avjenî]], [[ajne]]}} --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 23:09, 1 hezîran 2025 (UTC) == [[gurî]] == [[gurî]] / [[gurîtî]] / [[gurriyatî]]--[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 20:53, 6 îlon 2020 (UTC) '''Gotûbêj:''' <!--Li jêr fikrên xwe binivîsin. {{şîrove}} --> {{şîrove}} <!-- === Dengdan === {{dengdan/nû|destpêk=?|dawî=?}} piştî dengdan dest pê kir vê şablonê {{dengdan|destpêk=|dawî=}}, û kengî xilas bû vê şablonê {{dengdan/borî|destpêk=|dawî=}} bi kar bînin. --> == [[parsî]] == [[partî]]--[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 23:09, 7 îlon 2020 (UTC) '''Gotûbêj:''' <!--Li jêr fikrên xwe binivîsin. {{şîrove}} --> {{şîrove}} <!-- === Dengdan === {{dengdan/nû|destpêk=?|dawî=?}} piştî dengdan dest pê kir vê şablonê {{dengdan|destpêk=|dawî=}}, û kengî xilas bû vê şablonê {{dengdan/borî|destpêk=|dawî=}} bi kar bînin. --> == [[xwestin]] == xwestin / xwastin xwestin rasttir dibînim. -- [[Bikarhêner:Guherto|Guherto]] ([[Gotûbêja bikarhêner:Guherto|gotûbêj]]) 18:09, 9 îlon 2020 (UTC) {{rfk|xwastin|r=523}} -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 13:48, 6 adar 2025 (UTC) === Gotûbêj === <!--Li jêr fikrên xwe binivîsin. {{şîrove}} --> {{şîrove}} Ez jî '''''[[xwestin]]''''' rasttir dibînim; jixwe '''''[[xwastin]]''''' bi min giran têt, o '''''[[xwestin]]''''' di hemî lehceyên kirmancî da heye. -- [[Bikarhêner:Hakîmo|Hakîmo]] ([[Gotûbêja bikarhêner:Hakîmo|gotûbêj]]) 08:21, 19 îlon 2020 (UTC) <!-- === Dengdan === {{dengdan/nû|destpêk=?|dawî=?}} piştî dengdan dest pê kir vê şablonê {{dengdan|destpêk=|dawî=}}, û kengî xilas bû vê şablonê {{dengdan/borî|destpêk=|dawî=}} bi kar bînin. --> == [[îrrasyonel]] == [[îrrasyonal]]--[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 22:44, 9 îlon 2020 (UTC) {{rfk||}} Ev peyv derbas nabe, feqet peyva "rasyonel" wek standard cih girtîye (r. 403). Lewma ev jî dibe "'''îrrasyonel'''". -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 13:46, 6 adar 2025 (UTC) === Gotûbêj === <!--Li jêr fikrên xwe binivîsin. {{şîrove}} --> {{şîrove}} <!-- === Dengdan === {{dengdan/nû|destpêk=?|dawî=?}} piştî dengdan dest pê kir vê şablonê {{dengdan|destpêk=|dawî=}}, û kengî xilas bû vê şablonê {{dengdan/borî|destpêk=|dawî=}} bi kar bînin. --> == [[ajel]]/[[ajal]] == ajel / ajal Em dibêjin heywan :) -- [[Bikarhêner:Guherto|Guherto]] ([[Gotûbêja bikarhêner:Guherto|gotûbêj]]) 19:11, 10 îlon 2020 (UTC) * {{rfk|ajel|r=42}} --[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 19:34, 22 îlon 2023 (UTC) === Gotûbêj === <!--Li jêr fikrên xwe binivîsin. {{şîrove}} --> {{şîrove}} Peyva ajel ji peyva sewal a kurmancî hatiye standin (s>J) sewal anku ajel ew canewerên çarpayî yên kedîkirî ne. Wekî pez, bizin, çêlek.{{bêîmze|46.161.196.225}} {{ds-kirî|ajel}} --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 23:11, 1 hezîran 2025 (UTC) == [[pîrebok]]/[[pîrhebok]] == {{rfk|pîrebok|r=365}} -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 13:44, 6 adar 2025 (UTC) === Gotûbêj === <!--Li jêr fikrên xwe binivîsin. {{şîrove}} --> {{şîrove}} Ji bo Rastnivîsnê Ferhanga Kurdî; di pera 365 wek ''pîrebok'' hatiye standardîzekirin. Di ferhengê de herweha ev form jî hene: pîraboçk, pîrabok, pîraboşk, pîrabotîk, pîravok, pîravtong, pîreboşk, pîrebotk. Wîkîferhengê herwiha forma pîrhebok heye[[Bikarhêner:Rewiye tine|Rewiye tine]] ([[Gotûbêja bikarhêner:Rewiye tine|gotûbêj]]) 21:15, 10 îlon 2020 (UTC) {{ds-kirî|pîrebok}} --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 23:11, 1 hezîran 2025 (UTC) == [[şirove]] / [[şîrove]] == [[şirove]] / [[şîrove]] --[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 00:50, 11 îlon 2020 (UTC) {{rfk|şirove|r=466}} -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 13:41, 6 adar 2025 (UTC) {{ds-kirî|şirove}}--[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 08:48, 5 tîrmeh 2026 (UTC) == [[pezkûvî]]/[[pezkovî]] == [[pezkovî]]--[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 08:59, 11 îlon 2020 (UTC) {{rfk|pezkûvî|r=354}} -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 13:41, 6 adar 2025 (UTC) === Gotûbêj === <!--Li jêr fikrên xwe binivîsin. {{şîrove}} --> {{şîrove}} {{r|Balyozxane}} Yek hatîye jêbirin. -- [[Bikarhêner:Guherto|Guherto]] ([[Gotûbêja bikarhêner:Guherto|gotûbêj]]) 19:22, 23 çiriya pêşîn 2020 (UTC) {{ds-kirî|pezkûvî}} --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 23:13, 1 hezîran 2025 (UTC) == [[dibistana seretayî]]/[[dibistana seratayî]] == [[dibistana seratayî]]--[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 19:22, 12 îlon 2020 (UTC) {{rfk||}} -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 13:39, 6 adar 2025 (UTC) === Gotûbêj === <!--Li jêr fikrên xwe binivîsin. {{şîrove}} --> {{şîrove}} Bi min eşkere ye ku awayê standard "sereta" ye, lewma ya standard dibe "''[[dibistana seretayî]]''". -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 13:39, 6 adar 2025 (UTC) {{ds-kirî|dibistana seretayî}} --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 23:13, 1 hezîran 2025 (UTC) == [[sêzdeh]]/ [[sêzde]] == / sêzde. sêzdeh rasttir dibînim, sê + z + deh. Ti sedem nîne ji bo jêbirina "h" -- [[Bikarhêner:Guherto|Guherto]] ([[Gotûbêja bikarhêner:Guherto|gotûbêj]]) 09:34, 13 îlon 2020 (UTC) {{rfk|sêzdeh|r=441}} -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 13:37, 6 adar 2025 (UTC) === Gotûbêj === <!--Li jêr fikrên xwe binivîsin. {{şîrove}} --> {{şîrove}} Ferhenga Michael L. Chyet (2003) sêzde ber alî dike sêzdeh. -- [[Bikarhêner:Guherto|Guherto]] ([[Gotûbêja bikarhêner:Guherto|gotûbêj]]) 09:34, 13 îlon 2020 (UTC) : yazdeh/yazde (beralîkirin), çardeh/çarde (dubare), pazdeh/pazde (beralîkirin), şazdeh/şazde (beralîkirin), hevdeh/hevde (beralîkirin), hejdeh/hejde (beralîkirin), nozdeh/nozde (beralîkirin) -- [[Bikarhêner:Guherto|Guherto]] ([[Gotûbêja bikarhêner:Guherto|gotûbêj]]) 09:37, 13 îlon 2020 (UTC) {{ds-kirî|sêzdeh}} --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 23:14, 1 hezîran 2025 (UTC) == [[çirûsk]]/[[çirîsk]] == çirîsk/çirûsk çirûsk(m):1.kıvılcım, çıngı çirîsk(m): binêre(çirûsk)(per 116,117)[[Bikarhêner:Rewiye tine|Rewiye tine]] ([[Gotûbêja bikarhêner:Rewiye tine|gotûbêj]]) 22:46, 13 îlon 2020 (UTC) {{rfk|çirûsk|r=116}} -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 13:36, 6 adar 2025 (UTC) {{ds-kirî|çirûsk}} --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 23:15, 1 hezîran 2025 (UTC) == [[êriş]]/[[êrîş]] == [[êriş]]--[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 17:11, 15 îlon 2020 (UTC) * {{rfk|êriş|r=157}} --[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 19:36, 22 îlon 2023 (UTC) {{ds-kirî|êriş}} --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 23:15, 1 hezîran 2025 (UTC) == [[mûmin]] == [[momîn]]--[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 18:22, 16 îlon 2020 (UTC) {{rfk||}} -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 23:00, 5 sibat 2025 (UTC) === Gotûbêj === <!--Li jêr fikrên xwe binivîsin. {{şîrove}} --> {{şîrove}} Bi min ya standard "'''mumin'''" e. Bi apostrof baştir be jî, ji ber nestandardbûna emilandina apostrofan, ji bo halê standard bêapostrof baştir e. -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 23:00, 5 sibat 2025 (UTC) <!-- === Dengdan === {{dengdan/nû|destpêk=?|dawî=?}} piştî dengdan dest pê kir vê şablonê {{dengdan|destpêk=|dawî=}}, û kengî xilas bû vê şablonê {{dengdan/borî|destpêk=|dawî=}} bi kar bînin. --> == [[xwarza]] == [[xwarza]] / [[xwarzî]] / [[xuharzî]]--[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 15:14, 17 îlon 2020 (UTC) {{rfk|xwarza, xwarzî|r=523}} Her du peyv jî bi eynî maneyê di ferhengê de cih girtine. -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 22:34, 5 sibat 2025 (UTC) === Gotûbêj === <!--Li jêr fikrên xwe binivîsin. {{şîrove}} --> {{şîrove}} <!-- === Dengdan === {{dengdan/nû|destpêk=?|dawî=?}} piştî dengdan dest pê kir vê şablonê {{dengdan|destpêk=|dawî=}}, û kengî xilas bû vê şablonê {{dengdan/borî|destpêk=|dawî=}} bi kar bînin. --> == [[lênêrîn]] == [[nerîn]] / [[nêrîn]] / [[lênêrîn]] / [[lê nerîn]]--[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 21:19, 17 îlon 2020 (UTC) {{rfk|nêrîn|r=333}} -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 21:04, 5 sibat 2025 (UTC) === Gotûbêj === <!--Li jêr fikrên xwe binivîsin. {{şîrove}} --> {{şîrove}} "Lênêrîn" jixwe wek navdêr "''nêrîna li tiştekî''" ye, û "lê nêrîn" jî wek lêker "''li tiştekî nêrîn''" e, lê belê di her dukan de jî lêker/navdêr "nêrîn" e. "li"ya pêşî ji bo maneya "nêrîn"ê bêtesîr e/tesîreke wê lê nîne. Feqet ger were gotin ku "nêrîn" (bi îngilîzî "looking") wek forma "lênêrîn" xwedî maneyeke din e (ku divê ev yek jî bi çavkanîyan were îsbatkirin) wê gavê mirov kare wê peyvê cardin binirxîne. -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 21:04, 5 sibat 2025 (UTC) <!-- === Dengdan === {{dengdan/nû|destpêk=?|dawî=?}} piştî dengdan dest pê kir vê şablonê {{dengdan|destpêk=|dawî=}}, û kengî xilas bû vê şablonê {{dengdan/borî|destpêk=|dawî=}} bi kar bînin. --> == [[hewar]] == [[hewar]]/[[hawar]] --[[Bikarhêner:Şêr|Şêr]] ([[Gotûbêja bikarhêner:Şêr|gotûbêj]]) 10:07, 19 îlon 2020 (UTC) {{rfk|hawar|r=190}} -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 20:35, 5 sibat 2025 (UTC) === Gotûbêj === <!--Li jêr fikrên xwe binivîsin. {{şîrove}} --> {{şîrove}} <!-- === Dengdan === {{dengdan/nû|destpêk=?|dawî=?}} piştî dengdan dest pê kir vê şablonê {{dengdan|destpêk=|dawî=}}, û kengî xilas bû vê şablonê {{dengdan/borî|destpêk=|dawî=}} bi kar bînin. --> == [[muhakeme]] == [[muhakeme]] / [[mihakeme]]--[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 11:59, 19 îlon 2020 (UTC) {{rfk|mihakeme|r=309}} -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 20:34, 5 sibat 2025 (UTC) === Gotûbêj === <!--Li jêr fikrên xwe binivîsin. {{şîrove}} --> {{şîrove}} <!-- === Dengdan === {{dengdan/nû|destpêk=?|dawî=?}} piştî dengdan dest pê kir vê şablonê {{dengdan|destpêk=|dawî=}}, û kengî xilas bû vê şablonê {{dengdan/borî|destpêk=|dawî=}} bi kar bînin. --> == [[tevabûn]] == [[tewabûn]]--[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 18:22, 19 îlon 2020 (UTC) {{rfk|temambûn|r=477}} -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 20:32, 5 sibat 2025 (UTC) === Gotûbêj === <!--Li jêr fikrên xwe binivîsin. {{şîrove}} --> {{şîrove}} Tev jî formên "''temambûn''"ê ne. -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 20:32, 5 sibat 2025 (UTC) <!-- === Dengdan === {{dengdan/nû|destpêk=?|dawî=?}} piştî dengdan dest pê kir vê şablonê {{dengdan|destpêk=|dawî=}}, û kengî xilas bû vê şablonê {{dengdan/borî|destpêk=|dawî=}} bi kar bînin. --> == [[fiêl]] == [[fiêl]] / [[fîil]] / [[fîîl]] Standardkirin lazim e. -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 20:12, 19 îlon 2020 (UTC) {{rfk|fêl|r=164}} -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 20:21, 5 sibat 2025 (UTC) === Gotûbêj === <!--Li jêr fikrên xwe binivîsin. {{şîrove}} --> {{şîrove}} <!-- === Dengdan === {{dengdan/nû|destpêk=?|dawî=?}} piştî dengdan dest pê kir vê şablonê {{dengdan|destpêk=|dawî=}}, û kengî xilas bû vê şablonê {{dengdan/borî|destpêk=|dawî=}} bi kar bînin. --> == [[pêşniyazkirî]] == [[pêşniyarkirî]], [[pêşniyar]] beralî dike [[pêşniyaz]]--[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 22:24, 19 îlon 2020 (UTC) '''Eynî mijar li jêr hatîye vekirin. Ji bo standardkirinê binêrin ya jêr.''' -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 20:18, 5 sibat 2025 (UTC) '''Gotûbêj:''' <!--Li jêr fikrên xwe binivîsin. {{şîrove}} --> {{şîrove}} == [[xwehr]] == [[xwehr]] / [[xwar]] Standardkirin hewce ye. -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 07:43, 20 îlon 2020 (UTC) '''Gotûbêj:''' <!--Li jêr fikrên xwe binivîsin. {{şîrove}} --> {{şîrove}} {{r|Bikarhêner}} Kîjan mane? Jixwe ya xwehr (îng crooked) standardkirî bû lê te xwehr kopî kir xwar. Çima? -- [[Bikarhêner:Guherto|Guherto]] ([[Gotûbêja bikarhêner:Guherto|gotûbêj]]) 09:07, 20 îlon 2020 (UTC) : {{r|Guherto}} Merheba bira. Li ser rûpela "[[xwar]]" maneya rengdêrî ya "ne rast, tewandî" tinebû. Tenê maneyeke wek "çewt, xelet" ''(bi cureyê rengdêrî)'' hebû. Ji ber ku mane kêm û şaş hatibû dayîn min ji rûpela "[[xwehr]]" mane û beşên din kopî kir û bi rûpela "[[xwar]]" ve kir. Û ji ber ku ji bo tenê maneyekê du awayên nivîsê yê wek "[[xwar]]" û "[[xwehr]]" wek standard cih digirtin, min şablona standardkirinê tevlî wan her du rûpelan jî kir, û ji bo ku em awayê standard bibijêrin li vir beşekê nû vekir. -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 09:25, 20 îlon 2020 (UTC) ::Tu dikarîbû bnr-ek lê zêde bikê, ne hewce ye kopîkirin. -- [[Bikarhêner:Guherto|Guherto]] ([[Gotûbêja bikarhêner:Guherto|gotûbêj]]) 09:48, 20 îlon 2020 (UTC) ::: {{r|Guherto}} Ji ber ku ez awayê standard wek "[[xwar]]" dibînim min rûpelê wek standard hazir kir. Awayê bnr-yî ne awayê wek standard e. -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 10:07, 20 îlon 2020 (UTC) ::::Temam. Lê hêjî kopîkirin ne hewce ye, bnr min çawa kir li [[#girover]] ji ber ku ez wê standard didîtim (dibînim). -- [[Bikarhêner:Guherto|Guherto]] ([[Gotûbêja bikarhêner:Guherto|gotûbêj]]) 10:11, 20 îlon 2020 (UTC) ::::: {{r|Guherto}} Baş e, di yên din de êdî ez ê wisa bikim. -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 14:35, 20 îlon 2020 (UTC) xwehr = ne rast (tirkî:eğik) û xwar = jêr (tirkî:aşağı).—<small>[[Bikarhêner:Gomada|<span style="background:Yellow">'''''<span style="font-family:Verdana;color:red">Gom<span style="color:#006400">ada</span></span></span>''''']]<sup>[[Gotûbêja bikarhêner:Gomada|peyam]]</sup></small> 15:34, 21 kanûna paşîn 2021 (UTC) {{şirove}} Birêzan; li herêma me ev peyv wek ''xar'' tê bilêv kirin û li serhedê heta Sêwaz û ji wir hata Rojavayê Kurdistan bi vî awayîye.Min xwehr heya niha ji devê kesî nebihîstibû. Bi ya min xwar rasttire. Ji ber ku li devê meda di nav gellek peyvanda tîpa ''w'' nîne. Lê îjar jî bi peyva ''xwarin'' û ''xwarê''(berjêr) tevlihevî çêdibe.Dema ku standardizasyon çêdibe divê hemî peyvên watecûda bi wekhev neyê nivîsandin. Wek mînak niha peyvên kêr(alav,feyde,pozdewixî), ker(ajal,parçe,koma pez,nebihîz) 3-4 peyven ku xwendinên wan cûdane bi heman awayî tê nivîsin,ev zimanê me zortir dike û dibe sedema xeletîyan.Divê ziman standardîze be, lê ne bi vî awayî. {{bêîmze|Mihemed Qers}} == [[dirist]] == [[dirist]] / [[dirust]] -- [[Bikarhêner:Guherto|Guherto]] ([[Gotûbêja bikarhêner:Guherto|gotûbêj]]) 13:44, 20 îlon 2020 (UTC) {{rfk|dirust|r=137}} -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 20:15, 5 sibat 2025 (UTC) === Gotûbêj === <!--Li jêr fikrên xwe binivîsin. {{şîrove}} --> {{şîrove}} == [[neynok]] == [[neynok]] / [[neynûk]] / [[nînok]] / [[nênûk]] / [[nenîk]] Awayê ku herî kêm tê bikaranîn (nînok) weke standard hatîye neqandin, ez vê şaş dibînim. -- [[Bikarhêner:Guherto|Guherto]] ([[Gotûbêja bikarhêner:Guherto|gotûbêj]]) 20:43, 20 îlon 2020 (UTC) Eynî rûpel li nînok û nênûk hene. -- [[Bikarhêner:Guherto|Guherto]] ([[Gotûbêja bikarhêner:Guherto|gotûbêj]]) 20:45, 20 îlon 2020 (UTC) {{rfk|nenûk|r=328}} -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 20:10, 5 sibat 2025 (UTC) === Gotûbêj === <!--Li jêr fikrên xwe binivîsin. {{şîrove}} --> {{şîrove}} Bi qenaeta min divê halê standard "neynûk" be. -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 20:10, 5 sibat 2025 (UTC) == [[neynokbir]] == neynokbir/neynûkbir/nenîkbir Divê li gora encama [[#neynok]] werê standardkirin. -- [[Bikarhêner:Guherto|Guherto]] ([[Gotûbêja bikarhêner:Guherto|gotûbêj]]) 20:39, 20 îlon 2020 (UTC) {{rfk|nenûk|r=328}} Di vê ferhengê de ''nenûkbir'' nîne, lê ji bo peyva "neynûk"ê awayê standard wek "nenûk" hatîye nîşandayîn. -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 20:12, 5 sibat 2025 (UTC) === Gotûbêj === <!--Li jêr fikrên xwe binivîsin. {{şîrove}} --> {{şîrove}} Bi min wek halê standard forma "neynûk" baştir e. Lewma ev jî dibe "''neynûkbir''". -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 20:12, 5 sibat 2025 (UTC) == [[xwijok]] == [[xişok]]--[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 02:46, 21 îlon 2020 (UTC) {{rfk||}} -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 19:44, 5 sibat 2025 (UTC) === Gotûbêj === <!--Li jêr fikrên xwe binivîsin. {{şîrove}} --> {{şîrove}} Bi min ji ber ku halê wê yê lêker wek "''xişîn''" e, ya standard "'''xişok'''" e. -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 19:44, 5 sibat 2025 (UTC) == [[pirhindik]] == [[pir hindik]]--[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 20:34, 22 îlon 2020 (UTC) {{rfk||}} -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 22:30, 3 sibat 2025 (UTC) === Gotûbêj === <!--Li jêr fikrên xwe binivîsin. {{şîrove}} --> {{şîrove}} Formeke wek "pirhindik" bi min bêçavkanî ye. Lewma ya standard divê wek "pir hindik" be. Feqet peyva "pir hindik" jî bi maneya "teqrîben, nêzîkî" nîne. Divê ew qism jî were rastkirin. -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 22:30, 3 sibat 2025 (UTC) :Min maneya wê fam kir, feqet nizanim, emilandineke wisa heye an tine. -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 13:26, 6 adar 2025 (UTC) == [[qireqir]] == [[qîreqîr]]--[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 17:22, 23 îlon 2020 (UTC) {{rfk|qîreqîr|r=390}} -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 22:11, 3 sibat 2025 (UTC) === Gotûbêj === <!--Li jêr fikrên xwe binivîsin. {{şîrove}} --> {{şîrove}} == [[pênivîs]] == [[pênivîs]] / [[pênûs]] / [[pênivîsk]]. Pênivîs bêhtir tê bikaranîn. Ev û pênûs eynî peyv in, lê pênûs li gora "nûsîn"a soranî û pênivîs li gora "nivîsîn"a kurmancî hatîye çêkirin. Em wan bikin yek? -- [[Bikarhêner:Guherto|Guherto]] ([[Gotûbêja bikarhêner:Guherto|gotûbêj]]) 14:58, 24 îlon 2020 (UTC) {{rfk||}} -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 21:34, 3 sibat 2025 (UTC) === Gotûbêj === <!--Li jêr fikrên xwe binivîsin. {{şîrove}} --> {{şîrove}} # pênivîs - Ferhenga Birûskî Michael L. Chyet # pênivîs - Ferhenga Destî çap 2 Umîd Demîrhan # pênivîs - Ferhenga Kurdî ( Kurmancî ) - Farsî. Koma Kurdîya Kurmancî. Azad MAKÛYÎ,Haşim MEHMÛDÎ,Şehnaz OMERZADE, Nasir ECEMÎ,Mohsin QULÎZADE,Kejal PADAŞ,Efsûn YÛSIFÎ # pênivîsk - Rehnas Husein Muhammed {{şîrove}} Qertafa "-k"yê di çêkirina navdêran de li kar e. Lewma ji alîyê xisûsîyeta navderbûnê ve "''pênivîsk''", ji alîyê pratîkbûnê ve ''"pênivîs"'' baştir e. Lê eger krîtera girêdayîmayîna bi eslê peyvê ve were esasgirtin, wê gavê jî ''"pênûs"'' baştir e. Biqenaeta min "'''pênivîsk'''". : Ji xeynî vê qismeke ji [https://zimannas.wordpress.com/2015/12/21/em-cima-kurdi-li-ber-xwe-dikin-ciyayeki-ase/ nivîsa malpera Zimannasê]: : ''[Peyva ”qelem” ji aliyê hemû kurdan ve û ji hêla miletên misilman ve ji Indonezyayê heta Mexribê tê fehmkirin û bikaranîn. Lê nivîskarên me qîma xwe bi wê naînin ji ber ku bi xeletî bawer dikin ku eslê wê erebî ye. Lê eslê wê jî yûnaniya kevn e: κάλαμος (kálamos). Li cihê wê nivîskarên me xwe dispêrin peyvên çêkirok yên wek ”pênivîs(k)” yan jî ”pênûs” ya ji soranî wergirtî. Lê ”pênivîs(k)” yan ”pênûs” her tişt e ku mirov pê dinivîse, ne tenê qelem e: li vê serdemê mirov zêdetir ne bi qeleman lê bi kompûterê, bi telefona mobîl yan bi hin makîneyên din dinivîse. Amûrên nivîsînê yên serekî niha ne qelem in lê kompûter, laptop, tablet û telefon in. Li gor vê rêbazê be, divê mirov ji kompûteran, ji laptopan re, ji tabletan re û ji telefonan re jî bibêje ”pênivîsk/pênûs”, ne tenê ji qeleman re!]'' -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 21:34, 3 sibat 2025 (UTC) == [[behs]] == / [[bas]]. Em dibêjin beḧs. -- [[Bikarhêner:Guherto|Guherto]] ([[Gotûbêja bikarhêner:Guherto|gotûbêj]]) 17:49, 24 îlon 2020 (UTC) {{rfk|behs|r=64}} -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 14:42, 1 sibat 2025 (UTC) === Gotûbêj === <!--Li jêr fikrên xwe binivîsin. {{şîrove}} --> {{şîrove}} == [[dîmender]] == [[dîmender]] / [[dîmendêr]]. -- [[Bikarhêner:Guherto|Guherto]] ([[Gotûbêja bikarhêner:Guherto|gotûbêj]]) 21:43, 25 îlon 2020 (UTC) {{rfk||}} -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 18:45, 27 kanûna paşîn 2025 (UTC) === Gotûbêj === <!--Li jêr fikrên xwe binivîsin. {{şîrove}} --> {{şîrove}} Paşgira "der" / "dêr"ê li şûna hev hatine emilandin. Lê ji nimûneyên jêrîn ên ji ferhenga ''Ji bo Rastnivîsînê Ferhenga Kurdî (Kurmancî)-Tirkî ya Nû'' tê dîtin ku qerareke li ser zelalkirina halê standard nehatîye dayîn di wê ferhengê de. Bnr. [[agahîder]] (Ji bo Rastnivîsînê Ferhenga Kurdî (Kurmancî)-Tirkî ya Nû r. 41), [[hander]] (Ji bo Rastnivîsînê Ferhenga Kurdî (Kurmancî)-Tirkî ya Nû r. 189), [[kêfder]] (Ji bo Rastnivîsînê Ferhenga Kurdî (Kurmancî)-Tirkî ya Nû r. 253), [[avdêr]] (Ji bo Rastnivîsînê Ferhenga Kurdî (Kurmancî)-Tirkî ya Nû wek "avdêr" nîne, lê wek "''avdêrî''" r. 50), [[bangdêr]] (Ji bo Rastnivîsînê Ferhenga Kurdî (Kurmancî)-Tirkî ya Nû r. 58), [[dengdêr]] ''-ne zelal e, nimûneyên din fahmbartir in-'' (Ji bo Rastnivîsînê Ferhenga Kurdî (Kurmancî)-Tirkî ya Nû r. 127), [[kardêr]] (Ji bo Rastnivîsînê Ferhenga Kurdî (Kurmancî)-Tirkî ya Nû r. 239), [[saloxdêr]] (Ji bo Rastnivîsînê Ferhenga Kurdî (Kurmancî)-Tirkî ya Nû r. 425), [[serîhildêr]] (Ji bo Rastnivîsînê Ferhenga Kurdî (Kurmancî)-Tirkî ya Nû r. 435), [[xwepêşander]] (Di ''Ji bo Rastnivîsînê Ferhenga Kurdî (Kurmancî)-Tirkî ya Nû'' de nîne), [[dersder]] (Di ''Ji bo Rastnivîsînê Ferhenga Kurdî (Kurmancî)-Tirkî ya Nû'' de nîne), [[fermandêr]] (Di ''Ji bo Rastnivîsînê Ferhenga Kurdî (Kurmancî)-Tirkî ya Nû'' de ev form nîne, wek "''fermande''" qeyd kirine), [[deynder]] (Di ''Ji bo Rastnivîsînê Ferhenga Kurdî (Kurmancî)-Tirkî ya Nû'' de nîne), [[girêdêr]] (Di ''Ji bo Rastnivîsînê Ferhenga Kurdî (Kurmancî)-Tirkî ya Nû'' de nîne), [[mizgînder]] (Di ''Ji bo Rastnivîsînê Ferhenga Kurdî (Kurmancî)-Tirkî ya Nû'' de nîne). Bi min divê em li balê bidin ser ku paşgirên "der" / "dêr"ê eynî maneyê didin an na. Bi min paşgira "der"ê qismen nêzî paşgira "-dar"ê ye ku ew jî maneya xwedîbûna tiştekî dide. Lewma bi min ji bo peyvên bi maneya "kesê tiştekî dide" emilandina paşgira "-dêr"ê wê baştir be, lê ger em ji alîyê rehetîya telafûzê bifikirin jî paşgira "-der"ê baştir e ji bo awayê standard. Wek netîce bi min ji bo halê standard (ji bo peyvên bi maneya "kesê tiştekî dide") paşgira "-dêr"ê başttir e. -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 18:45, 27 kanûna paşîn 2025 (UTC) == [[Rojavayê Kurdistanê]] == /Rojavaya Kurdistanê. -- [[Bikarhêner:Guherto|Guherto]] ([[Gotûbêja bikarhêner:Guherto|gotûbêj]]) 12:16, 26 îlon 2020 (UTC) [[Rojavayê Kurdistanê]]-- [[Bikarhêner:Mihemed Qers|Mihemed Qers]] ([[Gotûbêja bikarhêner:Mihemed Qers|gotûbêj]]) 21:12, 9 adar 2021 (UTC) {{rfk|"rojava" wek nêr derbas dibe|r=416}} Peyva "rojava" wek nêr qeyd kirine. -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 21:13, 26 kanûna paşîn 2025 (UTC) === Gotûbêj === <!--Li jêr fikrên xwe binivîsin. {{şîrove}} --> {{şîrove}} ''{{g|ku|rojava}}'' navdêreke mê ye, li gori rêzimana kurdi nivîsa rast "Rojava'''ya''' ''(îzafe)'' Kurdistan'''ê''' ''(çemandî)''" ye. Feqet "Rojavayê Kurdistanê" jî pirr tê bikaranîn.. --[[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 21:27, 9 adar 2021 (UTC) {{şîrove}} Slav @[[Bikarhêner:Ghybu|Ghybu]], gelle me û mezinên me dema ku peyvan bilêv dikin nêr/mê bûna peyvan çîye nizanin,peyv û hevokên ku hezaran salanda terkîb bûne û derketine holê bi xwezayî ji devên wan dertê, heta eger ku ji wanra nêr/mê bûna peyvan qal bikin yê li me xerîb binêrin,lê wan bi hezaran saland a bê qest û bi xwezayî vî zimanî qasê ku meriva şaş bihêle bi duzen ava kirine. Ne tenê herêma me, min ji gellê çi bihîstîye wê dinivîsim. Lê ji bilî gellê meyê hin herêmên Mêrdînê min tu cîyek nebihîstye ku mînak şûna ″porê min″ ″pora min″,yan jî şûna ″Rojavayê Kurdistanê″ ″Rojavaya Kurdistanê″ bêjin. Lê bi ya min em nikarin bêjin jiber ku peyva ″roj″ mê ye divê ″rojava″ jî mê be. Rast e rojava ji roj tê lê edî rojava peyveke cûda ye. [[Bikarhêner:Mihemed Qers|Mihemed Qers]] ([[Gotûbêja bikarhêner:Mihemed Qers|gotûbêj]]) 23:09, 9 adar 2021 (UTC) {{şîrove}} Di Rêbera Rastnivîsînê ya Komxebata Kurmancîyê de (r.40) jî wek alî (wek hêl, ne parçe) "'''rojavayê''' Kurdistanê" derbas kirine. Ji ber ku eynî peyv e, em dibînin ku li wir jî wek "nêr" qebûl kirine. -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 21:13, 26 kanûna paşîn 2025 (UTC) == [[diz]] == [[diz]] / [[dizîker]] / [[dizîkar]]. -- [[Bikarhêner:Guherto|Guherto]] ([[Gotûbêja bikarhêner:Guherto|gotûbêj]]) 12:37, 27 îlon 2020 (UTC) {{rfk|diz, dizek|r=138}} -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 21:06, 26 kanûna paşîn 2025 (UTC) === Gotûbêj === <!--Li jêr fikrên xwe binivîsin. {{şîrove}} --> {{şîrove}} ″diz″ ji xwe kesek e ″dizî″ jî karesata wî/ê ye lewma ″dizîker/dizîkar″ xeletin.[[Bikarhêner:Mihemed Qers|Mihemed Qers]] ([[Gotûbêja bikarhêner:Mihemed Qers|gotûbêj]]) 20:38, 9 adar 2021 (UTC) :Kes nabêje "dizîker,/dizîkar", kurd dibêjin : dizek . [[Taybet:Beşdarî/83.252.83.100|83.252.83.100]] 19:25, 3 gulan 2023 (UTC) {{şîrove}} Şiroveyên hatî yên berê ji bo min jî rast dixuyin. -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 21:06, 26 kanûna paşîn 2025 (UTC) == [[rêkxistin]] == [[rêxistin]] --[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 22:03, 27 îlon 2020 (UTC) *{{rfk|rêxistin}}--[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 11:27, 23 îlon 2023 (UTC) === Gotûbêj === <!--Li jêr fikrên xwe binivîsin. {{şîrove}} --> {{şîrove}} [[rêxistin]] -- [[Bikarhêner:Mihemed Qers|Mihemed Qers]] ([[Gotûbêja bikarhêner:Mihemed Qers|gotûbêj]]) 20:39, 9 adar 2021 (UTC) == [[cihêl]] == [[cihêl]] / [[cehêl]] standardkirin lazim e. -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 14:38, 29 îlon 2020 (UTC) {{rfk|cahil|r=94}} Forma standard wek "'''cahil'''" hatîye nîşandan, ji bo kelîmeya "cihêl". -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 00:10, 4 çiriya paşîn 2024 (UTC) === Gotûbêj === <!--Li jêr fikrên xwe binivîsin. {{şîrove}} --> {{şîrove}} == [[tihn]] == [[tên]] --[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 20:41, 30 îlon 2020 (UTC) {{rfk|tîn|r=488}} -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 21:01, 26 kanûna paşîn 2025 (UTC) === Gotûbêj === <!--Li jêr fikrên xwe binivîsin. {{şîrove}} --> {{şîrove}} == [[gişt]] == [[gişt]] / [[giş]] / [[gî]] / [[gîh]] --[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 22:25, 30 îlon 2020 (UTC) {{rfk|gişt|r=179}} -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 20:55, 26 kanûna paşîn 2025 (UTC) === Gotûbêj === <!--Li jêr fikrên xwe binivîsin. {{şîrove}} --> {{şîrove}} == [[tal]] == [[tehl]]--[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 00:35, 1 çiriya pêşîn 2020 (UTC) {{rfk|tahl|r=472}} -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 20:51, 26 kanûna paşîn 2025 (UTC) === Gotûbêj === <!--Li jêr fikrên xwe binivîsin. {{şîrove}} --> {{şîrove}} Birêzan pirranîya gellê me vê peyvê wek ″تعال″ bilêv dike lê alfabeya me da tîpa ″ع″ tune.Divê em jibo vê tîpê standartekî çêkin, wek şûna ″ع″ ″a yan jî eh″ bikarbînin wê demê pirsgirêk yê jibo peyvên din jî çareser be. -- [[Bikarhêner:Mihemed Qers|Mihemed Qers]] ([[Gotûbêja bikarhêner:Mihemed Qers|gotûbêj]]) 21:31, 9 adar 2021 (UTC) == [[şuxl]] == [[şol]]--[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 02:56, 2 çiriya pêşîn 2020 (UTC) [[şuxil]]--[[Bikarhêner:Mihemed Qers|Mihemed Qers]] ([[Gotûbêja bikarhêner:Mihemed Qers|gotûbêj]]) 21:41, 9 adar 2021 (UTC) {{rfk|şixul|r=466}} -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 20:50, 26 kanûna paşîn 2025 (UTC) === Gotûbêj === <!--Li jêr fikrên xwe binivîsin. {{şîrove}} --> {{şîrove}} == [[gilîz]] == [[girêz]] / [[gilîz]] / [[gilêz]] -- [[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 12:25, 5 çiriya pêşîn 2020 (UTC) :girêz [[Taybet:Beşdarî/&#126;2026-20662-33|&#126;2026-20662-33]] ([[Gotûbêja bikarhêner:&#126;2026-20662-33|talk]]) 19:33, 3 nîsan 2026 (UTC) {{rfk|gilêz|r=176}} -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 20:46, 26 kanûna paşîn 2025 (UTC) === Gotûbêj === <!--Li jêr fikrên xwe binivîsin. {{şîrove}} --> {{şîrove}} Çi wê ê standardkirin? -- [[Bikarhêner:Guherto|Guherto]] ([[Gotûbêja bikarhêner:Guherto|gotûbêj]]) 17:27, 14 çiriya paşîn 2020 (UTC) {{şîrove}} [[girêz]] -- [[Bikarhêner:Mihemed Qers|Mihemed Qers]] ([[Gotûbêja bikarhêner:Mihemed Qers|gotûbêj]]) 20:42, 9 adar 2021 (UTC) == [[waris]] == / [[wêris]] -- [[Bikarhêner:Guherto|Guherto]] ([[Gotûbêja bikarhêner:Guherto|gotûbêj]]) 17:03, 6 çiriya pêşîn 2020 (UTC) {{rfk|waris|r=504}} -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 16:00, 26 kanûna paşîn 2025 (UTC) === Gotûbêj === <!--Li jêr fikrên xwe binivîsin. {{şîrove}} --> {{şîrove}} == [[rêveber]] == /birêveber. Ber alî dike "birêveber" lê bahwer im "rêveber" bêhtir tê bikaranîn. -- [[Bikarhêner:Guherto|Guherto]] ([[Gotûbêja bikarhêner:Guherto|gotûbêj]]) 19:50, 12 çiriya pêşîn 2020 (UTC) {{rfk|birêveber|r=86}} -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 15:15, 26 kanûna paşîn 2025 (UTC) === Gotûbêj === <!--Li jêr fikrên xwe binivîsin. {{şîrove}} --> {{şîrove}} Bi min her çiqas lêker "''bi rê ve birin''" be jî halê standard wek "''rêveber''" be baştir e. -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 15:15, 26 kanûna paşîn 2025 (UTC) == [[jêk cuda bûn]] == /jê cuda bûn. -- [[Bikarhêner:Guherto|Guherto]] ([[Gotûbêja bikarhêner:Guherto|gotûbêj]]) 15:15, 15 çiriya pêşîn 2020 (UTC) {{rfk|ji hev cihê bûn, ji hev cuda bûn|r=230}} Forma "jêk" (ji yek) di vê ferhengê de derbas nabe. -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 15:13, 26 kanûna paşîn 2025 (UTC) === Gotûbêj === <!--Li jêr fikrên xwe binivîsin. {{şîrove}} --> {{şîrove}} [[jê cuda bûn]]--[[Bikarhêner:Mihemed Qers|Mihemed Qers]] ([[Gotûbêja bikarhêner:Mihemed Qers|gotûbêj]]) 18:18, 7 adar 2021 (UTC) {{şîrove}} Di "Cuda bûn" / "cihê bûn"ê de jixwe du tişt ji hev cuda dibin, lewma bi min madeyeke wek "''jê cuda bûn''" / "''jê cihê bûn''" (ji tiştekî cuda bûn / ji tiştekî cihê bûn) nehewce (neferhengî) ye. Forma "''jêk''" ''(ji yek)'' di ferhenga 'Ji bo Rastnivîsînê Ferhenga Kurdî (Kurmancî)-Tirkî ya Nû' de derbas nabe. Lewma bi dîtina min her du formên mewcûd jî nestandard in, lê belê ya standard "'''''ji hev cuda bûn'''''" e. -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 15:13, 26 kanûna paşîn 2025 (UTC) == [[pakêt]] == /paket. -- [[Bikarhêner:Guherto|Guherto]] ([[Gotûbêja bikarhêner:Guherto|gotûbêj]]) 19:04, 24 çiriya pêşîn 2020 (UTC) {{rfk||}} -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 14:56, 26 kanûna paşîn 2025 (UTC) === Gotûbêj === <!--Li jêr fikrên xwe binivîsin. {{şîrove}} --> {{şîrove}} Di Ji bo Rastnivîsînê Ferhenga Kurdî (Kurmancî)-Tirkî ya Nû de (r. 346) ji bo halê standard yê kelîmeya "''parsêl''"ê "''parsel''" nîşan dane. Ev jî wekî wî ye, '''lewma halê standard "''paket''" e''', lê ne "''pakêt''". Ji ber ku telafûza "''pakêt''"ê jî li gor yê din zehmettir e. -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 14:56, 26 kanûna paşîn 2025 (UTC) == [[hevaltî]] == / [[hevalî]]. Hevaltî rasttir e û bêhtir tê bikaranîn. -- [[Bikarhêner:Guherto|Guherto]] ([[Gotûbêja bikarhêner:Guherto|gotûbêj]]) 21:32, 31 çiriya pêşîn 2020 (UTC) {{rfk|hevalî, hevaltî|r=200}} Di vê ferhengê de her du formên wek "''hevaltî''" û "''hevalî''" jî wek standard hatine qebûlkirin. -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 14:52, 26 kanûna paşîn 2025 (UTC) === Gotûbêj === <!--Li jêr fikrên xwe binivîsin. {{şîrove}} --> {{şîrove}} Bi min divê em tenê yekî ji wan wek ya standard bibijêrin. Ew jî divê '''''hevaltî''''' be. -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 14:52, 26 kanûna paşîn 2025 (UTC) == [[êzidî]] == [[êzîdî]]/[[êzdî]] - -[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 19:04, 11 çiriya paşîn 2020 (UTC) {{rfk|êzidî|r=158}} û wek kelîmeya jêçêbûyî: "êzidîtî". -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 14:48, 26 kanûna paşîn 2025 (UTC) === Gotûbêj === <!--Li jêr fikrên xwe binivîsin. {{şîrove}} --> {{şîrove}} [[êzdî]]--[[Bikarhêner:Mihemed Qers|Mihemed Qers]] ([[Gotûbêja bikarhêner:Mihemed Qers|gotûbêj]]) 18:16, 7 adar 2021 (UTC) == [[potîn]] == [[putîn]]--[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 18:04, 14 çiriya paşîn 2020 (UTC) {{rfk||}} -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 19:59, 19 adar 2025 (UTC) === Gotûbêj === <!--Li jêr fikrên xwe binivîsin. {{şîrove}} --> {{şîrove}} Di pir cihan de wek "potîn" derbas bûye, lê min li ti derê forma "putîn" nedît. Lewma bi min eşkere ye ku halê standard wek "'''potîn'''" e. Û ger forma din bi temamî bêçavkanî be, em wê formê jî jê bibin. -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 19:59, 19 adar 2025 (UTC) == [[diwazdeh]] == [[diwazdeh]] / [[dazde]] {{rfk|duwazdeh|r=142}} -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 00:19, 4 çiriya paşîn 2024 (UTC) === Gotûbêj === <!--Li jêr fikrên xwe binivîsin. {{şîrove}} --> {{şîrove}} == [[xwende]] == [[xwenda]]--[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 18:47, 25 çiriya paşîn 2020 (UTC) {{rfk|xwende|r=524}} -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 00:17, 4 çiriya paşîn 2024 (UTC) === Gotûbêj === <!--Li jêr fikrên xwe binivîsin. {{şîrove}} --> {{şîrove}} Bi min ji bo kelîmeya "'''xwende'''" divê forma standard "xwende" be, ne ku "xwendî". Maneya kesê perwerdegirtî û kesê du-kelîme-xwendî divê ne eynî be. Lewma ez kelîmeya "xwende" pêşnîyar dikim ji bo awayê standard. -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 00:17, 4 çiriya paşîn 2024 (UTC) == [[pêşniyaz]] == [[pêşniyaz]] / [[pêşniyar]] / [[pêşniyaz kirin]] / [[pêşniyar kirin]]--[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 19:06, 25 çiriya paşîn 2020 (UTC) {{rfk|pêşnîyaz|r=359}} Kelîmeyên jêçêbûyî ên "pêşnîyaz kirin", "pêşnîyazî", "pêşnîyazkirin" jî wek standard hatine nîşandan. -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 00:12, 4 çiriya paşîn 2024 (UTC) :Dibe ku ev peyv pêşniyaz be ne pêşn(î)yaz. Ev peyv hîn bêtir nêzî hizir e. Lewra niyaz wateya daxwazê dide lê niyar wateya neyartiyê dide. Divê ev peyv pêşniyaz be. [[Bikarhêner:Mûhemmed Seîd|Mûhemmed Seîd]] ([[Gotûbêja bikarhêner:Mûhemmed Seîd|gotûbêj]]) 21:03, 28 tebax 2025 (UTC) === Gotûbêj === <!--Li jêr fikrên xwe binivîsin. {{şîrove}} --> {{şîrove}} {{r|Balyozxane}} Wê çi ê standardkirin? Yan ti dixwazê ya standard werê guhertin? -- [[Bikarhêner:Guherto|Guherto]] ([[Gotûbêja bikarhêner:Guherto|gotûbêj]]) 20:06, 25 çiriya paşîn 2020 (UTC) :{{r|Guherto}} Nabînî pêşniyar dibêje pêşniyaz rast e pêşniyaz kirin dibêje pêşniyar kirin rast e. Kîjan rast e? --[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 20:21, 25 çiriya paşîn 2020 (UTC) ::Qusûrê ne mêzêne, mi tenê rûpela pêşniyaz vekir û dît ku dibêjê pêşniyaz / pêşniyar. -- [[Bikarhêner:Guherto|Guherto]] ([[Gotûbêja bikarhêner:Guherto|gotûbêj]]) 20:56, 25 çiriya paşîn 2020 (UTC) == [[kamil]] == [[kamil]], [[kamîl]], [[kamul]]--[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 20:02, 29 çiriya paşîn 2020 (UTC) {{rfk||}} -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 21:49, 3 çiriya paşîn 2024 (UTC) === Gotûbêj === <!--Li jêr fikrên xwe binivîsin. {{şîrove}} --> {{şîrove}} Ev peyveke Erebîye, lê dema ku Kurd wê bilêv dikin ″kamil″ dibêjin.Lewma ″kamil″ rasttire, ″kamîl û kamul″ bilêvkirinên tirk û hindîyane. [[Bikarhêner:Mihemed Qers|Mihemed Qers]] ([[Gotûbêja bikarhêner:Mihemed Qers|gotûbêj]]) 17:26, 7 adar 2021 (UTC) {{şîrove}} Ya standard bi eşkereyî "kamil" e. -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 21:49, 3 çiriya paşîn 2024 (UTC) : Lê di Ji bo Rastnivîsînê Ferhenga Kurdî (Kurmancî) - Tirkî ya Nû ya M. Malmîsanij û yên din de cih dane madeya "tekamil" û formên wê yên nestandard ên wek ''tekamîl'', ''tekamul''. Lewma ya standard li gor vê ferhengê dide "'''kamil'''". -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 21:54, 3 çiriya paşîn 2024 (UTC) = Daxwazên standardkirinê: 2021 = == [[fêrgeh]] == [[fêrgeh]] / [[fêrge]]--[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 16:58, 5 kanûna paşîn 2021 (UTC) {{rfk||}} -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 21:36, 3 çiriya paşîn 2024 (UTC) === Gotûbêj === <!--Li jêr fikrên xwe binivîsin. {{şîrove}} --> {{şîrove}} [[fêrgeh]] bê guman rasttire, ev tîpa ″h″ di gellek peyvanda li hin herêman nayê bilêvkirin.Lê ev nayê manê ku ″h″ tunne. {{şîrove}} Herçend ev kelîme di Ferhenga Kurdî ya Rastnivîsînê ya M. Malmîsanij û yên din de derbas nabe jî, ji madeyên "azmûngeh" (r. 54), "dadgeh" (r. 120), "dangeh" (r. 122) û yên din tê famkirin ku ji bo paşgira "-geh"ê (formên din: "-ge") ya standard "-geh" e. Lewma em karin bêjin ku ji bo vê kelîmeyê divê ya standard bibe "fêrgeh". -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 21:36, 3 çiriya paşîn 2024 (UTC) == [[bêhêwî]] == [[bêhewî]] Standardkirin hewce ye. -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 18:52, 23 kanûna paşîn 2021 (UTC) {{rfk|hewî|r=202}} Ji bo maneya "kuma" awayê standard wekî "hewî" hatiye nîşandan. -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 21:25, 3 îlon 2023 (UTC) === Gotûbêj === <!--Li jêr fikrên xwe binivîsin. {{şîrove}} --> {{şîrove}} Peyvên "hewî" û "hêwî" her du jî xweyî çendîn maneyan in. Lewma ger beralîkirin were danîn divê maneya ku jê tê beralîkirin jî were nivîsîn. -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 21:25, 3 îlon 2023 (UTC) == [[pêşnûma]] == [[pêşnima]] Divê bên standardkirin. Bi îxtîmalekî mezin ya standard "pêşnima" ye. -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 21:20, 12 sibat 2021 (UTC) '''Eynî mijar li jêr hatîye vekirin. Ji bo standardkirinê binêrin ya jêr.''' -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 21:15, 3 çiriya paşîn 2024 (UTC) '''Gotûbêj:''' <!--Li jêr fikrên xwe binivîsin. {{şîrove}} --> {{şîrove}} [[pêşnima]]--[[Bikarhêner:Mihemed Qers|Mihemed Qers]] ([[Gotûbêja bikarhêner:Mihemed Qers|gotûbêj]]) 18:13, 7 adar 2021 (UTC) == [[jenosîd]] == [[jînoside]] --[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 14:39, 13 sibat 2021 (UTC) {{rfk||}} -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 21:13, 3 çiriya paşîn 2024 (UTC) === Gotûbêj === <!--Li jêr fikrên xwe binivîsin. {{şîrove}} --> {{şîrove}} "jînoside" an "jînosid" ? Min nivîsandinên formên "jînosideyê" an "jînosideya" pirr nedîtiye...--[[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 14:48, 13 sibat 2021 (UTC) {{şîrove}} Bi min ya standard "[[jenosîd]]" e. Halên din ên "cenosîd", "jînosîd", "jînosid" kêm-li-kar in. -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 21:13, 3 çiriya paşîn 2024 (UTC) == [[kesaxtin]] == - [[kezaxtin]] Standardkirin hewce ye. Bi ya min ya rast "kesaxtin" e, yê din xelet e. -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 12:57, 14 sibat 2021 (UTC) {{rfk|kesaxtin|r=250}} -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 21:07, 3 çiriya paşîn 2024 (UTC) === Gotûbêj === <!--Li jêr fikrên xwe binivîsin. {{şîrove}} --> {{şîrove}} == [[derazîng]] == / [[derazînk]] Standardkirin lazim e. -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 22:54, 19 sibat 2021 (UTC) {{rfk|derazînk|r=127}} -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 19:53, 30 çiriya pêşîn 2024 (UTC) === Gotûbêj === <!--Li jêr fikrên xwe binivîsin. {{şîrove}} --> {{şîrove}} {{r|Bikarhêner}} bira navê sernavî neguherîne. Parametreya yekem ya şablona {{ş|ds}} divê sernavê vê gotûbêjê be.--[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 23:51, 19 sibat 2021 (UTC) == [[rovî]] == [[rûvî]]/[[rîvî]]. Bi ya min ji bo maneya "guhandarek" rovî zêdetir tê bikaranîn. Bi maneya "hinav" jî du rûpel ([[rûvî]]/[[rîvî]]) hene.--[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 21:19, 19 adar 2021 (UTC) {{rfk|rûvî|r=423}} Bi maneya "ince bağırsak". -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 18:40, 30 çiriya pêşîn 2024 (UTC) {{rfk|rovî|r=419}} Bi maneya "tilkî". -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 18:41, 30 çiriya pêşîn 2024 (UTC) === Gotûbêj === <!--Li jêr fikrên xwe binivîsin. {{şîrove}} --> {{şîrove}} == [[esman]] == [[esman]] | [[asman]] | [[ezman]] --[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 18:00, 24 adar 2021 (UTC) {{rfk|esman|r=152}} -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 18:38, 30 çiriya pêşîn 2024 (UTC) === Gotûbêj === <!--Li jêr fikrên xwe binivîsin. {{şîrove}} --> {{şîrove}} Ji ber ku ji didu peyvan pêk tê wek [[asê]]+[[man]]. Ezê peyva [[asman]] pêşniyar bikim. [[Bikarhêner:Key Mîrza|Key Mîrza]] ([[Gotûbêja bikarhêner:Key Mîrza|gotûbêj]]) 16:30, 10 gulan 2021 (UTC) == [[niha]] == [[niha]] / [[niho]]--[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 21:22, 25 adar 2021 (UTC) {{rfk|niha|r=333}} -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 18:35, 30 çiriya pêşîn 2024 (UTC) === Gotûbêj === <!--Li jêr fikrên xwe binivîsin. {{şîrove}} --> {{şîrove}} == [[sûper]] == Standardkirinê teleb dikim. -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 11:55, 26 adar 2021 (UTC) {{rfk||}} -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 21:27, 3 îlon 2023 (UTC) === Gotûbêj === <!--Li jêr fikrên xwe binivîsin. {{şîrove}} --> {{şîrove}} Li gorî telefûzê ya standard "super" e, kes halê dirêjkirî nabêje, bi qasî zanîna min. -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 17:48, 30 çiriya pêşîn 2024 (UTC) == [[sûperlatîv]] == Standardkirinê teleb dikim. -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 11:57, 26 adar 2021 (UTC) {{rfk||}} -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 21:28, 3 îlon 2023 (UTC) === Gotûbêj === <!--Li jêr fikrên xwe binivîsin. {{şîrove}} --> {{şîrove}} Bi ya min ya rast "super" û "superlatîv" e, ji ber ku gava em bi lêv dikin em wek "superlatîv" bi lêv dikin, ne wek "sûperlatîv". -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 11:57, 26 adar 2021 (UTC) == [[radîkalîzm]] == /[[radikalîzm]]--[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 16:21, 30 nîsan 2021 (UTC) {{rfk|}} -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 17:46, 30 çiriya pêşîn 2024 (UTC) === Gotûbêj === <!--Li jêr fikrên xwe binivîsin. {{şîrove}} --> {{şîrove}} {{r|Balyozxane}} Bi min peyveke wekî "radikalîzm" tine ye û bi xeletî wisa hatiye qeydkirin. -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 10:16, 17 tebax 2022 (UTC) == [[texdîr]] == [[teqdîr]] standardkirin hewce ye. Bi min "teqdîr" standardtir e. -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 10:52, 18 gulan 2021 (UTC) {{rfk|}} -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 17:45, 30 çiriya pêşîn 2024 (UTC) === Gotûbêj === <!--Li jêr fikrên xwe binivîsin. {{şîrove}} --> {{şîrove}} Pir eşkere ye ku ya standard "'''teqdîr'''" e. -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 17:45, 30 çiriya pêşîn 2024 (UTC) == [[tayîn]] == [[teyîn]] / [[tayîn]] / [[teîn]] / [[tayin]]. Standardkirin hewce ye. -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 09:30, 9 tîrmeh 2021 (UTC) {{rfk|}} -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 23:55, 29 çiriya pêşîn 2024 (UTC) === Gotûbêj === <!--Li jêr fikrên xwe binivîsin. {{şîrove}} --> {{şîrove}} Mirov di navbera "tayîn" û "tayin" de bêqerar dimîne. Lê bi min divê wek halê standard "'''tayîn'''" were dîyarkirin. Ji ber ku zêdetir li kar e (di lêgera Google Searche de jî zêdetir "tayîn" derdikeve, ''formata lêgerînê: wek "tayîna xwe" / "tayina xwe"''). -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 23:55, 29 çiriya pêşîn 2024 (UTC) == [[nod]] == * [[not]] Ev made li vir heye: [[Wîkîferheng:Daxwazên_standardkirinê#not,_nod]] Bi şaşî tekraren hatîye tevlîkirin. Ji bo agahîyan lê binêrin. -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 23:00, 29 çiriya pêşîn 2024 (UTC) '''Gotûbêj:''' <!--Li jêr fikrên xwe binivîsin. {{şîrove}} --> {{şîrove}} {{r|Zanavano}}. Bnr. [[WF:Rêzikên standardkirinê]]--[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 17:28, 1 çiriya pêşîn 2021 (UTC) = Daxwazên standardkirinê: 2022 = == [[xizar]] == [[xizar]], [[xîzar]]. Standardkirin hewce ye.{{bêîmze|Bikarhêner}} {{rfk|}} -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 23:46, 29 çiriya pêşîn 2024 (UTC) === Gotûbêj === <!--Li jêr fikrên xwe binivîsin. {{şîrove}} --> {{şîrove}} Forma xizar hema bêje li ti derê tine ye. Lewma halê standard divê "xîzar" be. -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 23:46, 29 çiriya pêşîn 2024 (UTC) == [[Nû Zelenda]] == [[Zelandaya Nû]] zêdetir tê bikaranîn.[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 23:18, 9 kanûna pêşîn 2022 (UTC) {{rfk|}} -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 23:39, 29 çiriya pêşîn 2024 (UTC) === Gotûbêj === <!--Li jêr fikrên xwe binivîsin. {{şîrove}} --> {{şîrove}} Di '''Rêbera Rastnivîsînê''' ya Komxebata Kurmancîyê de (r. 37) wek "Zelandaya Nû" hatîye qeydkirin. Di kitêba '''Rastnuştişê''' ya Gruba Xebatê ya Vateyî de jî ev peyv wek "Zelandaya Newîye" (r. 67) hatîye qeydkirin. Lewma bi min divê halê standard bibe "Zelandaya Nû." -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 23:39, 29 çiriya pêşîn 2024 (UTC) = Daxwazên standardkirinê: 2023 = == [[pirzik]] == [[pizik]] --[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 23:37, 15 kanûna paşîn 2023 (UTC) * {{rfk|pizrik}} --[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 23:37, 15 kanûna paşîn 2023 (UTC) === Gotûbêj === <!--Li jêr fikrên xwe binivîsin. {{şîrove}} --> {{şîrove}} Bi min forma wek "{{g|ku|pizrik}}" jî heye û divê ew jî were standardkirin. -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 19:53, 31 tebax 2023 (UTC) == [[bûro]] == {{g|ku|bûro}} / {{g|ku|buro}} / {{g|ku|buriyo}} standardkirin hewce ye. --- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 21:06, 22 kanûna paşîn 2023 (UTC) {{rfk|}} -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 19:58, 31 tebax 2023 (UTC) === Gotûbêj === <!--Li jêr fikrên xwe binivîsin. {{şîrove}} --> {{şîrove}} Di ''Rêbera Rastnivîsînê'' ya Komxebata Kurmancî de di rûpela 139em de nimûneyeke wek "'''buroya wî'''" hatiye dayîn. Ji vê nimûneyê mirov dikare bêje ku ji bo vê peyvê awayê standard wekî "buro" dibînin. -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 14:53, 3 îlon 2023 (UTC) == [[fezîlet]] == [[fazîlet]]--[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 11:47, 26 kanûna paşîn 2023 (UTC) === Gotûbêj === <!--Li jêr fikrên xwe binivîsin. {{şîrove}} --> {{şîrove}} Ev peyv jî ji erebî tê. Herçiqas di hin peyvên reh-erebî de (wek nimûne "edalet") ji bo eyna erebî "e" hatibe tercîhkirin jî bi min ji bo em li vir nêzî telafûza di pratîkê de bibin, forma bi "e"yê neyê tercîhkirin jî dibe. Lewma ez "fazîlet"ê pêşnîyar dikim. -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 22:57, 29 çiriya pêşîn 2024 (UTC) == [[Uman]] == {{g|ku|Uman}}, {{g|ku|Oman}}, {{g|ku|Iman}}, {{g|ku|'Iman}}, {{g|ku|'Uman}}, {{g|ku|Umman}} Standardkirin hewce ye. {{rfk|}} === Gotûbêj === <!--Li jêr fikrên xwe binivîsin. {{şîrove}} --> {{şîrove}} Di '''''Rêbera Rastnivîsînê''''' ya Komxebata Kurmancîyê de awayê "'''Uman'''" wekî standard hatiye nîşandan. -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 01:34, 3 nîsan 2023 (UTC) == [[hejî]] == {{g|ku|hejî}}, {{g|ku|hêja}} Standardkirin hewce ye. {{rfk|}} === Gotûbêj === <!--Li jêr fikrên xwe binivîsin. {{şîrove}} --> {{şîrove}} {{r|Ferhengvan}} Bi min ev herdu, wekî formên eynî peyvê dixuyin. Lewma standardkirinê teleb dikim. Her çiqas berçav be ku awayê stadard "hêja" ye jî, li vir teleb dikim. Lê ger ne formên eynî peyvê bin, xêra xwe li vir binivîsin. -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 01:52, 7 nîsan 2023 (UTC) ::{{Silav|Bikarhêner}} Rast dibêjî, "hejî" formeke devokî (behdînî) ya peyva "hêja" ye. --[[Bikarhêner:Ferhengvan|Ferhengvan]] ([[Gotûbêja bikarhêner:Ferhengvan|gotûbêj]]) 20:31, 7 nîsan 2023 (UTC) == [[sererast]] == {{q|ku|sererast}}, {{q|ku|serrast}} Standardkirin hewce ye. Bi min xuya ye ku forma standard "sererast" e. -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 10:02, 25 nîsan 2023 (UTC) {{rfk|serrast, serrast kirin|r=437}} -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 19:41, 31 tebax 2023 (UTC) === Gotûbêj === <!--Li jêr fikrên xwe binivîsin. {{şîrove}} --> {{şîrove}} Bila piştî gihîştina netîceyê, standardkirina formên din ên wekî "sererastkirin" / "serrastkirin", "sererast kirin" / "serrast kirin" jî neyê jibîrkirin. Bi min divê forma standard bibe "sererast". -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 19:41, 31 tebax 2023 (UTC) == [[fiqih]] == {{g|ku|fiqh}} / {{g|ku|fiqih}} Standardkirin hewce ye. -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 21:16, 30 nîsan 2023 (UTC) {{rfk|}} -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 21:16, 30 nîsan 2023 (UTC) === Gotûbêj === <!--Li jêr fikrên xwe binivîsin. {{şîrove}} --> {{şîrove}} Di ''Rêbera Rastnivîsînê'' ya Komxebata Kurmanciyê de (r.52, 53) behsa vê mijarê kirine: Bi sernavê "'''Nivîsîna hin bêjeyên bîyanî yên yekkîteyî ku di kurmancîyê da dibin dukîteyî'''", wek nimûne jî "'''aqil ✓''', '''aql ✗'''", "fikir ✓, fikr ✗", "qebir ✓, qebr ✗", "qebiz ✓, qebz ✗", "qedir ✓, qedr ✗", "qehir ✓, qehr ✗"... Li binî jÎ dibêjin divê li gel îzafeyê [i] bê parastin, wekî "aqilê min ✓, aqlê min ✗", "fikira min ✓, fikra min ✗", "qebira min ✓, qebra min ✗"... Lewma bi dîtina min, li gor vê rêberê divê wekî "fiqih" bibe ya standard. -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 19:38, 31 tebax 2023 (UTC) == [[îqaz]] == {{g|ku|îqaz}} - {{g|ku|îkaz}}. Standardkirin hewce ye. Piştî qerardana li ser forma standard, divê peyvên girêdayî wan jî yên wek "îqazker", "îqaz kirin" hwd jî bên guherandin. -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 23:14, 19 gulan 2023 (UTC) {{rfk|}} -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 23:14, 19 gulan 2023 (UTC) === Gotûbêj === <!--Li jêr fikrên xwe binivîsin. {{şîrove}} --> {{şîrove}} Di ''Rêbera Rastnivîsînê'' ya Komxebata Kurmanciyê de (r. 80) dibêjin "'''[q]ya bêjeyên biyanî neke [k]'''". "k"ya vê peyvê jî bi eslê xwe "[q]" ye, û lewma divê awayê standard bibe "îqaz". -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 19:22, 31 tebax 2023 (UTC) == [[hundirîn]] == {{g|ku|hindirîn}}, {{g|ku|hundirîn}} standardkirin hewce ye. -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 17:41, 27 gulan 2023 (UTC) {{rfk|hundir|r=217}} Ji ber ku awayê "hundir" wek standard hatiye bijartin, li gor vê "hundirîn" jî dibe awayê standard. -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 21:40, 29 tebax 2023 (UTC) === Gotûbêj === <!--Li jêr fikrên xwe binivîsin. {{şîrove}} --> {{şîrove}} == [[wasita]] == {{g|ku|wasita}}, {{g|ku|wesite}}, {{g|ku|wasîte}}, {{g|ku|wasta}}, {{g|ku|wesita}}, {{g|en|wesita}}, {{g|en|wesîte}}, {{g|en|wasite}} standardkirin hewce ye. -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 09:06, 21 hezîran 2023 (UTC) {{rfk|wasîte|r=504}} === Gotûbêj === <!--Li jêr fikrên xwe binivîsin. {{şîrove}} --> {{şîrove}} == [[qebe]] == {{g|ku|qebe}} / {{g|ku|qeba}} Standardkirin hewce ye. -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 20:10, 27 tebax 2023 (UTC) {{rfk|}} --[[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 21:35, 29 tebax 2023 (UTC) === Gotûbêj === <!--Li jêr fikrên xwe binivîsin. {{şîrove}} --> {{şîrove}} Bi min forma "qeba" baştir e ji bo halê standard. Helbet gava dîyarkirina halê standand divê em halên emilandinê û peyvên jêçêbûyî jî bifikirin. Ji bo vê peyvê wek "qebetî" / "qebatî". -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 22:26, 29 çiriya pêşîn 2024 (UTC) == [[sewgûr]] == {{g|ku|sewgur}} / {{g|en|sewgûr}} / {{g|en|sewgir}} / {{g|en|sewgor}} Standardkirin hewce ye. -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 21:33, 29 tebax 2023 (UTC) {{rfk|sewgurî, sewgura sibê|r=439}} Di ferhengê de wek "sewgurî" û wek "sewgura sibê" hatiye qeydkirin. -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 21:33, 29 tebax 2023 (UTC) === Gotûbêj === <!--Li jêr fikrên xwe binivîsin. {{şîrove}} --> {{şîrove}} == [[Danmarka]] == [[Danîmarka]] zêdetir tê bikaranîn--[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 19:54, 3 îlon 2023 (UTC) {{rfk|}} Di vê ferhengê de peyvên "danîmarkî" û "danîmarqî" ber bi rûpela "danmarkî" ve yê hatine alîkirin. Lewma mirov fam dike ku navê vî welatî li gorî vê ferhengê "'''Danmarka'''" ye. -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 20:12, 3 îlon 2023 (UTC) :@[[Bikarhêner:Bikarhêner|Bikarhêner]] Bi min ew mantiqeke şaş e. Loma em li ferhengên din jî binêrin baştir be. Ez fêm nakim çawa ferhengeke rastnivîsînê navên welatan qeyd nekirine. [[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 20:27, 3 îlon 2023 (UTC) === Gotûbêj === <!--Li jêr fikrên xwe binivîsin. {{şîrove}} --> {{şîrove}} Bi ya ''Rêbera Rastnivîsînê'' ya Komxebata Kurmancî jî awayê standard "'''Danîmarka'''" ye (r. 31). Ez bixwe jî ji bo awayê standard "Danîmarka"yê pêşniyar dikim. -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 20:55, 3 îlon 2023 (UTC) == [[dijmîn]] == {{g|ku|dijmîn}}, {{g|ku|dijûn}} Standardkirin lazim e. -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 16:57, 12 îlon 2023 (UTC) {{rfk|dijûn|r=135}} -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 22:04, 18 hezîran 2024 (UTC) === Gotûbêj === <!--Li jêr fikrên xwe binivîsin. {{şîrove}} --> {{şîrove}} == [[fîlmografî]] == [[filmografî]] :--[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 12:38, 20 îlon 2023 (UTC) {{rfk|fîlm|r=166}} Şiklê standard ji bo peyva "film / fîlm / fîlim" wek "fîlm" hatîye nîşandan. Lewma li gor vê awayê standard dibe "'''fîlmografî'''". -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 22:07, 18 hezîran 2024 (UTC) === Gotûbêj === <!--Li jêr fikrên xwe binivîsin. {{şîrove}} --> {{şîrove}} == [[not]], [[nod]] == [[not]], [[nod]]--[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 20:23, 11 çiriya pêşîn 2023 (UTC) {{rfk|nod|r=338}} -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 22:09, 18 hezîran 2024 (UTC) === Gotûbêj === <!--Li jêr fikrên xwe binivîsin. {{şîrove}} --> {{şîrove}} == [[afrîkî]] == [[afrîkî]] / [[afrîkayî]] ?--[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 18:06, 9 çiriya paşîn 2023 (UTC) {{rfk|afrîkayî|r=41}} -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 22:11, 18 hezîran 2024 (UTC) === Gotûbêj === <!--Li jêr fikrên xwe binivîsin. {{şîrove}} --> {{şîrove}} == [[eware]] == [[eware]]/[[aware]] :Bi maneya ''avare/aylak/serseri'' {{rfk|153}} :Ji bo maneya ''penaber'' di vê ferhengê de standardek tine ye. Loma divê du rûpel hebe ji bo kelîmeya kurmancî ya eware û yekî din ji bo maneya penaber. --[[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 12:14, 8 sibat 2024 (UTC) === Gotûbêj === <!--Li jêr fikrên xwe binivîsin. {{şîrove}} --> {{şîrove}} Di ferhenga ''Ji bo Rastnivîsînê Ferhenga Kurdî (Kurmancî)-Tirkî ya Nû'' de jixwe standarda ji bo vê peyvê heye. Ji bo maneya penaber jî hebûna vê maneyê bi min bişibhe ye, wekî din ''ger hebe jî'' ji ber ku ji berhirefkirina maneya "''yê derbeder û bê cih û mal''" hatîye çêkirin, dîsa girêdayî wê maneya eslî ya derbiderîyê ye, lewma divê li ser rûpelekî werin standardkirin û ew rûpel jî pêşnîyara di kitêba nav-zikirkirî de be baştir e. -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 22:22, 18 hezîran 2024 (UTC) == [[wesetî]] == [[wasatî]] / [[wesetî]] standardkirin hewce ye. -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 10:48, 29 adar 2024 (UTC) {{rfk|wesetî|r=506}} -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 22:27, 18 hezîran 2024 (UTC) === Gotûbêj === <!--Li jêr fikrên xwe binivîsin. {{şîrove}} --> {{şîrove}} == [[se direwît, karwan bi rêka xwe diçît]] == {{g|ku|se direwît, karwan bi rêka xwe diçît}} / {{g|ku|se direwin, karwan diborin}} / {{g|ku|seh direye kerwan dibihore}} Divê ev her sê form werin standardkirin. -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 14:51, 16 hezîran 2024 (UTC) {{rfk|}} -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 08:26, 7 tîrmeh 2024 (UTC) === Gotûbêj === <!--Li jêr fikrên xwe binivîsin. {{şîrove}} --> {{şîrove}} Bi min ya standardtir "'''seg direye karwan dibihure'''" ye ("seg", ''Ji Bo Rastnivîsînê Ferhenga Kurdî (Kurmancî) - Tirkî ya Nû'', r. 429; "reyîn", r. 410; "karwan", r. 240; "bihurîn", r. 83). Wekî form (di qismê "Herwiha" de) em "'''bi ewtîna seyan, ji rê namîne karwan'''" jî nîşan bidin. Lê ji alîyê xwedîçavkanîbûnê ve jî divê werin kontrolkirin. Min ji bo "''bi ewtîna seyan, ji rê namîne karwan''" çavkanî peyda nekir, min ji bo "''seg direye karwan dibihure''" jî tenê çavkanîyekê peyda kir ([https://www.tirejafrin.com/pdf/Pend%20.pdf ''Pend û Peng''], Bîlal Hesen, di kitêbê de wek "seh direye kerwan dibihore" derbas dibe). -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 08:26, 7 tîrmeh 2024 (UTC) == [[serobino bûn]] == {{g|ku|serobino bûn}} / {{g|ku|serûbin bûn}} Standardkirin hewce ye. -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 16:21, 14 tebax 2024 (UTC) {{rfk|serûbin|r=438}} "serûbin bûn, serûbin kirin, serûbinbûn, serûbinkirin, serûbinkirî" wek peyvên jêçêbûyî hatine nîşandayîn. -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 12:19, 29 çiriya pêşîn 2024 (UTC) === Gotûbêj === <!--Li jêr fikrên xwe binivîsin. {{şîrove}} --> {{şîrove}} == [[sanî]] == [[sanî]] / [[saniye]] {{rfk|}} -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 13:45, 29 çiriya pêşîn 2024 (UTC) === Gotûbêj === <!--Li jêr fikrên xwe binivîsin. {{şîrove}} --> {{şîrove}} Ez dibêjim ber saniye be. [[Bikarhêner:Guherto|Guherto]] ([[Gotûbêja bikarhêner:Guherto|gotûbêj]]) 15:22, 1 îlon 2024 (UTC) {{şîrove}} Ez dibêjim bila "sanîye" be. Em wek sanîye telafûz dikin. -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 13:45, 29 çiriya pêşîn 2024 (UTC) :@[[Bikarhêner:Bikarhêner|Bikarhêner]] "Sanîye" çênabe. Li vir em "îy" nanivîsînin. [[Bikarhêner:Guherto|Guherto]] ([[Gotûbêja bikarhêner:Guherto|gotûbêj]]) 13:34, 10 çiriya paşîn 2024 (UTC) == [[pêşnûma]] == [[pêşnûma]] / [[pêşnima]] Standardkirin lazim e. -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 18:00, 29 çiriya pêşîn 2024 (UTC) {{rfk|}} -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 18:00, 29 çiriya pêşîn 2024 (UTC) === Gotûbêj === <!--Li jêr fikrên xwe binivîsin. {{şîrove}} --> {{şîrove}} Bi min divê "pêşnima" be. Formên bi "u"yê zahfê caran nayên emilandin. -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 18:00, 29 çiriya pêşîn 2024 (UTC) == [[payîz]] == [[payîz]] / [[payiz]] Standardkirin hewce ye. -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 22:12, 29 çiriya pêşîn 2024 (UTC) {{rfk|payîz|347}} -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 22:12, 29 çiriya pêşîn 2024 (UTC) === Gotûbêj === <!--Li jêr fikrên xwe binivîsin. {{şîrove}} --> {{şîrove}} == [[behîv]] == {{g|ku|behîv}} / {{g|ku|bahîv}} Standardkirin hewce ye. -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 11:41, 26 kanûna paşîn 2025 (UTC) {{rfk|behîv|63}} -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 14:38, 26 kanûna paşîn 2025 (UTC) === Gotûbêj === <!--Li jêr fikrên xwe binivîsin. {{şîrove}} --> {{şîrove}} == [[mitîng]] == [[mitîng]] / [[mîtîng]] Standardkirin hewce ye. -- --[[Bikarhêner:Şêr|Şêr]] ([[Gotûbêja bikarhêner:Şêr|gotûbêj]]) 21:47, 27 kanûna paşîn 2025 (UTC) {{rfk|mîtîng|r=316}} -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 22:43, 1 hezîran 2025 (UTC) === Gotûbêj === <!--Li jêr fikrên xwe binivîsin. {{şîrove}} --> {{şîrove}} == [[rûtîn]] == [[rûtîn]], [[rutîn]] Standardkirin hewce ye. — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 23:47, 18 sibat 2025 (UTC) {{rfk||}} -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 22:42, 1 hezîran 2025 (UTC) === Gotûbêj === <!--Li jêr fikrên xwe binivîsin. {{şirove}} --> {{şirove}} Bi min eşkere ye ku ya standard "'''rutîn'''" e. Peyvên telafûza wan dirêj be, bi "û"yê tên gotin, lê li vir dirêj nayê gotin. Lewma bi "u"ya bêkumik çêtir e. -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 22:42, 1 hezîran 2025 (UTC) == [[parleman]] == [[parleman]] / [[perleman]] / [[parlament]]/[[parlemento]] / [[perlemen]], Standardkirin hewce ye.--[[Bikarhêner:Şêr|Şêr]] ([[Gotûbêja bikarhêner:Şêr|gotûbêj]]) 00:53, 22 sibat 2025 (UTC) {{rfk|parlamento|r=345}} -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 22:39, 1 hezîran 2025 (UTC) === Gotûbêj === {{şîrove}} Di ferhenga "Ji bo Rastnivîsînê Ferhenga Kurdî (Kurmancî)-Tirkî ya Nû" da bi maneya ''meclis''ê wek "parlamento" hatîye qeydkirin, bi maneya ''azayê meclisê'' wek "parlamenter" hatîye qeydkirin. -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 22:39, 1 hezîran 2025 (UTC) == [[sond]] == [[sond]], [[sûnd]]—[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 20:41, 21 adar 2025 (UTC) {{rfk|sond|r=447}} -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 22:35, 1 hezîran 2025 (UTC) === Gotûbêj === <!--Li jêr fikrên xwe binivîsin. {{şirove}} --> {{şirove}} == [[sifet]] / [[sîfet]] == {{rfk|}}--[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 13:41, 1 gulan 2025 (UTC) === Gotûbêj === <!--Li jêr fikrên xwe binivîsin. {{şîrove}} --> {{şîrove}} Bi dîtina min wek "sifet" zêdetir li kar e. (Ger rast transkrîbe kiribin) Di eserên berê yên kurdî de wek "sîfet" hatine gotin. -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 06:29, 31 gulan 2025 (UTC) == [[mane]] == [[mane]], [[mana]]—[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 10:13, 30 gulan 2025 (UTC) {{rfk|mane|r=297}} -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 06:20, 31 gulan 2025 (UTC) === Gotûbêj === {{şirove}} {{r|Bikarhêner}} [https://ferheng.wmezopotamyaye.org/ weqfa mezopotamyaye] dibêje forma standard "mana" ye. Dikarî ji ferhenga rastnivîsînê binêrî? --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 10:18, 30 gulan 2025 (UTC) : {{r|Wikihez}} Di Ferhenga Rastnivîsînê de wek "mane" (jê "mane dan", "manedan", "manedar", "manedarî") hatîye qeydkirin. -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 06:20, 31 gulan 2025 (UTC) == [[memnû]] == {{g|ku|memnû}} {{g|ku|memnûh}} Standardkirin lazim e. -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 22:34, 1 hezîran 2025 (UTC) {{rfk||}} -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 22:34, 1 hezîran 2025 (UTC) === Gotûbêj=== <!--Li jêr fikrên xwe binivîsin. {{şîrove}} --> {{şîrove}} Eşkere ye ku ya standard "'''memnû'''" ye. Forma "memnûh" ne li kar e. -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 22:34, 1 hezîran 2025 (UTC) == [[niha]] == === Gotûbêj === <!--Li jêr fikrên xwe binivîsin. {{şîrove}} --> {{şîrove}} {{rfk|niha|r=333}} [[Bikarhêner:Rewiye tine|Rewiye tine]] ([[Gotûbêja bikarhêner:Rewiye tine|gotûbêj]]) 11:22, 16 sibat 2026 (UTC) == [[gîya]] == === Gotûbêj === <!--Li jêr fikrên xwe binivîsin. {{şîrove}} --> {{şîrove}} {{rfk|gîya|r=180}} [[Bikarhêner:Rewiye tine|Rewiye tine]] ([[Gotûbêja bikarhêner:Rewiye tine|gotûbêj]]) 11:24, 16 sibat 2026 (UTC) Kelîmeya jêçêbûyî: {{g|ku|gîyagezk}} (mê, mane "''ısırgan otu''") -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 19:11, 5 tîrmeh 2026 (UTC) :@[[Bikarhêner:Bikarhêner|Bikarhêner]], @[[Bikarhêner:Rewiye tine|Rewiye tine]] Bi ya min, ev ne meseleya standardkirinê ye lê ya îmlayê ye çûnkî ev problema îy - iy zêde tevlihev e. Dengdanek hewce ye ku bibêje konsensusek heye li ser bikaranîna -îy û ne -iy. Lê dengdanek wisa dê têk biçe ji ber ku hejmara kesên -îy tercih dikin kêmtir e li ser Wikiferhengê. Loma divê ev gotûbêj wek çênebû were tayînkirin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 21:04, 5 tîrmeh 2026 (UTC) ::Bi qenaeta min jî "'''îy'''" rasttir e. Divê em di demên pêş da wî meseleyê hel bikin. Feqet wekî ku te jî got, ji ber ku vê gavê li ser vê qerar nehatîye dayîn, em karin wek xwe bihêlin. -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 07:45, 6 tîrmeh 2026 (UTC) == [[hincet]] == === Gotûbêj === <!--Li jêr fikrên xwe binivîsin. {{şîrove}} --> {{şîrove}} {{rfk|hincet|r=210}} [[Bikarhêner:Rewiye tine|Rewiye tine]] ([[Gotûbêja bikarhêner:Rewiye tine|gotûbêj]]) 11:18, 16 sibat 2026 (UTC) == [[kurmî]] == === Gotûbêj === <!--Li jêr fikrên xwe binivîsin. {{şîrove}} --> {{şîrove}} {{rfk|kurm (navdêr), kurmî (rengdêr)|r=269}} [[Bikarhêner:Rewiye tine|Rewiye tine]] ([[Gotûbêja bikarhêner:Rewiye tine|gotûbêj]]) 08:55, 23 adar 2026 (UTC) :kurmî berbelav e hem jî standardîze bûye bi min. Hem em dibêjin kurm bi gelemperî kirm kêm e. [[Bikarhêner:Bibliophile|Bibliophile]] ([[Gotûbêja bikarhêner:Bibliophile|gotûbêj]]) 10:55, 23 adar 2026 (UTC) ::Lê balkêş e ku rehê xwe yê qedîm zêdetir wekî [[kirm]] xuya dike. Lê etîmolojî nikare bikeve pêşberî bikaranîna giştî peyvekê ji aliyê xelkê ve. Helbet ev fikra min a şexsî ye. Ji bo selameta ferhengê kurdî ev yek gerek e bête çareserkirin. [[Bikarhêner:Bibliophile|Bibliophile]] ([[Gotûbêja bikarhêner:Bibliophile|gotûbêj]]) 11:01, 23 adar 2026 (UTC) == [[tihn]] == [[tihn]], [[tîn]], [[tên]] {{rfk|tîn (mê, mane: ''ısı; hararet, sıcaklık'')|r=488}} -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 19:18, 5 tîrmeh 2026 (UTC) === Gotûbêj === <!--Li jêr fikrên xwe binivîsin. {{şîrove}} --> {{şîrove}} Ez bawer dikim ku ''tîn'' zêdetir tê bikaranîn. == [[nehwirandin]] == [[nehwirandin]], [[norandin]] bnr [[Gotûbêj:norandin]] —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 11:52, 3 tîrmeh 2026 (UTC) {{rfk|nehwirandin|r=328}} -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 19:05, 5 tîrmeh 2026 (UTC) === Gotûbêj === == [[rus]], [[rûsî]] == [[rus]], [[rûs]], [[rûsî]], [[rusî]] bnr. [[Gotûbêja kategoriyê:Rusî]] —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 07:11, 5 tîrmeh 2026 (UTC) {{rfk|rûs, rûsî|r=422}} "rûs" wek navê miletê, "rûsî" wek navê zimanê hatîye qeydkirin. -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 18:57, 5 tîrmeh 2026 (UTC) === Gotûbêj === == [[dûkel]] == {{g|ku|dûkel}} / {{g|ku|dûkêl}} Standardkirin hewce ye. -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 23:14, 19 tîrmeh 2026 (UTC) {{rfk|dûkel (nêr)|r=143}} -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 23:16, 19 tîrmeh 2026 (UTC) === Gotûbêj === <!--Li jêr fikrên xwe binivîsin. {{şîrove}} --> {{şîrove}} nuikh64cg0wa3l5yuw6wlgdk9lqh9ql Bikarhêner:Wikihez/common.js 2 873671 6265693 6265487 2026-07-19T22:15:59Z Wikihez 7344 6265693 javascript text/javascript /*---------QQ.js------------- [[Bikarhêner:Wikihez/Gadget-QQ.js]] [[Bikarhêner:Wikihez/Gadget-QQ.css]]*/ mw.loader.load(mw.util.wikiScript() + '?title=Bikarhêner:Wikihez/Gadget-QQ.css&action=raw&ctype=text/css', 'text/css'); mw.loader.load('//ku.wiktionary.org/w/index.php?title=Bikarhêner:Wikihez/Gadget-QQ.js&action=raw&ctype=text/javascript'); /*---------start.js------------- [[Bikarhêner:Wikihez/Gadget-start.js]] [[Bikarhêner:Wikihez/Gadget-start.css]]*/ mw.loader.load(mw.util.wikiScript() + '?title=Bikarhêner:Wikihez/Gadget-start.css&action=raw&ctype=text/css', 'text/css'); mw.loader.load('//ku.wiktionary.org/w/index.php?title=Bikarhêner:Wikihez/Gadget-start.js&action=raw&ctype=text/javascript'); /*---------aWa.js------------- [[Bikarhêner:Wikihez/Gadget-aWa.js]] [[Bikarhêner:Wikihez/Gadget-aWa.css]] mw.loader.load(mw.util.wikiScript() + '?title=Bikarhêner:Wikihez/Gadget-aWa.css&action=raw&ctype=text/css', 'text/css'); mw.loader.load('//ku.wiktionary.org/w/index.php?title=Bikarhêner:Wikihez/Gadget-aWa.js&action=raw&ctype=text/javascript'); /* /*---------add-examples.js------------- [[Bikarhêner:Wikihez/Gadget-wikt.add-examples.js]] [[Bikarhêner:Wikihez/Gadget-wikt.add-examples.css]]*/ mw.loader.load(mw.util.wikiScript() + '?title=Bikarhêner:Wikihez/Gadget-wikt.add-examples.css&action=raw&ctype=text/css', 'text/css'); mw.loader.load('//ku.wiktionary.org/w/index.php?title=Bikarhêner:Wikihez/Gadget-wikt.add-examples.js&action=raw&ctype=text/javascript'); mw.loader.load('//ku.wiktionary.org/w/index.php?title=Bikarhêner:Wikihez/skrîpt/js/loader.js&action=raw&ctype=text/javascript') importScript( 'Bikarhêner:Wikihez/skrîpt/js/Gadget-citoid-helper.js' ); // Backlink: [[Bikarhêner:Wikihez/skrîpt/js/Gadget-citoid-helper.js]] importScript( 'Bikarhêner:Wikihez/skrîpt/js/copyTitle.js' ); // Backlink: [[Bikarhêner:Wikihez/skrîpt/js/copyTitle.js]] // [[Bikarhêner:Wikihez/addAutoCat.js]] mw.loader.load('//ku.wiktionary.org/w/index.php?title=Bikarhêner:Wikihez/skrîpt/js/addAutoCat.js&action=raw&ctype=text/javascript'); importScript( 'Bikarhêner:Wikihez/newentrywiz.js' ); // Backlink: [[Bikarhêner:Wikihez/newentrywiz.js]] //[[Bikarhêner:Wikihez/skrîpt/js/VisibilityToggles.js]] //mw.loader.load('//ku.wiktionary.org/w/index.php?title=Bikarhêner:Wikihez/skrîpt/js/VisibilityToggles.js&action=raw&ctype=text/javascript'); //[[Bikarhêner:Wikihez/CreateTranslation.js]] mw.loader.load('//ku.wiktionary.org/w/index.php?title=Bikarhêner:Wikihez/CreateTranslation.js&action=raw&ctype=text/javascript'); //[[Bikarhêner:Wikihez/skrîpt/js/defaultVisibilityToggles.js]] //mw.loader.load('//ku.wiktionary.org/w/index.php?title=Bikarhêner:Wikihez/skrîpt/js/defaultVisibilityToggles.js&action=raw&ctype=text/javascript'); //[[Bikarhêner:Wikihez/skrîpt/js/Gadget-catfix.js]] //mw.loader.load('//ku.wiktionary.org/w/index.php?title=Bikarhêner:Wikihez/skrîpt/js/Gadget-catfix.js&action=raw&ctype=text/javascript'); //[[Bikarhêner:Wikihez/wergerîne.js]] mw.loader.load('//ku.wiktionary.org/w/index.php?title=Bikarhêner:Wikihez/wergerîne.js&action=raw&ctype=text/javascript'); //[[Bikarhêner:Wikihez/skrîpt/js/getinflections.js]] mw.loader.load('//ku.wiktionary.org/w/index.php?title=Bikarhêner:Wikihez/skrîpt/js/getinflections.js&action=raw&ctype=text/javascript'); //[[Bikarhêner:Wikihez/templateScript2.js]] mw.loader.load('//ku.wiktionary.org/w/index.php?title=Bikarhêner:Wikihez/templateScript2.js&action=raw&ctype=text/javascript'); // [[Bikarhêner:Wikihez/şablon-lêke.js]] mw.loader.load('//ku.wiktionary.org/w/index.php?title=Bikarhêner:Wikihez/şablon-lêke.js&action=raw&ctype=text/javascript'); //[[Bikarhêner:Wikihez/skrîpt/js/editor.js]] //mw.loader.load('//ku.wiktionary.org/w/index.php?title=Bikarhêner:Wikihez/skrîpt/js/editor.js&action=raw&ctype=text/javascript'); //[[Bikarhêner:Wikihez/skrîpt/js/UpdateLanguageNameAndCode.js]] //mw.loader.load('//ku.wiktionary.org/w/index.php?title=Bikarhêner:Wikihez/skrîpt/js/UpdateLanguageNameAndCode.js&action=raw&ctype=text/javascript'); //[[Bikarhêner:Wikihez/skrîpt/js/TranslationAdder-Data.js]] //mw.loader.load('//ku.wiktionary.org/w/index.php?title=Bikarhêner:Wikihez/skrîpt/js/TranslationAdder-Data.js&action=raw&ctype=text/javascript'); //[[Bikarhêner:Wikihez/LanguageUtils.js]] //mw.loader.load('//ku.wiktionary.org/w/index.php?title=Bikarhêner:Wikihez/LanguageUtils.js&action=raw&ctype=text/javascript'); //[[:w:Bikarhêner:Wikihez/skrîpt/js/OngletPurge.js]] mw.loader.load('//ku.wikipedia.org/w/index.php?title=Bikarhêner:Wikihez/skrîpt/js/OngletPurge.js&action=raw&ctype=text/javascript'); //[[Bikarhêner:Wikihez/test.js]] mw.loader.load('//ku.wiktionary.org/w/index.php?title=Bikarhêner:Wikihez/test.js&action=raw&ctype=text/javascript'); // This array of dependencies comes from [[MediaWiki:Gadgets-definition]]. // If the list of dependencies changes, copy the text after dependencies= // for TranslationAdder and run console.log(JSON.stringify("paste dependencies here".split(/, ?/))) // in your browser's JavaScript console. Put the resulting array as the first argument to mw.loader.using. //[[User:Wikihez/skrîpt/js/TranslationAdder.js]] //mw.loader.using(["ext.gadget.LegacyScriptsNewNode","mediawiki.cookie","mediawiki.util"], //function() { // importScript('User:Wikihez/skrîpt/js/TranslationAdder.js'); //}); mw.loader.load('https://en.wikipedia.org/w/index.php?title=User:BrandonXLF/TodoList.js&action=raw&ctype=text/javascript'); /* // [[:w:en:MediaWiki:Gadget-edittop.js]] mw.loader.load('//en.wikipedia.org/w/index.php?title=MediaWiki:Gadget-edittop.js&action=raw&ctype=text/javascript'); // [[Bikarhêner:Wikihez/addAutoCat.js]] mw.loader.load('//ku.wiktionary.org/w/index.php?title=Bikarhêner:Wikihez/addAutoCat.js&action=raw&ctype=text/javascript'); //[[Bikarhêner:Balyozbot/Gadget-CommonWikt.js]] //mw.loader.load('//ku.wiktionary.org/w/index.php?title=Bikarhêner:Balyozbot/Gadget-CommonWikt.js&action=raw&ctype=text/javascript'); //[[Bikarhêner:Wikihez/hw-ceke.js]] mw.loader.load('//ku.wiktionary.org/w/index.php?title=Bikarhêner:Wikihez/hw-ceke.js&action=raw&ctype=text/javascript'); //[[Bikarhêner:Wikihez/sort-langheaders.js]] mw.loader.load('//ku.wiktionary.org/w/index.php?title=Bikarhêner:Wikihez/sort-langheaders.js&action=raw&ctype=text/javascript'); //[[:en:User:Conrad.Irwin/Api.js]] mw.loader.load('//en.wiktionary.org/w/index.php?title=User:Conrad.Irwin/Api.js&action=raw&ctype=text/javascript'); //[[Bikarhêner:Wikihez/etîket-çêke.js]] mw.loader.load('//ku.wiktionary.org/w/index.php?title=Bikarhêner:Wikihez/etîket-çêke.js&action=raw&ctype=text/javascript'); //[[Bikarhêner:Wikihez/tagger.js]] mw.loader.load('//ku.wiktionary.org/w/index.php?title=Bikarhêner:Wikihez/tagger.js&action=raw&ctype=text/javascript'); //[[Bikarhêner:Wikihez/Gadget-CatMaker.js]] //mw.loader.load('//ku.wiktionary.org/w/index.php?title=Bikarhêner:Wikihez/Gadget-CatMaker.js&action=raw&ctype=text/javascript'); //[[Bikarhêner:Wikihez/Gadget-defaultVisibilityToggles.js]] //mw.loader.load('//ku.wiktionary.org/w/index.php?title=Bikarhêner:Wikihez/Gadget-defaultVisibilityToggles.js&action=raw&ctype=text/javascript'); //[[Bikarhêner:Wikihez/VisibilityToggles.js]] //mw.loader.load('//ku.wiktionary.org/w/index.php?title=Bikarhêner:Wikihez/VisibilityToggles.js&action=raw&ctype=text/javascript'); //[[Bikarhêner:Wikihez/Gadget-WiktAccFormCreation.js]] //mw.loader.load('//ku.wiktionary.org/w/index.php?title=Bikarhêner:Wikihez/Gadget-WiktAccFormCreation.js&action=raw&ctype=text/javascript'); //[[Bikarhêner:Wikihez/XMLize.js]] //mw.loader.load('//ku.wiktionary.org/w/index.php?title=Bikarhêner:Wikihez/XMLize.js&action=raw&ctype=text/javascript'); //[[Bikarhêner:Wikihez/RhymesAdder.js]] //mw.loader.load('//ku.wiktionary.org/w/index.php?title=Bikarhêner:Wikihez/RhymesAdder.js&action=raw&ctype=text/javascript'); //[[Bikarhêner:Wikihez/Editor.js]] mw.loader.load('//ku.wiktionary.org/w/index.php?title=Bikarhêner:Wikihez/Editor.js&action=raw&ctype=text/javascript'); //[[Bikarhêner:Wikihez/FilterTranslations.js]] //mw.loader.load('//ku.wiktionary.org/w/index.php?title=Bikarhêner:Wikihez/FilterTranslations.js&action=raw&ctype=text/javascript'); //[[Bikarhêner:Wikihez/custom.js]] //mw.loader.load('//ku.wiktionary.org/w/index.php?title=Bikarhêner:Wikihez/custom.js&action=raw&ctype=text/javascript'); //[[Bikarhêner:Wikihez/reformat.js]] //mw.loader.load('//ku.wiktionary.org/w/index.php?title=Bikarhêner:Wikihez/reformat.js&action=raw&ctype=text/javascript'); //[[Bikarhêner:Wikihez/templateScript.js]] //mw.loader.load('//ku.wiktionary.org/w/index.php?title=Bikarhêner:Wikihez/templateScript.js&action=raw&ctype=text/javascript'); //[[Bikarhêner:Wikihez/translateWiki.js]] ji aliyê [[Bikarhêner:Guherto]], [[Taybet:PermanentLink/4854098#Translatewiki.net]] mw.loader.load('//ku.wiktionary.org/w/index.php?title=Bikarhêner:Wikihez/translateWiki.js&action=raw&ctype=text/javascript'); // Various fixes for the trees generated by [[Module:family tree]]. $(function () { // Show the top toggle. $('.familytree-toptoggle').css('display', ''); // Initialize the text of the toggles. $('.familytree').get().forEach(function (tree) { var isCollapsed = tree.classList.contains('mw-collapsed'); var toggles = $(tree).find('.familytree-toggle'); if (toggles[0]) { var customToggleClass = Array.prototype.filter.call(toggles[0].classList, function (className) { return className.indexOf('mw-customtoggle-familytree') === 0; })[0]; if (customToggleClass) { var toggledElement = $('#' + customToggleClass.replace('mw-customtoggle', 'mw-customcollapsible')); if (toggledElement) { toggles.html(toggledElement.data(isCollapsed ? 'expandtext' : 'collapsetext')); } } } }); // Change the text in the custom toggles generated by [[Module:family tree]] // when they are clicked. $('.mw-collapsible').on('beforeExpand.mw-collapsible beforeCollapse.mw-collapsible', function (event) { if (this.id.indexOf('mw-customcollapsible-familytree') === 0) { var toggle = $('.' + this.id.replace('mw-customcollapsible', 'mw-customtoggle')); if (event.type === 'beforeExpand') { toggle.html(this.dataset.collapsetext); } else { // beforeCollapse toggle.html(this.dataset.expandtext); } event.stopPropagation(); } }); }); */ mw.util.addPortletLink( mw.config.get('skin') === 'vector' ? 'p-views' : 'p-cactions', '/w/index.php?title=' + mw.config.get('wgPageName') + '&action=edit&editintro=User:Wikihez/usenec', 'nec', 'id', 'use the New Entry Creator to create a new entry', 'a', 'nextnode'); mbmx9dmmas051st66pyts62gme2dei9 6265707 6265693 2026-07-20T00:23:15Z Wikihez 7344 6265707 javascript text/javascript /*---------QQ.js------------- [[Bikarhêner:Wikihez/Gadget-QQ.js]] [[Bikarhêner:Wikihez/Gadget-QQ.css]]*/ mw.loader.load(mw.util.wikiScript() + '?title=Bikarhêner:Wikihez/Gadget-QQ.css&action=raw&ctype=text/css', 'text/css'); mw.loader.load('//ku.wiktionary.org/w/index.php?title=Bikarhêner:Wikihez/Gadget-QQ.js&action=raw&ctype=text/javascript'); /*---------start.js------------- [[Bikarhêner:Wikihez/Gadget-start.js]] [[Bikarhêner:Wikihez/Gadget-start.css]]*/ mw.loader.load(mw.util.wikiScript() + '?title=Bikarhêner:Wikihez/Gadget-start.css&action=raw&ctype=text/css', 'text/css'); mw.loader.load('//ku.wiktionary.org/w/index.php?title=Bikarhêner:Wikihez/Gadget-start.js&action=raw&ctype=text/javascript'); /*---------aWa.js------------- [[Bikarhêner:Wikihez/Gadget-aWa.js]] [[Bikarhêner:Wikihez/Gadget-aWa.css]] mw.loader.load(mw.util.wikiScript() + '?title=Bikarhêner:Wikihez/Gadget-aWa.css&action=raw&ctype=text/css', 'text/css'); mw.loader.load('//ku.wiktionary.org/w/index.php?title=Bikarhêner:Wikihez/Gadget-aWa.js&action=raw&ctype=text/javascript'); /* /*---------add-examples.js------------- [[Bikarhêner:Wikihez/Gadget-wikt.add-examples.js]] [[Bikarhêner:Wikihez/Gadget-wikt.add-examples.css]]*/ mw.loader.load(mw.util.wikiScript() + '?title=Bikarhêner:Wikihez/Gadget-wikt.add-examples.css&action=raw&ctype=text/css', 'text/css'); mw.loader.load('//ku.wiktionary.org/w/index.php?title=Bikarhêner:Wikihez/Gadget-wikt.add-examples.js&action=raw&ctype=text/javascript'); mw.loader.load('//ku.wiktionary.org/w/index.php?title=Bikarhêner:Wikihez/skrîpt/js/loader.js&action=raw&ctype=text/javascript') importScript( 'Bikarhêner:Wikihez/skrîpt/js/Gadget-citoid-helper.js' ); // Backlink: [[Bikarhêner:Wikihez/skrîpt/js/Gadget-citoid-helper.js]] importScript( 'Bikarhêner:Wikihez/Gadget-linkify.js' ); // Backlink: [[Bikarhêner:Wikihez/Gadget-linkify.js]] importScript( 'Bikarhêner:Wikihez/skrîpt/js/copyTitle.js' ); // Backlink: [[Bikarhêner:Wikihez/skrîpt/js/copyTitle.js]] // [[Bikarhêner:Wikihez/addAutoCat.js]] mw.loader.load('//ku.wiktionary.org/w/index.php?title=Bikarhêner:Wikihez/skrîpt/js/addAutoCat.js&action=raw&ctype=text/javascript'); importScript( 'Bikarhêner:Wikihez/newentrywiz.js' ); // Backlink: [[Bikarhêner:Wikihez/newentrywiz.js]] //[[Bikarhêner:Wikihez/skrîpt/js/VisibilityToggles.js]] //mw.loader.load('//ku.wiktionary.org/w/index.php?title=Bikarhêner:Wikihez/skrîpt/js/VisibilityToggles.js&action=raw&ctype=text/javascript'); //[[Bikarhêner:Wikihez/CreateTranslation.js]] mw.loader.load('//ku.wiktionary.org/w/index.php?title=Bikarhêner:Wikihez/CreateTranslation.js&action=raw&ctype=text/javascript'); //[[Bikarhêner:Wikihez/skrîpt/js/defaultVisibilityToggles.js]] //mw.loader.load('//ku.wiktionary.org/w/index.php?title=Bikarhêner:Wikihez/skrîpt/js/defaultVisibilityToggles.js&action=raw&ctype=text/javascript'); //[[Bikarhêner:Wikihez/skrîpt/js/Gadget-catfix.js]] //mw.loader.load('//ku.wiktionary.org/w/index.php?title=Bikarhêner:Wikihez/skrîpt/js/Gadget-catfix.js&action=raw&ctype=text/javascript'); //[[Bikarhêner:Wikihez/wergerîne.js]] mw.loader.load('//ku.wiktionary.org/w/index.php?title=Bikarhêner:Wikihez/wergerîne.js&action=raw&ctype=text/javascript'); //[[Bikarhêner:Wikihez/skrîpt/js/getinflections.js]] mw.loader.load('//ku.wiktionary.org/w/index.php?title=Bikarhêner:Wikihez/skrîpt/js/getinflections.js&action=raw&ctype=text/javascript'); //[[Bikarhêner:Wikihez/templateScript2.js]] mw.loader.load('//ku.wiktionary.org/w/index.php?title=Bikarhêner:Wikihez/templateScript2.js&action=raw&ctype=text/javascript'); // [[Bikarhêner:Wikihez/şablon-lêke.js]] mw.loader.load('//ku.wiktionary.org/w/index.php?title=Bikarhêner:Wikihez/şablon-lêke.js&action=raw&ctype=text/javascript'); //[[Bikarhêner:Wikihez/skrîpt/js/editor.js]] //mw.loader.load('//ku.wiktionary.org/w/index.php?title=Bikarhêner:Wikihez/skrîpt/js/editor.js&action=raw&ctype=text/javascript'); //[[Bikarhêner:Wikihez/skrîpt/js/UpdateLanguageNameAndCode.js]] //mw.loader.load('//ku.wiktionary.org/w/index.php?title=Bikarhêner:Wikihez/skrîpt/js/UpdateLanguageNameAndCode.js&action=raw&ctype=text/javascript'); //[[Bikarhêner:Wikihez/skrîpt/js/TranslationAdder-Data.js]] //mw.loader.load('//ku.wiktionary.org/w/index.php?title=Bikarhêner:Wikihez/skrîpt/js/TranslationAdder-Data.js&action=raw&ctype=text/javascript'); //[[Bikarhêner:Wikihez/LanguageUtils.js]] //mw.loader.load('//ku.wiktionary.org/w/index.php?title=Bikarhêner:Wikihez/LanguageUtils.js&action=raw&ctype=text/javascript'); //[[:w:Bikarhêner:Wikihez/skrîpt/js/OngletPurge.js]] mw.loader.load('//ku.wikipedia.org/w/index.php?title=Bikarhêner:Wikihez/skrîpt/js/OngletPurge.js&action=raw&ctype=text/javascript'); //[[Bikarhêner:Wikihez/test.js]] mw.loader.load('//ku.wiktionary.org/w/index.php?title=Bikarhêner:Wikihez/test.js&action=raw&ctype=text/javascript'); // This array of dependencies comes from [[MediaWiki:Gadgets-definition]]. // If the list of dependencies changes, copy the text after dependencies= // for TranslationAdder and run console.log(JSON.stringify("paste dependencies here".split(/, ?/))) // in your browser's JavaScript console. Put the resulting array as the first argument to mw.loader.using. //[[User:Wikihez/skrîpt/js/TranslationAdder.js]] //mw.loader.using(["ext.gadget.LegacyScriptsNewNode","mediawiki.cookie","mediawiki.util"], //function() { // importScript('User:Wikihez/skrîpt/js/TranslationAdder.js'); //}); mw.loader.load('https://en.wikipedia.org/w/index.php?title=User:BrandonXLF/TodoList.js&action=raw&ctype=text/javascript'); /* // [[:w:en:MediaWiki:Gadget-edittop.js]] mw.loader.load('//en.wikipedia.org/w/index.php?title=MediaWiki:Gadget-edittop.js&action=raw&ctype=text/javascript'); // [[Bikarhêner:Wikihez/addAutoCat.js]] mw.loader.load('//ku.wiktionary.org/w/index.php?title=Bikarhêner:Wikihez/addAutoCat.js&action=raw&ctype=text/javascript'); //[[Bikarhêner:Balyozbot/Gadget-CommonWikt.js]] //mw.loader.load('//ku.wiktionary.org/w/index.php?title=Bikarhêner:Balyozbot/Gadget-CommonWikt.js&action=raw&ctype=text/javascript'); //[[Bikarhêner:Wikihez/hw-ceke.js]] mw.loader.load('//ku.wiktionary.org/w/index.php?title=Bikarhêner:Wikihez/hw-ceke.js&action=raw&ctype=text/javascript'); //[[Bikarhêner:Wikihez/sort-langheaders.js]] mw.loader.load('//ku.wiktionary.org/w/index.php?title=Bikarhêner:Wikihez/sort-langheaders.js&action=raw&ctype=text/javascript'); //[[:en:User:Conrad.Irwin/Api.js]] mw.loader.load('//en.wiktionary.org/w/index.php?title=User:Conrad.Irwin/Api.js&action=raw&ctype=text/javascript'); //[[Bikarhêner:Wikihez/etîket-çêke.js]] mw.loader.load('//ku.wiktionary.org/w/index.php?title=Bikarhêner:Wikihez/etîket-çêke.js&action=raw&ctype=text/javascript'); //[[Bikarhêner:Wikihez/tagger.js]] mw.loader.load('//ku.wiktionary.org/w/index.php?title=Bikarhêner:Wikihez/tagger.js&action=raw&ctype=text/javascript'); //[[Bikarhêner:Wikihez/Gadget-CatMaker.js]] //mw.loader.load('//ku.wiktionary.org/w/index.php?title=Bikarhêner:Wikihez/Gadget-CatMaker.js&action=raw&ctype=text/javascript'); //[[Bikarhêner:Wikihez/Gadget-defaultVisibilityToggles.js]] //mw.loader.load('//ku.wiktionary.org/w/index.php?title=Bikarhêner:Wikihez/Gadget-defaultVisibilityToggles.js&action=raw&ctype=text/javascript'); //[[Bikarhêner:Wikihez/VisibilityToggles.js]] //mw.loader.load('//ku.wiktionary.org/w/index.php?title=Bikarhêner:Wikihez/VisibilityToggles.js&action=raw&ctype=text/javascript'); //[[Bikarhêner:Wikihez/Gadget-WiktAccFormCreation.js]] //mw.loader.load('//ku.wiktionary.org/w/index.php?title=Bikarhêner:Wikihez/Gadget-WiktAccFormCreation.js&action=raw&ctype=text/javascript'); //[[Bikarhêner:Wikihez/XMLize.js]] //mw.loader.load('//ku.wiktionary.org/w/index.php?title=Bikarhêner:Wikihez/XMLize.js&action=raw&ctype=text/javascript'); //[[Bikarhêner:Wikihez/RhymesAdder.js]] //mw.loader.load('//ku.wiktionary.org/w/index.php?title=Bikarhêner:Wikihez/RhymesAdder.js&action=raw&ctype=text/javascript'); //[[Bikarhêner:Wikihez/Editor.js]] mw.loader.load('//ku.wiktionary.org/w/index.php?title=Bikarhêner:Wikihez/Editor.js&action=raw&ctype=text/javascript'); //[[Bikarhêner:Wikihez/FilterTranslations.js]] //mw.loader.load('//ku.wiktionary.org/w/index.php?title=Bikarhêner:Wikihez/FilterTranslations.js&action=raw&ctype=text/javascript'); //[[Bikarhêner:Wikihez/custom.js]] //mw.loader.load('//ku.wiktionary.org/w/index.php?title=Bikarhêner:Wikihez/custom.js&action=raw&ctype=text/javascript'); //[[Bikarhêner:Wikihez/reformat.js]] //mw.loader.load('//ku.wiktionary.org/w/index.php?title=Bikarhêner:Wikihez/reformat.js&action=raw&ctype=text/javascript'); //[[Bikarhêner:Wikihez/templateScript.js]] //mw.loader.load('//ku.wiktionary.org/w/index.php?title=Bikarhêner:Wikihez/templateScript.js&action=raw&ctype=text/javascript'); //[[Bikarhêner:Wikihez/translateWiki.js]] ji aliyê [[Bikarhêner:Guherto]], [[Taybet:PermanentLink/4854098#Translatewiki.net]] mw.loader.load('//ku.wiktionary.org/w/index.php?title=Bikarhêner:Wikihez/translateWiki.js&action=raw&ctype=text/javascript'); // Various fixes for the trees generated by [[Module:family tree]]. $(function () { // Show the top toggle. $('.familytree-toptoggle').css('display', ''); // Initialize the text of the toggles. $('.familytree').get().forEach(function (tree) { var isCollapsed = tree.classList.contains('mw-collapsed'); var toggles = $(tree).find('.familytree-toggle'); if (toggles[0]) { var customToggleClass = Array.prototype.filter.call(toggles[0].classList, function (className) { return className.indexOf('mw-customtoggle-familytree') === 0; })[0]; if (customToggleClass) { var toggledElement = $('#' + customToggleClass.replace('mw-customtoggle', 'mw-customcollapsible')); if (toggledElement) { toggles.html(toggledElement.data(isCollapsed ? 'expandtext' : 'collapsetext')); } } } }); // Change the text in the custom toggles generated by [[Module:family tree]] // when they are clicked. $('.mw-collapsible').on('beforeExpand.mw-collapsible beforeCollapse.mw-collapsible', function (event) { if (this.id.indexOf('mw-customcollapsible-familytree') === 0) { var toggle = $('.' + this.id.replace('mw-customcollapsible', 'mw-customtoggle')); if (event.type === 'beforeExpand') { toggle.html(this.dataset.collapsetext); } else { // beforeCollapse toggle.html(this.dataset.expandtext); } event.stopPropagation(); } }); }); */ mw.util.addPortletLink( mw.config.get('skin') === 'vector' ? 'p-views' : 'p-cactions', '/w/index.php?title=' + mw.config.get('wgPageName') + '&action=edit&editintro=User:Wikihez/usenec', 'nec', 'id', 'use the New Entry Creator to create a new entry', 'a', 'nextnode'); sw5dgufxf8kfl648d7at2fmnkx3sppe Bikarhêner:Wikihez/common.css 2 874440 6265642 6265405 2026-07-19T19:41:36Z Wikihez 7344 6265642 css text/css /* [[Şablon:manelazim]]: dema ku amûra "Pênaseyê temam bike" bi awayekî serkeftî were barkirin, nivîsa cîgir a "manelazim" tê veşartin; ji bo bikarhênerên bêyî JavaScript, ev nivîs xuya dibe (ji ber vê yekê em .manelazim bi xwe naşehitînin). */ .fill-definition-resolved > .manelazim { display: none; } 8v47cjnw570spsn71cmkoba0n2c2h14 Bikarhêner:Wikihez/Gadget-QQ.js 2 958523 6265696 6265483 2026-07-19T22:52:38Z Wikihez 7344 6265696 javascript text/javascript 'use strict'; // Binêre: [[Gotûbêja MediaWiki:Gadget-QQ]] //[[en:MediaWiki:Gadget-QQ.js]]<nowiki> /*jshint shadow:true, scripturl:true, undef:true, latedef:true, unused:true, loopfunc:true */ // --- Cookie helpers (adapted from [[MediaWiki:Common.js]]'s wikt.cookie // pattern) — used to store the Google Books API key locally in the user's // own browser. This never touches the wiki (no page save, no server round // trip), so it stays private to whoever enters it, on that one device/browser. --- window.wikt = window.wikt || {}; wikt.cookie = wikt.cookie || {}; function qqCookieCreate(name, value, days) { var date = new Date(); date.setTime(date.getTime() + days * 86400000); document.cookie = name + "=" + encodeURIComponent(value) + "; expires=" + date.toGMTString() + "; path=/"; } wikt.cookie.create = wikt.cookie.create || qqCookieCreate; function qqCookieRead(name) { var cookies = document.cookie.split(';'); for (var i = 0; i < cookies.length; i++) { var cookie = cookies[i].trim(); if (cookie.indexOf(name + "=") === 0) { return decodeURIComponent(cookie.substr(name.length + 1)); } } return null; } wikt.cookie.read = wikt.cookie.read || qqCookieRead; function qqCookieDelete(name) { qqCookieCreate(name, "", -1); } wikt.cookie.delete = wikt.cookie.delete || qqCookieDelete; var QQ_API_KEY_COOKIE = 'kephir_qq_gbooks_key'; function getGoogleBooksApiKey() { return (qqCookieRead(QQ_API_KEY_COOKIE) || '').trim(); } function setGoogleBooksApiKey(key) { key = (key || '').trim(); if (key) { qqCookieCreate(QQ_API_KEY_COOKIE, key, 365); } else { qqCookieDelete(QQ_API_KEY_COOKIE); } } // Cleans up a raw Google Books snippet for use as |jêgirtin= in {{jêder-kitêb}}: // - Converts Google's <b>...</b> highlight (around the matched search term) // into wikitext '''bold''' instead of just stripping it. // - Decodes the handful of HTML entities Google/OCR text commonly contains // (Google escapes straight quotes as &#39;/&quot; even in non-HTML output). // - Strips any other leftover tags. // - Tidies OCR-typical stray spaces just inside parentheses: "( x )" -> "(x)". // - Escapes literal "|" as {{!}}, since a raw pipe would otherwise break the // {{jêder-kitêb|...}} template's parameter parsing. function cleanCitationText(text) { var htmlEntities = { '&amp;': '&', '&#39;': "'", '&apos;': "'", '&quot;': '"', '&nbsp;': ' ', '&lt;': '<', '&gt;': '>' }; var cleaned = text .replace(/\n/g, ' ') .replace(/<b>(.*?)<\/b>/g, "'''$1'''") // preserve Google's highlighted term as wikitext bold .replace(/<[^>]+>/g, '') // strip any other remaining tags .replace(/&(amp|#39|apos|quot|nbsp|lt|gt);/g, function(m) { return htmlEntities[m]; }) .replace(/\(\s+/g, '(') .replace(/\s+\)/g, ')') .replace(/\s{2,}/g, ' ') .replace(/\|/g, '{{!}}') .replace(/\s+\./g, '.') .replace(/\s+,/g, ',') .trim(); return cleaned; } function getInflections(word) { var inflections = ""; // Multi-word nouns need "-" instead of "mê û nêr" for the gender param var genderParam = word.indexOf(' ') !== -1 ? '-' : 'mê û nêr'; $.ajax({ url: mw.util.wikiScript('api'), data: { action: 'expandtemplates', format: 'json', text: `{{#invoke:ku-tewîn-nav|get_comma_separated_forms|${word}|${genderParam}|guherto=hemû}}`, prop: 'wikitext' }, type: 'GET', success: function(result) { inflections = result.expandtemplates.wikitext; }, error: function(xhr) { console.log('Error.\nRequest failed.'); }, async: false }); return inflections; } function getStems(verb) { const words = verb.split(' '); if (words.length > 1) { const firstWord = words[0]; const lastWord = words[words.length - 1]; if (firstWord.endsWith("kirin")) { const presentStem = "k"; const pastStem = "kir"; return { presentStem, pastStem, prefix: lastWord, valahi: true }; } else if (firstWord.endsWith("bûn")) { const presentStem = "b"; const pastStem = "bû"; return { presentStem, pastStem, prefix: lastWord, valahi: true }; } else if (firstWord.endsWith("dan")) { const presentStem = "d"; const pastStem = "da"; return { presentStem, pastStem, prefix: lastWord, valahi: true }; } else if (lastWord.endsWith("kirin")) { const presentStem = "k"; const pastStem = lastWord.slice(0, -4); return { presentStem, pastStem, prefix: firstWord, valahi: true }; } else if (lastWord.endsWith("bûn")) { const presentStem = "b"; const pastStem = "bû"; return { presentStem, pastStem, prefix: firstWord, valahi: true }; } else if (lastWord.endsWith("dan")) { const presentStem = "d"; const pastStem = "da"; return { presentStem, pastStem, prefix: firstWord, valahi: true }; } else { return null; // Not a valid verb pattern } } else { if (verb.endsWith("andin")) { const presentStem = verb.slice(0, -5) + "în"; const pastStem = verb.slice(0, -5) + "and"; return { presentStem, pastStem, prefix: '', valahi: false }; } else if (verb.endsWith("în")) { const presentStem = verb.slice(0, -2); const pastStem = verb + "iya"; return { presentStem, pastStem, prefix: '', valahi: false }; } else if (verb.endsWith("tin")) { const presentStem = verb.slice(0, -3); const pastStem = verb.slice(0, -2); return { presentStem, pastStem, prefix: '', valahi: false }; } else { return null; // Not a valid verb pattern } } } function getConj(word) { var inflections = ""; const stems = getStems(word); // getStems() returns null for words that don't match any known verb // pattern (e.g. multi-word verbs not based on kirin/bûn/dan, or // single words not ending in andin/în/tin). Without this guard, // accessing stems.valahi below throws a TypeError and silently kills // the whole click handler before uiQuery ever gets updated. if (!stems) { console.log('QQ gadget: could not determine verb stem for "' + word + '"'); return '"' + word + '"'; } var valahi; if (stems.valahi) { valahi = "erê"; } else { valahi = "na"; } $.ajax({ url: mw.util.wikiScript('api'), data: { action: 'expandtemplates', format: 'json', text: `{{#invoke:ku-tewandin|get_comma_separated_forms|${word}|form=negerguhêz|niha=${stems.presentStem}|borî=${stems.pastStem}|pêşgir=${stems.prefix}|valahî=${valahi}}}`, prop: 'wikitext' }, type: 'GET', success: function(result) { inflections = result.expandtemplates.wikitext; }, error: function(xhr) { console.log('Error.\nRequest failed.'); }, async: false }); return inflections; } // Plain DOM tree builder — unchanged. OOUI widgets get plugged into this // via their .$element[0] (see w2n() below), everything else stays native DOM. function el(tag, child, attr, events) { var node = document.createElement(tag); if (child) { if (typeof child !== 'object') child = [child]; for (var i = 0; i < child.length; ++i) { var ch = child[i]; if ((ch === void(null)) || (ch === null)) continue; else if (typeof ch !== 'object') ch = document.createTextNode(String(ch)); node.appendChild(ch); } } if (attr) for (var key in attr) { node.setAttribute(key, String(attr[key])); } if (events) for (var key in events) { node.addEventListener(key, events[key], false); } return node; } // Widget-to-node: unwraps an OOUI widget's raw DOM element so it can be // passed as a child to el(). function w2n(widget) { return widget.$element[0]; } // Minimal drag handler, replacing jQuery UI's .draggable(). Only starts a // drag if the mousedown didn't land on an interactive control inside the // handle (e.g. the OOUI "veşêre" button in the title bar). function makeDraggable(handle, target) { var startX, startY, startLeft, startTop, dragging = false; handle.addEventListener('mousedown', function(e) { if (e.target.closest('button, a, input, .oo-ui-buttonElement')) return; dragging = true; var rect = target.getBoundingClientRect(); startX = e.clientX; startY = e.clientY; startLeft = rect.left; startTop = rect.top; target.style.left = startLeft + 'px'; target.style.top = startTop + 'px'; target.style.right = 'auto'; document.addEventListener('mousemove', onMouseMove); document.addEventListener('mouseup', onMouseUp); e.preventDefault(); }); function onMouseMove(e) { if (!dragging) return; target.style.left = (startLeft + (e.clientX - startX)) + 'px'; target.style.top = (startTop + (e.clientY - startY)) + 'px'; } function onMouseUp() { dragging = false; document.removeEventListener('mousemove', onMouseMove); document.removeEventListener('mouseup', onMouseUp); } } var backends = { gbooks: { name: "Google Kitêb ", enabled: true, addResults: function(data, callback) { // Google may return {error: {...}} instead of {items: [...]} on // failures (bad query, quota, service unavailable, etc.) — surface // that instead of silently treating it as "no results", and make // sure the "more" button comes back so the user can retry instead // of it just vanishing. if (data.error) { this.uiStatus.textContent = "Xeletiya API: " + (data.error.message || JSON.stringify(data.error)) + " - dîsa biceribîne"; this.uiStatus.style.display = ''; this.uiMore.toggle(true); console.log('Google Books API error:', data.error); return; } function makeResult(item) { var year; if (item.volumeInfo.publishedDate) { var yearMatch = /^(\d+)/.exec(item.volumeInfo.publishedDate); if (yearMatch) year = yearMatch[1]; } var page; if (item.volumeInfo.previewLink) { var uri = new mw.Uri(item.volumeInfo.previewLink); if (uri.query.pg) { var pageMatch = /PA(\d+)/.exec(uri.query.pg); if (pageMatch) page = pageMatch[1]; } } var idents = {}; if (item.volumeInfo.industryIdentifiers) { for (var i = 0; i < item.volumeInfo.industryIdentifiers.length; ++i) { var ident = item.volumeInfo.industryIdentifiers[i]; idents[ident.type] = ident.identifier; } } var isbn = idents.ISBN_13 || idents.ISBN_10; return { generateCitation: function() { var result = "#* {{jêder-kitêb|ku|"; if (item.searchInfo && item.searchInfo.textSnippet) { result += "jêgirtin=" + cleanCitationText(item.searchInfo.textSnippet); } if (year) result += "|sal=" + year; else result += ""; if (item.volumeInfo.authors) result += "|nivîskar=" + item.volumeInfo.authors.join(", "); else result += ""; if (item.volumeInfo.previewLink) result += "|url=" + item.volumeInfo.previewLink; else result += ""; if (item.volumeInfo.title) { result += "|sernav=" + item.volumeInfo.title; if (item.volumeInfo.subtitle) result += ": " + item.volumeInfo.subtitle; result += ""; } if (item.volumeInfo.publisher) result += "|weşanxane=" + item.volumeInfo.publisher; else result += ""; if (isbn) result += "|ISBN=" + isbn + ""; else result += ""; if (page) result += "|rûpel=" + page + "}}"; else result += "}}"; result += "\n"; return result; }, populateNode: function(node, checkbox) { // "xav" raw-JSON link var rawLink = el('a', "xav", { 'href': 'javascript:void(0);' }); rawLink.addEventListener('click', function() { alert(JSON.stringify(item, null, ' ')); }); node.appendChild(el('label', [ checkbox, year ? el('strong', year) : el('i', "sal nayê zanîn"), item.volumeInfo.authors && ", ", item.volumeInfo.authors && item.volumeInfo.authors.join(", "), ", ", el('cite', [ item.volumeInfo.title, item.volumeInfo.subtitle && el('small', [": ", item.volumeInfo.subtitle]) ]), ])); node.appendChild(el('span', [ item.volumeInfo.publisher && el('span', [ ", ", item.volumeInfo.publisher, ], { 'class': 'publisher' }), isbn && el('span', [ " (", el('a', ["ISBN " + isbn], { 'href': mw.util.getUrl('Special:BookSources/' + isbn) }), ")" ], { 'class': 'isbn' }), page && el('span', [ ", page ", page, ], { 'class': 'page' }), item.volumeInfo.previewLink && el('small', [ " [", el('a', "veke", { 'href': item.volumeInfo.previewLink }), "]" ]), item.volumeInfo.infoLink && el('small', [ " [", el('a', "malûmat", { 'href': item.volumeInfo.infoLink }), "]" ]), el('small', [" [", rawLink, "]"]) ])); if (item.searchInfo && item.searchInfo.textSnippet) { var uiQuote = el('blockquote'); uiQuote.innerHTML = item.searchInfo.textSnippet.replace(/<br>/g, " "); node.appendChild(uiQuote); } } }; } if (!data.items) { this.uiStatus.textContent = "netîce nehat dîtin"; this.uiStatus.style.display = ''; return; } for (var i = 0; i < data.items.length; ++i) { if (data.items[i].searchInfo && data.items[i].searchInfo.textSnippet) { if (!/<b>/.test(data.items[i].searchInfo.textSnippet)) continue; // bogus result } callback(makeResult(data.items[i])); } this.uiMore.toggle(true); this.uiStatus.textContent = ""; this.data.startIndex += data.items.length; }, populateTab: function(tab) { var that = this; this.uiResults = el('ul'); this.uiStatus = el('div'); var moreButton = new OO.ui.ButtonWidget({ label: "bêhtir çavkanî" }); moreButton.on('click', function() { that.uiStatus.textContent = "ji kerema xwe bisekine..."; that.uiStatus.style.display = ''; moreButton.toggle(false); var apiKeyMore = getGoogleBooksApiKey(); if (apiKeyMore) { that.data.key = apiKeyMore; } jQuery.ajax({ url: location.protocol + '//www.googleapis.com/books/v1/volumes', dataType: 'jsonp', data: that.data, timeout: 10000 }).done(function(data) { that.addResults(data, that.callback); }).fail(function(jqXHR, textStatus) { that.uiStatus.textContent = "Çavkaniya Google Kitêban têk çû (" + textStatus + ") - dîsa biceribîne."; that.uiStatus.style.display = ''; // Bring the button back on failure too, so it doesn't just // disappear and leave the user with no way to retry. that.uiMore.toggle(true); console.log('Google Books request failed:', textStatus, jqXHR); }); }); this.uiMore = moreButton; tab.appendChild(this.uiResults); tab.appendChild(this.uiStatus); tab.appendChild(w2n(this.uiMore)); }, search: function(terms, options, callback) { var that = this; while (this.uiResults.firstChild) this.uiResults.removeChild(this.uiResults.firstChild); // An OR-joined list of every inflected form (especially verbs with // many conjugations) can exceed what the Books API will accept. // Cap the number of OR terms. var maxTerms = 8; var termList = terms.match(/"[^"]+"/g) || []; var limitedTerms = termList.length ? termList.slice(0, maxTerms).join(' OR ') : terms; this.data = { q: limitedTerms, startIndex: 0, maxResults: 20 }; this.callback = callback; this.uiMore.toggle(false); this.uiStatus.textContent = "ji kerema xwe bisekine..."; this.uiStatus.style.display = ''; var apiKey = getGoogleBooksApiKey(); if (apiKey) { this.data.key = apiKey; } jQuery.ajax({ url: location.protocol + '//www.googleapis.com/books/v1/volumes', dataType: 'jsonp', data: this.data, timeout: 10000 }).done(function(data) { that.addResults(data, callback); }).fail(function(jqXHR, textStatus) { that.uiStatus.textContent = "Çavkaniya Google Kitêban têk çû (" + textStatus + ") - dîsa biceribîne."; that.uiStatus.style.display = ''; // Same here: an initial-search failure shouldn't leave the // "more" button permanently hidden either. that.uiMore.toggle(true); console.log('Google Books request failed:', textStatus, jqXHR); }); } }, gsearch: { name: "Google Search", enabled: true, populateTab: function(tab) { this.uiResults = el('ul'); this.uiStatus = el('div'); tab.appendChild(this.uiResults); tab.appendChild(this.uiStatus); }, search: function(terms, options, callback) { while (this.uiResults.firstChild) this.uiResults.removeChild(this.uiResults.firstChild); this.uiStatus.textContent = "Lêgerana Googlê tê vekirin..."; var items = terms.match(/"([^"]+)"/g) || []; if (items.length === 0) { console.error("No items found."); return; } var chunkSize = 30; for (var i = 0; i < items.length; i += chunkSize) { var chunk = items.slice(i, i + chunkSize); var searchTerms = chunk.join(" OR "); var searchUrl = 'https://www.google.com/search?q=' + encodeURIComponent(searchTerms + " -wiktionary -instagram -facebook -dailymotion -youtube -tiktok -commons -wikidata -wikipedia"); var newTab = window.open(searchUrl, '_blank'); newTab.focus(); } } } }; function getForms(cure, word) { var targetWord = word || mw.config.get('wgTitle'); targetWord = targetWord.replace(/"/g, '').trim(); var inflections; var searchTerms; if (cure === "noun") { inflections = getInflections(targetWord); searchTerms = inflections.split(',').map(term => '"' + term.trim() + '"').join(' OR '); } else if (cure === "verb") { inflections = getConj(targetWord); searchTerms = inflections.split(',').map(term => '"' + term.trim() + '"').join(' OR '); } else if (cure === "adj") { inflections = [ targetWord, targetWord + "tir", targetWord + "tirîn", "herî " + targetWord, "tewrî " + targetWord ]; searchTerms = inflections.map(term => '"' + term.trim() + '"').join(' OR '); } return searchTerms; } // Figure out the bare word (page title / subpage / search box text) exactly // once, independently of whatever ends up in the query field later. function getDefaultBareWord() { if ([0, 1, 114].indexOf(mw.config.get('wgNamespaceNumber')) !== -1) // main, Talk, Citations return mw.config.get('wgTitle'); if (mw.config.get('wgNamespaceNumber') === 100) { var titleMatch = /[^/]+\/(.*)/.exec(mw.config.get('wgTitle')); if (titleMatch) return titleMatch[1]; } if (mw.config.get('wgCanonicalSpecialPageName') === 'search') { var searchBox = document.getElementById('searchText'); if (searchBox) return searchBox.value; } return ''; } // Holds the bare (un-inflected) word. Checkbox handlers read from this // instead of re-parsing the query field's value (which gets overwritten with // the expanded, quoted, OR-joined search terms every time a checkbox fires). var baseWord = getDefaultBareWord(); // Everything below builds UI, so it needs OOUI loaded first. mw.loader.using(['oojs-ui-core', 'oojs-ui-widgets'], function() { var uiQuery, uiTitle, uiBackends, uiTabs, uiTabLabels, uiCitationsTab, uiCitations, uiCurTab, uiCurTabLabel, uiForm; var nounCheckbox, verbCheckbox, adjCheckbox, uiCitationsHash; var searchTerms; // --- Title bar --- var hideMainButton = new OO.ui.ButtonWidget({ label: "veşêre", framed: false, classes: ['hide-link'] }); hideMainButton.on('click', function() { uiMain.style.display = 'none'; }); uiTitle = el('div', [ el('strong', "Quiet Quentin"), w2n(hideMainButton) ], { 'class': 'title' }); // --- Part-of-speech radios --- // NOTE: we deliberately do NOT rely on OO.ui.RadioInputWidget's synthesized // 'change' event here — on this wiki's (older / deprecated ResourceLoader) // OOUI bundle it was not firing reliably. Binding straight to the native // <input>'s 'click' event via .$input is more robust: it fires the instant // the browser toggles the radio, independent of OOUI's own event plumbing. function selectPOS(kind) { try { searchTerms = getForms(kind, baseWord); console.log('QQ gadget: selectPOS(' + kind + ') ->', searchTerms); uiQuery.setValue(searchTerms); } catch (e) { console.log('QQ gadget: selectPOS(' + kind + ') failed:', e); } } nounCheckbox = new OO.ui.RadioInputWidget({ name: 'partOfSpeech' }); nounCheckbox.$input.on('click', function() { selectPOS('noun'); }); var nounField = new OO.ui.FieldLayout(nounCheckbox, { label: "Îsm", align: 'inline' }); adjCheckbox = new OO.ui.RadioInputWidget({ name: 'partOfSpeech' }); adjCheckbox.$input.on('click', function() { selectPOS('adj'); }); var adjField = new OO.ui.FieldLayout(adjCheckbox, { label: "Sifet", align: 'inline' }); verbCheckbox = new OO.ui.RadioInputWidget({ name: 'partOfSpeech' }); verbCheckbox.$input.on('click', function() { selectPOS('verb'); }); var verbField = new OO.ui.FieldLayout(verbCheckbox, { label: "Fiîl", align: 'inline' }); // --- Query field --- uiQuery = new OO.ui.TextInputWidget({ placeholder: "peyv", classes: ['search-terms'], value: baseWord ? '"' + baseWord + '"' : '' }); uiQuery.on('change', function(value) { // Keep baseWord in sync when the user types manually. Programmatic // .setValue() calls elsewhere also fire 'change', but by then the value // is already an inflected list, so this simply re-derives the same // baseWord from its first term — harmless and keeps the logic in one place. baseWord = value.replace(/"/g, '').split(' OR ')[0].trim(); }); var submitButton = new OO.ui.ButtonInputWidget({ type: 'submit', label: "Lê bigere", flags: ['primary', 'progressive'] }); var clearButton = new OO.ui.ButtonWidget({ label: "Paqij bike" }); clearButton.on('click', function() { uiQuery.setValue(''); baseWord = ''; nounCheckbox.setSelected(false); adjCheckbox.setSelected(false); verbCheckbox.setSelected(false); uiQuery.focus(); }); // Lets the user store their own Google Books API key locally (in a cookie // in their own browser), so search doesn't hit Google's shared/exhausted // unauthenticated quota. Nothing is saved to the wiki or sent anywhere // except as the "key" param on their own Books API requests. var apiKeyButton = new OO.ui.ButtonWidget({ label: "API Key" }); var apiKeyInput = new OO.ui.TextInputWidget({ placeholder: "Google Books API key (vala bihêle da ku jê bibe)", classes: ['api-key-input'], value: getGoogleBooksApiKey() }); var apiKeySaveButton = new OO.ui.ButtonWidget({ label: "Qeyd bike", flags: ['progressive'] }); apiKeySaveButton.on('click', function() { var entered = apiKeyInput.getValue(); setGoogleBooksApiKey(entered); apiKeyStatus.textContent = entered.trim() ? "Kilîda API hate qeydkirin." : "Kilîda API hate jêbirin."; apiKeyStatus.style.display = ''; }); var apiKeyStatus = el('span', null, { 'class': 'api-key-status' }); var apiKeyPanel = el('div', [ w2n(apiKeyInput), w2n(apiKeySaveButton), apiKeyStatus ], { 'class': 'api-key-panel', 'style': 'display: none; margin-top: 0.5em;' }); apiKeyButton.on('click', function() { var showing = apiKeyPanel.style.display !== 'none'; if (showing) { apiKeyPanel.style.display = 'none'; } else { apiKeyStatus.textContent = ''; apiKeyStatus.style.display = 'none'; apiKeyInput.setValue(getGoogleBooksApiKey()); apiKeyPanel.style.display = ''; apiKeyInput.focus(); } }); uiBackends = el('div', [ el('strong', "Çavkanî"), ": " ]); uiForm = el('form', [ el('fieldset', [ el('legend', "Çavkaniyan lê bigere"), w2n(nounField), w2n(adjField), w2n(verbField), el('br'), w2n(uiQuery), w2n(submitButton), w2n(clearButton), w2n(apiKeyButton), apiKeyPanel, el('br'), uiBackends ]) ], { 'action': 'javascript:void(0);' }, { 'submit': function() { var hasAny = false; for (var key in backends) { hasAny = (function(backend) { if (!backend.enabled) { backend.uiTabLabel.style.display = 'none'; return hasAny; } else { backend.uiTabLabel.style.display = ''; if (!hasAny) { uiCurTab.style.display = 'none'; uiCurTabLabel.classList.remove('active'); uiCurTab = backend.uiTab; uiCurTabLabel = backend.uiTabLabel; uiCurTab.style.display = ''; uiCurTabLabel.classList.add('active'); } } backend.results = []; if (backend.enabled) { backend.search(uiQuery.getValue(), null, function(result) { backend.results.push(result); var node = el('li'); var takeLink = el('a', "jê bigere", { 'href': 'javascript:void(0);', 'class': 'qq-take-btn' }); takeLink.addEventListener('click', function() { if (result.taken) { result.taken = false; node.classList.remove('taken'); } else { result.taken = true; node.classList.add('taken'); } }); var hideLink = el('a', "veşêre", { 'href': 'javascript:void(0);', 'class': 'qq-hide-btn' }); hideLink.addEventListener('click', function() { node.classList.toggle('struck'); }); var checkbox = el('small', ["[", takeLink, "] [", hideLink, "]"]); result.populateNode(node, checkbox); backend.uiResults.appendChild(node); }); return true; } })(backends[key]); } if (hasAny) { uiTabs.style.display = ''; uiTabLabels.style.display = ''; } else { alert("No backends chosen"); uiTabs.style.display = 'none'; uiTabLabels.style.display = 'none'; } } }); uiTabLabels = el('ul', null, { 'class': 'tab-labels', 'style': 'display: none;' }); uiTabs = el('div', null, { 'class': 'tabs', 'style': 'display: none;' }); var uiMain = el('div', [ uiTitle, uiForm, uiTabLabels, uiTabs ], { 'class': 'kephir-qq', 'style': 'display: none; position: fixed;' }); // Dragging via the title bar. Skipped on Minerva (mobile) — touch-dragging a // fixed panel is impractical there; resizing (native CSS `resize: both`, // see stylesheet) is likewise desktop-only. if (mw.config.get('skin') !== 'minerva') { makeDraggable(uiTitle, uiMain); } document.body.appendChild(uiMain); function regenerateCitations() { var result = []; for (var key in backends) { var results = backends[key].results || []; for (var j = 0; j < results.length; ++j) { if (results[j].taken) result.push(results[j].generateCitation()); } } result = result.join(''); if (uiCitationsHash.isSelected()) { result = result.replace(/^/mg, '#').replace(/#$/, ''); } uiCitations.setValue(result); } uiCitations = new OO.ui.MultilineTextInputWidget({ rows: 20 }); uiCitationsHash = new OO.ui.CheckboxInputWidget(); uiCitationsHash.on('change', function() { regenerateCitations(); }); var hashField = new OO.ui.FieldLayout(uiCitationsHash, { label: "Li pêşiya her rêzê # zêde bike", align: 'inline' }); var copyButton = new OO.ui.ButtonWidget({ icon: 'copy', title: "Kopî bike", framed: false }); copyButton.on('click', function() { var text = uiCitations.getValue(); function onSuccess() { copyButton.setIcon('check'); setTimeout(function() { copyButton.setIcon('copy'); }, 1500); } function fallbackCopy(t) { var ta = document.createElement('textarea'); ta.value = t; ta.style.position = 'fixed'; ta.style.opacity = '0'; document.body.appendChild(ta); ta.select(); try { document.execCommand('copy'); onSuccess(); } catch (e) { /* empty */ } document.body.removeChild(ta); } if (navigator.clipboard && navigator.clipboard.writeText) { navigator.clipboard.writeText(text).then(onSuccess).catch(function() { fallbackCopy(text); }); } else { fallbackCopy(text); } }); uiTabs.appendChild(uiCurTab = uiCitationsTab = el('div', [ w2n(uiCitations), el('br'), w2n(hashField) ], { 'style': 'display: none' })); var citationsTabLi; var citationsTabButton = new OO.ui.ButtonWidget({ label: "Çavkaniyên ku hatine girtin", framed: false }); citationsTabButton.on('click', function() { regenerateCitations(); uiCurTab.style.display = 'none'; uiCurTabLabel.classList.remove('active'); uiCurTab = uiCitationsTab; uiCurTabLabel = citationsTabLi; uiCurTab.style.display = ''; uiCurTabLabel.classList.add('active'); }); citationsTabLi = el('li', [w2n(citationsTabButton), w2n(copyButton)], { 'class': 'citations-tab' }); uiTabLabels.appendChild(uiCurTabLabel = citationsTabLi); for (var key in backends) { (function(backend) { var backendCheckbox = new OO.ui.CheckboxInputWidget({ selected: backend.enabled }); backendCheckbox.on('change', function(selected) { backend.enabled = selected; }); var backendField = new OO.ui.FieldLayout(backendCheckbox, { label: backend.name, align: 'inline' }); uiBackends.appendChild(w2n(backendField)); backend.results = []; backend.uiTab = el('div', [], { 'style': 'display: none;' }); var tabButton = new OO.ui.ButtonWidget({ label: backend.name, framed: false }); tabButton.on('click', function() { uiCurTab.style.display = 'none'; uiCurTabLabel.classList.remove('active'); uiCurTab = backend.uiTab; uiCurTabLabel = backend.uiTabLabel; uiCurTab.style.display = ''; uiCurTabLabel.classList.add('active'); }); backend.uiTabLabel = el('li', [w2n(tabButton)]); backend.populateTab(backend.uiTab); uiTabs.appendChild(backend.uiTab); uiTabLabels.appendChild(backend.uiTabLabel); })(backends[key]); } // Choose a portlet that actually exists on the current skin, including var portletId; switch (mw.config.get('skin')) { case 'vector-2022': portletId = 'p-cactions'; break; default: portletId = 'p-tb'; } var link = mw.util.addPortletLink( portletId, 'javascript:void(0);', 'QQ', 'p-kephir-qq', "Jêgirtinan lê bigere", '9' ); // addPortletLink can return null if the target portlet isn't present on the // page — guard before attaching the listener. if (link) { link.addEventListener('click', function() { uiMain.style.display = ''; uiQuery.focus(); }, false); } else { console.log('QQ gadget: no portlet found for skin "' + mw.config.get('skin') + '".'); } }); //</nowiki> 2pfm3ncv9qlfgonn8tc1dm24zsfrqci Bikarhêner:Wikihez/Gadget-aWa.js 2 965057 6265612 6265387 2026-07-19T16:29:42Z Wikihez 7344 6265612 javascript text/javascript "use strict"; /*** [aWa]: [[en:MediaWiki:Gadget-aWa.js|A Wonderfool Archiver]] ***/ // {{documentation}} <nowiki> /*jshint shadow:true, scripturl:true, undef:true, latedef:true, unused:true */ /*global mw, jQuery */ (function () { if (mw.config.get('wgAction') !== 'view') return; var monthNames = [ "kanûna paşîn", "sibat", "adar", "nîsan", "gulan", "hezîran", "tîrmeh", "tebax", "îlon", "çiriya pêşîn", "çiriya paşîn", "kanûna pêşîn" ]; var revMonthNames = {}; for (var j = 0; j < monthNames.length; ++j) revMonthNames[monthNames[j]] = j; function el(tag, child, attr, events) { var node = document.createElement(tag); if (child) { if (typeof child !== 'object') child = [child]; for (var i = 0; i < child.length; ++i) { var ch = child[i]; if ((ch === void(null)) || (ch === null)) continue; else if (typeof ch !== 'object') ch = document.createTextNode(String(ch)); node.appendChild(ch); } } if (attr) for (var key in attr) { node.setAttribute(key, String(attr[key])); } if (events) for (var key in events) { node.addEventListener(key, events[key], false); } return node; } var forumId, remindersList = []; var wgPageName = mw.config.get('wgPageName'); if ((wgPageName === "Wîkîferheng:Daxwazên peyitandinê") ||/^Wîkîferheng:Daxwazên_peyitandinê/.test(wgPageName)) { forumId = 'dp'; remindersList.push(["Ji bîr neke ji bo madeyên peyitandî şablona ", el('code', "{{bêçavkanî}}"), " û/yan ", el('code', "{{p-mane}}"), " ji rûpelê rake."]); } else if ((wgPageName === "Wîkîferheng:Daxwazên_jêbirinê") || /^Wîkîferheng:Daxwazên_jêbirinê/.test(wgPageName)) { forumId = 'dj'; remindersList.push(["Ji bîr neke ji bo madeyên ku neyên jêbirin şablona ", el('code', "{{jêbirin}}"), " ji rûpelê rake."]); } else if ((wgPageName === "Wîkîferheng:Daxwazên_standardkirinê") || /^Wiktionary:Requests_for_moves,_mergers_and_splits\/Unresolved_requests\//.test(wgPageName)) { forumId = 'ds'; remindersList.push(["Ji bîr neke ji bo madeyên ku hatine standardkirin şablona ", el('code', "{{standardkirin}}"), " û/yan ", el('code', "{{ds}}"), " ji rûpelê rake."]); } else if ((wgPageName === "Wîkîferheng:Daxwazên_zelalkirinê") || /^Wiktionary:Requests_for_cleanup\/archive\/\d+\/Unresolved_requests$/.test(wgPageName)) { forumId = 'dz'; remindersList.push(["Ji bîr neke ji bo madeyên ku hatine sererastkirin şablona ", el('code', "{{wdz}}"), " ji rûpelê rake."]); } else if (wgPageName === "Wîkîferheng:Xebat") { forumId = 'xebat'; remindersList.push(["Nîqaşên vê rûpelê tim li [[Wîkîferheng:Xebat/arşîv 1|Wîkîferheng:Xebat/arşîv NO]] têne arşîvkirin."]); } else if (wgPageName === "Wîkîferheng:ceribandin/aWa") { forumId = 'SANDBOX'; remindersList.push(["NO DANGER: Nothing in this room will kill you."]); } else return; if (forumId !== 'feedback') remindersList.push(["Nîqaşên xilasbûyî herî kêm 7 rojan bê arşîv bihêlin."]); function link(child, href, attr, ev) { attr = attr || {}; ev = ev || {}; if (typeof href === 'string') attr.href = href; else { attr.href = 'javascript:void(null);'; ev.click = href; } return el('a', child, attr, ev); } var rxPath = new RegExp('^' + mw.config.get('wgArticlePath').replace('$1', '(.*)') + '$'); // XXX: ugly hack function getPageFromUrl(url) { var m, target; try { target = new mw.Uri(url); } catch (e) { return null; } if (target.host !== location.host) return null; if (target.path === mw.config.get('wgScript')) return new mw.Title(target.query.title); else if ((m = rxPath.exec(target.path))) return new mw.Title(decodeURIComponent(m[1])); return null; } // NOTE: findSectionNumber() previously relied on the .mw-editsection link's // action=edit&section=N query param. MobileFrontend/Minerva strips the // .mw-editsection span from headings entirely, so this always returned null // on mobile and silently dropped the "arşîv bike" link (and, worse, calling // .nextSibling on a missing .mw-editsection later on would throw and abort // the rest of the init loop). Section numbers are now resolved once up // front via action=parse&prop=sections (see sectionMapPromise below) and // matched to headings by document order instead. var api = new mw.Api(); // XXX: seriously, action=parse should return this. var starttimestamp, basetimestamp; api.get({ action: 'query', pageids: mw.config.get('wgArticleId'), prop: 'revisions', curtimestamp: 1, rvstartid: mw.config.get('wgRevisionId'), rvprop: 'timestamp', rvlimit: 1 }).done(function (result) { starttimestamp = result.curtimestamp; basetimestamp = result.query.pages[mw.config.get('wgArticleId')].revisions[0].timestamp; }); // Resolve top-level (level === '2') section indices via the API instead of // scraping .mw-editsection, so this also works on mobile skins that strip // that markup out of the rendered heading. var sectionMapPromise = api.get({ action: 'parse', page: wgPageName, prop: 'sections', formatversion: 2 }).then(function (result) { return result.parse.sections.filter(function (s) { return s.level === '2'; }); }, function (code, result) { console.error('aWa: failed to fetch section map', code, result); return []; }); var toArchive = {}; var uiQueue, uiStatus; function setStatus(child, node) { node = node || uiStatus; if (!node.preceder) node.parentNode.insertBefore(node.preceder = document.createTextNode(''), node); while (node.firstChild) node.removeChild(node.firstChild); if (!child) { if (node.preceder !== true) node.preceder.data = ""; return; } else { if (node.preceder !== true) node.preceder.data = ": "; } if (typeof child === 'string') { node.appendChild(document.createTextNode(child)); return; } for (var i = 0; i < child.length; ++i) { var ch = child[i]; if ((ch === void(null)) || (ch === null)) continue; else if (typeof ch !== 'object') ch = document.createTextNode(String(ch)); node.appendChild(ch); } } var uiProceed, uiWrapper; var uiArchiver = el('div', [ el('form', [ uiWrapper = el('fieldset', [ // ↓↓↓↓↓↓ how fitting. el('legend', [ "A ", link(["Wonderfool"], mw.util.getUrl("wonderfool")), " Archiver ", el('small', ["[", link('veşêre', function () { this.style.fontWeight = uiWrapper.classList.toggle('collapsed') ? 'bold' : ''; }), "]"]) ]), uiQueue = el('ul', null, { 'class': 'queue' }), el('ul', remindersList.map(function (nodes) { return el('li', nodes); }), { 'class': 'reminders' }), uiProceed = el('input', null, { type: 'submit', value: "Dewam bike" }), ' ', el('input', null, { type: 'button', value: "Bigre" }, { click: function () { uiArchiver.style.display = 'none'; } }), uiStatus = el('p', null, { 'class': 'main-statusbar' }) ]) ], { action: 'javascript:void(0);' }, { submit: function () { if (!uiQueue.hasChildNodes()) { // XXX: should probably check the toArchive object instead setStatus("The archiving queue is empty."); return; } if (forumId !== 'SANDBOX') { uiProceed.disabled = true; uiArchiver.classList.add('archiving-in-progress'); } var complete = false; window.addEventListener('beforeunload', function (ev) { if (!complete) { return (ev.returnValue = "Discussions are still being archived."); } }, false); setStatus("Naveroka rûpelê tê girtin…"); api.get({ action: 'parse', oldid: mw.config.get('wgRevisionId'), prop: 'parsetree', }).then(function (result) { setStatus("Slicing up discussions…"); var prettyPageName = (new mw.Title(wgPageName)).getPrefixedText(); function serialiseMarkup(node) { if (node.nodeType === node.TEXT_NODE) return node.data; var children = []; for (var child = node.firstChild; child; child = child.nextSibling) children.push(serialiseMarkup(child)); if (node.tagName === 'part') return '|' + children.join(''); else if (node.tagName === 'tplarg') return '{{{' + children.join('') + '}}}'; else if (node.tagName === 'template') return '{{' + children.join('') + '}}'; else if (node.tagName === 'ext') return '<' + children.join(''); else if (node.tagName === 'attr') return children.join('') + (node.parentNode.lastChild === node ? '/>' : ''); else if (node.tagName === 'inner') return '>' + children.join(''); else return children.join(''); } var parseTree = jQuery.parseXML(result.parse.parsetree['*']); var headerMap = {}; var headers = parseTree.getElementsByTagName('h'); for (var i = 0; i < headers.length; ++i) { headerMap[headers[i].getAttribute('i')] = headers[i]; } var majorQueue = [], minorQueue = [], obliterated = []; var keys = Object.keys(toArchive); for (var j = 0; j < keys.length; ++j) { var item = toArchive[keys[j]]; var sectHead = headerMap[item.sect]; var sectContents = []; for ( var node = sectHead, next = sectHead.nextSibling; node && (!node.getAttribute || !node.getAttribute('level') || (+node.getAttribute('level') > +sectHead.getAttribute('level')) || (node === sectHead)); (next = node.nextSibling, node.parentNode.removeChild(node), node = next) ) { sectContents.push(serialiseMarkup(node)); } var secttext = sectContents.join(''); var discussionTitle; switch (forumId) { case 'dj' : discussionTitle = "Nîqaşa [[" + prettyPageName + "|jêbirinê]]" ; break; case 'rfdo' : discussionTitle = "Nîqaşa [[" + prettyPageName + "|ceribandinê]]" ; break; case 'dp' : discussionTitle = "Nîqaşa [[" + prettyPageName + "|peyitandinê]]" ; break; case 'dz' : discussionTitle = "Nîqaşa [[" + prettyPageName + "|zelalkirinê]]" ; break; case 'ds' : discussionTitle = "Nîqaşa [[" + prettyPageName + "|standardkirinê]]" ; break; case 'xebat' : discussionTitle = item.secttitle ; break; default : discussionTitle = "Archived from [[" + prettyPageName + "]]" ; break; } var rxStamp = /(\d\d?):(\d\d),\s*(\d+)\s*([A-ZÎÛÇŞ][a-zîûçş]+)\s*(\d\d\d\d+)\s*\(UTC\)/g; var m, timestamps = []; while ((m = rxStamp.exec(secttext))) timestamps.push(Date.UTC(parseInt(m[5], 10), revMonthNames[m[4]], parseInt(m[3], 10), parseInt(m[1], 10), parseInt(m[2], 10))); timestamps.sort(); if ((timestamps.length > 0) && (forumId !== 'xebat')) { var first = new Date(timestamps[0]), last = new Date(timestamps[timestamps.length - 1]); if (first.getUTCFullYear() === last.getUTCFullYear()) { if (first.getUTCMonth() === last.getUTCMonth()) discussionTitle += ": " + monthNames[first.getUTCMonth()] + " " + first.getUTCFullYear(); else discussionTitle += ": " + monthNames[first.getUTCMonth()] + "–" + monthNames[last.getUTCMonth()] + " " + first.getUTCFullYear(); } else { discussionTitle += ": " + monthNames[first.getUTCMonth()] + " " + first.getUTCFullYear() + '–' + monthNames[last.getUTCMonth()] + " " + last.getUTCFullYear(); } } if (!item.talk) { obliterated.push(item.secttitle); continue; // requested not to archive. } if (forumId === 'xebat') { // The section title above is now the exact original // heading text (e.g. "Tercimeyên zel"), and // MediaWiki will add "== Tercimeyên zel ==" itself // via sectiontitle when posting with section=new. // So just drop the original heading line instead of // wrapping it in a {{fake==}} placeholder — keeping // it would duplicate the heading. secttext = secttext.replace(/^(=+)(.*?)\1\n?/, ''); } else { secttext = secttext.replace(/^(=+)(.*?)\1(?=\n|$)/, '{{fake$1|1=$2}}'); } majorQueue.push({ targetPage: item.talk, uiStatus: item.uiStatus, sectTitle: discussionTitle, summary: '[[MediaWiki:Gadget-aWa.js/belgekirin|aWa]]: Arşîvkirina nîqaşê ji rûpela [[' + prettyPageName + ']]', content: '{{arşîv-ser|' + forumId + '|' + item.result + '|link=Taybet:PermanentLink/' + mw.config.get('wgRevisionId') + '#' + item.sectid + '}}\n' + secttext.trimRight() + '\n{{arşîv-bin}}' }); var backlinks = item.backlinks; for (var k = 0; k < backlinks.length; ++k) { if (!backlinks[k]) continue; var saneDiscussionTitle = discussionTitle.replace(/\[\[(?:.*?\|)?(.*?)\]\]/g, '$1'); // XXX var linkTarget = item.talk.getPrefixedText() + "#" + saneDiscussionTitle; minorQueue.push({ targetPage: backlinks[k].page, uiStatus: backlinks[k].uiStatus, sectTitle: discussionTitle, summary: "[[MediaWiki:Gadget-aWa.js/belgekirin|aWa]]: Li [[" + linkTarget + "]] lînka nîqaşê ji [[" + prettyPageName + "]] tê zêdekirin", content: ": ''Binêre [[" + linkTarget + "]].''~~~~" }); } } var headers = Array.prototype.slice.call(parseTree.getElementsByTagName('h')); for (var i = 0; i < headers.length; ++i) { if (headers[i].getAttribute('level') !== '1') continue; if (!/^=\s*(Kanûna paşîn|Sibat|Adar|Nîsan|Gulan|Hezîran|Tîrmeh|Tebax|Îlon|Çiriya pêşîn|Çiriya paşîn|Kanûna pêşîn)\s+\d\d\d\d+\s*=$/.test(headers[i].textContent)) continue; out: for (var node = headers[i].nextSibling;; node = node.nextSibling) { switch (node ? node.nodeType : null) { case parseTree.ELEMENT_NODE: if ((node.tagName !== 'h') || (node.getAttribute('level') !== '1')) break out; /* fall through */ case null: while ((headers[i].nextSibling) !== node) headers[i].parentNode.removeChild(headers[i].nextSibling); headers[i].parentNode.removeChild(headers[i]); break out; case parseTree.TEXT_NODE: if (!/^\s*$/.test(node.data)) break out; break; default: break out; } } } var wikitext = serialiseMarkup(parseTree.documentElement); setStatus("Nîqaş ji rûpelê tên jêbirin…"); var summary; var no = "madeyê"; if (majorQueue.length > 1) no = "madeyan"; if (majorQueue.length) summary = '[[MediaWiki:Gadget-aWa.js/belgekirin|aWa]]: Arşîvkirina ' + majorQueue.length + ' ' + no +' li ' + majorQueue.map(function (item) { return '[[' + item.targetPage.getPrefixedText() + ']]'; }).join(", ") + (obliterated.length ? " û jêbirina " + obliterated.length + ": \"" + obliterated.join("\", \"") + "\"": ""); else summary = "[[MediaWiki:Gadget-aWa.js/belgekirin|aWa]]: Jêbirina " + obliterated.length + " made(yan): \"" + obliterated.join("\", \"") + "\""; if (forumId === 'SANDBOX') { setStatus(); alert("Kurte: " + summary + "\nWîkînivîsa dawî:\n\n" + wikitext); majorQueue.forEach(function (item) { alert("[[" + item.targetPage.getPrefixedText() + "]]: " + item.sectTitle + "\n\n" + item.content); }); minorQueue.forEach(function (item) { alert("[[" + item.targetPage.getPrefixedText() + "]]: " + item.sectTitle + "\n\n" + item.content); }); return; } api.post({ action: 'edit', pageid: mw.config.get('wgArticleId'), token: mw.user.tokens.get('csrfToken'), summary: summary, notminor: 1, text: wikitext, basetimestamp: basetimestamp, starttimestamp: starttimestamp }).then(function (result) { function processQueue(queue) { return jQuery.when.apply(jQuery, queue.map(function (item) { setStatus("Tê qeydkirin…", item.uiStatus); return jQuery.Deferred(function (d) { api.post({ action: 'edit', token: mw.user.tokens.get('csrfToken'), notminor: 1, section: 'new', sectiontitle: item.sectTitle, title: item.targetPage.getPrefixedDb(), text: item.content, summary: item.summary, redirect: 1 // XXX }).then(function (result) { if (result.edit.result !== 'Success') { setStatus("Xeletî binêre konsolê", item.uiStatus); d.reject(); console.error(result); return; } // XXX: preferably check if a page is a redirect BEFORE archiving. if (result.redirects) { var target = result.redirects.pop().to; setStatus(["Redirected to ", link(target, mw.util.getUrl(target))], item.uiStatus); d.resolve(); return; } setStatus("OK", item.uiStatus); d.resolve(); }, function (code, result) { setStatus(["Error: [", el('code', [code]), "]"], item.uiStatus); console.error('Request error', result); d.reject(); }); }).promise(); })); } if (result.edit.result !== 'Success') { setStatus("Xeletiyeke nediyar. Ji bo detayan li konsolê binêrin."); console.error(result); complete = true; return; } setStatus("Nîqaşên arşîvkirî li rûpelên gotûbêjan tên barkirin…"); processQueue(majorQueue).then(function () { setStatus("Lînkên vegerînê tên lêzêdekirin…"); processQueue(minorQueue).then(function () { setStatus("Temam. Tê dîsa barkirin…"); complete = true; location.reload(); }, function () { complete = true; setStatus("Archiving was successful, but there was an error while adding backlinks. You can visit the talk pages to add backlinks manually."); }); }, function () { complete = true; setStatus([ "Oops… there was an error while archiving discussions. Go to your ", link("contributions list", mw.util.getUrl('Special:Contributions/' + mw.config.get('wgUserName'))), " to clean things up and try again." ]); }); }, function (code, result) { complete = true; if (code === 'editconflict') { setStatus([ 'Edit conflict detected. Please ', link('refresh the page', function () { location.reload(); }), ' and try again.' ]); return; } if (code === 'http') { setStatus(['Request error: ' + result.textStatus]); console.error('API request error: ', result); return; } if (code === 'ok-but-empty') { setStatus(['Returned empty response from server.']); return; } setStatus([ 'Error while saving the main discussion page: ', result.error.info, ' [code ', el('code', result.error.code), ']' ]); console.error(arguments); }); }, function (code, result) { if (code === 'http') { setStatus('Request error: ' + result.textStatus); console.error('API request error: ', result); return; } if (code === 'ok-but-empty') { setStatus('Received empty response from server.'); return; } setStatus(['Error: ', result.error.info, ' [code ', el('code', [result.error.code]), ']']); return; }); } }) ], { 'class': 'kephir-awa-dialog', 'style': 'display: none;' }); document.body.appendChild(uiArchiver); uiStatus.preceder = true; // Resolves the target page for Xebat archiving: Wîkîferheng:Xebat/arşîv N, // starting at N=1. If that page exists and is over 70,000 bytes, tries // N+1, and so on, until it finds a page that's either missing (not yet // created) or still under the size limit. function findXebatArchiveTarget(n) { var pageTitle = 'Wîkîferheng:Xebat/arşîv ' + n; return api.get({ action: 'query', titles: pageTitle, prop: 'info' }).then(function (result) { var pages = result.query.pages; var pageId = Object.keys(pages)[0]; var page = pages[pageId]; // Page doesn't exist yet: safe to use. if (page.missing !== undefined) return new mw.Title(pageTitle); // Page exists but is too big: move on to the next number. if (page.length > 70000) return findXebatArchiveTarget(n + 1); return new mw.Title(pageTitle); }, function (code, result) { console.error('aWa: failed to check size of', pageTitle, code, result); // On error, fall back to using this page rather than blocking archiving. return new mw.Title(pageTitle); }); } var headers = document.querySelectorAll(".mw-heading > h2"); var dupTracker = {}; function makeLinkFor(headerNode, links, age, section) { var targetChecked = false, targetCheckRequest; if ((section === null) || (section === undefined)) return; // On desktop, insert right after the <h2> title but BEFORE any // DiscussionTools metadata bar (the "Şiroveya dawî" / comment-count / // author-count line, div.ext-discussiontools-init-section-bar) if one // is present, and before the plain .mw-editsection edit link — this is // static markup that nothing else touches, so it's safe. // // IMPORTANT: the class 'ext-discussiontools-init-section' on the // .mw-heading wrapper does NOT reliably indicate the mobile (Minerva) // skin — DiscussionTools adds this same class on desktop (Vector etc.) // whenever DT is enabled, which is the normal case on wikis that have // it turned on. Checking that class was previously used as a mobile // signal and caused the archive link to be inserted as a sibling AFTER // the whole .mw-heading div even on desktop, landing it after // "Şiroveya dawî" instead of before it. // // On real Minerva/mobile pages, .mw-heading's contents — the overflow // menu, subscribe button, and metadata bar — are OOUI widgets // built/rebuilt by DT's own JS shortly after page load, and that // rebuild wipes out anything inserted inside .mw-heading beforehand // (tried re-inserting via MutationObserver on every DT mutation too — // still didn't survive). So on Minerva we insert as a sibling right // after the whole .mw-heading div instead — outside DT's reach — which // lands the link after the metadata bar rather than before it. We // detect Minerva via mw.config's skin name, not via a DT-added class. var mwHeadingDiv = headerNode.parentNode; var isMobileSkin = mw.config.get('skin') === 'minerva'; var metadataBar = mwHeadingDiv.querySelector('.ext-discussiontools-init-section-bar'); var insertParent, insertBefore; if (isMobileSkin) { insertParent = mwHeadingDiv.parentNode; insertBefore = mwHeadingDiv.nextSibling; } else if (metadataBar) { // Desktop with DiscussionTools enabled: insert inside .mw-heading, // right before the metadata bar (which holds "Şiroveya dawî" etc.) insertParent = mwHeadingDiv; insertBefore = metadataBar; } else { // Desktop, no DT metadata bar at all (DT disabled/older markup): // fall back to right after the header node itself. insertParent = mwHeadingDiv; insertBefore = headerNode.nextSibling; } var archiveSpan = el('span', [ '[', link('arşîv bike', function (ev) { // Defensively stop this from bubbling into any ancestor click // handling (DiscussionTools on Minerva/mobile attaches its own // click handling across .mw-heading) and from following the // javascript:void(null) href as a "real" navigation. if (ev) { ev.preventDefault(); ev.stopPropagation(); } var that = this, config = { secttitle: headerNode.textContent, sect: section, sectid: headerNode.id, temp: 'archived', backlinks: [] }; setStatus(); uiArchiver.style.display = ''; if (this.item) return; toArchive[section] = config; var uiArchiveTarget, uiArchiveTargetLink, uiArchiveNowhereLink; var uiResult, results = {}; var uiBacklinks, uiAddBacklink, uiLinksFromSel; function setTarget(page, noCheck) { if (!page) { uiArchiveTarget.style.display = 'none'; uiArchiveNowhereLink.classList.add('active-mode'); uiBacklinks.classList.add('irrelevant'); uiAddBacklink.classList.add('irrelevant'); uiLinksFromSel.classList.add('irrelevant'); if (uiResult) uiResult.classList.add('irrelevant'); if (!config.talk) return; delete dupTracker[config.talk.getPrefixedDb()]; config.talk = null; return; } config.talk = page; dupTracker[page.getPrefixedDb()] = true; uiArchiveTarget.style.display = ''; uiArchiveTargetLink.textContent = page.getPrefixedText(); uiArchiveTargetLink.href = mw.util.getUrl(page.getPrefixedDb()); uiArchiveNowhereLink.classList.remove('active-mode'); uiBacklinks.classList.remove('irrelevant'); uiAddBacklink.classList.remove('irrelevant'); uiLinksFromSel.classList.remove('irrelevant'); if (uiResult) uiResult.classList.remove('irrelevant'); if (!noCheck) { targetCheckRequest = api.get({ action: 'query', titles: page.getPrefixedDb(), redirects: 1 }).then(function (result) { if (result.query.redirects) { setStatus([ "Archive destination [[", link(page.getPrefixedText(), mw.util.getUrl(page.getPrefixedDb(), { 'redirect': 'no' })), "]] is a redirect; corrected." ]); setTarget(new mw.Title(result.query.redirects.pop().to), true); } targetChecked = true; targetCheckRequest = null; }); } else targetChecked = true; } function addBacklink(page, noCheck) { if (!page) return; var uiItem, blConfig = {}; var i = config.backlinks.length; config.backlinks.push(blConfig); var uiLink; function changePage(newPage, noCheck) { blConfig.page = newPage; blConfig.checked = noCheck; uiLink.textContent = newPage.getPrefixedText(); dupTracker[newPage.getPrefixedDb()] = true; if (!noCheck) { blConfig.checkRequest = api.get({ action: 'query', titles: newPage.getPrefixedDb(), redirects: 1 }).then(function (result) { if (result.query.redirects) { setStatus([ "Backlink destination [[", link(newPage.getPrefixedText(), mw.util.getUrl(newPage.getPrefixedDb(), { 'redirect': 'no' })), "]] is a redirect; corrected." ]); changePage(new mw.Title(result.query.redirects.pop().to), true); page = blConfig.page; } blConfig.checked = true; blConfig.checkRequest = null; }); } } uiBacklinks.appendChild(uiItem = el('li', [ uiLink = link(page.getPrefixedText(), mw.util.getUrl(page.getPrefixedDb()), { 'title': "Lînkeke vê nîqaşê dê li vê rûpelê were danîn" }), el('span', [ " (", link('betal bike', function () { uiItem.parentNode.removeChild(uiItem); delete config.backlinks[i]; delete dupTracker[page.getPrefixedDb()]; }, { 'title': "Li wê rûpelê lînkeke nîqaşê daneyîne" }), " \u2022 ", link("bike ya sereke", function () { if (!config.talk) { uiItem.parentNode.removeChild(uiItem); delete config.backlinks[i]; if (blConfig.checkRequest) blConfig.checkRequest.abort(); setTarget(page, blConfig.checked); return; } if (blConfig.checkRequest) blConfig.checkRequest.abort(); if (targetCheckRequest) targetCheckRequest.abort(); changePage(config.talk, targetChecked); setTarget(page, blConfig.checked); page = blConfig.page; }, { 'title': "Vê rûpelê bike hedefa arşîvê ya sereke" }), ")" ], { 'class': 'hide-when-archiving' }), blConfig.uiStatus = el('span') ])); changePage(page, noCheck); return i; } function setResult(result) { for (var key in results) results[key].classList.remove('active-mode'); if (results[result]) results[result].classList.add('active-mode'); config.result = result; } uiQueue.appendChild(this.item = el('li', [ '"', link(headerNode.textContent, '#' + headerNode.id, { 'title': "Ji bo dîtina nîqaşê bitikîne" }), '"', uiArchiveTarget = el('span', [ "→ [[", uiArchiveTargetLink = link('?', 'javascript:void(window.warranty);', { 'title': "Nîqaş dê li vê rûpelê were arşîvkirin" }), "]]" ]), config.uiStatus = el('span'), el('br'), el('small', [ link("hedefê biguhêre", function () { var newTarget = prompt('Cihê nû ya arşîvê?', config.talk ? config.talk.getPrefixedText() : ""); if (!newTarget) return; try { newTarget = new mw.Title(newTarget); } catch (e) { setStatus("Navê rûpelê ne derbasdar e"); return; } if (newTarget.getNamespaceId() < 0) { setStatus("Li valahiyeke taybet nikare were arşîvkirin"); return; } newTarget.namespace |= 1; setTarget(newTarget); setStatus(); }, { 'title': "Cihê arşîvkirina gotûbêjê biguhêre" }), " \u2022 ", uiArchiveNowhereLink = link("jê bibe", function () { setTarget(null); }, { 'title': "Vê gotûbêjê arşîv neke û jê bibe" }), " \u2022 ", uiAddBacklink = link("Li rûpela din lînk zêde bike", function () { var newTarget = prompt("Li kû derê?", ''); if (!newTarget) return; try { newTarget = new mw.Title(newTarget); } catch (e) { setStatus("Navê rûpelê ne derbasdar e"); return; } if (newTarget.getNamespaceId() < 0) { setStatus("Li valahiyeke taybet nikare were arşîvkirin"); return; } newTarget.namespace |= 1; addBacklink(newTarget); setStatus(); }, { 'title': "Rûpelekê lê zêde bike ku tê de lînka vegerîna vê gotûbêjê were danîn" }), " \u2022 ", uiLinksFromSel = link("ji hilbijartinê", function () { var sel = window.getSelection(), taken = {}; var intersectsNode = function (node) { var tmp = document.createRange(); tmp.selectNode(node); return (this.compareBoundaryPoints(this.START_TO_START, tmp) >= 0) && (this.compareBoundaryPoints(this.END_TO_END, tmp) <= 0); }; for (var i = 0; i < sel.rangeCount; ++i) { var range = sel.getRangeAt(i); var links = range.commonAncestorContainer.getElementsByTagName('a'); if (!range.intersectsNode) range.intersectsNode = intersectsNode; for (var j = 0; j < links.length; ++j) { if (!range.intersectsNode(links[j])) continue; var title = getPageFromUrl(links[j].href); if (!title || (title.getNamespaceId() < 0)) continue; if (title) { title.namespace |= 1; if (taken[title.getPrefixedDb()]) continue; addBacklink(title); taken[title.getPrefixedDb()] = true; } } range.detach(); } }, { 'title': "Lînkên vegerînê li rûpelên ku di hilbijartina niha de zêde bike" }), " \u2022 ", link("betal bike", function () { that.item.parentNode.removeChild(that.item); delete toArchive[section]; delete that.item; }, { 'title': "Dev ji arşîvkirinê berde" }), ((forumId === 'dj') || (forumId === 'rfdo') || (forumId === 'dp') || (forumId === 'SANDBOX')) ? uiResult = el('span', [ " \u2022 netîce: ", results.passed = link("bi ser ket", function () { setResult('passed'); }, { 'title': "Ev nîqaş bi ser ket (hatiye peyitandin an nayê jêbirin)" }), " \u2022 ", results.failed = link("têk çû", function () { setResult('failed'); }, { 'title': "Ev nîqaş têk çû (nehatiye peyitandin an tê jêbirin" }), " \u2022 ", results.archived = link("tiştekî din", function () { setResult('archived'); }, { 'title': "Netîce tine ye yan tiştekî din" } ) ]) : null ], { 'class': 'hide-when-archiving' }), uiBacklinks = el('ul', [], { 'class': 'kephir-awa-backlinks' }) ])); var result = 'archived'; // Expected HTML elements: // <div class="mw-heading ..."><h2><span ... class="mw-headline" ...> var mwHeading = headerNode.parentNode; if (!mwHeading.classList.contains("mw-heading")) { console.error("Expected to find element with class mw-heading as parent of %o", headerNode); } if (results.passed) { var resultText; for (var node = mwHeading.nextSibling; node; node = node.nextSibling) { if (!node.getElementsByClassName) continue; if (node.classList.contains("mw-heading") || node.getElementsByClassName("mw-heading").length > 0) break; var bs = node.getElementsByTagName('b'); for (var j = 0; j < bs.length; ++j) { var b = bs[j]; resultText = b.textContent || b.innerText; if (/no\s+consensus/i.test(b.parentNode.textContent)) result = 'archived'; else { if (/\b(failed|Nehat peyitandin|jê bibe|not\s+restored)\b/i.test(resultText)) { result = 'failed'; } else if (/\b(passed|bim\u00EEne|Hat peyitandin|restored|undeleted)\b/i.test(resultText)) { result = 'passed'; } } } } } setResult(result); // Xebat always archives to a numbered page (Wîkîferheng:Xebat/arşîv N), // never to a page linked from the section heading itself — but if // the heading does link to a page, that page's talk page still // gets added as a backlink (see links[0] handling below). // Starting at N=1, check the byte size of each archive page in // turn; if it's over 70 KB, move on to N+1 (creating a new // archive page once we reach one that doesn't exist yet or is // still under the limit). if (forumId === 'xebat') { findXebatArchiveTarget(1).then(function (title) { setTarget(title); }); // The primary archive target is always the numbered Xebat // archive, but if the section title itself is a link (e.g. // to the article under discussion), still add that page's // talk page as a backlink. if (links[0]) { var titleLink = getPageFromUrl(links[0].href); if (titleLink && (titleLink.getNamespaceId() >= 0)) { titleLink.namespace |= 1; addBacklink(titleLink); } } } else if (links[0]) { var title = getPageFromUrl(links[0].href); if (title.getNamespaceId() >= 0) { title.namespace |= 1; setTarget(title); } else setTarget(null); } else { setTarget(null); } if (forumId !== 'xebat') { for (var i = 1; i < links.length; ++i) { var title = getPageFromUrl(links[i].href); title.namespace |= 1; addBacklink(title); } } }), age ? el('small', [' (mesaja dawî: ' + age + ')']) : void(0), ']' ], { "class": "mw-editsection" }); insertParent.insertBefore(archiveSpan, insertBefore); } var levels = {}; for (var i = 0; i < headers.length; ++i) { var level = parseInt(headers[i].parentNode.tagName.substr(1), 10); for (var k = 1; k <= 6; ++k) { if (k < level) { if (levels[k]) levels[k].subHeaders.push(headers[i]); } else delete levels[k]; } levels[level] = headers[i]; headers[i].subHeaders = []; } function collectUntilH2(node) { var nodes = []; while (node && (node.tagName !== 'H2')) { if (node.getElementsByTagName && node.getElementsByTagName('h2').length) { return nodes.concat(collectUntilH2(node.firstChild)); } nodes.push(node); node = node.nextSibling; } return nodes; } sectionMapPromise.then(function (sectionMap) { for (var i = 0; i < headers.length; ++i) { /*jshint loopfunc:true */ var links = Array.prototype.filter.call( headers[i].querySelectorAll('a:not(.ext-discussiontools-init-section-subscribe a)'), function (item) { var title = getPageFromUrl(item.href); return title && (title.getNamespaceId() >= 0); } ); if (!links.length) links.unshift(null); for (var j = 0; j < headers[i].subHeaders.length; ++j) { links = links.concat(Array.prototype.filter.call(headers[i].subHeaders[j].querySelectorAll('a:not(.ext-discussiontools-init-section-subscribe a)'), function (item) { var title = getPageFromUrl(item.href); return title && (title.getNamespaceId() >= 0); })); } // Fixed: previously .parentNode.parentNode climbed one level too // high past the .mw-heading wrapper, so collectUntilH2 walked an // unrelated sibling subtree and found no timestamps, leaving `age` // null forever. .parentNode (the .mw-heading div) is the correct // starting point. var nodes = collectUntilH2(headers[i].parentNode.nextSibling); var timestamps = Array.prototype.concat.call(nodes.map(function (node) { return node.textContent || ''; }).join('').match(/(\d\d?):(\d\d),\s*(\d+)\s*(.*?)\s*(\d\d\d\d+)\s*\(UTC\)/g) || [], nodes.map(function(node) { // Comments in Local Time if (!node.getElementsByClassName) return; var nodes = Array.prototype.slice.call(node.getElementsByClassName('localcomments')); if (/(^|\s)localcomments(\s|$)/.test(node.className)) nodes.push(node); return nodes.map(function (node) { return node.title; }); }).reduce(function (accum, item) { return item ? accum.concat(item) : accum; }, [])).map(function (ts) { var m = /(\d\d?):(\d\d),\s*(\d+)\s*(.*?)\s*(\d\d\d\d+)\s*\(UTC\)/.exec(ts); return Date.UTC(parseInt(m[5], 10), revMonthNames[m[4]], parseInt(m[3], 10), parseInt(m[1], 10), parseInt(m[2], 10)); }).sort(); var age = null; if (timestamps.length) { age = Math.floor((Date.now() - timestamps[timestamps.length - 1]) / 86400000) + ' roj'; } var sectionEntry = sectionMap[i]; makeLinkFor(headers[i], links, age, sectionEntry ? sectionEntry.index : null); } }); })(); // </nowiki> 8jjd23ldbgke0k2ob1fppud6qu29thn Bikarhêner:Wikihez/Gadget-QQ.css 2 968235 6265626 6265444 2026-07-19T18:12:24Z Wikihez 7344 6265626 css text/css .kephir-qq { font-size: 10pt; position: fixed !important; width: 40%; left: 30%; top: 3em; border: 1px solid var(--wikt-palette-mint); background: var(--wikt-palette-palegreen); color: var(--wikt-palette-black); z-index: 12; box-sizing: border-box; max-width: 100%; max-height: 90vh; min-width: 20em; min-height: 10em; overflow: auto; /* required for the native resize handle to appear */ resize: both; /* replaces jQuery UI's .resizable() */ display: flex; flex-direction: column; } .kephir-qq .title { padding: 0.15em 0.5em; /* was 0.5em all round — the biggest single contributor to the bar's height */ font-size: 0.85em; /* slightly smaller text so the bar can shrink further */ line-height: 1.6em; background: var(--wikt-palette-mint); cursor: move; flex: 0 0 auto; } .kephir-qq .hide-link { float: right; } .kephir-qq .search-terms { width: 70%; box-sizing: border-box; } .kephir-qq .tabs { flex: 1 1 auto; overflow-y: auto; margin: 0.5em; } .kephir-qq form { clear: both; margin: 0.5em; flex: 0 0 auto; } .kephir-qq .struck { opacity: .3; text-decoration: line-through; } .kephir-qq .hide-struck .struck:not(.taken) { display: none; } .kephir-qq .struck cite > small, .kephir-qq .struck .publisher, .kephir-qq .struck .page { display: none; } .kephir-qq .struck.taken { opacity: .6; text-decoration: none; } .kephir-qq .taken .take-link { font-weight: bold; } .kephir-qq .struck blockquote { display: none; } .kephir-qq .tab-labels { margin: 0; padding: 0; background: var(--wikt-palette-palegreen); flex: 0 0 auto; } .kephir-qq .tab-labels .active { font-weight: bold; } .kephir-qq .tab-labels > .citations-tab { float: right; } .kephir-qq .tab-labels + * { clear: both; } .kephir-qq .tab-labels > li { display: inline-block; } /* OOUI FieldLayout defaults to block-level rows; lay the part-of-speech radios and backend checkboxes out inline like the old <label> markup did */ .kephir-qq .oo-ui-fieldLayout { display: inline-block; margin-right: 0.75em; } .kephir-qq fieldset .oo-ui-fieldLayout { display: inline-block; } /* ── Compact form: shrink OOUI radios, labels, inputs, buttons ── */ .kephir-qq fieldset { font-size: 0.82em; } .kephir-qq fieldset legend { font-size: 1em; } .kephir-qq .oo-ui-fieldLayout-body .oo-ui-labelElement-label { font-size: 1.1em; } .kephir-qq .oo-ui-buttonElement-button { font-size: 0.85em; padding: 2px 8px; min-height: unset; } .kephir-qq .oo-ui-textInputWidget input { font-size: 0.9em; padding: 2px 6px; height: auto; min-height: unset; } /* ── Per-result action links (jê bigere / veşêre / xav) ── */ .kephir-qq li small .qq-take-btn { font-weight: bold; color: var(--wikt-palette-forestgreen); } .kephir-qq li small .qq-hide-btn { color: var(--wikt-palette-dullgold); } /* ── Copy icon button in the citations tab label ── */ .kephir-qq .citations-tab .oo-ui-buttonWidget { vertical-align: middle; margin-left: 2px; } /* Mobile / Minerva: the 40%/30% desktop layout is unusable on phones */ @media (max-width: 720px) { .kephir-qq { width: 94%; left: 3%; right: 3%; top: 3.5em; /* clears Minerva's sticky header */ font-size: 12pt; /* larger touch-friendly text */ resize: none; /* dragging the resize handle with a finger is impractical */ } .kephir-qq .title { padding: 0.3em 0.5em; /* a bit roomier than desktop for touch, still tighter than the old 0.5em all round */ font-size: 1em; } .kephir-qq .search-terms { width: 100%; margin-bottom: 0.4em; } .kephir-qq .oo-ui-fieldLayout { display: block; margin-right: 0; } .kephir-qq input[type="text"] { min-height: 2em; } .kephir-qq .tabs { max-height: 60vh; } .kephir-qq .tab-labels > li > a, .kephir-qq .tab-labels .oo-ui-buttonElement-button { padding: 0.6em 0.5em; /* larger tap targets */ } } kjwdk45r9u8qutq97rwltzzk85cp6vw Bikarhêner:Wikihez/test.js 2 969083 6265630 6265456 2026-07-19T19:17:11Z Wikihez 7344 6265630 javascript text/javascript // <nowiki> if (!String.prototype.format) { String.prototype.format = function(var_args) { var args = arguments; return this.replace(/{(\d+)}/g, function(match, number) { return typeof args[number] !== "undefined" ? args[number] : match; }); }; } $(function() { "use strict"; if ( mw.config.get("wgNamespaceNumber") !== 0 || mw.config.get("wgArticleId") === 0 ) return; console.log("Gadget-wikt.fill-definition.js dest pê dike…"); var NAME = "[[Mediawiki:Gadget-wikt.fill-definition|Pênaseyê temam bike]]"; var VERSION = "1.0"; // Navên şablonên "cihê pênaseya vala". Texmîn dikim her yek ji van şablonan // di derana xwe de hêmanek bi vê heman navê wek çîn (class) çêdike, wek meriv // {{nm}} li ser add-examples.js hêmana bi çîna "benimune" çêdike. Eger ne // wisa be, tenê selectorê li jêr (PLACEHOLDER_SELECTOR) biguherîne. var PLACEHOLDER_TEMPLATES = ["bêmane", "bêwate", "wate", "mane"]; var PLACEHOLDER_SELECTOR = PLACEHOLDER_TEMPLATES.map(function(name) { return "li ." + name; }).join(", "); var sectionNames = { "Navdêr": ["Navdêr"], "Formeke navdêrê": ["Formeke navdêrê"], "Lêker": ["Lêker"], "Formeke lêkerê": ["Formeke lêkerê"], "Rengdêr": ["Rengdêr"], "Formeke rengdêrê": ["Formeke rengdêrê"], "Hoker": ["Hoker"], "Formeke hokerê": ["Formeke hokerê"], "Serenav": ["Serenav"], "Formeke serenavê": ["Formeke serenavê"], "Artîkel": ["Artîkel"], "Baneşan": ["Baneşan"], "Bazinedaçek": ["Bazinedaçek"], "Biwêj": ["Biwêj"], "Cînav": ["Cînav"], "Daçek": ["Daçek"], "Girêdek": ["Girêdek"], "Gotineke pêşiyan": ["Gotineke pêşiyan"], "Hejmar": ["Hejmar"], "Hevok": ["Hevok"], "Îfade": ["Îfade"], "Kurtenav": ["Kurtenav"], "Navgir": ["Navgir"], "Paşdaçek": ["Paşdaçek"], "Paşgir": ["Paşgir"], "Pêşdaçek": ["Pêşdaçek"], "Pêşgir": ["Pêşgir"], "Pirtik": ["Pirtik"], "Reh": ["Reh"], "Sembol": ["Sembol"], "Tîp": ["Tîp"] }; var languages = {}; var api = new mw.Api(); api.get({ action: "query", format: "json", titles: "MediaWiki:Gadget-translation editor.js/ziman.json", prop: "revisions", rvprop: "content", rvslots: "main", }).then(function(data) { for (var pageID in data.query.pages) { if (Object.prototype.hasOwnProperty.call(data.query.pages, pageID)) { languages = JSON.parse(data.query.pages[pageID].revisions[0].slots.main["*"]); break; } } init(); }, init); // heke barkirin bi ser nekeve jî, dîsa jî hewl bide bidomîne /** * Wîkîlînkan li nivîsê zêde dike bi karanîna amûra linkify. * @param text {string} * @param callback {function(string)} */ function linkify(text, callback) { var didTryToLoad = function() { if (typeof $.wiktviLinkify === "function") { $.wiktviLinkify(text, function(linked) { callback(linked); }); } else { callback(text); } }; mw.loader.using("ext.gadget.linkify", didTryToLoad, didTryToLoad); } /** * Ji hêmaneke <li> (definîsyona xwe), definitionLevel (mîna ya li * add-examples.js) û koda zimanê wê hesab dike, bi vegerîna heman şêwazê * jorîn (jimartina li:not(.mw-empty-elt) berî xwe, heta li beşa h3/h2 tê). * @param $li {jQuery} * @return {{definitionLevel: Array<string|number>, language: string}|null} */ function resolveDefinition($li) { var definitionLevel = []; var $definitionItem = $li; var $topItem; do { definitionLevel.splice(0, 0, $definitionItem.prevAll("li:not(.mw-empty-elt)").length); $topItem = $definitionItem; $definitionItem = $definitionItem.parent().parent(); } while ($definitionItem.prop("tagName") === "LI"); var $ol = $topItem.parent(); var $h3Wrap = $($ol.prevAll(".mw-heading3, h3").get(0)); if (!$h3Wrap.length) return null; var $h3 = $h3Wrap.find("h3").length ? $h3Wrap.find("h3") : $h3Wrap; definitionLevel.splice(0, 0, $h3.attr("id")); var $h2Wrap = $($h3Wrap.prevAll(".mw-heading2, h2").get(0)); if (!$h2Wrap.length) return null; var $h2 = $h2Wrap.find("h2").length ? $h2Wrap.find("h2") : $h2Wrap; var languageName = $h2.text().trim(); var languageCode = null; for (var code in languages) { if (languages.hasOwnProperty(code) && languages[code] === languageName) { languageCode = code; break; } } if (!languageCode) return null; return { definitionLevel: definitionLevel, language: languageCode }; } function init() { $(PLACEHOLDER_SELECTOR).each(function() { var $placeholder = $(this); var $item = $placeholder.closest("li"); if (!$item.length || $item.data("fillDefinitionDone")) return; $item.data("fillDefinitionDone", true); var resolved = resolveDefinition($item); if (!resolved) { console.warn("Gadget-wikt.fill-definition: Section/ziman nehat dîtin ji bo:", $item); return; } var $button = $("<a href='#'>Pênaseyê temam bike</a>"); $button.css("color", "var( --color-progressive, #3366cc )"); $button.on("click", function() { if (!$button.form) { $button.form = new Form($item, $placeholder, resolved.definitionLevel, resolved.language); $item.append($button.form.$element); } $button.form.setVisible(true); return false; }); $placeholder.after(" ").after($button); }); } /** * Forma pêşxistina pênaseyê. * @param $item {jQuery} Hêmana <li> ya definîsyonê. * @param $placeholder {jQuery} Hêmana şablona vala (bêmane/bêwate/…) di hundirê wê de. * @param definitionLevel {Array<string|number>} * @param language {string} * @constructor */ function Form($item, $placeholder, definitionLevel, language) { var self = this; this._$item = $item; this._$placeholder = $placeholder; this._definitionLevel = definitionLevel; this._language = language; this._textInput = new OO.ui.MultilineTextInputWidget({ autosize: true, rows: 2 }); var textInputLayout = new OO.ui.FieldLayout(this._textInput, { label: "Pênase", align: "top", }); this._textInput.on("change", function(value) { var empty = !value.trim(); self._previewButton.setDisabled(empty); self._applyButton.setDisabled(empty); }); this._previewButton = new OO.ui.ButtonWidget({ label: "Pêşdîtin", disabled: true, }); this._previewButton.on("click", this.preview.bind(this)); this._applyButton = new OO.ui.ButtonWidget({ label: "Tomar bike", flags: ["progressive", "primary"], disabled: true, }); this._applyButton.on("click", this.submit.bind(this)); this._cancelButton = new OO.ui.ButtonWidget({ label: "Betal bike", flags: ["destructive"], }); this._cancelButton.on("click", function() { self.setVisible(false); }); this._loadingImage = new OO.ui.LabelWidget({ label: $('<img src="https://upload.wikimedia.org/wikipedia/commons/7/7a/Ajax_loader_metal_512.gif" alt="loading" style="width: 1.5em">'), }); this._loadingImage.toggle(false); this._previewArea = $("<div class='fill-definition-preview' style='margin-top:0.5em;padding:0.3em 0.6em;border:1px dashed #aaa;'></div>").hide(); var fieldsLayout = new OO.ui.FieldsetLayout({ label: "Pênaseyeke bi " + (languages[this._language] || "zimanekî nenas") + " lê zêde dikî.", items: [textInputLayout], classes: ["fill-definition-fieldset"], }); var buttonsLayout = new OO.ui.HorizontalLayout({ items: [this._previewButton, this._applyButton, this._cancelButton, this._loadingImage], }); this._frame = new OO.ui.PanelLayout({ classes: ["fill-definition-form"], expanded: false, content: [fieldsLayout, buttonsLayout, this._previewArea], }); } Form.prototype = { get $element() { return this._frame.$element; }, setVisible: function(visible) { this._frame.toggle(visible); }, /** * Nivîsê linkify dike û bi rastî bi mw.Api parse dike da ku were xuyakirin * çawa dê xuya bike piştî tomarkirinê. */ preview: function() { var self = this; var text = this._textInput.getValue().trim(); if (!text) return; this._previewButton.setDisabled(true); this._loadingImage.toggle(true); linkify(text, function(linked) { api.parse("# " + linked, { title: mw.config.get("wgPageName") }).done(function(html) { self._previewArea.html(html).show(); }).fail(function() { self._previewArea.text(linked).show(); }).always(function() { self._previewButton.setDisabled(false); self._loadingImage.toggle(false); }); }); }, /** * Şablona vala di wîkîkoda rûpelê de bi nivîsa (linkify-kirî) diguherîne. */ submit: function() { var self = this; var text = this._textInput.getValue().trim(); if (!text) return; this._textInput.setDisabled(true); this._previewButton.setDisabled(true); this._applyButton.setDisabled(true); this._cancelButton.setDisabled(true); this._loadingImage.toggle(true); function reenable() { self._textInput.setDisabled(false); self._previewButton.setDisabled(false); self._applyButton.setDisabled(false); self._cancelButton.setDisabled(false); self._loadingImage.toggle(false); } function error(msg) { mw.notify(msg || "Nimûne nehat weşandin, îhtimalen rûpel hate guhartin. Ji kerema xwe re rûpelê dîsa bar bike û dîsa biceribîne."); reenable(); } linkify(text, function(linked) { api.get({ action: "query", titles: mw.config.get("wgPageName"), prop: "revisions", rvprop: "content", rvslots: "main", }).then(function(data) { var pageContent; for (var pageID in data.query.pages) { if (Object.prototype.hasOwnProperty.call(data.query.pages, pageID)) { languages = JSON.parse(data.query.pages[pageID].revisions[0].slots.main["*"]); break; } } var langSectionRegex = new RegExp("==[ ]*{{ziman\\|{0}}}[ ]*==".format(self._language)); var langSectionIndex = pageContent.search(langSectionRegex); if (langSectionIndex === -1) { error("Xeletiyeke bi koda zimanî heye. Koda zimanî: " + self._language); return; } var lines = pageContent.slice(langSectionIndex).split("\n"); var sectionNamesRegex = Object.keys(sectionNames).join('|'); var sectionRegex = new RegExp('^===[ ]*(' + sectionNamesRegex + ')\\s*(\\d+)?'); var targetLineIndex; var sectionIDPattern = new RegExp("^([\\wîêçş_]+?)_?(\\d+)?_?(\\d+)?$"); var matchSectionID = sectionIDPattern.exec(self._definitionLevel[0]); var sectionType = matchSectionID[1].replace(/_/, ' '); sectionType = sectionType.replace(/_\d+$/, ''); var sectionNum = matchSectionID[2] ? parseInt(matchSectionID[2]) : ""; for (targetLineIndex = 0; targetLineIndex < lines.length; targetLineIndex++) { var line = lines[targetLineIndex]; var matchSection = sectionRegex.exec(line); if (matchSection) { var matchedSectionName = matchSection[1]; var matchedSectionNum = matchSection[2]; if (!sectionNames[sectionType]) { error('Navê beşê xelet e.'); return; } if (sectionNames[sectionType].includes(matchedSectionName)) { if (!matchedSectionNum || line.includes(" " + matchedSectionNum)) { break; } } } } if (targetLineIndex === lines.length) { error("Di navê beşê de xeletî heye. Îhtimalen bi vî navê beşê çend heb hene."); return; } var defIndex = -1; var level = 1; for (; targetLineIndex < lines.length; targetLineIndex++) { var m = /^(#+)[^*#:]/.exec(lines[targetLineIndex]); if (m) { if (level === m[1].length) { defIndex++; if (self._definitionLevel[level] === defIndex) { if (level === self._definitionLevel.length - 1) { break; } else { level++; defIndex = -1; } } } } } if (targetLineIndex === lines.length) { error("Definîsyon nehat dîtin, îhtimalen rûpel hate guhartin."); return; } var markerMatch = /^(#+)\s*/.exec(lines[targetLineIndex]); var marker = markerMatch ? markerMatch[1] : "#"; var newLine = marker + " " + linked; lines[targetLineIndex] = newLine; api.edit(mw.config.get("wgPageName"), function() { return { text: pageContent.slice(0, langSectionIndex) + lines.join("\n"), summary: "pênase hat temamkirin bi amûra «\u00a0{0}\u00a0» (v{1}).".format(NAME, VERSION), }; }).then(function() { api.parse(newLine).done(function(html) { var $rendered = $(html).find("li").first(); self._$item.html($rendered.length ? $rendered.html() : linked); self._$item.css("background-color", "lightgreen"); setTimeout(function() { self._$item.css("background-color", "inherit"); }, 1000); }); self.setVisible(false); reenable(); }, function() { error("Tomarkirin serneket."); }); }); }); }, }; }); // </nowiki> c54bqxpn6bmezu9ti4f7r62mj2ccx15 6265631 6265630 2026-07-19T19:18:03Z Wikihez 7344 6265631 javascript text/javascript // <nowiki> if (!String.prototype.format) { String.prototype.format = function(var_args) { var args = arguments; return this.replace(/{(\d+)}/g, function(match, number) { return typeof args[number] !== "undefined" ? args[number] : match; }); }; } $(function() { "use strict"; if ( mw.config.get("wgNamespaceNumber") == 0 || mw.config.get("wgArticleId") === 0 ) return; console.log("Gadget-wikt.fill-definition.js dest pê dike…"); var NAME = "[[Mediawiki:Gadget-wikt.fill-definition|Pênaseyê temam bike]]"; var VERSION = "1.0"; // Navên şablonên "cihê pênaseya vala". Texmîn dikim her yek ji van şablonan // di derana xwe de hêmanek bi vê heman navê wek çîn (class) çêdike, wek meriv // {{nm}} li ser add-examples.js hêmana bi çîna "benimune" çêdike. Eger ne // wisa be, tenê selectorê li jêr (PLACEHOLDER_SELECTOR) biguherîne. var PLACEHOLDER_TEMPLATES = ["bêmane", "bêwate", "wate", "mane"]; var PLACEHOLDER_SELECTOR = PLACEHOLDER_TEMPLATES.map(function() { return "li .manelazim"; }).join(", "); var sectionNames = { "Navdêr": ["Navdêr"], "Formeke navdêrê": ["Formeke navdêrê"], "Lêker": ["Lêker"], "Formeke lêkerê": ["Formeke lêkerê"], "Rengdêr": ["Rengdêr"], "Formeke rengdêrê": ["Formeke rengdêrê"], "Hoker": ["Hoker"], "Formeke hokerê": ["Formeke hokerê"], "Serenav": ["Serenav"], "Formeke serenavê": ["Formeke serenavê"], "Artîkel": ["Artîkel"], "Baneşan": ["Baneşan"], "Bazinedaçek": ["Bazinedaçek"], "Biwêj": ["Biwêj"], "Cînav": ["Cînav"], "Daçek": ["Daçek"], "Girêdek": ["Girêdek"], "Gotineke pêşiyan": ["Gotineke pêşiyan"], "Hejmar": ["Hejmar"], "Hevok": ["Hevok"], "Îfade": ["Îfade"], "Kurtenav": ["Kurtenav"], "Navgir": ["Navgir"], "Paşdaçek": ["Paşdaçek"], "Paşgir": ["Paşgir"], "Pêşdaçek": ["Pêşdaçek"], "Pêşgir": ["Pêşgir"], "Pirtik": ["Pirtik"], "Reh": ["Reh"], "Sembol": ["Sembol"], "Tîp": ["Tîp"] }; var languages = {}; var api = new mw.Api(); api.get({ action: "query", format: "json", titles: "MediaWiki:Gadget-translation editor.js/ziman.json", prop: "revisions", rvprop: "content", rvslots: "main", }).then(function(data) { for (var pageID in data.query.pages) { if (Object.prototype.hasOwnProperty.call(data.query.pages, pageID)) { languages = JSON.parse(data.query.pages[pageID].revisions[0].slots.main["*"]); break; } } init(); }, init); // heke barkirin bi ser nekeve jî, dîsa jî hewl bide bidomîne /** * Wîkîlînkan li nivîsê zêde dike bi karanîna amûra linkify. * @param text {string} * @param callback {function(string)} */ function linkify(text, callback) { var didTryToLoad = function() { if (typeof $.wiktviLinkify === "function") { $.wiktviLinkify(text, function(linked) { callback(linked); }); } else { callback(text); } }; mw.loader.using("ext.gadget.linkify", didTryToLoad, didTryToLoad); } /** * Ji hêmaneke <li> (definîsyona xwe), definitionLevel (mîna ya li * add-examples.js) û koda zimanê wê hesab dike, bi vegerîna heman şêwazê * jorîn (jimartina li:not(.mw-empty-elt) berî xwe, heta li beşa h3/h2 tê). * @param $li {jQuery} * @return {{definitionLevel: Array<string|number>, language: string}|null} */ function resolveDefinition($li) { var definitionLevel = []; var $definitionItem = $li; var $topItem; do { definitionLevel.splice(0, 0, $definitionItem.prevAll("li:not(.mw-empty-elt)").length); $topItem = $definitionItem; $definitionItem = $definitionItem.parent().parent(); } while ($definitionItem.prop("tagName") === "LI"); var $ol = $topItem.parent(); var $h3Wrap = $($ol.prevAll(".mw-heading3, h3").get(0)); if (!$h3Wrap.length) return null; var $h3 = $h3Wrap.find("h3").length ? $h3Wrap.find("h3") : $h3Wrap; definitionLevel.splice(0, 0, $h3.attr("id")); var $h2Wrap = $($h3Wrap.prevAll(".mw-heading2, h2").get(0)); if (!$h2Wrap.length) return null; var $h2 = $h2Wrap.find("h2").length ? $h2Wrap.find("h2") : $h2Wrap; var languageName = $h2.text().trim(); var languageCode = null; for (var code in languages) { if (languages.hasOwnProperty(code) && languages[code] === languageName) { languageCode = code; break; } } if (!languageCode) return null; return { definitionLevel: definitionLevel, language: languageCode }; } function init() { $(PLACEHOLDER_SELECTOR).each(function() { var $placeholder = $(this); var $item = $placeholder.closest("li"); if (!$item.length || $item.data("fillDefinitionDone")) return; $item.data("fillDefinitionDone", true); var resolved = resolveDefinition($item); if (!resolved) { console.warn("Gadget-wikt.fill-definition: Section/ziman nehat dîtin ji bo:", $item); return; } var $button = $("<a href='#'>Pênaseyê temam bike</a>"); $button.css("color", "var( --color-progressive, #3366cc )"); $button.on("click", function() { if (!$button.form) { $button.form = new Form($item, $placeholder, resolved.definitionLevel, resolved.language); $item.append($button.form.$element); } $button.form.setVisible(true); return false; }); $placeholder.after(" ").after($button); }); } /** * Forma pêşxistina pênaseyê. * @param $item {jQuery} Hêmana <li> ya definîsyonê. * @param $placeholder {jQuery} Hêmana şablona vala (bêmane/bêwate/…) di hundirê wê de. * @param definitionLevel {Array<string|number>} * @param language {string} * @constructor */ function Form($item, $placeholder, definitionLevel, language) { var self = this; this._$item = $item; this._$placeholder = $placeholder; this._definitionLevel = definitionLevel; this._language = language; this._textInput = new OO.ui.MultilineTextInputWidget({ autosize: true, rows: 2 }); var textInputLayout = new OO.ui.FieldLayout(this._textInput, { label: "Pênase", align: "top", }); this._textInput.on("change", function(value) { var empty = !value.trim(); self._previewButton.setDisabled(empty); self._applyButton.setDisabled(empty); }); this._previewButton = new OO.ui.ButtonWidget({ label: "Pêşdîtin", disabled: true, }); this._previewButton.on("click", this.preview.bind(this)); this._applyButton = new OO.ui.ButtonWidget({ label: "Tomar bike", flags: ["progressive", "primary"], disabled: true, }); this._applyButton.on("click", this.submit.bind(this)); this._cancelButton = new OO.ui.ButtonWidget({ label: "Betal bike", flags: ["destructive"], }); this._cancelButton.on("click", function() { self.setVisible(false); }); this._loadingImage = new OO.ui.LabelWidget({ label: $('<img src="https://upload.wikimedia.org/wikipedia/commons/7/7a/Ajax_loader_metal_512.gif" alt="loading" style="width: 1.5em">'), }); this._loadingImage.toggle(false); this._previewArea = $("<div class='fill-definition-preview' style='margin-top:0.5em;padding:0.3em 0.6em;border:1px dashed #aaa;'></div>").hide(); var fieldsLayout = new OO.ui.FieldsetLayout({ label: "Pênaseyeke bi " + (languages[this._language] || "zimanekî nenas") + " lê zêde dikî.", items: [textInputLayout], classes: ["fill-definition-fieldset"], }); var buttonsLayout = new OO.ui.HorizontalLayout({ items: [this._previewButton, this._applyButton, this._cancelButton, this._loadingImage], }); this._frame = new OO.ui.PanelLayout({ classes: ["fill-definition-form"], expanded: false, content: [fieldsLayout, buttonsLayout, this._previewArea], }); } Form.prototype = { get $element() { return this._frame.$element; }, setVisible: function(visible) { this._frame.toggle(visible); }, /** * Nivîsê linkify dike û bi rastî bi mw.Api parse dike da ku were xuyakirin * çawa dê xuya bike piştî tomarkirinê. */ preview: function() { var self = this; var text = this._textInput.getValue().trim(); if (!text) return; this._previewButton.setDisabled(true); this._loadingImage.toggle(true); linkify(text, function(linked) { api.parse("# " + linked, { title: mw.config.get("wgPageName") }).done(function(html) { self._previewArea.html(html).show(); }).fail(function() { self._previewArea.text(linked).show(); }).always(function() { self._previewButton.setDisabled(false); self._loadingImage.toggle(false); }); }); }, /** * Şablona vala di wîkîkoda rûpelê de bi nivîsa (linkify-kirî) diguherîne. */ submit: function() { var self = this; var text = this._textInput.getValue().trim(); if (!text) return; this._textInput.setDisabled(true); this._previewButton.setDisabled(true); this._applyButton.setDisabled(true); this._cancelButton.setDisabled(true); this._loadingImage.toggle(true); function reenable() { self._textInput.setDisabled(false); self._previewButton.setDisabled(false); self._applyButton.setDisabled(false); self._cancelButton.setDisabled(false); self._loadingImage.toggle(false); } function error(msg) { mw.notify(msg || "Nimûne nehat weşandin, îhtimalen rûpel hate guhartin. Ji kerema xwe re rûpelê dîsa bar bike û dîsa biceribîne."); reenable(); } linkify(text, function(linked) { api.get({ action: "query", titles: mw.config.get("wgPageName"), prop: "revisions", rvprop: "content", rvslots: "main", }).then(function(data) { var pageContent; for (var pageID in data.query.pages) { if (Object.prototype.hasOwnProperty.call(data.query.pages, pageID)) { languages = JSON.parse(data.query.pages[pageID].revisions[0].slots.main["*"]); break; } } var langSectionRegex = new RegExp("==[ ]*{{ziman\\|{0}}}[ ]*==".format(self._language)); var langSectionIndex = pageContent.search(langSectionRegex); if (langSectionIndex === -1) { error("Xeletiyeke bi koda zimanî heye. Koda zimanî: " + self._language); return; } var lines = pageContent.slice(langSectionIndex).split("\n"); var sectionNamesRegex = Object.keys(sectionNames).join('|'); var sectionRegex = new RegExp('^===[ ]*(' + sectionNamesRegex + ')\\s*(\\d+)?'); var targetLineIndex; var sectionIDPattern = new RegExp("^([\\wîêçş_]+?)_?(\\d+)?_?(\\d+)?$"); var matchSectionID = sectionIDPattern.exec(self._definitionLevel[0]); var sectionType = matchSectionID[1].replace(/_/, ' '); sectionType = sectionType.replace(/_\d+$/, ''); var sectionNum = matchSectionID[2] ? parseInt(matchSectionID[2]) : ""; for (targetLineIndex = 0; targetLineIndex < lines.length; targetLineIndex++) { var line = lines[targetLineIndex]; var matchSection = sectionRegex.exec(line); if (matchSection) { var matchedSectionName = matchSection[1]; var matchedSectionNum = matchSection[2]; if (!sectionNames[sectionType]) { error('Navê beşê xelet e.'); return; } if (sectionNames[sectionType].includes(matchedSectionName)) { if (!matchedSectionNum || line.includes(" " + matchedSectionNum)) { break; } } } } if (targetLineIndex === lines.length) { error("Di navê beşê de xeletî heye. Îhtimalen bi vî navê beşê çend heb hene."); return; } var defIndex = -1; var level = 1; for (; targetLineIndex < lines.length; targetLineIndex++) { var m = /^(#+)[^*#:]/.exec(lines[targetLineIndex]); if (m) { if (level === m[1].length) { defIndex++; if (self._definitionLevel[level] === defIndex) { if (level === self._definitionLevel.length - 1) { break; } else { level++; defIndex = -1; } } } } } if (targetLineIndex === lines.length) { error("Definîsyon nehat dîtin, îhtimalen rûpel hate guhartin."); return; } var markerMatch = /^(#+)\s*/.exec(lines[targetLineIndex]); var marker = markerMatch ? markerMatch[1] : "#"; var newLine = marker + " " + linked; lines[targetLineIndex] = newLine; api.edit(mw.config.get("wgPageName"), function() { return { text: pageContent.slice(0, langSectionIndex) + lines.join("\n"), summary: "pênase hat temamkirin bi amûra «\u00a0{0}\u00a0» (v{1}).".format(NAME, VERSION), }; }).then(function() { api.parse(newLine).done(function(html) { var $rendered = $(html).find("li").first(); self._$item.html($rendered.length ? $rendered.html() : linked); self._$item.css("background-color", "lightgreen"); setTimeout(function() { self._$item.css("background-color", "inherit"); }, 1000); }); self.setVisible(false); reenable(); }, function() { error("Tomarkirin serneket."); }); }); }); }, }; }); // </nowiki> tc8h5c1c4zxxywu12i1l05ksnotnowh 6265635 6265631 2026-07-19T19:25:50Z Wikihez 7344 6265635 javascript text/javascript // <nowiki> if (!String.prototype.format) { String.prototype.format = function(var_args) { var args = arguments; return this.replace(/{(\d+)}/g, function(match, number) { return typeof args[number] !== "undefined" ? args[number] : match; }); }; } $(function() { "use strict"; if ( mw.config.get("wgNamespaceNumber") == 0 || mw.config.get("wgArticleId") === 0 ) return; console.log("Gadget-wikt.fill-definition.js dest pê dike…"); var NAME = "[[Mediawiki:Gadget-wikt.fill-definition|Pênaseyê temam bike]]"; var VERSION = "1.0"; // Navên şablonên "cihê pênaseya vala". Texmîn dikim her yek ji van şablonan // di derana xwe de hêmanek bi vê heman navê wek çîn (class) çêdike, wek meriv // {{nm}} li ser add-examples.js hêmana bi çîna "benimune" çêdike. Eger ne // wisa be, tenê selectorê li jêr (PLACEHOLDER_SELECTOR) biguherîne. var PLACEHOLDER_SELECTOR = "li .manelazim" var sectionNames = { "Navdêr": ["Navdêr"], "Formeke navdêrê": ["Formeke navdêrê"], "Lêker": ["Lêker"], "Formeke lêkerê": ["Formeke lêkerê"], "Rengdêr": ["Rengdêr"], "Formeke rengdêrê": ["Formeke rengdêrê"], "Hoker": ["Hoker"], "Formeke hokerê": ["Formeke hokerê"], "Serenav": ["Serenav"], "Formeke serenavê": ["Formeke serenavê"], "Artîkel": ["Artîkel"], "Baneşan": ["Baneşan"], "Bazinedaçek": ["Bazinedaçek"], "Biwêj": ["Biwêj"], "Cînav": ["Cînav"], "Daçek": ["Daçek"], "Girêdek": ["Girêdek"], "Gotineke pêşiyan": ["Gotineke pêşiyan"], "Hejmar": ["Hejmar"], "Hevok": ["Hevok"], "Îfade": ["Îfade"], "Kurtenav": ["Kurtenav"], "Navgir": ["Navgir"], "Paşdaçek": ["Paşdaçek"], "Paşgir": ["Paşgir"], "Pêşdaçek": ["Pêşdaçek"], "Pêşgir": ["Pêşgir"], "Pirtik": ["Pirtik"], "Reh": ["Reh"], "Sembol": ["Sembol"], "Tîp": ["Tîp"] }; var languages = {}; var api = new mw.Api(); api.get({ action: "query", format: "json", titles: "MediaWiki:Gadget-translation editor.js/ziman.json", prop: "revisions", rvprop: "content", rvslots: "main", }).then(function(data) { for (var pageID in data.query.pages) { if (Object.prototype.hasOwnProperty.call(data.query.pages, pageID)) { languages = JSON.parse(data.query.pages[pageID].revisions[0].slots.main["*"]); break; } } init(); }, init); // heke barkirin bi ser nekeve jî, dîsa jî hewl bide bidomîne /** * Wîkîlînkan li nivîsê zêde dike bi karanîna amûra linkify. * @param text {string} * @param callback {function(string)} */ function linkify(text, callback) { var didTryToLoad = function() { if (typeof $.wiktviLinkify === "function") { $.wiktviLinkify(text, function(linked) { callback(linked); }); } else { callback(text); } }; mw.loader.using("ext.gadget.linkify", didTryToLoad, didTryToLoad); } /** * Ji hêmaneke <li> (definîsyona xwe), definitionLevel (mîna ya li * add-examples.js) û koda zimanê wê hesab dike, bi vegerîna heman şêwazê * jorîn (jimartina li:not(.mw-empty-elt) berî xwe, heta li beşa h3/h2 tê). * @param $li {jQuery} * @return {{definitionLevel: Array<string|number>, language: string}|null} */ function resolveDefinition($li) { var definitionLevel = []; var $definitionItem = $li; var $topItem; do { definitionLevel.splice(0, 0, $definitionItem.prevAll("li:not(.mw-empty-elt)").length); $topItem = $definitionItem; $definitionItem = $definitionItem.parent().parent(); } while ($definitionItem.prop("tagName") === "LI"); var $ol = $topItem.parent(); var $h3Wrap = $($ol.prevAll(".mw-heading3, h3").get(0)); if (!$h3Wrap.length) return null; var $h3 = $h3Wrap.find("h3").length ? $h3Wrap.find("h3") : $h3Wrap; definitionLevel.splice(0, 0, $h3.attr("id")); var $h2Wrap = $($h3Wrap.prevAll(".mw-heading2, h2").get(0)); if (!$h2Wrap.length) return null; var $h2 = $h2Wrap.find("h2").length ? $h2Wrap.find("h2") : $h2Wrap; var languageName = $h2.text().trim(); var languageCode = null; for (var code in languages) { if (languages.hasOwnProperty(code) && languages[code] === languageName) { languageCode = code; break; } } if (!languageCode) return null; return { definitionLevel: definitionLevel, language: languageCode }; } function init() { $(PLACEHOLDER_SELECTOR).each(function() { var $placeholder = $(this); var $item = $placeholder.closest("li"); if (!$item.length || $item.data("fillDefinitionDone")) return; $item.data("fillDefinitionDone", true); var resolved = resolveDefinition($item); if (!resolved) { console.warn("Gadget-wikt.fill-definition: Section/ziman nehat dîtin ji bo:", $item); return; } var $button = $("<a href='#'>Pênaseyê temam bike</a>"); $button.css("color", "var( --color-progressive, #3366cc )"); $button.on("click", function() { if (!$button.form) { $button.form = new Form($item, $placeholder, resolved.definitionLevel, resolved.language); $item.append($button.form.$element); } $button.form.setVisible(true); return false; }); $placeholder.after(" ").after($button); }); } /** * Forma pêşxistina pênaseyê. * @param $item {jQuery} Hêmana <li> ya definîsyonê. * @param $placeholder {jQuery} Hêmana şablona vala (bêmane/bêwate/…) di hundirê wê de. * @param definitionLevel {Array<string|number>} * @param language {string} * @constructor */ function Form($item, $placeholder, definitionLevel, language) { var self = this; this._$item = $item; this._$placeholder = $placeholder; this._definitionLevel = definitionLevel; this._language = language; this._textInput = new OO.ui.MultilineTextInputWidget({ autosize: true, rows: 2 }); var textInputLayout = new OO.ui.FieldLayout(this._textInput, { label: "Pênase", align: "top", }); this._textInput.on("change", function(value) { var empty = !value.trim(); self._previewButton.setDisabled(empty); self._applyButton.setDisabled(empty); }); this._previewButton = new OO.ui.ButtonWidget({ label: "Pêşdîtin", disabled: true, }); this._previewButton.on("click", this.preview.bind(this)); this._applyButton = new OO.ui.ButtonWidget({ label: "Tomar bike", flags: ["progressive", "primary"], disabled: true, }); this._applyButton.on("click", this.submit.bind(this)); this._cancelButton = new OO.ui.ButtonWidget({ label: "Betal bike", flags: ["destructive"], }); this._cancelButton.on("click", function() { self.setVisible(false); }); this._loadingImage = new OO.ui.LabelWidget({ label: $('<img src="https://upload.wikimedia.org/wikipedia/commons/7/7a/Ajax_loader_metal_512.gif" alt="loading" style="width: 1.5em">'), }); this._loadingImage.toggle(false); this._previewArea = $("<div class='fill-definition-preview' style='margin-top:0.5em;padding:0.3em 0.6em;border:1px dashed #aaa;'></div>").hide(); var fieldsLayout = new OO.ui.FieldsetLayout({ label: "Pênaseyeke bi " + (languages[this._language] || "zimanekî nenas") + " lê zêde dikî.", items: [textInputLayout], classes: ["fill-definition-fieldset"], }); var buttonsLayout = new OO.ui.HorizontalLayout({ items: [this._previewButton, this._applyButton, this._cancelButton, this._loadingImage], }); this._frame = new OO.ui.PanelLayout({ classes: ["fill-definition-form"], expanded: false, content: [fieldsLayout, buttonsLayout, this._previewArea], }); } Form.prototype = { get $element() { return this._frame.$element; }, setVisible: function(visible) { this._frame.toggle(visible); }, /** * Nivîsê linkify dike û bi rastî bi mw.Api parse dike da ku were xuyakirin * çawa dê xuya bike piştî tomarkirinê. */ preview: function() { var self = this; var text = this._textInput.getValue().trim(); if (!text) return; this._previewButton.setDisabled(true); this._loadingImage.toggle(true); linkify(text, function(linked) { api.parse("# " + linked, { title: mw.config.get("wgPageName") }).done(function(html) { self._previewArea.html(html).show(); }).fail(function() { self._previewArea.text(linked).show(); }).always(function() { self._previewButton.setDisabled(false); self._loadingImage.toggle(false); }); }); }, /** * Şablona vala di wîkîkoda rûpelê de bi nivîsa (linkify-kirî) diguherîne. */ submit: function() { var self = this; var text = this._textInput.getValue().trim(); if (!text) return; this._textInput.setDisabled(true); this._previewButton.setDisabled(true); this._applyButton.setDisabled(true); this._cancelButton.setDisabled(true); this._loadingImage.toggle(true); function reenable() { self._textInput.setDisabled(false); self._previewButton.setDisabled(false); self._applyButton.setDisabled(false); self._cancelButton.setDisabled(false); self._loadingImage.toggle(false); } function error(msg) { mw.notify(msg || "Nimûne nehat weşandin, îhtimalen rûpel hate guhartin. Ji kerema xwe re rûpelê dîsa bar bike û dîsa biceribîne."); reenable(); } linkify(text, function(linked) { api.get({ action: "query", titles: mw.config.get("wgPageName"), prop: "revisions", rvprop: "content", rvslots: "main", }).then(function(data) { var pageContent; for (var pageID in data.query.pages) { if (Object.prototype.hasOwnProperty.call(data.query.pages, pageID)) { pageContent = data.query.pages[pageID].revisions[0].slots.main["*"]; break; } } var langSectionRegex = new RegExp("==[ ]*{{ziman\\|{0}}}[ ]*==".format(self._language)); var langSectionIndex = pageContent.search(langSectionRegex); if (langSectionIndex === -1) { error("Xeletiyeke bi koda zimanî heye. Koda zimanî: " + self._language); return; } var lines = pageContent.slice(langSectionIndex).split("\n"); var sectionNamesRegex = Object.keys(sectionNames).join('|'); var sectionRegex = new RegExp('^===[ ]*(' + sectionNamesRegex + ')\\s*(\\d+)?'); var targetLineIndex; var sectionIDPattern = new RegExp("^([\\wîêçş_]+?)_?(\\d+)?_?(\\d+)?$"); var matchSectionID = sectionIDPattern.exec(self._definitionLevel[0]); var sectionType = matchSectionID[1].replace(/_/, ' '); sectionType = sectionType.replace(/_\d+$/, ''); var sectionNum = matchSectionID[2] ? parseInt(matchSectionID[2]) : ""; for (targetLineIndex = 0; targetLineIndex < lines.length; targetLineIndex++) { var line = lines[targetLineIndex]; var matchSection = sectionRegex.exec(line); if (matchSection) { var matchedSectionName = matchSection[1]; var matchedSectionNum = matchSection[2]; if (!sectionNames[sectionType]) { error('Navê beşê xelet e.'); return; } if (sectionNames[sectionType].includes(matchedSectionName)) { if (!matchedSectionNum || line.includes(" " + matchedSectionNum)) { break; } } } } if (targetLineIndex === lines.length) { error("Di navê beşê de xeletî heye. Îhtimalen bi vî navê beşê çend heb hene."); return; } var defIndex = -1; var level = 1; for (; targetLineIndex < lines.length; targetLineIndex++) { var m = /^(#+)[^*#:]/.exec(lines[targetLineIndex]); if (m) { if (level === m[1].length) { defIndex++; if (self._definitionLevel[level] === defIndex) { if (level === self._definitionLevel.length - 1) { break; } else { level++; defIndex = -1; } } } } } if (targetLineIndex === lines.length) { error("Definîsyon nehat dîtin, îhtimalen rûpel hate guhartin."); return; } var markerMatch = /^(#+)\s*/.exec(lines[targetLineIndex]); var marker = markerMatch ? markerMatch[1] : "#"; var newLine = marker + " " + linked; lines[targetLineIndex] = newLine; api.edit(mw.config.get("wgPageName"), function() { return { text: pageContent.slice(0, langSectionIndex) + lines.join("\n"), summary: "pênase hat temamkirin bi amûra «\u00a0{0}\u00a0» (v{1}).".format(NAME, VERSION), }; }).then(function() { api.parse(newLine).done(function(html) { var $rendered = $(html).find("li").first(); self._$item.html($rendered.length ? $rendered.html() : linked); self._$item.css("background-color", "lightgreen"); setTimeout(function() { self._$item.css("background-color", "inherit"); }, 1000); }); self.setVisible(false); reenable(); }, function() { error("Tomarkirin serneket."); }); }); }); }, }; }); // </nowiki> acy1zyspysl5936n72hsfyhuxnlsvcj 6265636 6265635 2026-07-19T19:32:17Z Wikihez 7344 6265636 javascript text/javascript // <nowiki> if (!String.prototype.format) { String.prototype.format = function(var_args) { var args = arguments; return this.replace(/{(\d+)}/g, function(match, number) { return typeof args[number] !== "undefined" ? args[number] : match; }); }; } $(function() { "use strict"; if ( mw.config.get("wgNamespaceNumber") == 0 || mw.config.get("wgArticleId") === 0 ) return; console.log("Gadget-wikt.fill-definition.js dest pê dike…"); var NAME = "[[Mediawiki:Gadget-wikt.fill-definition|Pênaseyê temam bike]]"; var VERSION = "1.0"; // Navên şablonên "cihê pênaseya vala". Texmîn dikim her yek ji van şablonan // di derana xwe de hêmanek bi vê heman navê wek çîn (class) çêdike, wek meriv // {{nm}} li ser add-examples.js hêmana bi çîna "benimune" çêdike. Eger ne // wisa be, tenê selectorê li jêr (PLACEHOLDER_SELECTOR) biguherîne. var PLACEHOLDER_SELECTOR = "li .manelazim" var sectionNames = { "Navdêr": ["Navdêr"], "Formeke navdêrê": ["Formeke navdêrê"], "Lêker": ["Lêker"], "Formeke lêkerê": ["Formeke lêkerê"], "Rengdêr": ["Rengdêr"], "Formeke rengdêrê": ["Formeke rengdêrê"], "Hoker": ["Hoker"], "Formeke hokerê": ["Formeke hokerê"], "Serenav": ["Serenav"], "Formeke serenavê": ["Formeke serenavê"], "Artîkel": ["Artîkel"], "Baneşan": ["Baneşan"], "Bazinedaçek": ["Bazinedaçek"], "Biwêj": ["Biwêj"], "Cînav": ["Cînav"], "Daçek": ["Daçek"], "Girêdek": ["Girêdek"], "Gotineke pêşiyan": ["Gotineke pêşiyan"], "Hejmar": ["Hejmar"], "Hevok": ["Hevok"], "Îfade": ["Îfade"], "Kurtenav": ["Kurtenav"], "Navgir": ["Navgir"], "Paşdaçek": ["Paşdaçek"], "Paşgir": ["Paşgir"], "Pêşdaçek": ["Pêşdaçek"], "Pêşgir": ["Pêşgir"], "Pirtik": ["Pirtik"], "Reh": ["Reh"], "Sembol": ["Sembol"], "Tîp": ["Tîp"] }; var languages = {}; var api = new mw.Api(); api.get({ action: "query", format: "json", titles: "MediaWiki:Gadget-translation editor.js/ziman.json", prop: "revisions", rvprop: "content", rvslots: "main", }).then(function(data) { for (var pageID in data.query.pages) { if (Object.prototype.hasOwnProperty.call(data.query.pages, pageID)) { languages = JSON.parse(data.query.pages[pageID].revisions[0].slots.main["*"]); break; } } init(); }, init); // heke barkirin bi ser nekeve jî, dîsa jî hewl bide bidomîne /** * Wîkîlînkan li nivîsê zêde dike bi karanîna amûra linkify. * @param text {string} * @param callback {function(string)} */ function linkify(text, callback) { var didTryToLoad = function() { if (typeof $.wiktviLinkify === "function") { $.wiktviLinkify(text, function(linked) { callback(linked); }); } else { callback(text); } }; mw.loader.using("ext.gadget.linkify", didTryToLoad, didTryToLoad); } /** * Ji hêmaneke <li> (definîsyona xwe), definitionLevel (mîna ya li * add-examples.js) û koda zimanê wê hesab dike, bi vegerîna heman şêwazê * jorîn (jimartina li:not(.mw-empty-elt) berî xwe, heta li beşa h3/h2 tê). * @param $li {jQuery} * @return {{definitionLevel: Array<string|number>, language: string}|null} */ function resolveDefinition($li) { var definitionLevel = []; var $definitionItem = $li; var $topItem; do { definitionLevel.splice(0, 0, $definitionItem.prevAll("li:not(.mw-empty-elt)").length); $topItem = $definitionItem; $definitionItem = $definitionItem.parent().parent(); } while ($definitionItem.prop("tagName") === "LI"); var $ol = $topItem.parent(); var $h3Wrap = $($ol.prevAll(".mw-heading3, h3").last().get(0)); console.log("[fill-definition] h3Wrap:", $h3Wrap.length, $h3Wrap.text()); if (!$h3Wrap.length) return null; var $h3 = $h3Wrap.find("h3").length ? $h3Wrap.find("h3") : $h3Wrap; definitionLevel.splice(0, 0, $h3.attr("id")); var $h2Wrap = $($h3Wrap.prevAll(".mw-heading2, h2").last().get(0)); console.log("[fill-definition] h2Wrap:", $h2Wrap.length, $h2Wrap.text()); if (!$h2Wrap.length) return null; var $h2 = $h2Wrap.find("h2").length ? $h2Wrap.find("h2") : $h2Wrap; var languageName = $h2.text().trim(); console.log("[fill-definition] languageName:", JSON.stringify(languageName)); var languageCode = null; for (var code in languages) { if (Object.prototype.hasOwnProperty.call(languages, code) && languages[code] === languageName) { languageCode = code; break; } } console.log("[fill-definition] languageCode:", languageCode, "| known languages sample:", languages["ku"]); if (!languageCode) return null; return { definitionLevel: definitionLevel, language: languageCode }; } function init() { $(PLACEHOLDER_SELECTOR).each(function() { var $placeholder = $(this); var $item = $placeholder.closest("li"); if (!$item.length || $item.data("fillDefinitionDone")) return; $item.data("fillDefinitionDone", true); var resolved = resolveDefinition($item); if (!resolved) { console.warn("Gadget-wikt.fill-definition: Section/ziman nehat dîtin ji bo:", $item); return; } var $button = $("<a href='#'>Pênaseyê temam bike</a>"); $button.css("color", "var( --color-progressive, #3366cc )"); $button.on("click", function() { if (!$button.form) { $button.form = new Form($item, $placeholder, resolved.definitionLevel, resolved.language); $item.append($button.form.$element); } $button.form.setVisible(true); return false; }); $placeholder.after(" ").after($button); }); } /** * Forma pêşxistina pênaseyê. * @param $item {jQuery} Hêmana <li> ya definîsyonê. * @param $placeholder {jQuery} Hêmana şablona vala (bêmane/bêwate/…) di hundirê wê de. * @param definitionLevel {Array<string|number>} * @param language {string} * @constructor */ function Form($item, $placeholder, definitionLevel, language) { var self = this; this._$item = $item; this._$placeholder = $placeholder; this._definitionLevel = definitionLevel; this._language = language; this._textInput = new OO.ui.MultilineTextInputWidget({ autosize: true, rows: 2 }); var textInputLayout = new OO.ui.FieldLayout(this._textInput, { label: "Pênase", align: "top", }); this._textInput.on("change", function(value) { var empty = !value.trim(); self._previewButton.setDisabled(empty); self._applyButton.setDisabled(empty); }); this._previewButton = new OO.ui.ButtonWidget({ label: "Pêşdîtin", disabled: true, }); this._previewButton.on("click", this.preview.bind(this)); this._applyButton = new OO.ui.ButtonWidget({ label: "Tomar bike", flags: ["progressive", "primary"], disabled: true, }); this._applyButton.on("click", this.submit.bind(this)); this._cancelButton = new OO.ui.ButtonWidget({ label: "Betal bike", flags: ["destructive"], }); this._cancelButton.on("click", function() { self.setVisible(false); }); this._loadingImage = new OO.ui.LabelWidget({ label: $('<img src="https://upload.wikimedia.org/wikipedia/commons/7/7a/Ajax_loader_metal_512.gif" alt="loading" style="width: 1.5em">'), }); this._loadingImage.toggle(false); this._previewArea = $("<div class='fill-definition-preview' style='margin-top:0.5em;padding:0.3em 0.6em;border:1px dashed #aaa;'></div>").hide(); var fieldsLayout = new OO.ui.FieldsetLayout({ label: "Pênaseyeke bi " + (languages[this._language] || "zimanekî nenas") + " lê zêde dikî.", items: [textInputLayout], classes: ["fill-definition-fieldset"], }); var buttonsLayout = new OO.ui.HorizontalLayout({ items: [this._previewButton, this._applyButton, this._cancelButton, this._loadingImage], }); this._frame = new OO.ui.PanelLayout({ classes: ["fill-definition-form"], expanded: false, content: [fieldsLayout, buttonsLayout, this._previewArea], }); } Form.prototype = { get $element() { return this._frame.$element; }, setVisible: function(visible) { this._frame.toggle(visible); }, /** * Nivîsê linkify dike û bi rastî bi mw.Api parse dike da ku were xuyakirin * çawa dê xuya bike piştî tomarkirinê. */ preview: function() { var self = this; var text = this._textInput.getValue().trim(); if (!text) return; this._previewButton.setDisabled(true); this._loadingImage.toggle(true); linkify(text, function(linked) { api.parse("# " + linked, { title: mw.config.get("wgPageName") }).done(function(html) { self._previewArea.html(html).show(); }).fail(function() { self._previewArea.text(linked).show(); }).always(function() { self._previewButton.setDisabled(false); self._loadingImage.toggle(false); }); }); }, /** * Şablona vala di wîkîkoda rûpelê de bi nivîsa (linkify-kirî) diguherîne. */ submit: function() { var self = this; var text = this._textInput.getValue().trim(); if (!text) return; this._textInput.setDisabled(true); this._previewButton.setDisabled(true); this._applyButton.setDisabled(true); this._cancelButton.setDisabled(true); this._loadingImage.toggle(true); function reenable() { self._textInput.setDisabled(false); self._previewButton.setDisabled(false); self._applyButton.setDisabled(false); self._cancelButton.setDisabled(false); self._loadingImage.toggle(false); } function error(msg) { mw.notify(msg || "Nimûne nehat weşandin, îhtimalen rûpel hate guhartin. Ji kerema xwe re rûpelê dîsa bar bike û dîsa biceribîne."); reenable(); } linkify(text, function(linked) { api.get({ action: "query", titles: mw.config.get("wgPageName"), prop: "revisions", rvprop: "content", rvslots: "main", }).then(function(data) { var pageContent; for (var pageID in data.query.pages) { if (Object.prototype.hasOwnProperty.call(data.query.pages, pageID)) { pageContent = data.query.pages[pageID].revisions[0].slots.main["*"]; break; } } var langSectionRegex = new RegExp("==[ ]*{{ziman\\|{0}}}[ ]*==".format(self._language)); var langSectionIndex = pageContent.search(langSectionRegex); if (langSectionIndex === -1) { error("Xeletiyeke bi koda zimanî heye. Koda zimanî: " + self._language); return; } var lines = pageContent.slice(langSectionIndex).split("\n"); var sectionNamesRegex = Object.keys(sectionNames).join('|'); var sectionRegex = new RegExp('^===[ ]*(' + sectionNamesRegex + ')\\s*(\\d+)?'); var targetLineIndex; var sectionIDPattern = new RegExp("^([\\wîêçş_]+?)_?(\\d+)?_?(\\d+)?$"); var matchSectionID = sectionIDPattern.exec(self._definitionLevel[0]); var sectionType = matchSectionID[1].replace(/_/, ' '); sectionType = sectionType.replace(/_\d+$/, ''); var sectionNum = matchSectionID[2] ? parseInt(matchSectionID[2]) : ""; for (targetLineIndex = 0; targetLineIndex < lines.length; targetLineIndex++) { var line = lines[targetLineIndex]; var matchSection = sectionRegex.exec(line); if (matchSection) { var matchedSectionName = matchSection[1]; var matchedSectionNum = matchSection[2]; if (!sectionNames[sectionType]) { error('Navê beşê xelet e.'); return; } if (sectionNames[sectionType].includes(matchedSectionName)) { if (!matchedSectionNum || line.includes(" " + matchedSectionNum)) { break; } } } } if (targetLineIndex === lines.length) { error("Di navê beşê de xeletî heye. Îhtimalen bi vî navê beşê çend heb hene."); return; } var defIndex = -1; var level = 1; for (; targetLineIndex < lines.length; targetLineIndex++) { var m = /^(#+)[^*#:]/.exec(lines[targetLineIndex]); if (m) { if (level === m[1].length) { defIndex++; if (self._definitionLevel[level] === defIndex) { if (level === self._definitionLevel.length - 1) { break; } else { level++; defIndex = -1; } } } } } if (targetLineIndex === lines.length) { error("Definîsyon nehat dîtin, îhtimalen rûpel hate guhartin."); return; } var markerMatch = /^(#+)\s*/.exec(lines[targetLineIndex]); var marker = markerMatch ? markerMatch[1] : "#"; var newLine = marker + " " + linked; lines[targetLineIndex] = newLine; api.edit(mw.config.get("wgPageName"), function() { return { text: pageContent.slice(0, langSectionIndex) + lines.join("\n"), summary: "pênase hat temamkirin bi amûra «\u00a0{0}\u00a0» (v{1}).".format(NAME, VERSION), }; }).then(function() { api.parse(newLine).done(function(html) { var $rendered = $(html).find("li").first(); self._$item.html($rendered.length ? $rendered.html() : linked); self._$item.css("background-color", "lightgreen"); setTimeout(function() { self._$item.css("background-color", "inherit"); }, 1000); }); self.setVisible(false); reenable(); }, function() { error("Tomarkirin serneket."); }); }); }); }, }; }); // </nowiki> 27p2c60zndyc8ghah4ryrmpxmdoxypl 6265637 6265636 2026-07-19T19:34:52Z Wikihez 7344 6265637 javascript text/javascript // <nowiki> if (!String.prototype.format) { String.prototype.format = function(var_args) { var args = arguments; return this.replace(/{(\d+)}/g, function(match, number) { return typeof args[number] !== "undefined" ? args[number] : match; }); }; } $(function() { "use strict"; if ( mw.config.get("wgNamespaceNumber") == 0 || mw.config.get("wgArticleId") === 0 ) return; console.log("Gadget-wikt.fill-definition.js dest pê dike…"); var NAME = "[[Mediawiki:Gadget-wikt.fill-definition|Pênaseyê temam bike]]"; var VERSION = "1.0"; // Navên şablonên "cihê pênaseya vala". Texmîn dikim her yek ji van şablonan // di derana xwe de hêmanek bi vê heman navê wek çîn (class) çêdike, wek meriv // {{nm}} li ser add-examples.js hêmana bi çîna "benimune" çêdike. Eger ne // wisa be, tenê selectorê li jêr (PLACEHOLDER_SELECTOR) biguherîne. var PLACEHOLDER_SELECTOR = "li .manelazim" var sectionNames = { "Navdêr": ["Navdêr"], "Formeke navdêrê": ["Formeke navdêrê"], "Lêker": ["Lêker"], "Formeke lêkerê": ["Formeke lêkerê"], "Rengdêr": ["Rengdêr"], "Formeke rengdêrê": ["Formeke rengdêrê"], "Hoker": ["Hoker"], "Formeke hokerê": ["Formeke hokerê"], "Serenav": ["Serenav"], "Formeke serenavê": ["Formeke serenavê"], "Artîkel": ["Artîkel"], "Baneşan": ["Baneşan"], "Bazinedaçek": ["Bazinedaçek"], "Biwêj": ["Biwêj"], "Cînav": ["Cînav"], "Daçek": ["Daçek"], "Girêdek": ["Girêdek"], "Gotineke pêşiyan": ["Gotineke pêşiyan"], "Hejmar": ["Hejmar"], "Hevok": ["Hevok"], "Îfade": ["Îfade"], "Kurtenav": ["Kurtenav"], "Navgir": ["Navgir"], "Paşdaçek": ["Paşdaçek"], "Paşgir": ["Paşgir"], "Pêşdaçek": ["Pêşdaçek"], "Pêşgir": ["Pêşgir"], "Pirtik": ["Pirtik"], "Reh": ["Reh"], "Sembol": ["Sembol"], "Tîp": ["Tîp"] }; var languages = {}; var api = new mw.Api(); api.get({ action: "query", format: "json", titles: "MediaWiki:Gadget-translation editor.js/ziman.json", prop: "revisions", rvprop: "content", rvslots: "main", }).then(function(data) { for (var pageID in data.query.pages) { if (Object.prototype.hasOwnProperty.call(data.query.pages, pageID)) { languages = JSON.parse(data.query.pages[pageID].revisions[0].slots.main["*"]); break; } } init(); }, init); // heke barkirin bi ser nekeve jî, dîsa jî hewl bide bidomîne /** * Wîkîlînkan li nivîsê zêde dike bi karanîna amûra linkify. * @param text {string} * @param callback {function(string)} */ function linkify(text, callback) { var didTryToLoad = function() { if (typeof $.wiktviLinkify === "function") { $.wiktviLinkify(text, function(linked) { callback(linked); }); } else { callback(text); } }; mw.loader.using("ext.gadget.linkify", didTryToLoad, didTryToLoad); } /** * Ji hêmaneke <li> (definîsyona xwe), definitionLevel (mîna ya li * add-examples.js) û koda zimanê wê hesab dike, bi vegerîna heman şêwazê * jorîn (jimartina li:not(.mw-empty-elt) berî xwe, heta li beşa h3/h2 tê). * @param $li {jQuery} * @return {{definitionLevel: Array<string|number>, language: string}|null} */ function resolveDefinition($li) { var definitionLevel = []; var $definitionItem = $li; var $topItem; do { definitionLevel.splice(0, 0, $definitionItem.prevAll("li:not(.mw-empty-elt)").length); $topItem = $definitionItem; $definitionItem = $definitionItem.parent().parent(); } while ($definitionItem.prop("tagName") === "LI"); var $ol = $topItem.parent(); var $h3Wrap = $($ol.prevAll(".mw-heading3, h3").first().get(0)); if (!$h3Wrap.length) return null; var $h3 = $h3Wrap.find("h3").length ? $h3Wrap.find("h3") : $h3Wrap; definitionLevel.splice(0, 0, $h3.attr("id")); var $h2Wrap = $($h3Wrap.prevAll(".mw-heading2, h2").first().get(0)); if (!$h2Wrap.length) return null; var $h2 = $h2Wrap.find("h2").length ? $h2Wrap.find("h2") : $h2Wrap; var languageName = $h2.text().trim(); var languageCode = null; var languageNameLower = languageName.toLowerCase(); for (var code in languages) { if (Object.prototype.hasOwnProperty.call(languages, code) && languages[code].toLowerCase() === languageNameLower) { languageCode = code; break; } } if (!languageCode) return null; return { definitionLevel: definitionLevel, language: languageCode }; } function init() { $(PLACEHOLDER_SELECTOR).each(function() { var $placeholder = $(this); var $item = $placeholder.closest("li"); if (!$item.length || $item.data("fillDefinitionDone")) return; $item.data("fillDefinitionDone", true); var resolved = resolveDefinition($item); if (!resolved) { console.warn("Gadget-wikt.fill-definition: Section/ziman nehat dîtin ji bo:", $item); return; } var $button = $("<a href='#'>Pênaseyê temam bike</a>"); $button.css("color", "var( --color-progressive, #3366cc )"); $button.on("click", function() { if (!$button.form) { $button.form = new Form($item, $placeholder, resolved.definitionLevel, resolved.language); $item.append($button.form.$element); } $button.form.setVisible(true); return false; }); $placeholder.after(" ").after($button); }); } /** * Forma pêşxistina pênaseyê. * @param $item {jQuery} Hêmana <li> ya definîsyonê. * @param $placeholder {jQuery} Hêmana şablona vala (bêmane/bêwate/…) di hundirê wê de. * @param definitionLevel {Array<string|number>} * @param language {string} * @constructor */ function Form($item, $placeholder, definitionLevel, language) { var self = this; this._$item = $item; this._$placeholder = $placeholder; this._definitionLevel = definitionLevel; this._language = language; this._textInput = new OO.ui.MultilineTextInputWidget({ autosize: true, rows: 2 }); var textInputLayout = new OO.ui.FieldLayout(this._textInput, { label: "Pênase", align: "top", }); this._textInput.on("change", function(value) { var empty = !value.trim(); self._previewButton.setDisabled(empty); self._applyButton.setDisabled(empty); }); this._previewButton = new OO.ui.ButtonWidget({ label: "Pêşdîtin", disabled: true, }); this._previewButton.on("click", this.preview.bind(this)); this._applyButton = new OO.ui.ButtonWidget({ label: "Tomar bike", flags: ["progressive", "primary"], disabled: true, }); this._applyButton.on("click", this.submit.bind(this)); this._cancelButton = new OO.ui.ButtonWidget({ label: "Betal bike", flags: ["destructive"], }); this._cancelButton.on("click", function() { self.setVisible(false); }); this._loadingImage = new OO.ui.LabelWidget({ label: $('<img src="https://upload.wikimedia.org/wikipedia/commons/7/7a/Ajax_loader_metal_512.gif" alt="loading" style="width: 1.5em">'), }); this._loadingImage.toggle(false); this._previewArea = $("<div class='fill-definition-preview' style='margin-top:0.5em;padding:0.3em 0.6em;border:1px dashed #aaa;'></div>").hide(); var fieldsLayout = new OO.ui.FieldsetLayout({ label: "Pênaseyeke bi " + (languages[this._language] || "zimanekî nenas") + " lê zêde dikî.", items: [textInputLayout], classes: ["fill-definition-fieldset"], }); var buttonsLayout = new OO.ui.HorizontalLayout({ items: [this._previewButton, this._applyButton, this._cancelButton, this._loadingImage], }); this._frame = new OO.ui.PanelLayout({ classes: ["fill-definition-form"], expanded: false, content: [fieldsLayout, buttonsLayout, this._previewArea], }); } Form.prototype = { get $element() { return this._frame.$element; }, setVisible: function(visible) { this._frame.toggle(visible); }, /** * Nivîsê linkify dike û bi rastî bi mw.Api parse dike da ku were xuyakirin * çawa dê xuya bike piştî tomarkirinê. */ preview: function() { var self = this; var text = this._textInput.getValue().trim(); if (!text) return; this._previewButton.setDisabled(true); this._loadingImage.toggle(true); linkify(text, function(linked) { api.parse("# " + linked, { title: mw.config.get("wgPageName") }).done(function(html) { self._previewArea.html(html).show(); }).fail(function() { self._previewArea.text(linked).show(); }).always(function() { self._previewButton.setDisabled(false); self._loadingImage.toggle(false); }); }); }, /** * Şablona vala di wîkîkoda rûpelê de bi nivîsa (linkify-kirî) diguherîne. */ submit: function() { var self = this; var text = this._textInput.getValue().trim(); if (!text) return; this._textInput.setDisabled(true); this._previewButton.setDisabled(true); this._applyButton.setDisabled(true); this._cancelButton.setDisabled(true); this._loadingImage.toggle(true); function reenable() { self._textInput.setDisabled(false); self._previewButton.setDisabled(false); self._applyButton.setDisabled(false); self._cancelButton.setDisabled(false); self._loadingImage.toggle(false); } function error(msg) { mw.notify(msg || "Nimûne nehat weşandin, îhtimalen rûpel hate guhartin. Ji kerema xwe re rûpelê dîsa bar bike û dîsa biceribîne."); reenable(); } linkify(text, function(linked) { api.get({ action: "query", titles: mw.config.get("wgPageName"), prop: "revisions", rvprop: "content", rvslots: "main", }).then(function(data) { var pageContent; for (var pageID in data.query.pages) { if (Object.prototype.hasOwnProperty.call(data.query.pages, pageID)) { pageContent = data.query.pages[pageID].revisions[0].slots.main["*"]; break; } } var langSectionRegex = new RegExp("==[ ]*{{ziman\\|{0}}}[ ]*==".format(self._language)); var langSectionIndex = pageContent.search(langSectionRegex); if (langSectionIndex === -1) { error("Xeletiyeke bi koda zimanî heye. Koda zimanî: " + self._language); return; } var lines = pageContent.slice(langSectionIndex).split("\n"); var sectionNamesRegex = Object.keys(sectionNames).join('|'); var sectionRegex = new RegExp('^===[ ]*(' + sectionNamesRegex + ')\\s*(\\d+)?'); var targetLineIndex; var sectionIDPattern = new RegExp("^([\\wîêçş_]+?)_?(\\d+)?_?(\\d+)?$"); var matchSectionID = sectionIDPattern.exec(self._definitionLevel[0]); var sectionType = matchSectionID[1].replace(/_/, ' '); sectionType = sectionType.replace(/_\d+$/, ''); var sectionNum = matchSectionID[2] ? parseInt(matchSectionID[2]) : ""; for (targetLineIndex = 0; targetLineIndex < lines.length; targetLineIndex++) { var line = lines[targetLineIndex]; var matchSection = sectionRegex.exec(line); if (matchSection) { var matchedSectionName = matchSection[1]; var matchedSectionNum = matchSection[2]; if (!sectionNames[sectionType]) { error('Navê beşê xelet e.'); return; } if (sectionNames[sectionType].includes(matchedSectionName)) { if (!matchedSectionNum || line.includes(" " + matchedSectionNum)) { break; } } } } if (targetLineIndex === lines.length) { error("Di navê beşê de xeletî heye. Îhtimalen bi vî navê beşê çend heb hene."); return; } var defIndex = -1; var level = 1; for (; targetLineIndex < lines.length; targetLineIndex++) { var m = /^(#+)[^*#:]/.exec(lines[targetLineIndex]); if (m) { if (level === m[1].length) { defIndex++; if (self._definitionLevel[level] === defIndex) { if (level === self._definitionLevel.length - 1) { break; } else { level++; defIndex = -1; } } } } } if (targetLineIndex === lines.length) { error("Definîsyon nehat dîtin, îhtimalen rûpel hate guhartin."); return; } var markerMatch = /^(#+)\s*/.exec(lines[targetLineIndex]); var marker = markerMatch ? markerMatch[1] : "#"; var newLine = marker + " " + linked; lines[targetLineIndex] = newLine; api.edit(mw.config.get("wgPageName"), function() { return { text: pageContent.slice(0, langSectionIndex) + lines.join("\n"), summary: "pênase hat temamkirin bi amûra «\u00a0{0}\u00a0» (v{1}).".format(NAME, VERSION), }; }).then(function() { api.parse(newLine).done(function(html) { var $rendered = $(html).find("li").first(); self._$item.html($rendered.length ? $rendered.html() : linked); self._$item.css("background-color", "lightgreen"); setTimeout(function() { self._$item.css("background-color", "inherit"); }, 1000); }); self.setVisible(false); reenable(); }, function() { error("Tomarkirin serneket."); }); }); }); }, }; }); // </nowiki> nq8sedttcn0vlwngazpzgrf0pxzgmux 6265643 6265637 2026-07-19T19:42:38Z Wikihez 7344 6265643 javascript text/javascript // <nowiki> if (!String.prototype.format) { String.prototype.format = function(var_args) { var args = arguments; return this.replace(/{(\d+)}/g, function(match, number) { return typeof args[number] !== "undefined" ? args[number] : match; }); }; } $(function() { "use strict"; if ( mw.config.get("wgNamespaceNumber") == 0 || mw.config.get("wgArticleId") === 0 ) return; console.log("Gadget-wikt.fill-definition.js dest pê dike…"); var NAME = "[[Mediawiki:Gadget-wikt.fill-definition|Pênaseyê temam bike]]"; var VERSION = "1.0"; // Navên şablonên "cihê pênaseya vala". Texmîn dikim her yek ji van şablonan // di derana xwe de hêmanek bi vê heman navê wek çîn (class) çêdike, wek meriv // {{nm}} li ser add-examples.js hêmana bi çîna "benimune" çêdike. Eger ne // wisa be, tenê selectorê li jêr (PLACEHOLDER_SELECTOR) biguherîne. var PLACEHOLDER_SELECTOR = "li .manelazim" var sectionNames = { "Navdêr": ["Navdêr"], "Formeke navdêrê": ["Formeke navdêrê"], "Lêker": ["Lêker"], "Formeke lêkerê": ["Formeke lêkerê"], "Rengdêr": ["Rengdêr"], "Formeke rengdêrê": ["Formeke rengdêrê"], "Hoker": ["Hoker"], "Formeke hokerê": ["Formeke hokerê"], "Serenav": ["Serenav"], "Formeke serenavê": ["Formeke serenavê"], "Artîkel": ["Artîkel"], "Baneşan": ["Baneşan"], "Bazinedaçek": ["Bazinedaçek"], "Biwêj": ["Biwêj"], "Cînav": ["Cînav"], "Daçek": ["Daçek"], "Girêdek": ["Girêdek"], "Gotineke pêşiyan": ["Gotineke pêşiyan"], "Hejmar": ["Hejmar"], "Hevok": ["Hevok"], "Îfade": ["Îfade"], "Kurtenav": ["Kurtenav"], "Navgir": ["Navgir"], "Paşdaçek": ["Paşdaçek"], "Paşgir": ["Paşgir"], "Pêşdaçek": ["Pêşdaçek"], "Pêşgir": ["Pêşgir"], "Pirtik": ["Pirtik"], "Reh": ["Reh"], "Sembol": ["Sembol"], "Tîp": ["Tîp"] }; var languages = {}; var api = new mw.Api(); api.get({ action: "query", format: "json", titles: "MediaWiki:Gadget-translation editor.js/ziman.json", prop: "revisions", rvprop: "content", rvslots: "main", }).then(function(data) { for (var pageID in data.query.pages) { if (Object.prototype.hasOwnProperty.call(data.query.pages, pageID)) { languages = JSON.parse(data.query.pages[pageID].revisions[0].slots.main["*"]); break; } } init(); }, init); // heke barkirin bi ser nekeve jî, dîsa jî hewl bide bidomîne /** * Wîkîlînkan li nivîsê zêde dike bi karanîna amûra linkify. * @param text {string} * @param callback {function(string)} */ function linkify(text, callback) { var didTryToLoad = function() { if (typeof $.wiktviLinkify === "function") { $.wiktviLinkify(text, function(linked) { callback(linked); }); } else { callback(text); } }; mw.loader.using("ext.gadget.linkify", didTryToLoad, didTryToLoad); } /** * Ji hêmaneke <li> (definîsyona xwe), definitionLevel (mîna ya li * add-examples.js) û koda zimanê wê hesab dike, bi vegerîna heman şêwazê * jorîn (jimartina li:not(.mw-empty-elt) berî xwe, heta li beşa h3/h2 tê). * @param $li {jQuery} * @return {{definitionLevel: Array<string|number>, language: string}|null} */ function resolveDefinition($li) { var definitionLevel = []; var $definitionItem = $li; var $topItem; do { definitionLevel.splice(0, 0, $definitionItem.prevAll("li:not(.mw-empty-elt)").length); $topItem = $definitionItem; $definitionItem = $definitionItem.parent().parent(); } while ($definitionItem.prop("tagName") === "LI"); var $ol = $topItem.parent(); var $h3Wrap = $($ol.prevAll(".mw-heading3, h3").first().get(0)); if (!$h3Wrap.length) return null; var $h3 = $h3Wrap.find("h3").length ? $h3Wrap.find("h3") : $h3Wrap; definitionLevel.splice(0, 0, $h3.attr("id")); var $h2Wrap = $($h3Wrap.prevAll(".mw-heading2, h2").first().get(0)); if (!$h2Wrap.length) return null; var $h2 = $h2Wrap.find("h2").length ? $h2Wrap.find("h2") : $h2Wrap; var languageName = $h2.text().trim(); var languageCode = null; var languageNameLower = languageName.toLowerCase(); for (var code in languages) { if (Object.prototype.hasOwnProperty.call(languages, code) && languages[code].toLowerCase() === languageNameLower) { languageCode = code; break; } } if (!languageCode) return null; return { definitionLevel: definitionLevel, language: languageCode }; } function init() { $(PLACEHOLDER_SELECTOR).each(function() { var $placeholder = $(this); var $item = $placeholder.closest("li"); if (!$item.length || $item.data("fillDefinitionDone")) return; $item.data("fillDefinitionDone", true); var resolved = resolveDefinition($item); if (!resolved) { console.warn("Gadget-wikt.fill-definition: Section/ziman nehat dîtin ji bo:", $item); return; // placeholder text stays visible — nothing changed, so this is a safe no-op } var $button = $("<a href='#'>Pênaseyê temam bike</a>"); $button.css("color", "var( --color-progressive, #3366cc )"); $button.on("click", function() { if (!$button.form) { $button.form = new Form($item, $placeholder, resolved.definitionLevel, resolved.language); $item.append($button.form.$element); } $button.form.setVisible(true); return false; }); $placeholder.hide(); // only hidden once we know the button actually works $placeholder.addClass("fill-definition-resolved").hide(); $placeholder.after($button); }); } /** * Forma pêşxistina pênaseyê. * @param $item {jQuery} Hêmana <li> ya definîsyonê. * @param $placeholder {jQuery} Hêmana şablona vala (bêmane/bêwate/…) di hundirê wê de. * @param definitionLevel {Array<string|number>} * @param language {string} * @constructor */ function Form($item, $placeholder, definitionLevel, language) { var self = this; this._$item = $item; this._$placeholder = $placeholder; this._definitionLevel = definitionLevel; this._language = language; this._textInput = new OO.ui.MultilineTextInputWidget({ autosize: true, rows: 2 }); var textInputLayout = new OO.ui.FieldLayout(this._textInput, { label: "Pênase", align: "top", }); this._textInput.on("change", function(value) { var empty = !value.trim(); self._previewButton.setDisabled(empty); self._applyButton.setDisabled(empty); }); this._previewButton = new OO.ui.ButtonWidget({ label: "Pêşdîtin", disabled: true, }); this._previewButton.on("click", this.preview.bind(this)); this._applyButton = new OO.ui.ButtonWidget({ label: "Tomar bike", flags: ["progressive", "primary"], disabled: true, }); this._applyButton.on("click", this.submit.bind(this)); this._cancelButton = new OO.ui.ButtonWidget({ label: "Betal bike", flags: ["destructive"], }); this._cancelButton.on("click", function() { self.setVisible(false); }); this._loadingImage = new OO.ui.LabelWidget({ label: $('<img src="https://upload.wikimedia.org/wikipedia/commons/7/7a/Ajax_loader_metal_512.gif" alt="loading" style="width: 1.5em">'), }); this._loadingImage.toggle(false); this._previewArea = $("<div class='fill-definition-preview' style='margin-top:0.5em;padding:0.3em 0.6em;border:1px dashed #aaa;'></div>").hide(); var fieldsLayout = new OO.ui.FieldsetLayout({ label: "Pênaseyeke bi " + (languages[this._language] || "zimanekî nenas") + " lê zêde dikî.", items: [textInputLayout], classes: ["fill-definition-fieldset"], }); var buttonsLayout = new OO.ui.HorizontalLayout({ items: [this._previewButton, this._applyButton, this._cancelButton, this._loadingImage], }); this._frame = new OO.ui.PanelLayout({ classes: ["fill-definition-form"], expanded: false, content: [fieldsLayout, buttonsLayout, this._previewArea], }); } Form.prototype = { get $element() { return this._frame.$element; }, setVisible: function(visible) { this._frame.toggle(visible); }, /** * Nivîsê linkify dike û bi rastî bi mw.Api parse dike da ku were xuyakirin * çawa dê xuya bike piştî tomarkirinê. */ preview: function() { var self = this; var text = this._textInput.getValue().trim(); if (!text) return; this._previewButton.setDisabled(true); this._loadingImage.toggle(true); linkify(text, function(linked) { api.parse("# " + linked, { title: mw.config.get("wgPageName") }).done(function(html) { self._previewArea.html(html).show(); }).fail(function() { self._previewArea.text(linked).show(); }).always(function() { self._previewButton.setDisabled(false); self._loadingImage.toggle(false); }); }); }, /** * Şablona vala di wîkîkoda rûpelê de bi nivîsa (linkify-kirî) diguherîne. */ submit: function() { var self = this; var text = this._textInput.getValue().trim(); if (!text) return; this._textInput.setDisabled(true); this._previewButton.setDisabled(true); this._applyButton.setDisabled(true); this._cancelButton.setDisabled(true); this._loadingImage.toggle(true); function reenable() { self._textInput.setDisabled(false); self._previewButton.setDisabled(false); self._applyButton.setDisabled(false); self._cancelButton.setDisabled(false); self._loadingImage.toggle(false); } function error(msg) { mw.notify(msg || "Nimûne nehat weşandin, îhtimalen rûpel hate guhartin. Ji kerema xwe re rûpelê dîsa bar bike û dîsa biceribîne."); reenable(); } linkify(text, function(linked) { api.get({ action: "query", titles: mw.config.get("wgPageName"), prop: "revisions", rvprop: "content", rvslots: "main", }).then(function(data) { var pageContent; for (var pageID in data.query.pages) { if (Object.prototype.hasOwnProperty.call(data.query.pages, pageID)) { pageContent = data.query.pages[pageID].revisions[0].slots.main["*"]; break; } } var langSectionRegex = new RegExp("==[ ]*{{ziman\\|{0}}}[ ]*==".format(self._language)); var langSectionIndex = pageContent.search(langSectionRegex); if (langSectionIndex === -1) { error("Xeletiyeke bi koda zimanî heye. Koda zimanî: " + self._language); return; } var lines = pageContent.slice(langSectionIndex).split("\n"); var sectionNamesRegex = Object.keys(sectionNames).join('|'); var sectionRegex = new RegExp('^===[ ]*(' + sectionNamesRegex + ')\\s*(\\d+)?'); var targetLineIndex; var sectionIDPattern = new RegExp("^([\\wîêçş_]+?)_?(\\d+)?_?(\\d+)?$"); var matchSectionID = sectionIDPattern.exec(self._definitionLevel[0]); var sectionType = matchSectionID[1].replace(/_/, ' '); sectionType = sectionType.replace(/_\d+$/, ''); var sectionNum = matchSectionID[2] ? parseInt(matchSectionID[2]) : ""; for (targetLineIndex = 0; targetLineIndex < lines.length; targetLineIndex++) { var line = lines[targetLineIndex]; var matchSection = sectionRegex.exec(line); if (matchSection) { var matchedSectionName = matchSection[1]; var matchedSectionNum = matchSection[2]; if (!sectionNames[sectionType]) { error('Navê beşê xelet e.'); return; } if (sectionNames[sectionType].includes(matchedSectionName)) { if (!matchedSectionNum || line.includes(" " + matchedSectionNum)) { break; } } } } if (targetLineIndex === lines.length) { error("Di navê beşê de xeletî heye. Îhtimalen bi vî navê beşê çend heb hene."); return; } var defIndex = -1; var level = 1; for (; targetLineIndex < lines.length; targetLineIndex++) { var m = /^(#+)[^*#:]/.exec(lines[targetLineIndex]); if (m) { if (level === m[1].length) { defIndex++; if (self._definitionLevel[level] === defIndex) { if (level === self._definitionLevel.length - 1) { break; } else { level++; defIndex = -1; } } } } } if (targetLineIndex === lines.length) { error("Definîsyon nehat dîtin, îhtimalen rûpel hate guhartin."); return; } var markerMatch = /^(#+)\s*/.exec(lines[targetLineIndex]); var marker = markerMatch ? markerMatch[1] : "#"; var newLine = marker + " " + linked; lines[targetLineIndex] = newLine; api.edit(mw.config.get("wgPageName"), function() { return { text: pageContent.slice(0, langSectionIndex) + lines.join("\n"), summary: "pênase hat temamkirin bi amûra «\u00a0{0}\u00a0» (v{1}).".format(NAME, VERSION), }; }).then(function() { api.parse(newLine).done(function(html) { var $rendered = $(html).find("li").first(); self._$item.html($rendered.length ? $rendered.html() : linked); self._$item.css("background-color", "lightgreen"); setTimeout(function() { self._$item.css("background-color", "inherit"); }, 1000); }); self.setVisible(false); reenable(); }, function() { error("Tomarkirin serneket."); }); }); }); }, }; }); // </nowiki> fkih9xluyr7e6102wuixg6g6d1smo7z Modesache 0 974009 6265729 5766842 2026-07-20T05:35:51Z Wikihez 7344 6265729 wikitext text/x-wiki == {{ziman|de}} == === Navdêr === {{navdêr|de}} # [[tişt|tiştê]] [[mod|moda]], tiştê [[trend|trend]] dmrysvy9aqllf6f38o4oertmvrkd3rj Bikarhêner:Wikihez/Gadget-linkify.js 2 974481 6265705 6031435 2026-07-20T00:15:50Z Wikihez 7344 6265705 javascript text/javascript // Çavkanî [[vi:MediaWiki:Gadget-linkify.js]] (function ($) { var messages = { vi: {toolbarButtonName: "Tự động đặt liên kết trong lựa chọn"}, en: {toolbarButtonName: "Automatically link selected text"}, ku: {toolbarButtonName: "Li nivîsa bijartî bi otomatîkî girêdan lê zêde bike"}, es: {toolbarButtonName: "Automáticamente insertar enlaces en la selección"} }; var ignoredWordList = ("de|di|da|li|re|ve|tê|jî|jê|û|ya|a|ê|ên|î|ku").split("|"); var ignoredWords = {}; $.each(ignoredWordList, function (i, word) { ignoredWords[word] = true; }); /** * One less than the maximum number of syllables to be considered as a compound * word. */ var lookahead = 2; var tokenRE = /(\s*(?:<!--[\s\S]+?-->|\{\{[\s\S]+?\}\}|\[\[.+?\]\]|[^A-ZÀÁẢÃẠÂẦẤẨẪẬĂẰẮẲẴẶĐÈÉẺẼẸÊỀẾỂỄỆÌÍỈĨỊÒÓỎÕỌÔỒỐỔỖỘƠỜỚỞỠỢÙÚỦŨỤƯỪỨỬỮỰỲÝỶỸỴŞşÇçÎîÛûÊê\u0300-\u036F{[< ]+|[{[<])\s*)/i; String.prototype.wiktviUncapitalize = function () { return this[0].toLowerCase() + this.substr(1); }; var userLang = mw.config.get("wgUserLanguage"); function getMessage(name) { return (messages[userLang] || messages.vi)[name] || messages.vi[name]; } $.wiktviLinkify = function (text, callback, debug) { var tokens = text.split(tokenRE); var displayTokens = []; var words = {}; var existingLinks = {}; $.each(tokens, function (i, token) { if (debug) displayTokens.push(mw.html.escape(token)); var tokenLinks = token.match(/\[\[.+?(?:\|.+?)?\]\]/g); $.each(tokenLinks || [], function () { existingLinks[this.match(/\[\[(.+?)(?:\|.+?)?\]\]/)[1]] = true; }); if (!token || token.match(tokenRE)) return; var tokenWords = token.split(" "); $.each(tokenWords, function (j, word) { for (var k = 0; k < lookahead + 1 && tokenWords[j + k]; k++) { if (k) word += " " + tokenWords[j + k]; if (!ignoredWords[word]) words[word] = true; if (word[0] != word[0].toLowerCase()) { var lowerWord = word.wiktviUncapitalize(); if (!ignoredWords[lowerWord]) { words[lowerWord] = true; } } } }); if (debug) { displayTokens[i] = "<b style='border: 1px solid gray;'>" + mw.html.escape(token) + "</b>"; } }); var uniqueWords = []; $.each(words, function (word) { if (!ignoredWords[word]) uniqueWords.push(word); }); if (debug) { var uniqueLinks = []; $.each(existingLinks, function (link) { uniqueLinks.push(link); }); var list = "<pre id='linkify-tokens'>\n" + displayTokens.join("") + "\n</pre>"; list += "<hr /><p>Các cụm từ sẽ tìm kiếm:</p><p>" + uniqueWords + "</p>"; list += "<hr /><p>Các cụm từ đã có liên kết:</p><p>" + uniqueLinks + "</p>"; $("#linkify-progress").html(list).dialog({modal: true}); } if (!uniqueWords.length) return; mw.loader.using("mediawiki.api", function () { var api = new mw.Api(); api.get({ action: "parse", text: "[[" + uniqueWords.join("]] [[") + "]]", prop: "links" }).done(function (results) { $("#linkify-progress").append("<hr />"); var displayLinks = []; var links = {}; $.each(results.parse.links, function () { if (debug && "exists" in this) displayLinks.push(this["*"]); if ("exists" in this) links[this["*"]] = true; }); if (debug) { $("#linkify-progress").append("<p>Các mục từ:</p><p>" + displayLinks + "</p>"); } $.each(tokens, function (i, token) { if (!token || token.match(tokenRE)) return; var tokenWords = token.split(" "); for (var j = 0; j < tokenWords.length; j++) { var word = []; for (var k = 0; k < lookahead + 1; k++) { word.push(tokenWords[j + k]); } for (var k = lookahead; k >= 0; k--) { var compoundWord = word.join(" "); if (compoundWord in links) { if ((compoundWord in existingLinks) || ignoredWords[compoundWord]) { j += k; break; } existingLinks[compoundWord] = true; tokenWords[j] = "[[" + tokenWords[j]; tokenWords[j + k] += "]]"; j += k; break; } var lowerWord = compoundWord.wiktviUncapitalize(); if (lowerWord in links) { if ((lowerWord in existingLinks) || ignoredWords[lowerWord]) { j += k; break; } existingLinks[lowerWord] = true; tokenWords[j] = "[[" + lowerWord + "|" + tokenWords[j]; tokenWords[j + k] += "]]"; j += k; break; } if (k) word.splice(-1, 1); else if (!ignoredWords[compoundWord]) { var lowerWord = compoundWord.wiktviUncapitalize(); if (!ignoredWords[lowerWord]) { existingLinks[compoundWord] = true; tokenWords[j] = "[[" + tokenWords[j] + "]]"; } } } } tokens[i] = tokenWords.join(" "); if (debug) { displayTokens[i] = "<b style='border: 1px solid gray;'>" + mw.html.escape(tokens[i]) + "</b>"; } }); if (debug) { $("#linkify-tokens").html("\n" + displayTokens.join("") + "\n"); } callback(tokens.join("")); }).fail(function (error) { console.warn(error); callback(); }); }); } function addLinkifyButton() { if ($.wiktviLinkify) { $("#wpTextbox1").after($(mw.html.element("div", { id: "linkify-progress", title: getMessage("toolbarButtonName") })).hide()); } mw.loader.using("ext.wikiEditor", function () { $("#wpTextbox1").on('wikiEditor-toolbar-buildSection-main', function (evt, section) { section.groups.insert.tools.linkify = { type: "button", action: { type: "callback", execute: function () { mw.loader.using("jquery.textSelection", function () { var selection = $("#wpTextbox1").textSelection("getSelection"); $.wiktviLinkify(selection, function (linkedText) { if (!linkedText) return; $("#wpTextbox1").textSelection("encapsulateSelection", { peri: linkedText, replace: true }); }, $.wiktviLinkify_debug); }); } }, label: getMessage("toolbarButtonName"), icon: "//upload.wikimedia.org/wikipedia/commons/b/ba/Norwegian_link_sign.png" }; }); }); }; addLinkifyButton(); })(jQuery); ikri1qvev0580excsv7sqgh47jykinv 6265706 6265705 2026-07-20T00:21:26Z Wikihez 7344 6265706 javascript text/javascript // Çavkanî [[vi:MediaWiki:Gadget-linkify.js]] (function ($) { var messages = { vi: {toolbarButtonName: "Tự động đặt liên kết trong lựa chọn"}, en: {toolbarButtonName: "Automatically link selected text"}, ku: {toolbarButtonName: "Li nivîsa bijartî bi otomatîkî girêdan lê zêde bike"}, es: {toolbarButtonName: "Automáticamente insertar enlaces en la selección"} }; var ignoredWordList = ("de|di|da|li|re|ve|tê|jî|jê|û|ya|a|ê|ên|î|ku").split("|"); var ignoredWords = {}; $.each(ignoredWordList, function (i, word) { ignoredWords[word] = true; }); /** * One less than the maximum number of syllables to be considered as a compound * word. */ var lookahead = 2; var tokenRE = /(\s*(?:<!--[\s\S]+?-->|\{\{[\s\S]+?\}\}|\[\[.+?\]\]|[^A-ZÀÁẢÃẠÂẦẤẨẪẬĂẰẮẲẴẶĐÈÉẺẼẸÊỀẾỂỄỆÌÍỈĨỊÒÓỎÕỌÔỒỐỔỖỘƠỜỚỞỠỢÙÚỦŨỤƯỪỨỬỮỰỲÝỶỸỴŞşÇçÎîÛûÊê\u0300-\u036F{[< ]+|[{[<])\s*)/i; String.prototype.wiktviUncapitalize = function () { return this[0].toLowerCase() + this.substr(1); }; var userLang = mw.config.get("wgUserLanguage"); function getMessage(name) { return (messages[userLang] || messages.vi)[name] || messages.vi[name]; } $.wiktviLinkify = function (text, callback, debug) { var tokens = text.split(tokenRE); var displayTokens = []; var words = {}; var existingLinks = {}; $.each(tokens, function (i, token) { if (debug) displayTokens.push(mw.html.escape(token)); var tokenLinks = token.match(/\[\[.+?(?:\|.+?)?\]\]/g); $.each(tokenLinks || [], function () { existingLinks[this.match(/\[\[(.+?)(?:\|.+?)?\]\]/)[1]] = true; }); if (!token || token.match(tokenRE)) return; var tokenWords = token.split(" "); $.each(tokenWords, function (j, word) { for (var k = 0; k < lookahead + 1 && tokenWords[j + k]; k++) { if (k) word += " " + tokenWords[j + k]; if (!ignoredWords[word]) words[word] = true; if (word[0] != word[0].toLowerCase()) { var lowerWord = word.wiktviUncapitalize(); if (!ignoredWords[lowerWord]) { words[lowerWord] = true; } } } }); if (debug) { displayTokens[i] = "<b style='border: 1px solid gray;'>" + mw.html.escape(token) + "</b>"; } }); var uniqueWords = []; $.each(words, function (word) { if (!ignoredWords[word]) uniqueWords.push(word); }); if (debug) { var uniqueLinks = []; $.each(existingLinks, function (link) { uniqueLinks.push(link); }); var list = "<pre id='linkify-tokens'>\n" + displayTokens.join("") + "\n</pre>"; list += "<hr /><p>Các cụm từ sẽ tìm kiếm:</p><p>" + uniqueWords + "</p>"; list += "<hr /><p>Các cụm từ đã có liên kết:</p><p>" + uniqueLinks + "</p>"; $("#linkify-progress").html(list).dialog({modal: true}); } if (!uniqueWords.length) return; mw.loader.using("mediawiki.api", function () { var api = new mw.Api(); api.get({ action: "parse", text: "[[" + uniqueWords.join("]] [[") + "]]", prop: "links" }).done(function (results) { $("#linkify-progress").append("<hr />"); var displayLinks = []; var links = {}; $.each(results.parse.links, function () { if (debug && "exists" in this) displayLinks.push(this["*"]); if ("exists" in this) links[this["*"]] = true; }); if (debug) { $("#linkify-progress").append("<p>Các mục từ:</p><p>" + displayLinks + "</p>"); } $.each(tokens, function (i, token) { if (!token || token.match(tokenRE)) return; var tokenWords = token.split(" "); for (var j = 0; j < tokenWords.length; j++) { var word = []; for (var k = 0; k < lookahead + 1; k++) { word.push(tokenWords[j + k]); } for (var k = lookahead; k >= 0; k--) { var compoundWord = word.join(" "); if (compoundWord in links) { if ((compoundWord in existingLinks) || ignoredWords[compoundWord]) { j += k; break; } existingLinks[compoundWord] = true; tokenWords[j] = "[[" + tokenWords[j]; tokenWords[j + k] += "]]"; j += k; break; } var lowerWord = compoundWord.wiktviUncapitalize(); if (lowerWord in links) { if ((lowerWord in existingLinks) || ignoredWords[lowerWord]) { j += k; break; } existingLinks[lowerWord] = true; tokenWords[j] = "[[" + lowerWord + "|" + tokenWords[j]; tokenWords[j + k] += "]]"; j += k; break; } if (k) word.splice(-1, 1); else if (!ignoredWords[compoundWord]) { var lowerWord = compoundWord.wiktviUncapitalize(); if (!ignoredWords[lowerWord]) { existingLinks[compoundWord] = true; tokenWords[j] = "[[" + tokenWords[j] + "]]"; } } } } tokens[i] = tokenWords.join(" "); if (debug) { displayTokens[i] = "<b style='border: 1px solid gray;'>" + mw.html.escape(tokens[i]) + "</b>"; } }); if (debug) { $("#linkify-tokens").html("\n" + displayTokens.join("") + "\n"); } callback(tokens.join("")); }).fail(function (error) { console.warn(error); callback(); }); }); } function getLinkifyTool() { return { type: "button", action: { type: "callback", execute: function () { mw.loader.using("jquery.textSelection", function () { var selection = $("#wpTextbox1").textSelection("getSelection"); $.wiktviLinkify(selection, function (linkedText) { if (!linkedText) return; $("#wpTextbox1").textSelection("encapsulateSelection", { peri: linkedText, replace: true }); }, $.wiktviLinkify_debug); }); } }, label: getMessage("toolbarButtonName"), icon: "//upload.wikimedia.org/wikipedia/commons/b/ba/Norwegian_link_sign.png" }; } function addLinkifyButton() { var $textbox = $("#wpTextbox1"); // Nothing to attach to on this page (VisualEditor, 2017 editor, non-edit // pages, etc.) — bail out instead of silently binding to an empty set. if (!$textbox.length) return; if ($.wiktviLinkify) { $textbox.after($(mw.html.element("div", { id: "linkify-progress", title: getMessage("toolbarButtonName") })).hide()); } // Bind the listener immediately, synchronously, rather than inside the // mw.loader.using("ext.wikiEditor", ...) callback. If we wait for that // callback to fire before attaching the listener, ext.wikiEditor may // already be loaded and may have already built (and fired the event for) // the main toolbar section by the time our callback runs -- in which case // the event has already come and gone and our button never gets added. // Attaching the listener up front means we won't miss the event even if // ext.wikiEditor resolves "instantly" (e.g. already cached/loaded). $textbox.on('wikiEditor-toolbar-buildSection-main', function (evt, section) { section.groups.insert.tools.linkify = getLinkifyTool(); }); mw.loader.using("ext.wikiEditor", function () { // Fallback for the case where the toolbar's main section was already // built (and the event already fired) before this gadget's script // even started executing -- e.g. another gadget loaded ext.wikiEditor // earlier and the toolbar finished initializing first. In that case // the listener above is too late, so we check whether the toolbar // context already exists and, if so, add the tool directly via the // public addToToolbar API instead of waiting for an event that has // already happened. var context = $textbox.data("wikiEditor-context"); if (context && context.modules && context.modules.toolbar) { $textbox.wikiEditor("addToToolbar", { section: "main", group: "insert", tools: { linkify: getLinkifyTool() } }); } }); }; // Only try to add the button on pages that actually have an edit form -- // running unconditionally on every page load (including view/history/etc. // pages where #wpTextbox1 never exists) wastes a mw.loader.using round trip // and can look like "sometimes nothing happens" if a user doesn't realize // they weren't on an edit screen. if ($.inArray(mw.config.get("wgAction"), ["edit", "submit"]) !== -1) { addLinkifyButton(); } })(jQuery); 9wt90fwsjf1rg9qlslytlrwxkn2sstu 6265708 6265706 2026-07-20T00:30:29Z Wikihez 7344 6265708 javascript text/javascript // MediaWiki gadget: automatically link selected text to existing wiktionary entries (function ($) { var messages = { ku: {toolbarButtonName: "Li nivîsa bijartî bi otomatîkî girêdan lê zêde bike"}, en: {toolbarButtonName: "Automatically link selected text"}, es: {toolbarButtonName: "Automáticamente insertar enlaces en la selección"} }; // Kurmanji function words (prepositions, conjunctions, pronouns, particles, // demonstratives, copula/negation forms) that should never be turned into // links on their own, even though they're short enough to match compound // candidates during scanning. var ignoredWordList = ( "a|an|ba|bê|bi|bin|çi|çu|da|de|di|ê|ên|erê|ev|ew|em|gel|ha|her|" + "hûn|î|jê|jî|ka|kî|ku|lê|li|me|min|na|nav|ne|pê|re|ser|ta|te|tê|" + "tu|û|va|van|ve|vê|vî|wan|we|wê|wî|wir|vir|ya|yan|yê" ).split("|"); var ignoredWords = {}; $.each(ignoredWordList, function (i, word) { ignoredWords[word] = true; }); /** * One less than the maximum number of syllables to be considered as a compound * word. */ var lookahead = 2; // Tokenizer boundary class: standard uppercase Latin A-Z plus the Kurmanji // Latin alphabet's diacritic letters (both cases: Ç ç, Ê ê, Î î, Ş ş, Û û), // combining diacritical marks, and wiki markup delimiters. var tokenRE = /(\s*(?:<!--[\s\S]+?-->|\{\{[\s\S]+?\}\}|\[\[.+?\]\]|[^A-ZÇÊÎŞÛçêîşû\u0300-\u036F{[< ]+|[{[<])\s*)/i; String.prototype.linkifyUncapitalize = function () { return this[0].toLowerCase() + this.substr(1); }; var userLang = mw.config.get("wgUserLanguage"); function getMessage(name) { return (messages[userLang] || messages.ku)[name] || messages.ku[name]; } $.kuLinkify = function (text, callback, debug) { var tokens = text.split(tokenRE); var displayTokens = []; var words = {}; var existingLinks = {}; $.each(tokens, function (i, token) { if (debug) displayTokens.push(mw.html.escape(token)); var tokenLinks = token.match(/\[\[.+?(?:\|.+?)?\]\]/g); $.each(tokenLinks || [], function () { existingLinks[this.match(/\[\[(.+?)(?:\|.+?)?\]\]/)[1]] = true; }); if (!token || token.match(tokenRE)) return; var tokenWords = token.split(" "); $.each(tokenWords, function (j, word) { for (var k = 0; k < lookahead + 1 && tokenWords[j + k]; k++) { if (k) word += " " + tokenWords[j + k]; if (!ignoredWords[word]) words[word] = true; if (word[0] != word[0].toLowerCase()) { var lowerWord = word.linkifyUncapitalize(); if (!ignoredWords[lowerWord]) { words[lowerWord] = true; } } } }); if (debug) { displayTokens[i] = "<b style='border: 1px solid gray;'>" + mw.html.escape(token) + "</b>"; } }); var uniqueWords = []; $.each(words, function (word) { if (!ignoredWords[word]) uniqueWords.push(word); }); if (debug) { var uniqueLinks = []; $.each(existingLinks, function (link) { uniqueLinks.push(link); }); var list = "<pre id='linkify-tokens'>\n" + displayTokens.join("") + "\n</pre>"; list += "<hr /><p>Words to search for:</p><p>" + uniqueWords + "</p>"; list += "<hr /><p>Words that already have links:</p><p>" + uniqueLinks + "</p>"; $("#linkify-progress").html(list).dialog({modal: true}); } if (!uniqueWords.length) return; mw.loader.using("mediawiki.api", function () { var api = new mw.Api(); api.get({ action: "parse", text: "[[" + uniqueWords.join("]] [[") + "]]", prop: "links" }).done(function (results) { $("#linkify-progress").append("<hr />"); var displayLinks = []; var links = {}; $.each(results.parse.links, function () { if (debug && "exists" in this) displayLinks.push(this["*"]); if ("exists" in this) links[this["*"]] = true; }); if (debug) { $("#linkify-progress").append("<p>Existing entries:</p><p>" + displayLinks + "</p>"); } $.each(tokens, function (i, token) { if (!token || token.match(tokenRE)) return; var tokenWords = token.split(" "); for (var j = 0; j < tokenWords.length; j++) { var word = []; for (var k = 0; k < lookahead + 1; k++) { word.push(tokenWords[j + k]); } for (var k = lookahead; k >= 0; k--) { var compoundWord = word.join(" "); if (compoundWord in links) { if ((compoundWord in existingLinks) || ignoredWords[compoundWord]) { j += k; break; } existingLinks[compoundWord] = true; tokenWords[j] = "[[" + tokenWords[j]; tokenWords[j + k] += "]]"; j += k; break; } var lowerWord = compoundWord.linkifyUncapitalize(); if (lowerWord in links) { if ((lowerWord in existingLinks) || ignoredWords[lowerWord]) { j += k; break; } existingLinks[lowerWord] = true; tokenWords[j] = "[[" + lowerWord + "|" + tokenWords[j]; tokenWords[j + k] += "]]"; j += k; break; } if (k) word.splice(-1, 1); else if (!ignoredWords[compoundWord]) { var lowerWord = compoundWord.linkifyUncapitalize(); if (!ignoredWords[lowerWord]) { existingLinks[compoundWord] = true; tokenWords[j] = "[[" + tokenWords[j] + "]]"; } } } } tokens[i] = tokenWords.join(" "); if (debug) { displayTokens[i] = "<b style='border: 1px solid gray;'>" + mw.html.escape(tokens[i]) + "</b>"; } }); if (debug) { $("#linkify-tokens").html("\n" + displayTokens.join("") + "\n"); } callback(tokens.join("")); }).fail(function (error) { console.warn(error); callback(); }); }); } function getLinkifyTool() { return { type: "button", action: { type: "callback", execute: function () { mw.loader.using("jquery.textSelection", function () { var selection = $("#wpTextbox1").textSelection("getSelection"); $.kuLinkify(selection, function (linkedText) { if (!linkedText) return; $("#wpTextbox1").textSelection("encapsulateSelection", { peri: linkedText, replace: true }); }, $.kuLinkify_debug); }); } }, label: getMessage("toolbarButtonName"), icon: "//upload.wikimedia.org/wikipedia/commons/b/ba/Norwegian_link_sign.png" }; } function addLinkifyButton() { var $textbox = $("#wpTextbox1"); // Nothing to attach to on this page (VisualEditor, 2017 editor, non-edit // pages, etc.) — bail out instead of silently binding to an empty set. if (!$textbox.length) return; if ($.kuLinkify) { $textbox.after($(mw.html.element("div", { id: "linkify-progress", title: getMessage("toolbarButtonName") })).hide()); } // Bind the listener immediately, synchronously, rather than inside the // mw.loader.using("ext.wikiEditor", ...) callback. If we wait for that // callback to fire before attaching the listener, ext.wikiEditor may // already be loaded and may have already built (and fired the event for) // the main toolbar section by the time our callback runs -- in which case // the event has already come and gone and our button never gets added. // Attaching the listener up front means we won't miss the event even if // ext.wikiEditor resolves "instantly" (e.g. already cached/loaded). $textbox.on('wikiEditor-toolbar-buildSection-main', function (evt, section) { section.groups.insert.tools.linkify = getLinkifyTool(); }); mw.loader.using("ext.wikiEditor", function () { // Fallback for the case where the toolbar's main section was already // built (and the event already fired) before this gadget's script // even started executing -- e.g. another gadget loaded ext.wikiEditor // earlier and the toolbar finished initializing first. In that case // the listener above is too late, so we check whether the toolbar // context already exists and, if so, add the tool directly via the // public addToToolbar API instead of waiting for an event that has // already happened. var context = $textbox.data("wikiEditor-context"); if (context && context.modules && context.modules.toolbar) { $textbox.wikiEditor("addToToolbar", { section: "main", group: "insert", tools: { linkify: getLinkifyTool() } }); } }); }; // Only try to add the button on pages that actually have an edit form -- // running unconditionally on every page load (including view/history/etc. // pages where #wpTextbox1 never exists) wastes a mw.loader.using round trip // and can look like "sometimes nothing happens" if a user doesn't realize // they weren't on an edit screen. if ($.inArray(mw.config.get("wgAction"), ["edit", "submit"]) !== -1) { addLinkifyButton(); } })(jQuery); 9p8m2w4mjkljrpa7kl1vpk730x2p3ma 6265709 6265708 2026-07-20T00:35:06Z Wikihez 7344 6265709 javascript text/javascript // MediaWiki gadget: automatically link selected text to existing wiktionary entries (function ($) { var messages = { ku: {toolbarButtonName: "Li nivîsa bijartî bi otomatîkî girêdan lê zêde bike"}, en: {toolbarButtonName: "Automatically link selected text"}, es: {toolbarButtonName: "Automáticamente insertar enlaces en la selección"} }; // Kurmanji function words (prepositions, conjunctions, pronouns, particles, // demonstratives, copula/negation forms) that should never be turned into // links on their own, even though they're short enough to match compound // candidates during scanning. var ignoredWordList = ( "a|an|ba|bê|bi|bin|çi|çu|da|de|di|ê|ên|erê|ev|ew|em|gel|ha|her|" + "hûn|î|jê|jî|ka|kî|ku|lê|li|me|min|na|nav|ne|pê|re|ser|ta|te|tê|" + "tu|û|va|van|ve|vê|vî|wan|we|wê|wî|wir|vir|ya|yan|yê" ).split("|"); var ignoredWords = {}; $.each(ignoredWordList, function (i, word) { ignoredWords[word] = true; }); /** * One less than the maximum number of syllables to be considered as a compound * word. */ var lookahead = 2; // Tokenizer boundary class: standard uppercase Latin A-Z plus the Kurmanji // Latin alphabet's diacritic letters (both cases: Ç ç, Ê ê, Î î, Ş ş, Û û), // combining diacritical marks, and wiki markup delimiters. var tokenRE = /(\s*(?:<!--[\s\S]+?-->|\{\{[\s\S]+?\}\}|\[\[.+?\]\]|[^A-ZÇÊÎŞÛçêîşû\u0300-\u036F{[< ]+|[{[<])\s*)/i; String.prototype.linkifyUncapitalize = function () { return this[0].toLowerCase() + this.substr(1); }; // Common Kurmanji noun-declension suffixes (indefinite/definite, // nominative/construct/oblique/vocative -- see Module:ku-nouns' // declSimpleNoun), longest first so the greedy match below prefers the // most specific ending (e.g. "eke" before a bare "e"). // // This list is intentionally generous rather than grammatically precise: // unlike declSimpleNoun, the gadget doesn't know a word's gender or its // exact stem class when scanning arbitrary running text, so it can't // reproduce that branching logic exactly. Instead, every candidate root // produced here is verified against real wiktionary entries via the API // before it's ever used (see the "stems" check below) -- so an // over-aggressive strip that doesn't correspond to a genuine entry is // simply discarded, never turned into a bad link. var nounSuffixes = [ "iyekî", "iyekê", "iyeke", "iyinan", "iyino", "yekî", "yekê", "yeke", "yinan", "yino", "ekî", "ekê", "eke", "inan", "ine", "ino", "iyên", "iyan", "iyek", "iyin", "iyo", "iyî", "iyê", "iya", "yên", "yan", "yek", "yin", "yo", "yî", "yê", "ya", "ek", "ên", "an", "in", "a", "ê", "î", "o" ]; /** * Given a lowercase surface word, returns candidate noun roots obtained by * stripping a known declension suffix -- e.g. "rûpeleke" -> ["rûpel"]. * Candidates are ordered from least- to most-aggressively stripped (longest * remaining root first), so that when several candidates turn out to match * real entries, the safer/more specific one wins. */ function getNounStemCandidates(word) { var candidates = []; for (var i = 0; i < nounSuffixes.length; i++) { var suf = nounSuffixes[i]; // Require at least a 2-character root left over, so we don't // generate degenerate single-letter "roots". if (word.length > suf.length + 1 && word.slice(-suf.length) === suf) { candidates.push(word.slice(0, -suf.length)); } } candidates.sort(function (a, b) { return b.length - a.length; }); return candidates; } var userLang = mw.config.get("wgUserLanguage"); function getMessage(name) { return (messages[userLang] || messages.ku)[name] || messages.ku[name]; } $.kuLinkify = function (text, callback, debug) { var tokens = text.split(tokenRE); var displayTokens = []; var words = {}; var existingLinks = {}; // Maps a surface word (as typed, and its lowercase form) to candidate // noun roots -- e.g. stemCandidates["rûpeleke"] = ["rûpel"]. Filled in // below and consulted during reconstruction so an inflected word whose // exact surface form has no entry can still be linked to its root. var stemCandidates = {}; $.each(tokens, function (i, token) { if (debug) displayTokens.push(mw.html.escape(token)); var tokenLinks = token.match(/\[\[.+?(?:\|.+?)?\]\]/g); $.each(tokenLinks || [], function () { existingLinks[this.match(/\[\[(.+?)(?:\|.+?)?\]\]/)[1]] = true; }); if (!token || token.match(tokenRE)) return; var tokenWords = token.split(" "); $.each(tokenWords, function (j, word) { for (var k = 0; k < lookahead + 1 && tokenWords[j + k]; k++) { if (k) word += " " + tokenWords[j + k]; if (!ignoredWords[word]) words[word] = true; if (word[0] != word[0].toLowerCase()) { var lowerWord = word.linkifyUncapitalize(); if (!ignoredWords[lowerWord]) { words[lowerWord] = true; } } } }); // Also collect candidate noun roots for every individual word (not // multi-word compounds -- declension endings attach to a single // word), so inflected forms like "rûpeleke" can still be linked to // an existing root entry like "rûpel" even when the inflected form // itself has no entry. $.each(tokenWords, function (j, word) { if (!word) return; var lower = word.linkifyUncapitalize(); var stems = getNounStemCandidates(lower); if (stems.length) { stemCandidates[word] = stems; $.each(stems, function (s, stem) { if (!ignoredWords[stem]) words[stem] = true; }); } }); if (debug) { displayTokens[i] = "<b style='border: 1px solid gray;'>" + mw.html.escape(token) + "</b>"; } }); var uniqueWords = []; $.each(words, function (word) { if (!ignoredWords[word]) uniqueWords.push(word); }); if (debug) { var uniqueLinks = []; $.each(existingLinks, function (link) { uniqueLinks.push(link); }); var list = "<pre id='linkify-tokens'>\n" + displayTokens.join("") + "\n</pre>"; list += "<hr /><p>Words to search for:</p><p>" + uniqueWords + "</p>"; list += "<hr /><p>Words that already have links:</p><p>" + uniqueLinks + "</p>"; $("#linkify-progress").html(list).dialog({modal: true}); } if (!uniqueWords.length) return; mw.loader.using("mediawiki.api", function () { var api = new mw.Api(); api.get({ action: "parse", text: "[[" + uniqueWords.join("]] [[") + "]]", prop: "links" }).done(function (results) { $("#linkify-progress").append("<hr />"); var displayLinks = []; var links = {}; $.each(results.parse.links, function () { if (debug && "exists" in this) displayLinks.push(this["*"]); if ("exists" in this) links[this["*"]] = true; }); if (debug) { $("#linkify-progress").append("<p>Existing entries:</p><p>" + displayLinks + "</p>"); } $.each(tokens, function (i, token) { if (!token || token.match(tokenRE)) return; var tokenWords = token.split(" "); for (var j = 0; j < tokenWords.length; j++) { var word = []; for (var k = 0; k < lookahead + 1; k++) { word.push(tokenWords[j + k]); } for (var k = lookahead; k >= 0; k--) { var compoundWord = word.join(" "); if (compoundWord in links) { if ((compoundWord in existingLinks) || ignoredWords[compoundWord]) { j += k; break; } existingLinks[compoundWord] = true; tokenWords[j] = "[[" + tokenWords[j]; tokenWords[j + k] += "]]"; j += k; break; } var lowerWord = compoundWord.linkifyUncapitalize(); if (lowerWord in links) { if ((lowerWord in existingLinks) || ignoredWords[lowerWord]) { j += k; break; } existingLinks[lowerWord] = true; tokenWords[j] = "[[" + lowerWord + "|" + tokenWords[j]; tokenWords[j + k] += "]]"; j += k; break; } if (k) { word.splice(-1, 1); } else if (!ignoredWords[compoundWord]) { var lowerWord = compoundWord.linkifyUncapitalize(); // Neither the exact word nor its lowercase form // matched an existing entry -- try declension // roots computed earlier (e.g. "rûpeleke" -> // "rûpel") before giving up and linking the raw // surface form as-is. var stems = stemCandidates[compoundWord] || stemCandidates[lowerWord] || []; var stemLinked = false; for (var s = 0; s < stems.length; s++) { var stem = stems[s]; if ((stem in links) && !(stem in existingLinks) && !ignoredWords[stem]) { existingLinks[stem] = true; tokenWords[j] = "[[" + stem + "|" + tokenWords[j] + "]]"; stemLinked = true; break; } } if (!stemLinked && !ignoredWords[lowerWord]) { existingLinks[compoundWord] = true; tokenWords[j] = "[[" + tokenWords[j] + "]]"; } } } } tokens[i] = tokenWords.join(" "); if (debug) { displayTokens[i] = "<b style='border: 1px solid gray;'>" + mw.html.escape(tokens[i]) + "</b>"; } }); if (debug) { $("#linkify-tokens").html("\n" + displayTokens.join("") + "\n"); } callback(tokens.join("")); }).fail(function (error) { console.warn(error); callback(); }); }); } function getLinkifyTool() { return { type: "button", action: { type: "callback", execute: function () { mw.loader.using("jquery.textSelection", function () { var selection = $("#wpTextbox1").textSelection("getSelection"); $.kuLinkify(selection, function (linkedText) { if (!linkedText) return; $("#wpTextbox1").textSelection("encapsulateSelection", { peri: linkedText, replace: true }); }, $.kuLinkify_debug); }); } }, label: getMessage("toolbarButtonName"), icon: "//upload.wikimedia.org/wikipedia/commons/b/ba/Norwegian_link_sign.png" }; } function addLinkifyButton() { var $textbox = $("#wpTextbox1"); // Nothing to attach to on this page (VisualEditor, 2017 editor, non-edit // pages, etc.) — bail out instead of silently binding to an empty set. if (!$textbox.length) return; if ($.kuLinkify) { $textbox.after($(mw.html.element("div", { id: "linkify-progress", title: getMessage("toolbarButtonName") })).hide()); } // Bind the listener immediately, synchronously, rather than inside the // mw.loader.using("ext.wikiEditor", ...) callback. If we wait for that // callback to fire before attaching the listener, ext.wikiEditor may // already be loaded and may have already built (and fired the event for) // the main toolbar section by the time our callback runs -- in which case // the event has already come and gone and our button never gets added. // Attaching the listener up front means we won't miss the event even if // ext.wikiEditor resolves "instantly" (e.g. already cached/loaded). $textbox.on('wikiEditor-toolbar-buildSection-main', function (evt, section) { section.groups.insert.tools.linkify = getLinkifyTool(); }); mw.loader.using("ext.wikiEditor", function () { // Fallback for the case where the toolbar's main section was already // built (and the event already fired) before this gadget's script // even started executing -- e.g. another gadget loaded ext.wikiEditor // earlier and the toolbar finished initializing first. In that case // the listener above is too late, so we check whether the toolbar // context already exists and, if so, add the tool directly via the // public addToToolbar API instead of waiting for an event that has // already happened. var context = $textbox.data("wikiEditor-context"); if (context && context.modules && context.modules.toolbar) { $textbox.wikiEditor("addToToolbar", { section: "main", group: "insert", tools: { linkify: getLinkifyTool() } }); } }); }; // Only try to add the button on pages that actually have an edit form -- // running unconditionally on every page load (including view/history/etc. // pages where #wpTextbox1 never exists) wastes a mw.loader.using round trip // and can look like "sometimes nothing happens" if a user doesn't realize // they weren't on an edit screen. if ($.inArray(mw.config.get("wgAction"), ["edit", "submit"]) !== -1) { addLinkifyButton(); } })(jQuery); jbjpe0tprfvn1uzyqse669grpvu6cah 6265710 6265709 2026-07-20T00:47:39Z Wikihez 7344 6265710 javascript text/javascript // MediaWiki gadget: automatically link selected text to existing wiktionary entries (function ($) { var messages = { ku: {toolbarButtonName: "Li nivîsa bijartî bi otomatîkî girêdan lê zêde bike"}, en: {toolbarButtonName: "Automatically link selected text"}, es: {toolbarButtonName: "Automáticamente insertar enlaces en la selección"} }; // Kurmanji function words (prepositions, conjunctions, pronouns, particles, // demonstratives, copula/negation forms) that should never be turned into // links on their own, even though they're short enough to match compound // candidates during scanning. Also includes all 8 bare Kurmanji vowels // (a, e, ê, i, î, o, u, û) on their own, since a lone vowel is never a // meaningful link target even if it happens to match part of a scan. var ignoredWordList = ( "a|an|ba|bê|bi|bin|çi|çu|da|de|di|e|ê|ên|erê|ev|ew|em|gel|ha|her|" + "hûn|i|î|jê|jî|ka|kî|ku|lê|li|me|min|na|nav|ne|o|pê|re|ser|ta|te|tê|" + "tu|u|û|va|van|ve|vê|vî|wan|we|wê|wî|wir|vir|ya|yan|yê" ).split("|"); var ignoredWords = {}; $.each(ignoredWordList, function (i, word) { ignoredWords[word] = true; }); /** * One less than the maximum number of syllables to be considered as a compound * word. */ var lookahead = 2; // Tokenizer boundary class: standard uppercase Latin A-Z plus the Kurmanji // Latin alphabet's diacritic letters (both cases: Ç ç, Ê ê, Î î, Ş ş, Û û), // combining diacritical marks, and wiki markup delimiters. var tokenRE = /(\s*(?:<!--[\s\S]+?-->|\{\{[\s\S]+?\}\}|\[\[.+?\]\]|[^A-ZÇÊÎŞÛçêîşû\u0300-\u036F{[< ]+|[{[<])\s*)/i; String.prototype.linkifyUncapitalize = function () { return this[0].toLowerCase() + this.substr(1); }; // Common Kurmanji noun-declension suffixes (indefinite/definite, // nominative/construct/oblique/vocative -- see Module:ku-nouns' // declSimpleNoun), longest first so the greedy match below prefers the // most specific ending (e.g. "eke" before a bare "e"). // // This list is intentionally generous rather than grammatically precise: // unlike declSimpleNoun, the gadget doesn't know a word's gender or its // exact stem class when scanning arbitrary running text, so it can't // reproduce that branching logic exactly. Instead, every candidate root // produced here is verified against real wiktionary entries via the API // before it's ever used (see the "stems" check below) -- so an // over-aggressive strip that doesn't correspond to a genuine entry is // simply discarded, never turned into a bad link. var nounSuffixes = [ "iyekî", "iyekê", "iyeke", "iyinan", "iyino", "yekî", "yekê", "yeke", "yinan", "yino", "ekî", "ekê", "eke", "inan", "ine", "ino", "iyên", "iyan", "iyek", "iyin", "iyo", "iyî", "iyê", "iya", "yên", "yan", "yek", "yin", "yo", "yî", "yê", "ya", "ek", "ên", "an", "in", "a", "ê", "î", "o" ]; /** * Given a lowercase surface word, returns candidate noun roots obtained by * stripping a known declension suffix -- e.g. "rûpeleke" -> ["rûpel"]. * Candidates are ordered from least- to most-aggressively stripped (longest * remaining root first), so that when several candidates turn out to match * real entries, the safer/more specific one wins. */ function getNounStemCandidates(word) { var candidates = []; for (var i = 0; i < nounSuffixes.length; i++) { var suf = nounSuffixes[i]; // Require at least a 2-character root left over, so we don't // generate degenerate single-letter "roots". if (word.length > suf.length + 1 && word.slice(-suf.length) === suf) { candidates.push(word.slice(0, -suf.length)); } } candidates.sort(function (a, b) { return b.length - a.length; }); return candidates; } var userLang = mw.config.get("wgUserLanguage"); function getMessage(name) { return (messages[userLang] || messages.ku)[name] || messages.ku[name]; } $.kuLinkify = function (text, callback, debug) { var tokens = text.split(tokenRE); var displayTokens = []; var words = {}; var existingLinks = {}; // Maps a surface word (as typed, and its lowercase form) to candidate // noun roots -- e.g. stemCandidates["rûpeleke"] = ["rûpel"]. Filled in // below and consulted during reconstruction so an inflected word whose // exact surface form has no entry can still be linked to its root. var stemCandidates = {}; $.each(tokens, function (i, token) { if (debug) displayTokens.push(mw.html.escape(token)); var tokenLinks = token.match(/\[\[.+?(?:\|.+?)?\]\]/g); $.each(tokenLinks || [], function () { existingLinks[this.match(/\[\[(.+?)(?:\|.+?)?\]\]/)[1]] = true; }); if (!token || token.match(tokenRE)) return; var tokenWords = token.split(" "); $.each(tokenWords, function (j, word) { for (var k = 0; k < lookahead + 1 && tokenWords[j + k]; k++) { if (k) word += " " + tokenWords[j + k]; if (!ignoredWords[word]) words[word] = true; if (word[0] != word[0].toLowerCase()) { var lowerWord = word.linkifyUncapitalize(); if (!ignoredWords[lowerWord]) { words[lowerWord] = true; } } } }); // Also collect candidate noun roots for every individual word (not // multi-word compounds -- declension endings attach to a single // word), so inflected forms like "rûpeleke" can still be linked to // an existing root entry like "rûpel" even when the inflected form // itself has no entry. $.each(tokenWords, function (j, word) { if (!word) return; var lower = word.linkifyUncapitalize(); var stems = getNounStemCandidates(lower); if (stems.length) { stemCandidates[word] = stems; $.each(stems, function (s, stem) { if (!ignoredWords[stem]) words[stem] = true; }); } }); if (debug) { displayTokens[i] = "<b style='border: 1px solid gray;'>" + mw.html.escape(token) + "</b>"; } }); var uniqueWords = []; $.each(words, function (word) { if (!ignoredWords[word]) uniqueWords.push(word); }); if (debug) { var uniqueLinks = []; $.each(existingLinks, function (link) { uniqueLinks.push(link); }); var list = "<pre id='linkify-tokens'>\n" + displayTokens.join("") + "\n</pre>"; list += "<hr /><p>Words to search for:</p><p>" + uniqueWords + "</p>"; list += "<hr /><p>Words that already have links:</p><p>" + uniqueLinks + "</p>"; $("#linkify-progress").html(list).dialog({modal: true}); } if (!uniqueWords.length) return; mw.loader.using("mediawiki.api", function () { var api = new mw.Api(); api.get({ action: "parse", text: "[[" + uniqueWords.join("]] [[") + "]]", prop: "links" }).done(function (results) { $("#linkify-progress").append("<hr />"); var displayLinks = []; var links = {}; $.each(results.parse.links, function () { if (debug && "exists" in this) displayLinks.push(this["*"]); if ("exists" in this) links[this["*"]] = true; }); if (debug) { $("#linkify-progress").append("<p>Existing entries:</p><p>" + displayLinks + "</p>"); } $.each(tokens, function (i, token) { if (!token || token.match(tokenRE)) return; var tokenWords = token.split(" "); for (var j = 0; j < tokenWords.length; j++) { var word = []; for (var k = 0; k < lookahead + 1; k++) { word.push(tokenWords[j + k]); } for (var k = lookahead; k >= 0; k--) { var compoundWord = word.join(" "); if (k === 0) { var lowerSingle = compoundWord.linkifyUncapitalize(); // 1. Prefer linking to the declension root (lemma) // over the inflected surface form's own page -- // e.g. link "pîvana" as [[pîvan|pîvana]] rather // than [[pîvana]], since wiktionary entries for // inflected forms are usually secondary "form of" // pages rather than the main lemma readers want. var stems = stemCandidates[compoundWord] || stemCandidates[lowerSingle] || []; var stemLinked = false; for (var s = 0; s < stems.length; s++) { var stem = stems[s]; if ((stem in links) && !(stem in existingLinks) && !ignoredWords[stem]) { existingLinks[stem] = true; tokenWords[j] = "[[" + stem + "|" + tokenWords[j] + "]]"; stemLinked = true; break; } } if (stemLinked) break; if (!ignoredWords[compoundWord] && !ignoredWords[lowerSingle]) { // 2. No usable root -- link the word to // itself. Always use piped syntax // (target|display) even though target and // display are identical text, so a reader // who spots a wrong or missing link can // simply edit the part before the "|" to // point it at the correct term, instead of // having to first rewrite a bare [[word]] // link into piped form themselves. var target = compoundWord; if (!(compoundWord in links) && (lowerSingle in links)) { target = lowerSingle; } if (!(target in existingLinks)) { existingLinks[target] = true; tokenWords[j] = "[[" + target + "|" + tokenWords[j] + "]]"; } } break; } if (compoundWord in links) { if ((compoundWord in existingLinks) || ignoredWords[compoundWord]) { j += k; break; } existingLinks[compoundWord] = true; tokenWords[j] = "[[" + tokenWords[j]; tokenWords[j + k] += "]]"; j += k; break; } var lowerWord = compoundWord.linkifyUncapitalize(); if (lowerWord in links) { if ((lowerWord in existingLinks) || ignoredWords[lowerWord]) { j += k; break; } existingLinks[lowerWord] = true; tokenWords[j] = "[[" + lowerWord + "|" + tokenWords[j]; tokenWords[j + k] += "]]"; j += k; break; } word.splice(-1, 1); } } tokens[i] = tokenWords.join(" "); if (debug) { displayTokens[i] = "<b style='border: 1px solid gray;'>" + mw.html.escape(tokens[i]) + "</b>"; } }); if (debug) { $("#linkify-tokens").html("\n" + displayTokens.join("") + "\n"); } callback(tokens.join("")); }).fail(function (error) { console.warn(error); callback(); }); }); } function getLinkifyTool() { return { type: "button", action: { type: "callback", execute: function () { mw.loader.using("jquery.textSelection", function () { var selection = $("#wpTextbox1").textSelection("getSelection"); $.kuLinkify(selection, function (linkedText) { if (!linkedText) return; $("#wpTextbox1").textSelection("encapsulateSelection", { peri: linkedText, replace: true }); }, $.kuLinkify_debug); }); } }, label: getMessage("toolbarButtonName"), icon: "//upload.wikimedia.org/wikipedia/commons/b/ba/Norwegian_link_sign.png" }; } function addLinkifyButton() { var $textbox = $("#wpTextbox1"); // Nothing to attach to on this page (VisualEditor, 2017 editor, non-edit // pages, etc.) — bail out instead of silently binding to an empty set. if (!$textbox.length) return; if ($.kuLinkify) { $textbox.after($(mw.html.element("div", { id: "linkify-progress", title: getMessage("toolbarButtonName") })).hide()); } // Bind the listener immediately, synchronously, rather than inside the // mw.loader.using("ext.wikiEditor", ...) callback. If we wait for that // callback to fire before attaching the listener, ext.wikiEditor may // already be loaded and may have already built (and fired the event for) // the main toolbar section by the time our callback runs -- in which case // the event has already come and gone and our button never gets added. // Attaching the listener up front means we won't miss the event even if // ext.wikiEditor resolves "instantly" (e.g. already cached/loaded). $textbox.on('wikiEditor-toolbar-buildSection-main', function (evt, section) { section.groups.insert.tools.linkify = getLinkifyTool(); }); mw.loader.using("ext.wikiEditor", function () { // Fallback for the case where the toolbar's main section was already // built (and the event already fired) before this gadget's script // even started executing -- e.g. another gadget loaded ext.wikiEditor // earlier and the toolbar finished initializing first. In that case // the listener above is too late, so we check whether the toolbar // context already exists and, if so, add the tool directly via the // public addToToolbar API instead of waiting for an event that has // already happened. var context = $textbox.data("wikiEditor-context"); if (context && context.modules && context.modules.toolbar) { $textbox.wikiEditor("addToToolbar", { section: "main", group: "insert", tools: { linkify: getLinkifyTool() } }); } }); }; // Only try to add the button on pages that actually have an edit form -- // running unconditionally on every page load (including view/history/etc. // pages where #wpTextbox1 never exists) wastes a mw.loader.using round trip // and can look like "sometimes nothing happens" if a user doesn't realize // they weren't on an edit screen. if ($.inArray(mw.config.get("wgAction"), ["edit", "submit"]) !== -1) { addLinkifyButton(); } })(jQuery); 67m6q5r9wz4zd42azspga5w8mzhyflv 6265711 6265710 2026-07-20T00:52:52Z Wikihez 7344 6265711 javascript text/javascript // MediaWiki gadget: automatically link selected text to existing wiktionary entries (function ($) { var messages = { ku: {toolbarButtonName: "Li nivîsa bijartî bi otomatîkî girêdan lê zêde bike"}, en: {toolbarButtonName: "Automatically link selected text"}, es: {toolbarButtonName: "Automáticamente insertar enlaces en la selección"} }; // Kurmanji function words (prepositions, conjunctions, pronouns, particles, // demonstratives, copula/negation forms) that should never be turned into // links on their own, even though they're short enough to match compound // candidates during scanning. Also includes all 8 bare Kurmanji vowels // (a, e, ê, i, î, o, u, û) on their own, since a lone vowel is never a // meaningful link target even if it happens to match part of a scan. var ignoredWordList = ( "a|an|ba|bê|bi|bin|çi|çu|da|de|di|e|ê|ên|erê|ev|ew|em|gel|ha|her|" + "hûn|i|î|jê|jî|ka|kî|ku|kû|lê|li|me|min|na|ne|o|pê|re|ti|te|tê|" + "tu|u|û|va|van|ve|vê|vî|wan|we|wê|wî|wir|vir|ya|yan|yê|yên" ).split("|"); var ignoredWords = {}; $.each(ignoredWordList, function (i, word) { ignoredWords[word] = true; }); /** * One less than the maximum number of syllables to be considered as a compound * word. */ var lookahead = 2; // Tokenizer boundary class: standard uppercase Latin A-Z plus the Kurmanji // Latin alphabet's diacritic letters (both cases: Ç ç, Ê ê, Î î, Ş ş, Û û), // combining diacritical marks, and wiki markup delimiters. var tokenRE = /(\s*(?:<!--[\s\S]+?-->|\{\{[\s\S]+?\}\}|\[\[.+?\]\]|[^A-ZÇÊÎŞÛçêîşû\u0300-\u036F{[< ]+|[{[<])\s*)/i; String.prototype.linkifyUncapitalize = function () { return this[0].toLowerCase() + this.substr(1); }; // Common Kurmanji noun-declension suffixes (indefinite/definite, // nominative/construct/oblique/vocative -- see Module:ku-nouns' // declSimpleNoun), longest first so the greedy match below prefers the // most specific ending (e.g. "eke" before a bare "e"). // // This list is intentionally generous rather than grammatically precise: // unlike declSimpleNoun, the gadget doesn't know a word's gender or its // exact stem class when scanning arbitrary running text, so it can't // reproduce that branching logic exactly. Instead, every candidate root // produced here is verified against real wiktionary entries via the API // before it's ever used (see the "stems" check below) -- so an // over-aggressive strip that doesn't correspond to a genuine entry is // simply discarded, never turned into a bad link. var nounSuffixes = [ "iyekî", "iyekê", "iyeke", "iyinan", "iyino", "yekî", "yekê", "yeke", "yinan", "yino", "ekî", "ekê", "eke", "inan", "ine", "ino", "iyên", "iyan", "iyek", "iyin", "iyo", "iyî", "iyê", "iya", "yên", "yan", "yek", "yin", "yo", "yî", "yê", "ya", "ek", "ên", "an", "in", "a", "ê", "î", "o" ]; /** * Given a lowercase surface word, returns candidate noun roots obtained by * stripping a known declension suffix -- e.g. "rûpeleke" -> ["rûpel"]. * Candidates are ordered from least- to most-aggressively stripped (longest * remaining root first), so that when several candidates turn out to match * real entries, the safer/more specific one wins. */ function getNounStemCandidates(word) { var candidates = []; for (var i = 0; i < nounSuffixes.length; i++) { var suf = nounSuffixes[i]; // Require at least a 2-character root left over, so we don't // generate degenerate single-letter "roots". if (word.length > suf.length + 1 && word.slice(-suf.length) === suf) { candidates.push(word.slice(0, -suf.length)); } } candidates.sort(function (a, b) { return b.length - a.length; }); return candidates; } var userLang = mw.config.get("wgUserLanguage"); function getMessage(name) { return (messages[userLang] || messages.ku)[name] || messages.ku[name]; } $.kuLinkify = function (text, callback, debug) { var tokens = text.split(tokenRE); var displayTokens = []; var words = {}; var existingLinks = {}; // Maps a surface word (as typed, and its lowercase form) to candidate // noun roots -- e.g. stemCandidates["rûpeleke"] = ["rûpel"]. Filled in // below and consulted during reconstruction so an inflected word whose // exact surface form has no entry can still be linked to its root. var stemCandidates = {}; $.each(tokens, function (i, token) { if (debug) displayTokens.push(mw.html.escape(token)); var tokenLinks = token.match(/\[\[.+?(?:\|.+?)?\]\]/g); $.each(tokenLinks || [], function () { existingLinks[this.match(/\[\[(.+?)(?:\|.+?)?\]\]/)[1]] = true; }); if (!token || token.match(tokenRE)) return; var tokenWords = token.split(" "); $.each(tokenWords, function (j, word) { for (var k = 0; k < lookahead + 1 && tokenWords[j + k]; k++) { if (k) word += " " + tokenWords[j + k]; if (!ignoredWords[word]) words[word] = true; if (word[0] != word[0].toLowerCase()) { var lowerWord = word.linkifyUncapitalize(); if (!ignoredWords[lowerWord]) { words[lowerWord] = true; } } } }); // Also collect candidate noun roots for every individual word (not // multi-word compounds -- declension endings attach to a single // word), so inflected forms like "rûpeleke" can still be linked to // an existing root entry like "rûpel" even when the inflected form // itself has no entry. $.each(tokenWords, function (j, word) { if (!word) return; var lower = word.linkifyUncapitalize(); var stems = getNounStemCandidates(lower); if (stems.length) { stemCandidates[word] = stems; $.each(stems, function (s, stem) { if (!ignoredWords[stem]) words[stem] = true; }); } }); if (debug) { displayTokens[i] = "<b style='border: 1px solid gray;'>" + mw.html.escape(token) + "</b>"; } }); var uniqueWords = []; $.each(words, function (word) { if (!ignoredWords[word]) uniqueWords.push(word); }); if (debug) { var uniqueLinks = []; $.each(existingLinks, function (link) { uniqueLinks.push(link); }); var list = "<pre id='linkify-tokens'>\n" + displayTokens.join("") + "\n</pre>"; list += "<hr /><p>Words to search for:</p><p>" + uniqueWords + "</p>"; list += "<hr /><p>Words that already have links:</p><p>" + uniqueLinks + "</p>"; $("#linkify-progress").html(list).dialog({modal: true}); } if (!uniqueWords.length) return; mw.loader.using("mediawiki.api", function () { var api = new mw.Api(); api.get({ action: "parse", text: "[[" + uniqueWords.join("]] [[") + "]]", prop: "links" }).done(function (results) { $("#linkify-progress").append("<hr />"); var displayLinks = []; var links = {}; $.each(results.parse.links, function () { if (debug && "exists" in this) displayLinks.push(this["*"]); if ("exists" in this) links[this["*"]] = true; }); if (debug) { $("#linkify-progress").append("<p>Existing entries:</p><p>" + displayLinks + "</p>"); } $.each(tokens, function (i, token) { if (!token || token.match(tokenRE)) return; var tokenWords = token.split(" "); for (var j = 0; j < tokenWords.length; j++) { var word = []; for (var k = 0; k < lookahead + 1; k++) { word.push(tokenWords[j + k]); } for (var k = lookahead; k >= 0; k--) { var compoundWord = word.join(" "); if (k === 0) { var lowerSingle = compoundWord.linkifyUncapitalize(); // 1. Prefer linking to the declension root (lemma) // over the inflected surface form's own page -- // e.g. link "pîvana" as [[pîvan|pîvana]] rather // than [[pîvana]], since wiktionary entries for // inflected forms are usually secondary "form of" // pages rather than the main lemma readers want. var stems = stemCandidates[compoundWord] || stemCandidates[lowerSingle] || []; var stemLinked = false; for (var s = 0; s < stems.length; s++) { var stem = stems[s]; if ((stem in links) && !(stem in existingLinks) && !ignoredWords[stem]) { existingLinks[stem] = true; tokenWords[j] = "[[" + stem + "|" + tokenWords[j] + "]]"; stemLinked = true; break; } } if (stemLinked) break; if (!ignoredWords[compoundWord] && !ignoredWords[lowerSingle]) { // 2. No usable root -- link the word to // itself. Always use piped syntax // (target|display) even though target and // display are identical text, so a reader // who spots a wrong or missing link can // simply edit the part before the "|" to // point it at the correct term, instead of // having to first rewrite a bare [[word]] // link into piped form themselves. var target = compoundWord; if (!(compoundWord in links) && (lowerSingle in links)) { target = lowerSingle; } if (!(target in existingLinks)) { existingLinks[target] = true; tokenWords[j] = "[[" + target + "|" + tokenWords[j] + "]]"; } } break; } if (compoundWord in links) { if ((compoundWord in existingLinks) || ignoredWords[compoundWord]) { j += k; break; } existingLinks[compoundWord] = true; tokenWords[j] = "[[" + tokenWords[j]; tokenWords[j + k] += "]]"; j += k; break; } var lowerWord = compoundWord.linkifyUncapitalize(); if (lowerWord in links) { if ((lowerWord in existingLinks) || ignoredWords[lowerWord]) { j += k; break; } existingLinks[lowerWord] = true; tokenWords[j] = "[[" + lowerWord + "|" + tokenWords[j]; tokenWords[j + k] += "]]"; j += k; break; } word.splice(-1, 1); } } tokens[i] = tokenWords.join(" "); if (debug) { displayTokens[i] = "<b style='border: 1px solid gray;'>" + mw.html.escape(tokens[i]) + "</b>"; } }); if (debug) { $("#linkify-tokens").html("\n" + displayTokens.join("") + "\n"); } callback(tokens.join("")); }).fail(function (error) { console.warn(error); callback(); }); }); } function getLinkifyTool() { return { type: "button", action: { type: "callback", execute: function () { mw.loader.using("jquery.textSelection", function () { var selection = $("#wpTextbox1").textSelection("getSelection"); $.kuLinkify(selection, function (linkedText) { if (!linkedText) return; $("#wpTextbox1").textSelection("encapsulateSelection", { peri: linkedText, replace: true }); }, $.kuLinkify_debug); }); } }, label: getMessage("toolbarButtonName"), icon: "//upload.wikimedia.org/wikipedia/commons/b/ba/Norwegian_link_sign.png" }; } function addLinkifyButton() { var $textbox = $("#wpTextbox1"); // Nothing to attach to on this page (VisualEditor, 2017 editor, non-edit // pages, etc.) — bail out instead of silently binding to an empty set. if (!$textbox.length) return; if ($.kuLinkify) { $textbox.after($(mw.html.element("div", { id: "linkify-progress", title: getMessage("toolbarButtonName") })).hide()); } // Bind the listener immediately, synchronously, rather than inside the // mw.loader.using("ext.wikiEditor", ...) callback. If we wait for that // callback to fire before attaching the listener, ext.wikiEditor may // already be loaded and may have already built (and fired the event for) // the main toolbar section by the time our callback runs -- in which case // the event has already come and gone and our button never gets added. // Attaching the listener up front means we won't miss the event even if // ext.wikiEditor resolves "instantly" (e.g. already cached/loaded). $textbox.on('wikiEditor-toolbar-buildSection-main', function (evt, section) { section.groups.insert.tools.linkify = getLinkifyTool(); }); mw.loader.using("ext.wikiEditor", function () { // Fallback for the case where the toolbar's main section was already // built (and the event already fired) before this gadget's script // even started executing -- e.g. another gadget loaded ext.wikiEditor // earlier and the toolbar finished initializing first. In that case // the listener above is too late, so we check whether the toolbar // context already exists and, if so, add the tool directly via the // public addToToolbar API instead of waiting for an event that has // already happened. var context = $textbox.data("wikiEditor-context"); if (context && context.modules && context.modules.toolbar) { $textbox.wikiEditor("addToToolbar", { section: "main", group: "insert", tools: { linkify: getLinkifyTool() } }); } }); }; // Only try to add the button on pages that actually have an edit form -- // running unconditionally on every page load (including view/history/etc. // pages where #wpTextbox1 never exists) wastes a mw.loader.using round trip // and can look like "sometimes nothing happens" if a user doesn't realize // they weren't on an edit screen. if ($.inArray(mw.config.get("wgAction"), ["edit", "submit"]) !== -1) { addLinkifyButton(); } })(jQuery); 8wj7j9vh5uqhv0g2avuc362erosaxa6 6265712 6265711 2026-07-20T00:55:40Z Wikihez 7344 6265712 javascript text/javascript // MediaWiki gadget: automatically link selected text to existing wiktionary entries (function ($) { var messages = { ku: {toolbarButtonName: "Li nivîsa bijartî bi otomatîkî girêdan lê zêde bike"}, en: {toolbarButtonName: "Automatically link selected text"}, es: {toolbarButtonName: "Automáticamente insertar enlaces en la selección"} }; // Kurmanji function words (prepositions, conjunctions, pronouns, particles, // demonstratives, copula/negation forms) that should never be turned into // links on their own, even though they're short enough to match compound // candidates during scanning. Also includes all 8 bare Kurmanji vowels // (a, e, ê, i, î, o, u, û) on their own, since a lone vowel is never a // meaningful link target even if it happens to match part of a scan. var ignoredWordList = ( "a|an|ba|bê|bi|bin|çi|çu|da|de|di|e|ê|ên|erê|ev|ew|em|gel|ha|her|" + "hûn|i|î|jê|jî|ka|kî|ku|lê|li|me|min|na|nav|ne|o|pê|re|ser|ta|te|tê|" + "tu|u|û|va|van|ve|vê|vî|wan|we|wê|wî|wir|vir|ya|yan|yê" ).split("|"); var ignoredWords = {}; $.each(ignoredWordList, function (i, word) { ignoredWords[word] = true; }); /** * One less than the maximum number of syllables to be considered as a compound * word. */ var lookahead = 2; // Tokenizer boundary class: standard uppercase Latin A-Z plus the Kurmanji // Latin alphabet's diacritic letters (both cases: Ç ç, Ê ê, Î î, Ş ş, Û û), // combining diacritical marks, and wiki markup delimiters. var tokenRE = /(\s*(?:<!--[\s\S]+?-->|\{\{[\s\S]+?\}\}|\[\[.+?\]\]|[^A-ZÇÊÎŞÛçêîşû\u0300-\u036F{[< ]+|[{[<])\s*)/i; String.prototype.linkifyUncapitalize = function () { return this[0].toLowerCase() + this.substr(1); }; // Common Kurmanji noun-declension suffixes (indefinite/definite, // nominative/construct/oblique/vocative -- see Module:ku-nouns' // declSimpleNoun), longest first so the greedy match below prefers the // most specific ending (e.g. "eke" before a bare "e"). // // This list is intentionally generous rather than grammatically precise: // unlike declSimpleNoun, the gadget doesn't know a word's gender or its // exact stem class when scanning arbitrary running text, so it can't // reproduce that branching logic exactly. Instead, every candidate root // produced here is verified against real wiktionary entries via the API // before it's ever used (see the "stems" check below) -- so an // over-aggressive strip that doesn't correspond to a genuine entry is // simply discarded, never turned into a bad link. var nounSuffixes = [ "iyekî", "iyekê", "iyeke", "iyinan", "iyino", "yekî", "yekê", "yeke", "yinan", "yino", "ekî", "ekê", "eke", "inan", "ine", "ino", "iyên", "iyan", "iyek", "iyin", "iyo", "iyî", "iyê", "iya", "yên", "yan", "yek", "yin", "yo", "yî", "yê", "ya", "ek", "ên", "an", "in", "a", "ê", "î", "o" ]; /** * Given a lowercase surface word, returns candidate noun roots obtained by * stripping a known declension suffix -- e.g. "rûpeleke" -> ["rûpel"]. * Candidates are ordered from least- to most-aggressively stripped (longest * remaining root first), so that when several candidates turn out to match * real entries, the safer/more specific one wins. */ function getNounStemCandidates(word) { var candidates = []; for (var i = 0; i < nounSuffixes.length; i++) { var suf = nounSuffixes[i]; // Require at least a 2-character root left over, so we don't // generate degenerate single-letter "roots". if (word.length > suf.length + 1 && word.slice(-suf.length) === suf) { candidates.push(word.slice(0, -suf.length)); } } candidates.sort(function (a, b) { return b.length - a.length; }); return candidates; } var userLang = mw.config.get("wgUserLanguage"); function getMessage(name) { return (messages[userLang] || messages.ku)[name] || messages.ku[name]; } $.kuLinkify = function (text, callback, debug) { var tokens = text.split(tokenRE); var displayTokens = []; var words = {}; var existingLinks = {}; // Maps a surface word (as typed, and its lowercase form) to candidate // noun roots -- e.g. stemCandidates["rûpeleke"] = ["rûpel"]. Filled in // below and consulted during reconstruction so an inflected word whose // exact surface form has no entry can still be linked to its root. var stemCandidates = {}; $.each(tokens, function (i, token) { if (debug) displayTokens.push(mw.html.escape(token)); var tokenLinks = token.match(/\[\[.+?(?:\|.+?)?\]\]/g); $.each(tokenLinks || [], function () { existingLinks[this.match(/\[\[(.+?)(?:\|.+?)?\]\]/)[1]] = true; }); if (!token || token.match(tokenRE)) return; var tokenWords = token.split(" "); $.each(tokenWords, function (j, word) { for (var k = 0; k < lookahead + 1 && tokenWords[j + k]; k++) { if (k) word += " " + tokenWords[j + k]; if (!ignoredWords[word]) words[word] = true; if (word[0] != word[0].toLowerCase()) { var lowerWord = word.linkifyUncapitalize(); if (!ignoredWords[lowerWord]) { words[lowerWord] = true; } } } }); // Also collect candidate noun roots for every individual word (not // multi-word compounds -- declension endings attach to a single // word), so inflected forms like "rûpeleke" can still be linked to // an existing root entry like "rûpel" even when the inflected form // itself has no entry. $.each(tokenWords, function (j, word) { if (!word) return; var lower = word.linkifyUncapitalize(); var stems = getNounStemCandidates(lower); if (stems.length) { stemCandidates[word] = stems; $.each(stems, function (s, stem) { if (!ignoredWords[stem]) words[stem] = true; }); } }); if (debug) { displayTokens[i] = "<b style='border: 1px solid gray;'>" + mw.html.escape(token) + "</b>"; } }); var uniqueWords = []; $.each(words, function (word) { if (!ignoredWords[word]) uniqueWords.push(word); }); if (debug) { var uniqueLinks = []; $.each(existingLinks, function (link) { uniqueLinks.push(link); }); var list = "<pre id='linkify-tokens'>\n" + displayTokens.join("") + "\n</pre>"; list += "<hr /><p>Words to search for:</p><p>" + uniqueWords + "</p>"; list += "<hr /><p>Words that already have links:</p><p>" + uniqueLinks + "</p>"; $("#linkify-progress").html(list).dialog({modal: true}); } if (!uniqueWords.length) return; mw.loader.using("mediawiki.api", function () { var api = new mw.Api(); api.get({ action: "parse", text: "[[" + uniqueWords.join("]] [[") + "]]", prop: "links" }).done(function (results) { $("#linkify-progress").append("<hr />"); var displayLinks = []; var links = {}; $.each(results.parse.links, function () { if (debug && "exists" in this) displayLinks.push(this["*"]); if ("exists" in this) links[this["*"]] = true; }); if (debug) { $("#linkify-progress").append("<p>Existing entries:</p><p>" + displayLinks + "</p>"); } $.each(tokens, function (i, token) { if (!token || token.match(tokenRE)) return; var tokenWords = token.split(" "); for (var j = 0; j < tokenWords.length; j++) { var word = []; for (var k = 0; k < lookahead + 1; k++) { word.push(tokenWords[j + k]); } for (var k = lookahead; k >= 0; k--) { var compoundWord = word.join(" "); if (k === 0) { var lowerSingle = compoundWord.linkifyUncapitalize(); // 1. Prefer linking to the declension root (lemma) // over the inflected surface form's own page -- // e.g. link "pîvana" as [[pîvan|pîvana]] rather // than [[pîvana]], since wiktionary entries for // inflected forms are usually secondary "form of" // pages rather than the main lemma readers want. var stems = stemCandidates[compoundWord] || stemCandidates[lowerSingle] || []; var stemLinked = false; for (var s = 0; s < stems.length; s++) { var stem = stems[s]; if ((stem in links) && !(stem in existingLinks) && !ignoredWords[stem]) { existingLinks[stem] = true; tokenWords[j] = "[[" + stem + "|" + tokenWords[j] + "]]"; stemLinked = true; break; } } if (stemLinked) break; if (!ignoredWords[compoundWord] && !ignoredWords[lowerSingle]) { // 2. No usable root. If the word (or its // lowercase form) is itself a confirmed // entry, link it normally -- this is a real // match, not a guess. Otherwise, only add a // speculative self-link -- always piped // (target|display), even though target and // display are identical text, so a reader // who spots a wrong link can simply edit the // part before the "|" -- when the word's // shape actually looks like an inflected // noun (it matched at least two different // candidate declension suffixes). A word // that matched zero or only one suffix isn't // strong enough evidence that it's inflected // at all, so it's left unlinked rather than // guessed at. var target = null; if (compoundWord in links) { target = compoundWord; } else if (lowerSingle in links) { target = lowerSingle; } else if (stems.length >= 2) { target = compoundWord; } if (target && !(target in existingLinks)) { existingLinks[target] = true; tokenWords[j] = "[[" + target + "|" + tokenWords[j] + "]]"; } } break; } if (compoundWord in links) { if ((compoundWord in existingLinks) || ignoredWords[compoundWord]) { j += k; break; } existingLinks[compoundWord] = true; tokenWords[j] = "[[" + tokenWords[j]; tokenWords[j + k] += "]]"; j += k; break; } var lowerWord = compoundWord.linkifyUncapitalize(); if (lowerWord in links) { if ((lowerWord in existingLinks) || ignoredWords[lowerWord]) { j += k; break; } existingLinks[lowerWord] = true; tokenWords[j] = "[[" + lowerWord + "|" + tokenWords[j]; tokenWords[j + k] += "]]"; j += k; break; } word.splice(-1, 1); } } tokens[i] = tokenWords.join(" "); if (debug) { displayTokens[i] = "<b style='border: 1px solid gray;'>" + mw.html.escape(tokens[i]) + "</b>"; } }); if (debug) { $("#linkify-tokens").html("\n" + displayTokens.join("") + "\n"); } callback(tokens.join("")); }).fail(function (error) { console.warn(error); callback(); }); }); } function getLinkifyTool() { return { type: "button", action: { type: "callback", execute: function () { mw.loader.using("jquery.textSelection", function () { var selection = $("#wpTextbox1").textSelection("getSelection"); $.kuLinkify(selection, function (linkedText) { if (!linkedText) return; $("#wpTextbox1").textSelection("encapsulateSelection", { peri: linkedText, replace: true }); }, $.kuLinkify_debug); }); } }, label: getMessage("toolbarButtonName"), icon: "//upload.wikimedia.org/wikipedia/commons/b/ba/Norwegian_link_sign.png" }; } function addLinkifyButton() { var $textbox = $("#wpTextbox1"); // Nothing to attach to on this page (VisualEditor, 2017 editor, non-edit // pages, etc.) — bail out instead of silently binding to an empty set. if (!$textbox.length) return; if ($.kuLinkify) { $textbox.after($(mw.html.element("div", { id: "linkify-progress", title: getMessage("toolbarButtonName") })).hide()); } // Bind the listener immediately, synchronously, rather than inside the // mw.loader.using("ext.wikiEditor", ...) callback. If we wait for that // callback to fire before attaching the listener, ext.wikiEditor may // already be loaded and may have already built (and fired the event for) // the main toolbar section by the time our callback runs -- in which case // the event has already come and gone and our button never gets added. // Attaching the listener up front means we won't miss the event even if // ext.wikiEditor resolves "instantly" (e.g. already cached/loaded). $textbox.on('wikiEditor-toolbar-buildSection-main', function (evt, section) { section.groups.insert.tools.linkify = getLinkifyTool(); }); mw.loader.using("ext.wikiEditor", function () { // Fallback for the case where the toolbar's main section was already // built (and the event already fired) before this gadget's script // even started executing -- e.g. another gadget loaded ext.wikiEditor // earlier and the toolbar finished initializing first. In that case // the listener above is too late, so we check whether the toolbar // context already exists and, if so, add the tool directly via the // public addToToolbar API instead of waiting for an event that has // already happened. var context = $textbox.data("wikiEditor-context"); if (context && context.modules && context.modules.toolbar) { $textbox.wikiEditor("addToToolbar", { section: "main", group: "insert", tools: { linkify: getLinkifyTool() } }); } }); }; // Only try to add the button on pages that actually have an edit form -- // running unconditionally on every page load (including view/history/etc. // pages where #wpTextbox1 never exists) wastes a mw.loader.using round trip // and can look like "sometimes nothing happens" if a user doesn't realize // they weren't on an edit screen. if ($.inArray(mw.config.get("wgAction"), ["edit", "submit"]) !== -1) { addLinkifyButton(); } })(jQuery); k1h88aa79tbsezxsfpp5uig5ak75z7y 6265714 6265712 2026-07-20T00:56:59Z Wikihez 7344 6265714 javascript text/javascript // MediaWiki gadget: automatically link selected text to existing wiktionary entries (function ($) { var messages = { ku: {toolbarButtonName: "Li nivîsa bijartî bi otomatîkî girêdan lê zêde bike"}, en: {toolbarButtonName: "Automatically link selected text"}, es: {toolbarButtonName: "Automáticamente insertar enlaces en la selección"} }; // Kurmanji function words (prepositions, conjunctions, pronouns, particles, // demonstratives, copula/negation forms) that should never be turned into // links on their own, even though they're short enough to match compound // candidates during scanning. Also includes all 8 bare Kurmanji vowels // (a, e, ê, i, î, o, u, û) on their own, since a lone vowel is never a // meaningful link target even if it happens to match part of a scan. var ignoredWordList = ( "a|an|ba|bê|bi|bin|çi|çu|da|de|di|e|ê|ên|erê|ev|ew|em|gel|ha|her|" + "hûn|i|î|jê|jî|ka|kî|ku|lê|li|me|min|na|nav|ne|o|pê|re|ser|ta|te|tê|" + "tu|u|û|va|van|ve|vê|vî|wan|we|wê|wî|wir|vir|ya|yan|yê" ).split("|"); var ignoredWords = {}; $.each(ignoredWordList, function (i, word) { ignoredWords[word] = true; }); /** * One less than the maximum number of syllables to be considered as a compound * word. */ var lookahead = 2; // Tokenizer boundary class: standard uppercase Latin A-Z plus the Kurmanji // Latin alphabet's diacritic letters (both cases: Ç ç, Ê ê, Î î, Ş ş, Û û), // combining diacritical marks, and wiki markup delimiters. var tokenRE = /(\s*(?:<!--[\s\S]+?-->|\{\{[\s\S]+?\}\}|\[\[.+?\]\]|[^A-ZÇÊÎŞÛçêîşû\u0300-\u036F{[< ]+|[{[<])\s*)/i; String.prototype.linkifyUncapitalize = function () { return this[0].toLowerCase() + this.substr(1); }; // Common Kurmanji noun-declension suffixes (indefinite/definite, // nominative/construct/oblique/vocative -- see Module:ku-nouns' // declSimpleNoun), longest first so the greedy match below prefers the // most specific ending (e.g. "eke" before a bare "e"). // // This list is intentionally generous rather than grammatically precise: // unlike declSimpleNoun, the gadget doesn't know a word's gender or its // exact stem class when scanning arbitrary running text, so it can't // reproduce that branching logic exactly. Instead, every candidate root // produced here is verified against real wiktionary entries via the API // before it's ever used (see the "stems" check below) -- so an // over-aggressive strip that doesn't correspond to a genuine entry is // simply discarded, never turned into a bad link. var nounSuffixes = [ "iyekî", "iyekê", "iyeke", "iyinan", "iyino", "yekî", "yekê", "yeke", "yinan", "yino", "ekî", "ekê", "eke", "inan", "ine", "ino", "iyên", "iyan", "iyek", "iyin", "iyo", "iyî", "iyê", "iya", "yên", "yan", "yek", "yin", "yo", "yî", "yê", "ya", "ek", "ên", "an", "in", "a", "ê", "î", "o" ]; /** * Given a lowercase surface word, returns candidate noun roots obtained by * stripping a known declension suffix -- e.g. "rûpeleke" -> ["rûpel"]. * Candidates are ordered from least- to most-aggressively stripped (longest * remaining root first), so that when several candidates turn out to match * real entries, the safer/more specific one wins. */ function getNounStemCandidates(word) { var candidates = []; for (var i = 0; i < nounSuffixes.length; i++) { var suf = nounSuffixes[i]; // Require at least a 2-character root left over, so we don't // generate degenerate single-letter "roots". if (word.length > suf.length + 1 && word.slice(-suf.length) === suf) { candidates.push(word.slice(0, -suf.length)); } } // Orthographic correction: a root ending in î drops its circumflex when // it meets a glide suffix starting with y -- "giranî" + "yê" spells as // "giraniyê", not "giranîyê". Stripping the short suffix "yê" from that // surface form literally gives "girani" (bare i); stripping the longer // "iyê" suffix instead gives the shorter, unrelated root "giran". Since // the î-final noun is the actual root in this pattern, also offer the // î-restored form as a candidate for any stripped result ending in a // bare "i" -- e.g. "girani" -> "giranî". Because it's one character // longer than the "iyê"-derived candidate, the length-based sort below // naturally tries it first. var restored = []; $.each(candidates, function (idx, root) { if (root.length > 1 && root.slice(-1) === "i") { restored.push(root.slice(0, -1) + "î"); } }); candidates = candidates.concat(restored); candidates.sort(function (a, b) { return b.length - a.length; }); return candidates; } var userLang = mw.config.get("wgUserLanguage"); function getMessage(name) { return (messages[userLang] || messages.ku)[name] || messages.ku[name]; } $.kuLinkify = function (text, callback, debug) { var tokens = text.split(tokenRE); var displayTokens = []; var words = {}; var existingLinks = {}; // Maps a surface word (as typed, and its lowercase form) to candidate // noun roots -- e.g. stemCandidates["rûpeleke"] = ["rûpel"]. Filled in // below and consulted during reconstruction so an inflected word whose // exact surface form has no entry can still be linked to its root. var stemCandidates = {}; $.each(tokens, function (i, token) { if (debug) displayTokens.push(mw.html.escape(token)); var tokenLinks = token.match(/\[\[.+?(?:\|.+?)?\]\]/g); $.each(tokenLinks || [], function () { existingLinks[this.match(/\[\[(.+?)(?:\|.+?)?\]\]/)[1]] = true; }); if (!token || token.match(tokenRE)) return; var tokenWords = token.split(" "); $.each(tokenWords, function (j, word) { for (var k = 0; k < lookahead + 1 && tokenWords[j + k]; k++) { if (k) word += " " + tokenWords[j + k]; if (!ignoredWords[word]) words[word] = true; if (word[0] != word[0].toLowerCase()) { var lowerWord = word.linkifyUncapitalize(); if (!ignoredWords[lowerWord]) { words[lowerWord] = true; } } } }); // Also collect candidate noun roots for every individual word (not // multi-word compounds -- declension endings attach to a single // word), so inflected forms like "rûpeleke" can still be linked to // an existing root entry like "rûpel" even when the inflected form // itself has no entry. $.each(tokenWords, function (j, word) { if (!word) return; var lower = word.linkifyUncapitalize(); var stems = getNounStemCandidates(lower); if (stems.length) { stemCandidates[word] = stems; $.each(stems, function (s, stem) { if (!ignoredWords[stem]) words[stem] = true; }); } }); if (debug) { displayTokens[i] = "<b style='border: 1px solid gray;'>" + mw.html.escape(token) + "</b>"; } }); var uniqueWords = []; $.each(words, function (word) { if (!ignoredWords[word]) uniqueWords.push(word); }); if (debug) { var uniqueLinks = []; $.each(existingLinks, function (link) { uniqueLinks.push(link); }); var list = "<pre id='linkify-tokens'>\n" + displayTokens.join("") + "\n</pre>"; list += "<hr /><p>Words to search for:</p><p>" + uniqueWords + "</p>"; list += "<hr /><p>Words that already have links:</p><p>" + uniqueLinks + "</p>"; $("#linkify-progress").html(list).dialog({modal: true}); } if (!uniqueWords.length) return; mw.loader.using("mediawiki.api", function () { var api = new mw.Api(); api.get({ action: "parse", text: "[[" + uniqueWords.join("]] [[") + "]]", prop: "links" }).done(function (results) { $("#linkify-progress").append("<hr />"); var displayLinks = []; var links = {}; $.each(results.parse.links, function () { if (debug && "exists" in this) displayLinks.push(this["*"]); if ("exists" in this) links[this["*"]] = true; }); if (debug) { $("#linkify-progress").append("<p>Existing entries:</p><p>" + displayLinks + "</p>"); } $.each(tokens, function (i, token) { if (!token || token.match(tokenRE)) return; var tokenWords = token.split(" "); for (var j = 0; j < tokenWords.length; j++) { var word = []; for (var k = 0; k < lookahead + 1; k++) { word.push(tokenWords[j + k]); } for (var k = lookahead; k >= 0; k--) { var compoundWord = word.join(" "); if (k === 0) { var lowerSingle = compoundWord.linkifyUncapitalize(); // 1. Prefer linking to the declension root (lemma) // over the inflected surface form's own page -- // e.g. link "pîvana" as [[pîvan|pîvana]] rather // than [[pîvana]], since wiktionary entries for // inflected forms are usually secondary "form of" // pages rather than the main lemma readers want. var stems = stemCandidates[compoundWord] || stemCandidates[lowerSingle] || []; var stemLinked = false; for (var s = 0; s < stems.length; s++) { var stem = stems[s]; if ((stem in links) && !(stem in existingLinks) && !ignoredWords[stem]) { existingLinks[stem] = true; tokenWords[j] = "[[" + stem + "|" + tokenWords[j] + "]]"; stemLinked = true; break; } } if (stemLinked) break; if (!ignoredWords[compoundWord] && !ignoredWords[lowerSingle]) { // 2. No usable root. If the word (or its // lowercase form) is itself a confirmed // entry, link it normally -- this is a real // match, not a guess. Otherwise, only add a // speculative self-link -- always piped // (target|display), even though target and // display are identical text, so a reader // who spots a wrong link can simply edit the // part before the "|" -- when the word's // shape actually looks like an inflected // noun (it matched at least two different // candidate declension suffixes). A word // that matched zero or only one suffix isn't // strong enough evidence that it's inflected // at all, so it's left unlinked rather than // guessed at. var target = null; if (compoundWord in links) { target = compoundWord; } else if (lowerSingle in links) { target = lowerSingle; } else if (stems.length >= 2) { target = compoundWord; } if (target && !(target in existingLinks)) { existingLinks[target] = true; tokenWords[j] = "[[" + target + "|" + tokenWords[j] + "]]"; } } break; } if (compoundWord in links) { if ((compoundWord in existingLinks) || ignoredWords[compoundWord]) { j += k; break; } existingLinks[compoundWord] = true; tokenWords[j] = "[[" + tokenWords[j]; tokenWords[j + k] += "]]"; j += k; break; } var lowerWord = compoundWord.linkifyUncapitalize(); if (lowerWord in links) { if ((lowerWord in existingLinks) || ignoredWords[lowerWord]) { j += k; break; } existingLinks[lowerWord] = true; tokenWords[j] = "[[" + lowerWord + "|" + tokenWords[j]; tokenWords[j + k] += "]]"; j += k; break; } word.splice(-1, 1); } } tokens[i] = tokenWords.join(" "); if (debug) { displayTokens[i] = "<b style='border: 1px solid gray;'>" + mw.html.escape(tokens[i]) + "</b>"; } }); if (debug) { $("#linkify-tokens").html("\n" + displayTokens.join("") + "\n"); } callback(tokens.join("")); }).fail(function (error) { console.warn(error); callback(); }); }); } function getLinkifyTool() { return { type: "button", action: { type: "callback", execute: function () { mw.loader.using("jquery.textSelection", function () { var selection = $("#wpTextbox1").textSelection("getSelection"); $.kuLinkify(selection, function (linkedText) { if (!linkedText) return; $("#wpTextbox1").textSelection("encapsulateSelection", { peri: linkedText, replace: true }); }, $.kuLinkify_debug); }); } }, label: getMessage("toolbarButtonName"), icon: "//upload.wikimedia.org/wikipedia/commons/b/ba/Norwegian_link_sign.png" }; } function addLinkifyButton() { var $textbox = $("#wpTextbox1"); // Nothing to attach to on this page (VisualEditor, 2017 editor, non-edit // pages, etc.) — bail out instead of silently binding to an empty set. if (!$textbox.length) return; if ($.kuLinkify) { $textbox.after($(mw.html.element("div", { id: "linkify-progress", title: getMessage("toolbarButtonName") })).hide()); } // Bind the listener immediately, synchronously, rather than inside the // mw.loader.using("ext.wikiEditor", ...) callback. If we wait for that // callback to fire before attaching the listener, ext.wikiEditor may // already be loaded and may have already built (and fired the event for) // the main toolbar section by the time our callback runs -- in which case // the event has already come and gone and our button never gets added. // Attaching the listener up front means we won't miss the event even if // ext.wikiEditor resolves "instantly" (e.g. already cached/loaded). $textbox.on('wikiEditor-toolbar-buildSection-main', function (evt, section) { section.groups.insert.tools.linkify = getLinkifyTool(); }); mw.loader.using("ext.wikiEditor", function () { // Fallback for the case where the toolbar's main section was already // built (and the event already fired) before this gadget's script // even started executing -- e.g. another gadget loaded ext.wikiEditor // earlier and the toolbar finished initializing first. In that case // the listener above is too late, so we check whether the toolbar // context already exists and, if so, add the tool directly via the // public addToToolbar API instead of waiting for an event that has // already happened. var context = $textbox.data("wikiEditor-context"); if (context && context.modules && context.modules.toolbar) { $textbox.wikiEditor("addToToolbar", { section: "main", group: "insert", tools: { linkify: getLinkifyTool() } }); } }); }; // Only try to add the button on pages that actually have an edit form -- // running unconditionally on every page load (including view/history/etc. // pages where #wpTextbox1 never exists) wastes a mw.loader.using round trip // and can look like "sometimes nothing happens" if a user doesn't realize // they weren't on an edit screen. if ($.inArray(mw.config.get("wgAction"), ["edit", "submit"]) !== -1) { addLinkifyButton(); } })(jQuery); 0wsuq7aqqegrm4lw4fywukikjy3uxb1 6265715 6265714 2026-07-20T01:03:38Z Wikihez 7344 6265715 javascript text/javascript // MediaWiki gadget: automatically link selected text to existing wiktionary entries (function ($) { var messages = { ku: {toolbarButtonName: "Li nivîsa bijartî bi otomatîkî girêdan lê zêde bike"}, en: {toolbarButtonName: "Automatically link selected text"}, es: {toolbarButtonName: "Automáticamente insertar enlaces en la selección"} }; // Kurmanji function words (prepositions, conjunctions, pronouns, particles, // demonstratives, copula/negation forms) that should never be turned into // links on their own, even though they're short enough to match compound // candidates during scanning. Also includes all 8 bare Kurmanji vowels // (a, e, ê, i, î, o, u, û) on their own, since a lone vowel is never a // meaningful link target even if it happens to match part of a scan. var ignoredWordList = ( "a|an|ba|bê|bi|çi|çu|çû|da|de|dê|dî|di|e|ê|ên|erê|ev|ew|em|gel|ha|hê|her|" + "hûn|i|î|jê|jî|ka|kî|ku|kû|lê|li|me|min|na|ne|o|pê|re|ra|ti|te|tê|" + "tu|u|û|va|van|ve|vê|vî|wan|we|wê|wî|wir|vir|ya|yan|yê|yên" ).split("|"); var ignoredWords = {}; $.each(ignoredWordList, function (i, word) { ignoredWords[word] = true; }); /** * One less than the maximum number of syllables to be considered as a compound * word. */ var lookahead = 2; // Tokenizer boundary class: standard uppercase Latin A-Z plus the Kurmanji // Latin alphabet's diacritic letters (both cases: Ç ç, Ê ê, Î î, Ş ş, Û û), // combining diacritical marks, and wiki markup delimiters. var tokenRE = /(\s*(?:<!--[\s\S]+?-->|\{\{[\s\S]+?\}\}|\[\[.+?\]\]|[^A-ZÇÊÎŞÛçêîşû\u0300-\u036F{[< ]+|[{[<])\s*)/i; String.prototype.linkifyUncapitalize = function () { return this[0].toLowerCase() + this.substr(1); }; // Common Kurmanji noun-declension suffixes (indefinite/definite, // nominative/construct/oblique/vocative -- see Module:ku-nouns' // declSimpleNoun), longest first so the greedy match below prefers the // most specific ending (e.g. "eke" before a bare "e"). // // This list is intentionally generous rather than grammatically precise: // unlike declSimpleNoun, the gadget doesn't know a word's gender or its // exact stem class when scanning arbitrary running text, so it can't // reproduce that branching logic exactly. Instead, every candidate root // produced here is verified against real wiktionary entries via the API // before it's ever used (see the "stems" check below) -- so an // over-aggressive strip that doesn't correspond to a genuine entry is // simply discarded, never turned into a bad link. var nounSuffixes = [ "iyekî", "iyekê", "iyeke", "iyinan", "iyino", "yekî", "yekê", "yeke", "yinan", "yino", "ekî", "ekê", "eke", "inan", "ine", "ino", "iyên", "iyan", "iyek", "iyin", "iyo", "iyî", "iyê", "iya", "yên", "yan", "yek", "yin", "yo", "yî", "yê", "ya", "ek", "ên", "an", "in", "a", "ê", "î", "o" ]; /** * Given a lowercase surface word, returns candidate noun roots obtained by * stripping a known declension suffix -- e.g. "rûpeleke" -> ["rûpel"]. * Candidates are ordered from least- to most-aggressively stripped (longest * remaining root first), so that when several candidates turn out to match * real entries, the safer/more specific one wins. */ function getNounStemCandidates(word) { var candidates = []; for (var i = 0; i < nounSuffixes.length; i++) { var suf = nounSuffixes[i]; // Require at least a 2-character root left over, so we don't // generate degenerate single-letter "roots". if (word.length > suf.length + 1 && word.slice(-suf.length) === suf) { candidates.push(word.slice(0, -suf.length)); } } // Orthographic correction: a root ending in î drops its circumflex when // it meets a glide suffix starting with y -- "giranî" + "yê" spells as // "giraniyê", not "giranîyê". Stripping the short suffix "yê" from that // surface form literally gives "girani" (bare i); stripping the longer // "iyê" suffix instead gives the shorter, unrelated root "giran". Since // the î-final noun is the actual root in this pattern, also offer the // î-restored form as a candidate for any stripped result ending in a // bare "i" -- e.g. "girani" -> "giranî". Because it's one character // longer than the "iyê"-derived candidate, the length-based sort below // naturally tries it first. var restored = []; $.each(candidates, function (idx, root) { if (root.length > 1 && root.slice(-1) === "i") { restored.push(root.slice(0, -1) + "î"); } }); candidates = candidates.concat(restored); candidates.sort(function (a, b) { return b.length - a.length; }); return candidates; } var userLang = mw.config.get("wgUserLanguage"); function getMessage(name) { return (messages[userLang] || messages.ku)[name] || messages.ku[name]; } $.kuLinkify = function (text, callback, debug) { var tokens = text.split(tokenRE); var displayTokens = []; var words = {}; var existingLinks = {}; // Maps a surface word (as typed, and its lowercase form) to candidate // noun roots -- e.g. stemCandidates["rûpeleke"] = ["rûpel"]. Filled in // below and consulted during reconstruction so an inflected word whose // exact surface form has no entry can still be linked to its root. var stemCandidates = {}; $.each(tokens, function (i, token) { if (debug) displayTokens.push(mw.html.escape(token)); var tokenLinks = token.match(/\[\[.+?(?:\|.+?)?\]\]/g); $.each(tokenLinks || [], function () { existingLinks[this.match(/\[\[(.+?)(?:\|.+?)?\]\]/)[1]] = true; }); if (!token || token.match(tokenRE)) return; var tokenWords = token.split(" "); $.each(tokenWords, function (j, word) { for (var k = 0; k < lookahead + 1 && tokenWords[j + k]; k++) { if (k) word += " " + tokenWords[j + k]; if (!ignoredWords[word]) words[word] = true; if (word[0] != word[0].toLowerCase()) { var lowerWord = word.linkifyUncapitalize(); if (!ignoredWords[lowerWord]) { words[lowerWord] = true; } } } }); // Also collect candidate noun roots for every individual word (not // multi-word compounds -- declension endings attach to a single // word), so inflected forms like "rûpeleke" can still be linked to // an existing root entry like "rûpel" even when the inflected form // itself has no entry. $.each(tokenWords, function (j, word) { if (!word) return; var lower = word.linkifyUncapitalize(); var stems = getNounStemCandidates(lower); if (stems.length) { stemCandidates[word] = stems; $.each(stems, function (s, stem) { if (!ignoredWords[stem]) words[stem] = true; }); } }); if (debug) { displayTokens[i] = "<b style='border: 1px solid gray;'>" + mw.html.escape(token) + "</b>"; } }); var uniqueWords = []; $.each(words, function (word) { if (!ignoredWords[word]) uniqueWords.push(word); }); if (debug) { var uniqueLinks = []; $.each(existingLinks, function (link) { uniqueLinks.push(link); }); var list = "<pre id='linkify-tokens'>\n" + displayTokens.join("") + "\n</pre>"; list += "<hr /><p>Words to search for:</p><p>" + uniqueWords + "</p>"; list += "<hr /><p>Words that already have links:</p><p>" + uniqueLinks + "</p>"; $("#linkify-progress").html(list).dialog({modal: true}); } if (!uniqueWords.length) return; mw.loader.using("mediawiki.api", function () { var api = new mw.Api(); api.get({ action: "parse", text: "[[" + uniqueWords.join("]] [[") + "]]", prop: "links" }).done(function (results) { $("#linkify-progress").append("<hr />"); var displayLinks = []; var links = {}; $.each(results.parse.links, function () { if (debug && "exists" in this) displayLinks.push(this["*"]); if ("exists" in this) links[this["*"]] = true; }); if (debug) { $("#linkify-progress").append("<p>Existing entries:</p><p>" + displayLinks + "</p>"); } $.each(tokens, function (i, token) { if (!token || token.match(tokenRE)) return; var tokenWords = token.split(" "); for (var j = 0; j < tokenWords.length; j++) { var word = []; for (var k = 0; k < lookahead + 1; k++) { word.push(tokenWords[j + k]); } for (var k = lookahead; k >= 0; k--) { var compoundWord = word.join(" "); if (k === 0) { var lowerSingle = compoundWord.linkifyUncapitalize(); // 1. Prefer linking to the declension root (lemma) // over the inflected surface form's own page -- // e.g. link "pîvana" as [[pîvan|pîvana]] rather // than [[pîvana]], since wiktionary entries for // inflected forms are usually secondary "form of" // pages rather than the main lemma readers want. var stems = stemCandidates[compoundWord] || stemCandidates[lowerSingle] || []; var stemLinked = false; for (var s = 0; s < stems.length; s++) { var stem = stems[s]; if ((stem in links) && !(stem in existingLinks) && !ignoredWords[stem]) { existingLinks[stem] = true; tokenWords[j] = "[[" + stem + "|" + tokenWords[j] + "]]"; stemLinked = true; break; } } if (stemLinked) break; if (!ignoredWords[compoundWord] && !ignoredWords[lowerSingle]) { // 2. No usable root. If the word (or its // lowercase form) is itself a confirmed // entry, link it normally -- this is a real // match, not a guess. Otherwise, only add a // speculative self-link -- always piped // (target|display), even though target and // display are identical text, so a reader // who spots a wrong link can simply edit the // part before the "|" -- when the word's // shape actually looks like an inflected // noun (it matched at least two different // candidate declension suffixes). A word // that matched zero or only one suffix isn't // strong enough evidence that it's inflected // at all, so it's left unlinked rather than // guessed at. var target = null; if (compoundWord in links) { target = compoundWord; } else if (lowerSingle in links) { target = lowerSingle; } else if (stems.length >= 2) { target = compoundWord; } if (target && !(target in existingLinks)) { existingLinks[target] = true; tokenWords[j] = "[[" + target + "|" + tokenWords[j] + "]]"; } } break; } if (compoundWord in links) { if ((compoundWord in existingLinks) || ignoredWords[compoundWord]) { j += k; break; } existingLinks[compoundWord] = true; tokenWords[j] = "[[" + tokenWords[j]; tokenWords[j + k] += "]]"; j += k; break; } var lowerWord = compoundWord.linkifyUncapitalize(); if (lowerWord in links) { if ((lowerWord in existingLinks) || ignoredWords[lowerWord]) { j += k; break; } existingLinks[lowerWord] = true; tokenWords[j] = "[[" + lowerWord + "|" + tokenWords[j]; tokenWords[j + k] += "]]"; j += k; break; } word.splice(-1, 1); } } tokens[i] = tokenWords.join(" "); if (debug) { displayTokens[i] = "<b style='border: 1px solid gray;'>" + mw.html.escape(tokens[i]) + "</b>"; } }); if (debug) { $("#linkify-tokens").html("\n" + displayTokens.join("") + "\n"); } callback(tokens.join("")); }).fail(function (error) { console.warn(error); callback(); }); }); } function getLinkifyTool() { return { type: "button", action: { type: "callback", execute: function () { mw.loader.using("jquery.textSelection", function () { var selection = $("#wpTextbox1").textSelection("getSelection"); $.kuLinkify(selection, function (linkedText) { if (!linkedText) return; $("#wpTextbox1").textSelection("encapsulateSelection", { peri: linkedText, replace: true }); }, $.kuLinkify_debug); }); } }, label: getMessage("toolbarButtonName"), icon: "//upload.wikimedia.org/wikipedia/commons/b/ba/Norwegian_link_sign.png" }; } function addLinkifyButton() { var $textbox = $("#wpTextbox1"); // Nothing to attach to on this page (VisualEditor, 2017 editor, non-edit // pages, etc.) — bail out instead of silently binding to an empty set. if (!$textbox.length) return; if ($.kuLinkify) { $textbox.after($(mw.html.element("div", { id: "linkify-progress", title: getMessage("toolbarButtonName") })).hide()); } // Bind the listener immediately, synchronously, rather than inside the // mw.loader.using("ext.wikiEditor", ...) callback. If we wait for that // callback to fire before attaching the listener, ext.wikiEditor may // already be loaded and may have already built (and fired the event for) // the main toolbar section by the time our callback runs -- in which case // the event has already come and gone and our button never gets added. // Attaching the listener up front means we won't miss the event even if // ext.wikiEditor resolves "instantly" (e.g. already cached/loaded). $textbox.on('wikiEditor-toolbar-buildSection-main', function (evt, section) { section.groups.insert.tools.linkify = getLinkifyTool(); }); mw.loader.using("ext.wikiEditor", function () { // Fallback for the case where the toolbar's main section was already // built (and the event already fired) before this gadget's script // even started executing -- e.g. another gadget loaded ext.wikiEditor // earlier and the toolbar finished initializing first. In that case // the listener above is too late, so we check whether the toolbar // context already exists and, if so, add the tool directly via the // public addToToolbar API instead of waiting for an event that has // already happened. var context = $textbox.data("wikiEditor-context"); if (context && context.modules && context.modules.toolbar) { $textbox.wikiEditor("addToToolbar", { section: "main", group: "insert", tools: { linkify: getLinkifyTool() } }); } }); }; // Only try to add the button on pages that actually have an edit form -- // running unconditionally on every page load (including view/history/etc. // pages where #wpTextbox1 never exists) wastes a mw.loader.using round trip // and can look like "sometimes nothing happens" if a user doesn't realize // they weren't on an edit screen. if ($.inArray(mw.config.get("wgAction"), ["edit", "submit"]) !== -1) { addLinkifyButton(); } })(jQuery); dvj2bl4txpdnooe625gyvyl2excrig4 6265719 6265715 2026-07-20T01:11:44Z Wikihez 7344 6265719 javascript text/javascript // MediaWiki gadget: automatically link selected text to existing wiktionary entries (function ($) { var messages = { ku: { toolbarButtonName: "Li nivîsa bijartî bi otomatîkî girêdan lê zêde bike", delinkifyButtonName: "Ji nivîsa bijartî girêdanan rake" }, en: { toolbarButtonName: "Automatically link selected text", delinkifyButtonName: "Remove links from selected text" }, es: { toolbarButtonName: "Automáticamente insertar enlaces en la selección", delinkifyButtonName: "Quitar enlaces del texto seleccionado" } }; // Kurmanji function words (prepositions, conjunctions, pronouns, particles, // demonstratives, copula/negation forms) that should never be turned into // links on their own, even though they're short enough to match compound // candidates during scanning. Also includes all 8 bare Kurmanji vowels // (a, e, ê, i, î, o, u, û) on their own, since a lone vowel is never a // meaningful link target even if it happens to match part of a scan. var ignoredWordList = ( "a|an|ba|bê|bi|çi|çu|çû|da|de|dê|dî|di|e|ê|ên|erê|ev|ew|em|gel|ha|hê|her|" + "hûn|i|î|jê|jî|ka|kî|ku|kû|lê|li|me|min|na|ne|o|pê|re|ra|ti|te|tê|" + "tu|u|û|va|van|ve|vê|vî|wan|we|wê|wî|wir|vir|ya|yan|yê|yên" ).split("|"); var ignoredWords = {}; $.each(ignoredWordList, function (i, word) { ignoredWords[word] = true; }); /** * One less than the maximum number of syllables to be considered as a compound * word. */ var lookahead = 2; // Tokenizer boundary class: standard uppercase Latin A-Z plus the Kurmanji // Latin alphabet's diacritic letters (both cases: Ç ç, Ê ê, Î î, Ş ş, Û û), // combining diacritical marks, and wiki markup delimiters. var tokenRE = /(\s*(?:<!--[\s\S]+?-->|\{\{[\s\S]+?\}\}|\[\[.+?\]\]|[^A-ZÇÊÎŞÛçêîşû\u0300-\u036F{[< ]+|[{[<])\s*)/i; String.prototype.linkifyUncapitalize = function () { return this[0].toLowerCase() + this.substr(1); }; // Common Kurmanji noun-declension suffixes (indefinite/definite, // nominative/construct/oblique/vocative -- see Module:ku-nouns' // declSimpleNoun), longest first so the greedy match below prefers the // most specific ending (e.g. "eke" before a bare "e"). // // This list is intentionally generous rather than grammatically precise: // unlike declSimpleNoun, the gadget doesn't know a word's gender or its // exact stem class when scanning arbitrary running text, so it can't // reproduce that branching logic exactly. Instead, every candidate root // produced here is verified against real wiktionary entries via the API // before it's ever used (see the "stems" check below) -- so an // over-aggressive strip that doesn't correspond to a genuine entry is // simply discarded, never turned into a bad link. var nounSuffixes = [ "iyekî", "iyekê", "iyeke", "iyinan", "iyino", "yekî", "yekê", "yeke", "yinan", "yino", "ekî", "ekê", "eke", "inan", "ine", "ino", "iyên", "iyan", "iyek", "iyin", "iyo", "iyî", "iyê", "iya", "yên", "yan", "yek", "yin", "yo", "yî", "yê", "ya", "ek", "ên", "an", "in", "a", "ê", "î", "o" ]; /** * Given a lowercase surface word, returns candidate noun roots obtained by * stripping a known declension suffix -- e.g. "rûpeleke" -> ["rûpel"]. * Candidates are ordered from least- to most-aggressively stripped (longest * remaining root first), so that when several candidates turn out to match * real entries, the safer/more specific one wins. */ function getNounStemCandidates(word) { var candidates = []; for (var i = 0; i < nounSuffixes.length; i++) { var suf = nounSuffixes[i]; // Require at least a 2-character root left over, so we don't // generate degenerate single-letter "roots". if (word.length > suf.length + 1 && word.slice(-suf.length) === suf) { candidates.push(word.slice(0, -suf.length)); } } // Orthographic correction: a root ending in î drops its circumflex when // it meets a glide suffix starting with y -- "giranî" + "yê" spells as // "giraniyê", not "giranîyê". Stripping the short suffix "yê" from that // surface form literally gives "girani" (bare i); stripping the longer // "iyê" suffix instead gives the shorter, unrelated root "giran". Since // the î-final noun is the actual root in this pattern, also offer the // î-restored form as a candidate for any stripped result ending in a // bare "i" -- e.g. "girani" -> "giranî". Because it's one character // longer than the "iyê"-derived candidate, the length-based sort below // naturally tries it first. var restored = []; $.each(candidates, function (idx, root) { if (root.length > 1 && root.slice(-1) === "i") { restored.push(root.slice(0, -1) + "î"); } }); candidates = candidates.concat(restored); candidates.sort(function (a, b) { return b.length - a.length; }); return candidates; } var userLang = mw.config.get("wgUserLanguage"); function getMessage(name) { return (messages[userLang] || messages.ku)[name] || messages.ku[name]; } $.kuLinkify = function (text, callback, debug) { var tokens = text.split(tokenRE); var displayTokens = []; var words = {}; var existingLinks = {}; // Maps a surface word (as typed, and its lowercase form) to candidate // noun roots -- e.g. stemCandidates["rûpeleke"] = ["rûpel"]. Filled in // below and consulted during reconstruction so an inflected word whose // exact surface form has no entry can still be linked to its root. var stemCandidates = {}; $.each(tokens, function (i, token) { if (debug) displayTokens.push(mw.html.escape(token)); var tokenLinks = token.match(/\[\[.+?(?:\|.+?)?\]\]/g); $.each(tokenLinks || [], function () { existingLinks[this.match(/\[\[(.+?)(?:\|.+?)?\]\]/)[1]] = true; }); if (!token || token.match(tokenRE)) return; var tokenWords = token.split(" "); $.each(tokenWords, function (j, word) { for (var k = 0; k < lookahead + 1 && tokenWords[j + k]; k++) { if (k) word += " " + tokenWords[j + k]; if (!ignoredWords[word]) words[word] = true; if (word[0] != word[0].toLowerCase()) { var lowerWord = word.linkifyUncapitalize(); if (!ignoredWords[lowerWord]) { words[lowerWord] = true; } } } }); // Also collect candidate noun roots for every individual word (not // multi-word compounds -- declension endings attach to a single // word), so inflected forms like "rûpeleke" can still be linked to // an existing root entry like "rûpel" even when the inflected form // itself has no entry. $.each(tokenWords, function (j, word) { if (!word) return; var lower = word.linkifyUncapitalize(); var stems = getNounStemCandidates(lower); if (stems.length) { stemCandidates[word] = stems; $.each(stems, function (s, stem) { if (!ignoredWords[stem]) words[stem] = true; }); } }); if (debug) { displayTokens[i] = "<b style='border: 1px solid gray;'>" + mw.html.escape(token) + "</b>"; } }); var uniqueWords = []; $.each(words, function (word) { if (!ignoredWords[word]) uniqueWords.push(word); }); if (debug) { var uniqueLinks = []; $.each(existingLinks, function (link) { uniqueLinks.push(link); }); var list = "<pre id='linkify-tokens'>\n" + displayTokens.join("") + "\n</pre>"; list += "<hr /><p>Words to search for:</p><p>" + uniqueWords + "</p>"; list += "<hr /><p>Words that already have links:</p><p>" + uniqueLinks + "</p>"; $("#linkify-progress").html(list).dialog({modal: true}); } if (!uniqueWords.length) return; mw.loader.using("mediawiki.api", function () { var api = new mw.Api(); api.get({ action: "parse", text: "[[" + uniqueWords.join("]] [[") + "]]", prop: "links" }).done(function (results) { $("#linkify-progress").append("<hr />"); var displayLinks = []; var links = {}; $.each(results.parse.links, function () { if (debug && "exists" in this) displayLinks.push(this["*"]); if ("exists" in this) links[this["*"]] = true; }); if (debug) { $("#linkify-progress").append("<p>Existing entries:</p><p>" + displayLinks + "</p>"); } $.each(tokens, function (i, token) { if (!token || token.match(tokenRE)) return; var tokenWords = token.split(" "); for (var j = 0; j < tokenWords.length; j++) { var word = []; for (var k = 0; k < lookahead + 1; k++) { word.push(tokenWords[j + k]); } for (var k = lookahead; k >= 0; k--) { var compoundWord = word.join(" "); if (k === 0) { var lowerSingle = compoundWord.linkifyUncapitalize(); // 1. Prefer linking to the declension root (lemma) // over the inflected surface form's own page -- // e.g. link "pîvana" as [[pîvan|pîvana]] rather // than [[pîvana]], since wiktionary entries for // inflected forms are usually secondary "form of" // pages rather than the main lemma readers want. var stems = stemCandidates[compoundWord] || stemCandidates[lowerSingle] || []; var stemLinked = false; for (var s = 0; s < stems.length; s++) { var stem = stems[s]; if ((stem in links) && !(stem in existingLinks) && !ignoredWords[stem]) { existingLinks[stem] = true; tokenWords[j] = "[[" + stem + "|" + tokenWords[j] + "]]"; stemLinked = true; break; } } if (stemLinked) break; if (!ignoredWords[compoundWord] && !ignoredWords[lowerSingle]) { // 2. No usable root. If the word (or its // lowercase form) is itself a confirmed // entry, link it normally -- this is a real // match, not a guess. Otherwise, only add a // speculative self-link -- always piped // (target|display), even though target and // display are identical text, so a reader // who spots a wrong link can simply edit the // part before the "|" -- when the word's // shape actually looks like an inflected // noun (it matched at least two different // candidate declension suffixes). A word // that matched zero or only one suffix isn't // strong enough evidence that it's inflected // at all, so it's left unlinked rather than // guessed at. var target = null; if (compoundWord in links) { target = compoundWord; } else if (lowerSingle in links) { target = lowerSingle; } else if (stems.length >= 2) { target = compoundWord; } if (target && !(target in existingLinks)) { existingLinks[target] = true; tokenWords[j] = "[[" + target + "|" + tokenWords[j] + "]]"; } } break; } if (compoundWord in links) { if ((compoundWord in existingLinks) || ignoredWords[compoundWord]) { j += k; break; } existingLinks[compoundWord] = true; tokenWords[j] = "[[" + tokenWords[j]; tokenWords[j + k] += "]]"; j += k; break; } var lowerWord = compoundWord.linkifyUncapitalize(); if (lowerWord in links) { if ((lowerWord in existingLinks) || ignoredWords[lowerWord]) { j += k; break; } existingLinks[lowerWord] = true; tokenWords[j] = "[[" + lowerWord + "|" + tokenWords[j]; tokenWords[j + k] += "]]"; j += k; break; } word.splice(-1, 1); } } tokens[i] = tokenWords.join(" "); if (debug) { displayTokens[i] = "<b style='border: 1px solid gray;'>" + mw.html.escape(tokens[i]) + "</b>"; } }); if (debug) { $("#linkify-tokens").html("\n" + displayTokens.join("") + "\n"); } callback(tokens.join("")); }).fail(function (error) { console.warn(error); callback(); }); }); } // Regex for a single wikilink: [[target]] or [[target|display]]. Also // matches file/category-style links (e.g. [[File:...]]) the same way as any // other link -- this gadget doesn't try to special-case those, since a user // invoking "remove links" on a stretch of text presumably wants every // [[...]] construct in that stretch unwrapped, not just plain word links. var wikilinkRE = /\[\[([^\]|]*)\|([^\]]*)\]\]|\[\[([^\]|]*)\]\]/g; /** * Strips wikilink markup from text, keeping only the reader-facing text. * [[target|display]] -> display * [[target]] -> target * Unlike $.kuLinkify, this needs no API round-trip: removing markup that's * already there doesn't require checking whether any page exists. */ $.kuDelinkify = function (text) { return text.replace(wikilinkRE, function (match, pipedTarget, pipedDisplay, bareTarget) { return pipedDisplay !== undefined ? pipedDisplay : bareTarget; }); }; function getLinkifyTool() { return { type: "button", action: { type: "callback", execute: function () { mw.loader.using("jquery.textSelection", function () { var selection = $("#wpTextbox1").textSelection("getSelection"); $.kuLinkify(selection, function (linkedText) { if (!linkedText) return; $("#wpTextbox1").textSelection("encapsulateSelection", { peri: linkedText, replace: true }); }, $.kuLinkify_debug); }); } }, label: getMessage("toolbarButtonName"), icon: "//upload.wikimedia.org/wikipedia/commons/b/ba/Norwegian_link_sign.png" }; } function getDelinkifyTool() { return { type: "button", action: { type: "callback", execute: function () { mw.loader.using("jquery.textSelection", function () { var selection = $("#wpTextbox1").textSelection("getSelection"); var plainText = $.kuDelinkify(selection); if (plainText === selection) return; $("#wpTextbox1").textSelection("encapsulateSelection", { peri: plainText, replace: true }); }); } }, label: getMessage("delinkifyButtonName"), // Reuses the same icon as the link tool -- the distinct label makes // the tool's purpose clear regardless. icon: "//upload.wikimedia.org/wikipedia/commons/b/ba/Norwegian_link_sign.png" }; } function addLinkifyButton() { var $textbox = $("#wpTextbox1"); // Nothing to attach to on this page (VisualEditor, 2017 editor, non-edit // pages, etc.) — bail out instead of silently binding to an empty set. if (!$textbox.length) return; if ($.kuLinkify) { $textbox.after($(mw.html.element("div", { id: "linkify-progress", title: getMessage("toolbarButtonName") })).hide()); } // Bind the listener immediately, synchronously, rather than inside the // mw.loader.using("ext.wikiEditor", ...) callback. If we wait for that // callback to fire before attaching the listener, ext.wikiEditor may // already be loaded and may have already built (and fired the event for) // the main toolbar section by the time our callback runs -- in which case // the event has already come and gone and our button never gets added. // Attaching the listener up front means we won't miss the event even if // ext.wikiEditor resolves "instantly" (e.g. already cached/loaded). $textbox.on('wikiEditor-toolbar-buildSection-main', function (evt, section) { section.groups.insert.tools.linkify = getLinkifyTool(); section.groups.insert.tools.delinkify = getDelinkifyTool(); }); mw.loader.using("ext.wikiEditor", function () { // Fallback for the case where the toolbar's main section was already // built (and the event already fired) before this gadget's script // even started executing -- e.g. another gadget loaded ext.wikiEditor // earlier and the toolbar finished initializing first. In that case // the listener above is too late, so we check whether the toolbar // context already exists and, if so, add the tool directly via the // public addToToolbar API instead of waiting for an event that has // already happened. var context = $textbox.data("wikiEditor-context"); if (context && context.modules && context.modules.toolbar) { $textbox.wikiEditor("addToToolbar", { section: "main", group: "insert", tools: { linkify: getLinkifyTool(), delinkify: getDelinkifyTool() } }); } }); }; // Only try to add the button on pages that actually have an edit form -- // running unconditionally on every page load (including view/history/etc. // pages where #wpTextbox1 never exists) wastes a mw.loader.using round trip // and can look like "sometimes nothing happens" if a user doesn't realize // they weren't on an edit screen. if ($.inArray(mw.config.get("wgAction"), ["edit", "submit"]) !== -1) { addLinkifyButton(); } })(jQuery); oru1ojjd6rp9wuajw51y55140vepwzm 6265720 6265719 2026-07-20T01:20:40Z Wikihez 7344 6265720 javascript text/javascript // MediaWiki gadget: automatically link selected text to existing wiktionary entries (function ($) { var messages = { ku: { toolbarButtonName: "Li nivîsa bijartî bi otomatîkî girêdan lê zêde bike", delinkifyButtonName: "Ji nivîsa bijartî girêdanan rake", caseChangeLabel: "Guhartina herfan", caseUpperLabel: "MEZIN (UPPERCASE)", caseLowerLabel: "biçûk (lowercase)", caseSentenceLabel: "Cimle (Sentence case)", caseTitleLabel: "Her Kelîme Mezin (Title Case)" }, en: { toolbarButtonName: "Automatically link selected text", delinkifyButtonName: "Remove links from selected text", caseChangeLabel: "Change letter case", caseUpperLabel: "UPPERCASE", caseLowerLabel: "lowercase", caseSentenceLabel: "Sentence case", caseTitleLabel: "Title Case" }, es: { toolbarButtonName: "Automáticamente insertar enlaces en la selección", delinkifyButtonName: "Quitar enlaces del texto seleccionado", caseChangeLabel: "Cambiar mayúsculas/minúsculas", caseUpperLabel: "MAYÚSCULAS", caseLowerLabel: "minúsculas", caseSentenceLabel: "Case de oración", caseTitleLabel: "Case de Título" } }; // Kurmanji function words (prepositions, conjunctions, pronouns, particles, // demonstratives, copula/negation forms) that should never be turned into // links on their own, even though they're short enough to match compound // candidates during scanning. Also includes all 8 bare Kurmanji vowels // (a, e, ê, i, î, o, u, û) on their own, since a lone vowel is never a // meaningful link target even if it happens to match part of a scan. var ignoredWordList = ( "a|an|ba|bê|bi|çi|çu|çû|da|de|dê|dî|di|e|ê|ên|erê|ev|ew|em|gel|ha|hê|her|" + "hûn|i|î|jê|jî|ka|kî|ku|kû|lê|li|me|min|na|ne|o|pê|re|ra|ti|te|tê|" + "tu|u|û|va|van|ve|vê|vî|wan|we|wê|wî|wir|vir|ya|yan|yê|yên" ).split("|"); var ignoredWords = {}; $.each(ignoredWordList, function (i, word) { ignoredWords[word] = true; }); /** * One less than the maximum number of syllables to be considered as a compound * word. */ var lookahead = 2; // Tokenizer boundary class: standard uppercase Latin A-Z plus the Kurmanji // Latin alphabet's diacritic letters (both cases: Ç ç, Ê ê, Î î, Ş ş, Û û), // combining diacritical marks, and wiki markup delimiters. var tokenRE = /(\s*(?:<!--[\s\S]+?-->|\{\{[\s\S]+?\}\}|\[\[.+?\]\]|[^A-ZÇÊÎŞÛçêîşû\u0300-\u036F{[< ]+|[{[<])\s*)/i; String.prototype.linkifyUncapitalize = function () { return this[0].toLowerCase() + this.substr(1); }; // Common Kurmanji noun-declension suffixes (indefinite/definite, // nominative/construct/oblique/vocative -- see Module:ku-nouns' // declSimpleNoun), longest first so the greedy match below prefers the // most specific ending (e.g. "eke" before a bare "e"). // // This list is intentionally generous rather than grammatically precise: // unlike declSimpleNoun, the gadget doesn't know a word's gender or its // exact stem class when scanning arbitrary running text, so it can't // reproduce that branching logic exactly. Instead, every candidate root // produced here is verified against real wiktionary entries via the API // before it's ever used (see the "stems" check below) -- so an // over-aggressive strip that doesn't correspond to a genuine entry is // simply discarded, never turned into a bad link. var nounSuffixes = [ "iyekî", "iyekê", "iyeke", "iyinan", "iyino", "yekî", "yekê", "yeke", "yinan", "yino", "ekî", "ekê", "eke", "inan", "ine", "ino", "iyên", "iyan", "iyek", "iyin", "iyo", "iyî", "iyê", "iya", "yên", "yan", "yek", "yin", "yo", "yî", "yê", "ya", "ek", "ên", "an", "in", "a", "ê", "î", "o" ]; /** * Given a lowercase surface word, returns candidate noun roots obtained by * stripping a known declension suffix -- e.g. "rûpeleke" -> ["rûpel"]. * Candidates are ordered from least- to most-aggressively stripped (longest * remaining root first), so that when several candidates turn out to match * real entries, the safer/more specific one wins. */ function getNounStemCandidates(word) { var candidates = []; for (var i = 0; i < nounSuffixes.length; i++) { var suf = nounSuffixes[i]; // Require at least a 2-character root left over, so we don't // generate degenerate single-letter "roots". if (word.length > suf.length + 1 && word.slice(-suf.length) === suf) { candidates.push(word.slice(0, -suf.length)); } } // Orthographic correction: a root ending in î drops its circumflex when // it meets a glide suffix starting with y -- "giranî" + "yê" spells as // "giraniyê", not "giranîyê". Stripping the short suffix "yê" from that // surface form literally gives "girani" (bare i); stripping the longer // "iyê" suffix instead gives the shorter, unrelated root "giran". Since // the î-final noun is the actual root in this pattern, also offer the // î-restored form as a candidate for any stripped result ending in a // bare "i" -- e.g. "girani" -> "giranî". Because it's one character // longer than the "iyê"-derived candidate, the length-based sort below // naturally tries it first. var restored = []; $.each(candidates, function (idx, root) { if (root.length > 1 && root.slice(-1) === "i") { restored.push(root.slice(0, -1) + "î"); } }); candidates = candidates.concat(restored); candidates.sort(function (a, b) { return b.length - a.length; }); return candidates; } var userLang = mw.config.get("wgUserLanguage"); function getMessage(name) { return (messages[userLang] || messages.ku)[name] || messages.ku[name]; } $.kuLinkify = function (text, callback, debug) { var tokens = text.split(tokenRE); var displayTokens = []; var words = {}; var existingLinks = {}; // Maps a surface word (as typed, and its lowercase form) to candidate // noun roots -- e.g. stemCandidates["rûpeleke"] = ["rûpel"]. Filled in // below and consulted during reconstruction so an inflected word whose // exact surface form has no entry can still be linked to its root. var stemCandidates = {}; $.each(tokens, function (i, token) { if (debug) displayTokens.push(mw.html.escape(token)); var tokenLinks = token.match(/\[\[.+?(?:\|.+?)?\]\]/g); $.each(tokenLinks || [], function () { existingLinks[this.match(/\[\[(.+?)(?:\|.+?)?\]\]/)[1]] = true; }); if (!token || token.match(tokenRE)) return; var tokenWords = token.split(" "); $.each(tokenWords, function (j, word) { for (var k = 0; k < lookahead + 1 && tokenWords[j + k]; k++) { if (k) word += " " + tokenWords[j + k]; if (!ignoredWords[word]) words[word] = true; if (word[0] != word[0].toLowerCase()) { var lowerWord = word.linkifyUncapitalize(); if (!ignoredWords[lowerWord]) { words[lowerWord] = true; } } } }); // Also collect candidate noun roots for every individual word (not // multi-word compounds -- declension endings attach to a single // word), so inflected forms like "rûpeleke" can still be linked to // an existing root entry like "rûpel" even when the inflected form // itself has no entry. $.each(tokenWords, function (j, word) { if (!word) return; var lower = word.linkifyUncapitalize(); var stems = getNounStemCandidates(lower); if (stems.length) { stemCandidates[word] = stems; $.each(stems, function (s, stem) { if (!ignoredWords[stem]) words[stem] = true; }); } }); if (debug) { displayTokens[i] = "<b style='border: 1px solid gray;'>" + mw.html.escape(token) + "</b>"; } }); var uniqueWords = []; $.each(words, function (word) { if (!ignoredWords[word]) uniqueWords.push(word); }); if (debug) { var uniqueLinks = []; $.each(existingLinks, function (link) { uniqueLinks.push(link); }); var list = "<pre id='linkify-tokens'>\n" + displayTokens.join("") + "\n</pre>"; list += "<hr /><p>Words to search for:</p><p>" + uniqueWords + "</p>"; list += "<hr /><p>Words that already have links:</p><p>" + uniqueLinks + "</p>"; $("#linkify-progress").html(list).dialog({modal: true}); } if (!uniqueWords.length) return; mw.loader.using("mediawiki.api", function () { var api = new mw.Api(); api.get({ action: "parse", text: "[[" + uniqueWords.join("]] [[") + "]]", prop: "links" }).done(function (results) { $("#linkify-progress").append("<hr />"); var displayLinks = []; var links = {}; $.each(results.parse.links, function () { if (debug && "exists" in this) displayLinks.push(this["*"]); if ("exists" in this) links[this["*"]] = true; }); if (debug) { $("#linkify-progress").append("<p>Existing entries:</p><p>" + displayLinks + "</p>"); } $.each(tokens, function (i, token) { if (!token || token.match(tokenRE)) return; var tokenWords = token.split(" "); for (var j = 0; j < tokenWords.length; j++) { var word = []; for (var k = 0; k < lookahead + 1; k++) { word.push(tokenWords[j + k]); } for (var k = lookahead; k >= 0; k--) { var compoundWord = word.join(" "); if (k === 0) { var lowerSingle = compoundWord.linkifyUncapitalize(); // 1. Prefer linking to the declension root (lemma) // over the inflected surface form's own page -- // e.g. link "pîvana" as [[pîvan|pîvana]] rather // than [[pîvana]], since wiktionary entries for // inflected forms are usually secondary "form of" // pages rather than the main lemma readers want. var stems = stemCandidates[compoundWord] || stemCandidates[lowerSingle] || []; var stemLinked = false; for (var s = 0; s < stems.length; s++) { var stem = stems[s]; if ((stem in links) && !(stem in existingLinks) && !ignoredWords[stem]) { existingLinks[stem] = true; tokenWords[j] = "[[" + stem + "|" + tokenWords[j] + "]]"; stemLinked = true; break; } } if (stemLinked) break; if (!ignoredWords[compoundWord] && !ignoredWords[lowerSingle]) { // 2. No usable root. If the word (or its // lowercase form) is itself a confirmed // entry, link it normally -- this is a real // match, not a guess. Otherwise, only add a // speculative self-link -- always piped // (target|display), even though target and // display are identical text, so a reader // who spots a wrong link can simply edit the // part before the "|" -- when the word's // shape actually looks like an inflected // noun (it matched at least two different // candidate declension suffixes). A word // that matched zero or only one suffix isn't // strong enough evidence that it's inflected // at all, so it's left unlinked rather than // guessed at. var target = null; if (compoundWord in links) { target = compoundWord; } else if (lowerSingle in links) { target = lowerSingle; } else if (stems.length >= 2) { target = compoundWord; } if (target && !(target in existingLinks)) { existingLinks[target] = true; tokenWords[j] = "[[" + target + "|" + tokenWords[j] + "]]"; } } break; } if (compoundWord in links) { if ((compoundWord in existingLinks) || ignoredWords[compoundWord]) { j += k; break; } existingLinks[compoundWord] = true; tokenWords[j] = "[[" + tokenWords[j]; tokenWords[j + k] += "]]"; j += k; break; } var lowerWord = compoundWord.linkifyUncapitalize(); if (lowerWord in links) { if ((lowerWord in existingLinks) || ignoredWords[lowerWord]) { j += k; break; } existingLinks[lowerWord] = true; tokenWords[j] = "[[" + lowerWord + "|" + tokenWords[j]; tokenWords[j + k] += "]]"; j += k; break; } word.splice(-1, 1); } } tokens[i] = tokenWords.join(" "); if (debug) { displayTokens[i] = "<b style='border: 1px solid gray;'>" + mw.html.escape(tokens[i]) + "</b>"; } }); if (debug) { $("#linkify-tokens").html("\n" + displayTokens.join("") + "\n"); } callback(tokens.join("")); }).fail(function (error) { console.warn(error); callback(); }); }); } // Regex for a single wikilink: [[target]] or [[target|display]]. Also // matches file/category-style links (e.g. [[File:...]]) the same way as any // other link -- this gadget doesn't try to special-case those, since a user // invoking "remove links" on a stretch of text presumably wants every // [[...]] construct in that stretch unwrapped, not just plain word links. var wikilinkRE = /\[\[([^\]|]*)\|([^\]]*)\]\]|\[\[([^\]|]*)\]\]/g; /** * Strips wikilink markup from text, keeping only the reader-facing text. * [[target|display]] -> display * [[target]] -> target * Unlike $.kuLinkify, this needs no API round-trip: removing markup that's * already there doesn't require checking whether any page exists. */ $.kuDelinkify = function (text) { return text.replace(wikilinkRE, function (match, pipedTarget, pipedDisplay, bareTarget) { return pipedDisplay !== undefined ? pipedDisplay : bareTarget; }); }; // --------------------------------------------------------------- // Letter-case conversion (UPPERCASE / lowercase / Sentence case / // Title Case), adapted from the herfguhartin.js gadget's ku-locale // logic. Unlike that gadget, this one only ever deals with Kurmanji // text, so there's no per-language dotted/dotless-i handling to worry // about -- plain JS toUpperCase()/toLowerCase() already do the right // thing for Kurmanji's Latin letters (a e ê i î o u û plus ç ş, etc). // // For Title Case, this reuses the gadget's own `ignoredWords` list // (the Kurmanji function words already excluded from auto-linking) // as the set of small grammatical words that should stay lowercase, // rather than keeping a second, separately-maintained stopword list. // --------------------------------------------------------------- var KU_LETTER_CLASS = "a-zA-ZçêîşûÇÊÎŞÛ"; var kuNonLetterLeadingRE = new RegExp("^[^" + KU_LETTER_CLASS + "]*"); var kuNonLetterTrailingRE = new RegExp("[^" + KU_LETTER_CLASS + "]*$"); var kuSentenceBreakRE = new RegExp( "(^\\s*[a-zçêîşû]|[.!?][\"'\\)\\]]*\\s+[a-zçêîşû])", "gi" ); function kuCapitalizeFirstLetter(word) { if (word === "") return word; var lowered = word.toLowerCase(); return lowered.charAt(0).toUpperCase() + lowered.slice(1); } function kuToSentenceCase(text) { var lowered = text.toLowerCase(); return lowered.replace(kuSentenceBreakRE, function (match) { var idx = match.length - 1; return match.slice(0, idx) + match.charAt(idx).toUpperCase(); }); } // Capitalizes one "word chunk": handles leading/trailing punctuation // ("(çîroka" -> "(Çîroka"), hyphenated compounds ("kurdî-gerşûnî" -> // "Kurdî-Gerşûnî"), and keeps ignoredWords entries lowercase unless // forced (first word of the text, or right after an opening // bracket/quote). function kuCapitalizeWordChunk(chunk, forceCapitalize) { var leading = (chunk.match(kuNonLetterLeadingRE) || [""])[0]; var trailing = (chunk.match(kuNonLetterTrailingRE) || [""])[0]; var core = chunk.slice(leading.length, chunk.length - trailing.length); if (core === "") return chunk; if (/[(["'‘“]/.test(leading)) forceCapitalize = true; var loweredCore = core.toLowerCase(); var isStopWord = !forceCapitalize && ignoredWords[loweredCore]; var newCore; if (isStopWord) { newCore = loweredCore; } else { newCore = core.split("-").map(function (part) { return kuCapitalizeFirstLetter(part); }).join("-"); } return leading + newCore + trailing; } function kuToTitleCase(text) { var wordIndex = 0; return text.split(/(\s+)/).map(function (chunk) { if (chunk === "" || /^\s+$/.test(chunk)) return chunk; var isFirstWord = wordIndex === 0; wordIndex++; return kuCapitalizeWordChunk(chunk, isFirstWord); }).join(""); } $.kuApplyCase = function (text, form) { switch (form) { case "upper": return text.toUpperCase(); case "lower": return text.toLowerCase(); case "sentence": return kuToSentenceCase(text); case "title": return kuToTitleCase(text); default: return text; } }; function getLinkifyTool() { return { type: "button", action: { type: "callback", execute: function () { mw.loader.using("jquery.textSelection", function () { var selection = $("#wpTextbox1").textSelection("getSelection"); $.kuLinkify(selection, function (linkedText) { if (!linkedText) return; $("#wpTextbox1").textSelection("encapsulateSelection", { peri: linkedText, replace: true }); }, $.kuLinkify_debug); }); } }, label: getMessage("toolbarButtonName"), icon: "//upload.wikimedia.org/wikipedia/commons/b/ba/Norwegian_link_sign.png" }; } // Two link segments with a diagonal strike through them -- distinct from // the linkify tool's chain-link icon, but still visually "link-related" so // its relationship to the linkify button is obvious. Defined as an inline // SVG data URI rather than a Commons file reference, so the icon can't // silently break if a filename on Commons is ever renamed or deleted. var delinkifyIcon = "data:image/svg+xml;utf8," + encodeURIComponent( '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" width="20" height="20">' + '<rect x="2" y="7" width="7" height="6" rx="3" fill="none" stroke="#333" stroke-width="2"/>' + '<rect x="11" y="7" width="7" height="6" rx="3" fill="none" stroke="#333" stroke-width="2"/>' + '<line x1="2" y1="2" x2="18" y2="18" stroke="#d33" stroke-width="2.2" stroke-linecap="round"/>' + '</svg>' ); function getDelinkifyTool() { return { type: "button", action: { type: "callback", execute: function () { mw.loader.using("jquery.textSelection", function () { var selection = $("#wpTextbox1").textSelection("getSelection"); var plainText = $.kuDelinkify(selection); if (plainText === selection) return; $("#wpTextbox1").textSelection("encapsulateSelection", { peri: plainText, replace: true }); }); } }, label: getMessage("delinkifyButtonName"), icon: delinkifyIcon }; } // Applies a case transform to the current textbox selection and writes the // result back in place. Shared by every option in the case-change dropdown. function applyCaseToSelection(form) { mw.loader.using("jquery.textSelection", function () { var selection = $("#wpTextbox1").textSelection("getSelection"); if (!selection) return; var converted = $.kuApplyCase(selection, form); if (converted === selection) return; $("#wpTextbox1").textSelection("encapsulateSelection", { peri: converted, replace: true }); }); } // A wikiEditor "select" tool renders as a dropdown (like the core "heading" // tool) rather than a single button, which fits four mutually-exclusive // case options better than four separate toolbar buttons. function getCaseChangeTool() { return { type: "select", label: getMessage("caseChangeLabel"), list: { upper: { label: getMessage("caseUpperLabel"), action: { type: "callback", execute: function () { applyCaseToSelection("upper"); } } }, lower: { label: getMessage("caseLowerLabel"), action: { type: "callback", execute: function () { applyCaseToSelection("lower"); } } }, sentence: { label: getMessage("caseSentenceLabel"), action: { type: "callback", execute: function () { applyCaseToSelection("sentence"); } } }, title: { label: getMessage("caseTitleLabel"), action: { type: "callback", execute: function () { applyCaseToSelection("title"); } } } } }; } function addLinkifyButton() { var $textbox = $("#wpTextbox1"); // Nothing to attach to on this page (VisualEditor, 2017 editor, non-edit // pages, etc.) — bail out instead of silently binding to an empty set. if (!$textbox.length) return; if ($.kuLinkify) { $textbox.after($(mw.html.element("div", { id: "linkify-progress", title: getMessage("toolbarButtonName") })).hide()); } // Bind the listener immediately, synchronously, rather than inside the // mw.loader.using("ext.wikiEditor", ...) callback. If we wait for that // callback to fire before attaching the listener, ext.wikiEditor may // already be loaded and may have already built (and fired the event for) // the main toolbar section by the time our callback runs -- in which case // the event has already come and gone and our button never gets added. // Attaching the listener up front means we won't miss the event even if // ext.wikiEditor resolves "instantly" (e.g. already cached/loaded). $textbox.on('wikiEditor-toolbar-buildSection-main', function (evt, section) { section.groups.insert.tools.linkify = getLinkifyTool(); section.groups.insert.tools.delinkify = getDelinkifyTool(); section.groups.insert.tools.caseChange = getCaseChangeTool(); }); mw.loader.using("ext.wikiEditor", function () { // Fallback for the case where the toolbar's main section was already // built (and the event already fired) before this gadget's script // even started executing -- e.g. another gadget loaded ext.wikiEditor // earlier and the toolbar finished initializing first. In that case // the listener above is too late, so we check whether the toolbar // context already exists and, if so, add the tool directly via the // public addToToolbar API instead of waiting for an event that has // already happened. var context = $textbox.data("wikiEditor-context"); if (context && context.modules && context.modules.toolbar) { $textbox.wikiEditor("addToToolbar", { section: "main", group: "insert", tools: { linkify: getLinkifyTool(), delinkify: getDelinkifyTool(), caseChange: getCaseChangeTool() } }); } }); }; // Only try to add the button on pages that actually have an edit form -- // running unconditionally on every page load (including view/history/etc. // pages where #wpTextbox1 never exists) wastes a mw.loader.using round trip // and can look like "sometimes nothing happens" if a user doesn't realize // they weren't on an edit screen. if ($.inArray(mw.config.get("wgAction"), ["edit", "submit"]) !== -1) { addLinkifyButton(); } })(jQuery); f1m58guplt5b9zuikkkhpxbm8n62c79 6265721 6265720 2026-07-20T01:31:06Z Wikihez 7344 6265721 javascript text/javascript // MediaWiki gadget: automatically link selected text to existing wiktionary entries (function ($) { var messages = { ku: { toolbarButtonName: "Li nivîsa bijartî bi otomatîkî girêdan lê zêde bike", delinkifyButtonName: "Ji nivîsa bijartî girêdanan rake", caseChangeLabel: "Guhartina herfan", caseUpperLabel: "MEZIN (UPPERCASE)", caseLowerLabel: "biçûk (lowercase)", caseSentenceLabel: "Cimle (Sentence case)", caseTitleLabel: "Her Kelîme Mezin (Title Case)" }, en: { toolbarButtonName: "Automatically link selected text", delinkifyButtonName: "Remove links from selected text", caseChangeLabel: "Change letter case", caseUpperLabel: "UPPERCASE", caseLowerLabel: "lowercase", caseSentenceLabel: "Sentence case", caseTitleLabel: "Title Case" }, es: { toolbarButtonName: "Automáticamente insertar enlaces en la selección", delinkifyButtonName: "Quitar enlaces del texto seleccionado", caseChangeLabel: "Cambiar mayúsculas/minúsculas", caseUpperLabel: "MAYÚSCULAS", caseLowerLabel: "minúsculas", caseSentenceLabel: "Case de oración", caseTitleLabel: "Case de Título" } }; // Kurmanji function words (prepositions, conjunctions, pronouns, particles, // demonstratives, copula/negation forms) that should never be turned into // links on their own, even though they're short enough to match compound // candidates during scanning. Also includes all 8 bare Kurmanji vowels // (a, e, ê, i, î, o, u, û) on their own, since a lone vowel is never a // meaningful link target even if it happens to match part of a scan. var ignoredWordList = ( "a|an|ba|bê|bi|çi|çu|çû|da|de|dê|dî|di|e|ê|ên|erê|ev|ew|em|gel|ha|hê|her|" + "hûn|i|î|jê|jî|ka|kî|ku|kû|lê|li|me|min|na|ne|o|pê|re|ra|ti|te|tê|" + "tu|u|û|va|van|ve|vê|vî|wan|we|wê|wî|wir|vir|ya|yan|yê|yên" ).split("|"); var ignoredWords = {}; $.each(ignoredWordList, function (i, word) { ignoredWords[word] = true; }); /** * One less than the maximum number of syllables to be considered as a compound * word. */ var lookahead = 2; // Tokenizer boundary class: standard uppercase Latin A-Z plus the Kurmanji // Latin alphabet's diacritic letters (both cases: Ç ç, Ê ê, Î î, Ş ş, Û û), // combining diacritical marks, and wiki markup delimiters. var tokenRE = /(\s*(?:<!--[\s\S]+?-->|\{\{[\s\S]+?\}\}|\[\[.+?\]\]|[^A-ZÇÊÎŞÛçêîşû\u0300-\u036F{[< ]+|[{[<])\s*)/i; String.prototype.linkifyUncapitalize = function () { return this[0].toLowerCase() + this.substr(1); }; // Common Kurmanji noun-declension suffixes (indefinite/definite, // nominative/construct/oblique/vocative -- see Module:ku-nouns' // declSimpleNoun), longest first so the greedy match below prefers the // most specific ending (e.g. "eke" before a bare "e"). // // This list is intentionally generous rather than grammatically precise: // unlike declSimpleNoun, the gadget doesn't know a word's gender or its // exact stem class when scanning arbitrary running text, so it can't // reproduce that branching logic exactly. Instead, every candidate root // produced here is verified against real wiktionary entries via the API // before it's ever used (see the "stems" check below) -- so an // over-aggressive strip that doesn't correspond to a genuine entry is // simply discarded, never turned into a bad link. var nounSuffixes = [ "iyekî", "iyekê", "iyeke", "iyinan", "iyino", "yekî", "yekê", "yeke", "yinan", "yino", "ekî", "ekê", "eke", "inan", "ine", "ino", "iyên", "iyan", "iyek", "iyin", "iyo", "iyî", "iyê", "iya", "yên", "yan", "yek", "yin", "yo", "yî", "yê", "ya", "ek", "ên", "an", "in", "a", "ê", "î", "o" ]; /** * Given a lowercase surface word, returns candidate noun roots obtained by * stripping a known declension suffix -- e.g. "rûpeleke" -> ["rûpel"]. * Candidates are ordered from least- to most-aggressively stripped (longest * remaining root first), so that when several candidates turn out to match * real entries, the safer/more specific one wins. */ function getNounStemCandidates(word) { var candidates = []; for (var i = 0; i < nounSuffixes.length; i++) { var suf = nounSuffixes[i]; // Require at least a 2-character root left over, so we don't // generate degenerate single-letter "roots". if (word.length > suf.length + 1 && word.slice(-suf.length) === suf) { candidates.push(word.slice(0, -suf.length)); } } // Orthographic correction: a root ending in î drops its circumflex when // it meets a glide suffix starting with y -- "giranî" + "yê" spells as // "giraniyê", not "giranîyê". Stripping the short suffix "yê" from that // surface form literally gives "girani" (bare i); stripping the longer // "iyê" suffix instead gives the shorter, unrelated root "giran". Since // the î-final noun is the actual root in this pattern, also offer the // î-restored form as a candidate for any stripped result ending in a // bare "i" -- e.g. "girani" -> "giranî". Because it's one character // longer than the "iyê"-derived candidate, the length-based sort below // naturally tries it first. var restored = []; $.each(candidates, function (idx, root) { if (root.length > 1 && root.slice(-1) === "i") { restored.push(root.slice(0, -1) + "î"); } }); candidates = candidates.concat(restored); candidates.sort(function (a, b) { return b.length - a.length; }); return candidates; } var userLang = mw.config.get("wgUserLanguage"); function getMessage(name) { return (messages[userLang] || messages.ku)[name] || messages.ku[name]; } $.kuLinkify = function (text, callback, debug) { var tokens = text.split(tokenRE); var displayTokens = []; var words = {}; var existingLinks = {}; // Maps a surface word (as typed, and its lowercase form) to candidate // noun roots -- e.g. stemCandidates["rûpeleke"] = ["rûpel"]. Filled in // below and consulted during reconstruction so an inflected word whose // exact surface form has no entry can still be linked to its root. var stemCandidates = {}; $.each(tokens, function (i, token) { if (debug) displayTokens.push(mw.html.escape(token)); var tokenLinks = token.match(/\[\[.+?(?:\|.+?)?\]\]/g); $.each(tokenLinks || [], function () { existingLinks[this.match(/\[\[(.+?)(?:\|.+?)?\]\]/)[1]] = true; }); if (!token || token.match(tokenRE)) return; var tokenWords = token.split(" "); $.each(tokenWords, function (j, word) { for (var k = 0; k < lookahead + 1 && tokenWords[j + k]; k++) { if (k) word += " " + tokenWords[j + k]; if (!ignoredWords[word]) words[word] = true; if (word[0] != word[0].toLowerCase()) { var lowerWord = word.linkifyUncapitalize(); if (!ignoredWords[lowerWord]) { words[lowerWord] = true; } } } }); // Also collect candidate noun roots for every individual word (not // multi-word compounds -- declension endings attach to a single // word), so inflected forms like "rûpeleke" can still be linked to // an existing root entry like "rûpel" even when the inflected form // itself has no entry. $.each(tokenWords, function (j, word) { if (!word) return; var lower = word.linkifyUncapitalize(); var stems = getNounStemCandidates(lower); if (stems.length) { stemCandidates[word] = stems; $.each(stems, function (s, stem) { if (!ignoredWords[stem]) words[stem] = true; }); } }); if (debug) { displayTokens[i] = "<b style='border: 1px solid gray;'>" + mw.html.escape(token) + "</b>"; } }); var uniqueWords = []; $.each(words, function (word) { if (!ignoredWords[word]) uniqueWords.push(word); }); if (debug) { var uniqueLinks = []; $.each(existingLinks, function (link) { uniqueLinks.push(link); }); var list = "<pre id='linkify-tokens'>\n" + displayTokens.join("") + "\n</pre>"; list += "<hr /><p>Words to search for:</p><p>" + uniqueWords + "</p>"; list += "<hr /><p>Words that already have links:</p><p>" + uniqueLinks + "</p>"; $("#linkify-progress").html(list).dialog({modal: true}); } if (!uniqueWords.length) return; mw.loader.using("mediawiki.api", function () { var api = new mw.Api(); api.get({ action: "parse", text: "[[" + uniqueWords.join("]] [[") + "]]", prop: "links" }).done(function (results) { $("#linkify-progress").append("<hr />"); var displayLinks = []; var links = {}; $.each(results.parse.links, function () { if (debug && "exists" in this) displayLinks.push(this["*"]); if ("exists" in this) links[this["*"]] = true; }); if (debug) { $("#linkify-progress").append("<p>Existing entries:</p><p>" + displayLinks + "</p>"); } $.each(tokens, function (i, token) { if (!token || token.match(tokenRE)) return; var tokenWords = token.split(" "); for (var j = 0; j < tokenWords.length; j++) { var word = []; for (var k = 0; k < lookahead + 1; k++) { word.push(tokenWords[j + k]); } for (var k = lookahead; k >= 0; k--) { var compoundWord = word.join(" "); if (k === 0) { var lowerSingle = compoundWord.linkifyUncapitalize(); // 1. Prefer linking to the declension root (lemma) // over the inflected surface form's own page -- // e.g. link "pîvana" as [[pîvan|pîvana]] rather // than [[pîvana]], since wiktionary entries for // inflected forms are usually secondary "form of" // pages rather than the main lemma readers want. var stems = stemCandidates[compoundWord] || stemCandidates[lowerSingle] || []; var stemLinked = false; for (var s = 0; s < stems.length; s++) { var stem = stems[s]; if ((stem in links) && !(stem in existingLinks) && !ignoredWords[stem]) { existingLinks[stem] = true; tokenWords[j] = "[[" + stem + "|" + tokenWords[j] + "]]"; stemLinked = true; break; } } if (stemLinked) break; if (!ignoredWords[compoundWord] && !ignoredWords[lowerSingle]) { // 2. No usable root. If the word (or its // lowercase form) is itself a confirmed // entry, link it normally -- this is a real // match, not a guess. Otherwise, only add a // speculative self-link -- always piped // (target|display), even though target and // display are identical text, so a reader // who spots a wrong link can simply edit the // part before the "|" -- when the word's // shape actually looks like an inflected // noun (it matched at least two different // candidate declension suffixes). A word // that matched zero or only one suffix isn't // strong enough evidence that it's inflected // at all, so it's left unlinked rather than // guessed at. var target = null; if (compoundWord in links) { target = compoundWord; } else if (lowerSingle in links) { target = lowerSingle; } else if (stems.length >= 2) { target = compoundWord; } if (target && !(target in existingLinks)) { existingLinks[target] = true; tokenWords[j] = "[[" + target + "|" + tokenWords[j] + "]]"; } } break; } if (compoundWord in links) { if ((compoundWord in existingLinks) || ignoredWords[compoundWord]) { j += k; break; } existingLinks[compoundWord] = true; tokenWords[j] = "[[" + tokenWords[j]; tokenWords[j + k] += "]]"; j += k; break; } var lowerWord = compoundWord.linkifyUncapitalize(); if (lowerWord in links) { if ((lowerWord in existingLinks) || ignoredWords[lowerWord]) { j += k; break; } existingLinks[lowerWord] = true; tokenWords[j] = "[[" + lowerWord + "|" + tokenWords[j]; tokenWords[j + k] += "]]"; j += k; break; } word.splice(-1, 1); } } tokens[i] = tokenWords.join(" "); if (debug) { displayTokens[i] = "<b style='border: 1px solid gray;'>" + mw.html.escape(tokens[i]) + "</b>"; } }); if (debug) { $("#linkify-tokens").html("\n" + displayTokens.join("") + "\n"); } callback(tokens.join("")); }).fail(function (error) { console.warn(error); callback(); }); }); } // Regex for a single wikilink: [[target]] or [[target|display]]. Also // matches file/category-style links (e.g. [[File:...]]) the same way as any // other link -- this gadget doesn't try to special-case those, since a user // invoking "remove links" on a stretch of text presumably wants every // [[...]] construct in that stretch unwrapped, not just plain word links. var wikilinkRE = /\[\[([^\]|]*)\|([^\]]*)\]\]|\[\[([^\]|]*)\]\]/g; /** * Strips wikilink markup from text, keeping only the reader-facing text. * [[target|display]] -> display * [[target]] -> target * Unlike $.kuLinkify, this needs no API round-trip: removing markup that's * already there doesn't require checking whether any page exists. */ $.kuDelinkify = function (text) { return text.replace(wikilinkRE, function (match, pipedTarget, pipedDisplay, bareTarget) { return pipedDisplay !== undefined ? pipedDisplay : bareTarget; }); }; // --------------------------------------------------------------- // Letter-case conversion (UPPERCASE / lowercase / Sentence case / // Title Case), adapted from the herfguhartin.js gadget's ku-locale // logic. Unlike that gadget, this one only ever deals with Kurmanji // text, so there's no per-language dotted/dotless-i handling to worry // about -- plain JS toUpperCase()/toLowerCase() already do the right // thing for Kurmanji's Latin letters (a e ê i î o u û plus ç ş, etc). // // For Title Case, this reuses the gadget's own `ignoredWords` list // (the Kurmanji function words already excluded from auto-linking) // as the set of small grammatical words that should stay lowercase, // rather than keeping a second, separately-maintained stopword list. // --------------------------------------------------------------- var KU_LETTER_CLASS = "a-zA-ZçêîşûÇÊÎŞÛ"; var kuNonLetterLeadingRE = new RegExp("^[^" + KU_LETTER_CLASS + "]*"); var kuNonLetterTrailingRE = new RegExp("[^" + KU_LETTER_CLASS + "]*$"); var kuSentenceBreakRE = new RegExp( "(^\\s*[a-zçêîşû]|[.!?][\"'\\)\\]]*\\s+[a-zçêîşû])", "gi" ); function kuCapitalizeFirstLetter(word) { if (word === "") return word; var lowered = word.toLowerCase(); return lowered.charAt(0).toUpperCase() + lowered.slice(1); } function kuToSentenceCase(text) { var lowered = text.toLowerCase(); return lowered.replace(kuSentenceBreakRE, function (match) { var idx = match.length - 1; return match.slice(0, idx) + match.charAt(idx).toUpperCase(); }); } // Capitalizes one "word chunk": handles leading/trailing punctuation // ("(çîroka" -> "(Çîroka"), hyphenated compounds ("kurdî-gerşûnî" -> // "Kurdî-Gerşûnî"), and keeps ignoredWords entries lowercase unless // forced (first word of the text, or right after an opening // bracket/quote). function kuCapitalizeWordChunk(chunk, forceCapitalize) { var leading = (chunk.match(kuNonLetterLeadingRE) || [""])[0]; var trailing = (chunk.match(kuNonLetterTrailingRE) || [""])[0]; var core = chunk.slice(leading.length, chunk.length - trailing.length); if (core === "") return chunk; if (/[(["'‘“]/.test(leading)) forceCapitalize = true; var loweredCore = core.toLowerCase(); var isStopWord = !forceCapitalize && ignoredWords[loweredCore]; var newCore; if (isStopWord) { newCore = loweredCore; } else { newCore = core.split("-").map(function (part) { return kuCapitalizeFirstLetter(part); }).join("-"); } return leading + newCore + trailing; } function kuToTitleCase(text) { var wordIndex = 0; return text.split(/(\s+)/).map(function (chunk) { if (chunk === "" || /^\s+$/.test(chunk)) return chunk; var isFirstWord = wordIndex === 0; wordIndex++; return kuCapitalizeWordChunk(chunk, isFirstWord); }).join(""); } $.kuApplyCase = function (text, form) { switch (form) { case "upper": return text.toUpperCase(); case "lower": return text.toLowerCase(); case "sentence": return kuToSentenceCase(text); case "title": return kuToTitleCase(text); default: return text; } }; function getLinkifyTool() { return { type: "button", action: { type: "callback", execute: function () { mw.loader.using("jquery.textSelection", function () { var selection = $("#wpTextbox1").textSelection("getSelection"); $.kuLinkify(selection, function (linkedText) { if (!linkedText) return; $("#wpTextbox1").textSelection("encapsulateSelection", { peri: linkedText, replace: true }); }, $.kuLinkify_debug); }); } }, label: getMessage("toolbarButtonName"), icon: "//upload.wikimedia.org/wikipedia/commons/b/ba/Norwegian_link_sign.png" }; } // Two link segments with a diagonal strike through them -- distinct from // the linkify tool's chain-link icon, but still visually "link-related" so // its relationship to the linkify button is obvious. Defined as an inline // SVG data URI rather than a Commons file reference, so the icon can't // silently break if a filename on Commons is ever renamed or deleted. var delinkifyIcon = "data:image/svg+xml;utf8," + encodeURIComponent( '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" width="20" height="20">' + '<rect x="2" y="7" width="7" height="6" rx="3" fill="none" stroke="#333" stroke-width="2"/>' + '<rect x="11" y="7" width="7" height="6" rx="3" fill="none" stroke="#333" stroke-width="2"/>' + '<line x1="2" y1="2" x2="18" y2="18" stroke="#d33" stroke-width="2.2" stroke-linecap="round"/>' + '</svg>' ); function getDelinkifyTool() { return { type: "button", action: { type: "callback", execute: function () { mw.loader.using("jquery.textSelection", function () { var selection = $("#wpTextbox1").textSelection("getSelection"); var plainText = $.kuDelinkify(selection); if (plainText === selection) return; $("#wpTextbox1").textSelection("encapsulateSelection", { peri: plainText, replace: true }); }); } }, label: getMessage("delinkifyButtonName"), icon: delinkifyIcon }; } // Applies a case transform to the current textbox selection and writes the // result back in place. Shared by every option in the case-change dropdown. function applyCaseToSelection(form) { mw.loader.using("jquery.textSelection", function () { var selection = $("#wpTextbox1").textSelection("getSelection"); if (!selection) return; var converted = $.kuApplyCase(selection, form); if (converted === selection) return; $("#wpTextbox1").textSelection("encapsulateSelection", { peri: converted, replace: true }); }); } // The built-in wikiEditor "select" tool type (used for e.g. the core // "heading" dropdown) is supposed to close itself both on selecting an // option and on re-clicking its label, but that toggle lives entirely // inside jquery.wikiEditor.toolbar.js and isn't something a gadget can // patch if it misbehaves on a given wiki's deployed version. To make the // close behavior actually reliable, this builds the dropdown by hand as a // wikiEditor "element" tool (a raw DOM element wikiEditor just drops into // the toolbar) and manages its own open/closed state directly, while still // reusing wikiEditor's existing tool-select/label/menu/options/option CSS // classes so it looks identical to a native dropdown. function buildCaseChangeElement() { var forms = [ { key: "upper", label: getMessage("caseUpperLabel") }, { key: "lower", label: getMessage("caseLowerLabel") }, { key: "sentence", label: getMessage("caseSentenceLabel") }, { key: "title", label: getMessage("caseTitleLabel") } ]; var $select = $("<div>").addClass("tool tool-select").attr("rel", "caseChange"); var $options = $("<div>").addClass("options"); var $menu = $("<div>").addClass("menu").append($options).hide(); // Toggling both the class (for anyone's CSS keyed off .options-shown) // and an explicit .show()/.hide() (so the menu is guaranteed to // actually disappear even if that CSS rule is missing or overridden). function closeMenu() { $select.removeClass("options-shown"); $menu.hide(); $label.attr("aria-expanded", "false"); } function openMenu() { // Only one such dropdown open at a time. $(".tool-select").not($select).removeClass("options-shown").find(".menu").hide(); $select.addClass("options-shown"); $menu.show(); $label.attr("aria-expanded", "true"); } $.each(forms, function (i, form) { $("<a>") .addClass("option") .attr({ rel: form.key, tabindex: 0, role: "menuitem" }) .text(form.label) .on("mousedown", function (e) { e.preventDefault(); return false; }) .on("click keydown", function (e) { if (e.type === "click" || (e.type === "keydown" && e.key === "Enter")) { applyCaseToSelection(form.key); closeMenu(); e.preventDefault(); return false; } }) .appendTo($options); }); var $label = $("<a>") .addClass("label skin-invert") .text(getMessage("caseChangeLabel")) .attr({ role: "button", tabindex: 0, "aria-expanded": "false", "aria-haspopup": "menu" }) .on("mousedown", function (e) { e.preventDefault(); return false; }) .on("click keydown", function (e) { if (e.type === "click" || (e.type === "keydown" && e.key === "Enter")) { if ($select.hasClass("options-shown")) { closeMenu(); } else { openMenu(); } e.preventDefault(); return false; } }); $select.append($label, $menu); // Close on any click elsewhere on the page. Namespaced and re-bound // via .off() first so re-registering this tool never stacks up // duplicate document-level handlers. $(document).off("mousedown.kuCaseChange").on("mousedown.kuCaseChange", function (e) { if (!$(e.target).closest($select).length) { closeMenu(); } }); return $select; } function getCaseChangeTool() { return { type: "element", element: buildCaseChangeElement }; } function addLinkifyButton() { var $textbox = $("#wpTextbox1"); // Nothing to attach to on this page (VisualEditor, 2017 editor, non-edit // pages, etc.) — bail out instead of silently binding to an empty set. if (!$textbox.length) return; if ($.kuLinkify) { $textbox.after($(mw.html.element("div", { id: "linkify-progress", title: getMessage("toolbarButtonName") })).hide()); } // Bind the listener immediately, synchronously, rather than inside the // mw.loader.using("ext.wikiEditor", ...) callback. If we wait for that // callback to fire before attaching the listener, ext.wikiEditor may // already be loaded and may have already built (and fired the event for) // the main toolbar section by the time our callback runs -- in which case // the event has already come and gone and our button never gets added. // Attaching the listener up front means we won't miss the event even if // ext.wikiEditor resolves "instantly" (e.g. already cached/loaded). $textbox.on('wikiEditor-toolbar-buildSection-main', function (evt, section) { section.groups.insert.tools.linkify = getLinkifyTool(); section.groups.insert.tools.delinkify = getDelinkifyTool(); section.groups.insert.tools.caseChange = getCaseChangeTool(); }); mw.loader.using("ext.wikiEditor", function () { // Fallback for the case where the toolbar's main section was already // built (and the event already fired) before this gadget's script // even started executing -- e.g. another gadget loaded ext.wikiEditor // earlier and the toolbar finished initializing first. In that case // the listener above is too late, so we check whether the toolbar // context already exists and, if so, add the tool directly via the // public addToToolbar API instead of waiting for an event that has // already happened. var context = $textbox.data("wikiEditor-context"); if (context && context.modules && context.modules.toolbar) { $textbox.wikiEditor("addToToolbar", { section: "main", group: "insert", tools: { linkify: getLinkifyTool(), delinkify: getDelinkifyTool(), caseChange: getCaseChangeTool() } }); } }); }; // Only try to add the button on pages that actually have an edit form -- // running unconditionally on every page load (including view/history/etc. // pages where #wpTextbox1 never exists) wastes a mw.loader.using round trip // and can look like "sometimes nothing happens" if a user doesn't realize // they weren't on an edit screen. if ($.inArray(mw.config.get("wgAction"), ["edit", "submit"]) !== -1) { addLinkifyButton(); } })(jQuery); oabsltr0l31gum5zq2xtj1p97hmu8fh 6265722 6265721 2026-07-20T01:40:38Z Wikihez 7344 6265722 javascript text/javascript // MediaWiki gadget: automatically link selected text to existing wiktionary entries (function ($) { var messages = { ku: { toolbarButtonName: "Li nivîsa bijartî bi otomatîkî girêdan lê zêde bike", delinkifyButtonName: "Ji nivîsa bijartî girêdanan rake", caseChangeLabel: "Guhartina herfan", caseUpperLabel: "MEZIN (UPPERCASE)", caseLowerLabel: "biçûk (lowercase)", caseSentenceLabel: "Cimle (Sentence case)", caseTitleLabel: "Her Kelîme Mezin (Title Case)" }, en: { toolbarButtonName: "Automatically link selected text", delinkifyButtonName: "Remove links from selected text", caseChangeLabel: "Change letter case", caseUpperLabel: "UPPERCASE", caseLowerLabel: "lowercase", caseSentenceLabel: "Sentence case", caseTitleLabel: "Title Case" }, es: { toolbarButtonName: "Automáticamente insertar enlaces en la selección", delinkifyButtonName: "Quitar enlaces del texto seleccionado", caseChangeLabel: "Cambiar mayúsculas/minúsculas", caseUpperLabel: "MAYÚSCULAS", caseLowerLabel: "minúsculas", caseSentenceLabel: "Case de oración", caseTitleLabel: "Case de Título" } }; // Kurmanji function words (prepositions, conjunctions, pronouns, particles, // demonstratives, copula/negation forms) that should never be turned into // links on their own, even though they're short enough to match compound // candidates during scanning. Also includes all 8 bare Kurmanji vowels // (a, e, ê, i, î, o, u, û) on their own, since a lone vowel is never a // meaningful link target even if it happens to match part of a scan. var ignoredWordList = ( "a|an|ba|bê|bi|çi|çu|çû|da|de|dê|dî|di|e|ê|ên|erê|ev|ew|em|gel|ha|hê|her|" + "hûn|i|î|jê|jî|ka|kî|ku|kû|lê|li|me|min|na|ne|o|pê|re|ra|ti|te|tê|" + "tu|u|û|va|van|ve|vê|vî|wan|we|wê|wî|wir|vir|ya|yan|yê|yên" ).split("|"); var ignoredWords = {}; $.each(ignoredWordList, function (i, word) { ignoredWords[word] = true; }); /** * One less than the maximum number of syllables to be considered as a compound * word. */ var lookahead = 2; // Tokenizer boundary class: standard uppercase Latin A-Z plus the Kurmanji // Latin alphabet's diacritic letters (both cases: Ç ç, Ê ê, Î î, Ş ş, Û û), // combining diacritical marks, and wiki markup delimiters. var tokenRE = /(\s*(?:<!--[\s\S]+?-->|\{\{[\s\S]+?\}\}|\[\[.+?\]\]|[^A-ZÇÊÎŞÛçêîşû\u0300-\u036F{[< ]+|[{[<])\s*)/i; String.prototype.linkifyUncapitalize = function () { return this[0].toLowerCase() + this.substr(1); }; // Common Kurmanji noun-declension suffixes (indefinite/definite, // nominative/construct/oblique/vocative -- see Module:ku-nouns' // declSimpleNoun), longest first so the greedy match below prefers the // most specific ending (e.g. "eke" before a bare "e"). // // This list is intentionally generous rather than grammatically precise: // unlike declSimpleNoun, the gadget doesn't know a word's gender or its // exact stem class when scanning arbitrary running text, so it can't // reproduce that branching logic exactly. Instead, every candidate root // produced here is verified against real wiktionary entries via the API // before it's ever used (see the "stems" check below) -- so an // over-aggressive strip that doesn't correspond to a genuine entry is // simply discarded, never turned into a bad link. var nounSuffixes = [ "iyekî", "iyekê", "iyeke", "iyinan", "iyino", "yekî", "yekê", "yeke", "yinan", "yino", "ekî", "ekê", "eke", "inan", "ine", "ino", "iyên", "iyan", "iyek", "iyin", "iyo", "iyî", "iyê", "iya", "yên", "yan", "yek", "yin", "yo", "yî", "yê", "ya", "ek", "ên", "an", "in", "a", "ê", "î", "o" ]; /** * Given a lowercase surface word, returns candidate noun roots obtained by * stripping a known declension suffix -- e.g. "rûpeleke" -> ["rûpel"]. * Candidates are ordered from least- to most-aggressively stripped (longest * remaining root first), so that when several candidates turn out to match * real entries, the safer/more specific one wins. */ function getNounStemCandidates(word) { var candidates = []; for (var i = 0; i < nounSuffixes.length; i++) { var suf = nounSuffixes[i]; // Require at least a 2-character root left over, so we don't // generate degenerate single-letter "roots". if (word.length > suf.length + 1 && word.slice(-suf.length) === suf) { candidates.push(word.slice(0, -suf.length)); } } // Orthographic correction: a root ending in î drops its circumflex when // it meets a glide suffix starting with y -- "giranî" + "yê" spells as // "giraniyê", not "giranîyê". Stripping the short suffix "yê" from that // surface form literally gives "girani" (bare i); stripping the longer // "iyê" suffix instead gives the shorter, unrelated root "giran". Since // the î-final noun is the actual root in this pattern, also offer the // î-restored form as a candidate for any stripped result ending in a // bare "i" -- e.g. "girani" -> "giranî". Because it's one character // longer than the "iyê"-derived candidate, the length-based sort below // naturally tries it first. var restored = []; $.each(candidates, function (idx, root) { if (root.length > 1 && root.slice(-1) === "i") { restored.push(root.slice(0, -1) + "î"); } }); candidates = candidates.concat(restored); candidates.sort(function (a, b) { return b.length - a.length; }); return candidates; } var userLang = mw.config.get("wgUserLanguage"); function getMessage(name) { return (messages[userLang] || messages.ku)[name] || messages.ku[name]; } $.kuLinkify = function (text, callback, debug) { var tokens = text.split(tokenRE); var displayTokens = []; var words = {}; var existingLinks = {}; // Maps a surface word (as typed, and its lowercase form) to candidate // noun roots -- e.g. stemCandidates["rûpeleke"] = ["rûpel"]. Filled in // below and consulted during reconstruction so an inflected word whose // exact surface form has no entry can still be linked to its root. var stemCandidates = {}; $.each(tokens, function (i, token) { if (debug) displayTokens.push(mw.html.escape(token)); var tokenLinks = token.match(/\[\[.+?(?:\|.+?)?\]\]/g); $.each(tokenLinks || [], function () { existingLinks[this.match(/\[\[(.+?)(?:\|.+?)?\]\]/)[1]] = true; }); if (!token || token.match(tokenRE)) return; var tokenWords = token.split(" "); $.each(tokenWords, function (j, word) { for (var k = 0; k < lookahead + 1 && tokenWords[j + k]; k++) { if (k) word += " " + tokenWords[j + k]; if (!ignoredWords[word]) words[word] = true; if (word[0] != word[0].toLowerCase()) { var lowerWord = word.linkifyUncapitalize(); if (!ignoredWords[lowerWord]) { words[lowerWord] = true; } } } }); // Also collect candidate noun roots for every individual word (not // multi-word compounds -- declension endings attach to a single // word), so inflected forms like "rûpeleke" can still be linked to // an existing root entry like "rûpel" even when the inflected form // itself has no entry. $.each(tokenWords, function (j, word) { if (!word) return; var lower = word.linkifyUncapitalize(); var stems = getNounStemCandidates(lower); if (stems.length) { stemCandidates[word] = stems; $.each(stems, function (s, stem) { if (!ignoredWords[stem]) words[stem] = true; }); } }); if (debug) { displayTokens[i] = "<b style='border: 1px solid gray;'>" + mw.html.escape(token) + "</b>"; } }); var uniqueWords = []; $.each(words, function (word) { if (!ignoredWords[word]) uniqueWords.push(word); }); if (debug) { var uniqueLinks = []; $.each(existingLinks, function (link) { uniqueLinks.push(link); }); var list = "<pre id='linkify-tokens'>\n" + displayTokens.join("") + "\n</pre>"; list += "<hr /><p>Words to search for:</p><p>" + uniqueWords + "</p>"; list += "<hr /><p>Words that already have links:</p><p>" + uniqueLinks + "</p>"; $("#linkify-progress").html(list).dialog({modal: true}); } if (!uniqueWords.length) return; mw.loader.using("mediawiki.api", function () { var api = new mw.Api(); api.get({ action: "parse", text: "[[" + uniqueWords.join("]] [[") + "]]", prop: "links" }).done(function (results) { $("#linkify-progress").append("<hr />"); var displayLinks = []; var links = {}; $.each(results.parse.links, function () { if (debug && "exists" in this) displayLinks.push(this["*"]); if ("exists" in this) links[this["*"]] = true; }); if (debug) { $("#linkify-progress").append("<p>Existing entries:</p><p>" + displayLinks + "</p>"); } $.each(tokens, function (i, token) { if (!token || token.match(tokenRE)) return; var tokenWords = token.split(" "); for (var j = 0; j < tokenWords.length; j++) { var word = []; for (var k = 0; k < lookahead + 1; k++) { word.push(tokenWords[j + k]); } for (var k = lookahead; k >= 0; k--) { var compoundWord = word.join(" "); if (k === 0) { var lowerSingle = compoundWord.linkifyUncapitalize(); // 1. Prefer linking to the declension root (lemma) // over the inflected surface form's own page -- // e.g. link "pîvana" as [[pîvan|pîvana]] rather // than [[pîvana]], since wiktionary entries for // inflected forms are usually secondary "form of" // pages rather than the main lemma readers want. var stems = stemCandidates[compoundWord] || stemCandidates[lowerSingle] || []; var stemLinked = false; for (var s = 0; s < stems.length; s++) { var stem = stems[s]; if ((stem in links) && !(stem in existingLinks) && !ignoredWords[stem]) { existingLinks[stem] = true; tokenWords[j] = "[[" + stem + "|" + tokenWords[j] + "]]"; stemLinked = true; break; } } if (stemLinked) break; if (!ignoredWords[compoundWord] && !ignoredWords[lowerSingle]) { // 2. No usable root. If the word (or its // lowercase form) is itself a confirmed // entry, link it normally -- this is a real // match, not a guess. Otherwise, only add a // speculative self-link -- always piped // (target|display), even though target and // display are identical text, so a reader // who spots a wrong link can simply edit the // part before the "|" -- when the word's // shape actually looks like an inflected // noun (it matched at least two different // candidate declension suffixes). A word // that matched zero or only one suffix isn't // strong enough evidence that it's inflected // at all, so it's left unlinked rather than // guessed at. var target = null; if (compoundWord in links) { target = compoundWord; } else if (lowerSingle in links) { target = lowerSingle; } else if (stems.length >= 2) { target = compoundWord; } if (target && !(target in existingLinks)) { existingLinks[target] = true; tokenWords[j] = "[[" + target + "|" + tokenWords[j] + "]]"; } } break; } if (compoundWord in links) { if ((compoundWord in existingLinks) || ignoredWords[compoundWord]) { j += k; break; } existingLinks[compoundWord] = true; tokenWords[j] = "[[" + tokenWords[j]; tokenWords[j + k] += "]]"; j += k; break; } var lowerWord = compoundWord.linkifyUncapitalize(); if (lowerWord in links) { if ((lowerWord in existingLinks) || ignoredWords[lowerWord]) { j += k; break; } existingLinks[lowerWord] = true; tokenWords[j] = "[[" + lowerWord + "|" + tokenWords[j]; tokenWords[j + k] += "]]"; j += k; break; } word.splice(-1, 1); } } tokens[i] = tokenWords.join(" "); if (debug) { displayTokens[i] = "<b style='border: 1px solid gray;'>" + mw.html.escape(tokens[i]) + "</b>"; } }); if (debug) { $("#linkify-tokens").html("\n" + displayTokens.join("") + "\n"); } callback(tokens.join("")); }).fail(function (error) { console.warn(error); callback(); }); }); } // Regex for a single wikilink: [[target]] or [[target|display]]. Also // matches file/category-style links (e.g. [[File:...]]) the same way as any // other link -- this gadget doesn't try to special-case those, since a user // invoking "remove links" on a stretch of text presumably wants every // [[...]] construct in that stretch unwrapped, not just plain word links. var wikilinkRE = /\[\[([^\]|]*)\|([^\]]*)\]\]|\[\[([^\]|]*)\]\]/g; /** * Strips wikilink markup from text, keeping only the reader-facing text. * [[target|display]] -> display * [[target]] -> target * Unlike $.kuLinkify, this needs no API round-trip: removing markup that's * already there doesn't require checking whether any page exists. */ $.kuDelinkify = function (text) { return text.replace(wikilinkRE, function (match, pipedTarget, pipedDisplay, bareTarget) { return pipedDisplay !== undefined ? pipedDisplay : bareTarget; }); }; // --------------------------------------------------------------- // Letter-case conversion (UPPERCASE / lowercase / Sentence case / // Title Case), adapted from the herfguhartin.js gadget's ku-locale // logic. Unlike that gadget, this one only ever deals with Kurmanji // text, so there's no per-language dotted/dotless-i handling to worry // about -- plain JS toUpperCase()/toLowerCase() already do the right // thing for Kurmanji's Latin letters (a e ê i î o u û plus ç ş, etc). // // For Title Case, this reuses the gadget's own `ignoredWords` list // (the Kurmanji function words already excluded from auto-linking) // as the set of small grammatical words that should stay lowercase, // rather than keeping a second, separately-maintained stopword list. // --------------------------------------------------------------- var KU_LETTER_CLASS = "a-zA-ZçêîşûÇÊÎŞÛ"; var kuNonLetterLeadingRE = new RegExp("^[^" + KU_LETTER_CLASS + "]*"); var kuNonLetterTrailingRE = new RegExp("[^" + KU_LETTER_CLASS + "]*$"); var kuSentenceBreakRE = new RegExp( "(^\\s*[a-zçêîşû]|[.!?][\"'\\)\\]]*\\s+[a-zçêîşû])", "gi" ); function kuCapitalizeFirstLetter(word) { if (word === "") return word; var lowered = word.toLowerCase(); return lowered.charAt(0).toUpperCase() + lowered.slice(1); } function kuToSentenceCase(text) { var lowered = text.toLowerCase(); return lowered.replace(kuSentenceBreakRE, function (match) { var idx = match.length - 1; return match.slice(0, idx) + match.charAt(idx).toUpperCase(); }); } // Capitalizes one "word chunk": handles leading/trailing punctuation // ("(çîroka" -> "(Çîroka"), hyphenated compounds ("kurdî-gerşûnî" -> // "Kurdî-Gerşûnî"), and keeps ignoredWords entries lowercase unless // forced (first word of the text, or right after an opening // bracket/quote). function kuCapitalizeWordChunk(chunk, forceCapitalize) { var leading = (chunk.match(kuNonLetterLeadingRE) || [""])[0]; var trailing = (chunk.match(kuNonLetterTrailingRE) || [""])[0]; var core = chunk.slice(leading.length, chunk.length - trailing.length); if (core === "") return chunk; if (/[(["'‘“]/.test(leading)) forceCapitalize = true; var loweredCore = core.toLowerCase(); var isStopWord = !forceCapitalize && ignoredWords[loweredCore]; var newCore; if (isStopWord) { newCore = loweredCore; } else { newCore = core.split("-").map(function (part) { return kuCapitalizeFirstLetter(part); }).join("-"); } return leading + newCore + trailing; } function kuToTitleCase(text) { var wordIndex = 0; return text.split(/(\s+)/).map(function (chunk) { if (chunk === "" || /^\s+$/.test(chunk)) return chunk; var isFirstWord = wordIndex === 0; wordIndex++; return kuCapitalizeWordChunk(chunk, isFirstWord); }).join(""); } $.kuApplyCase = function (text, form) { switch (form) { case "upper": return text.toUpperCase(); case "lower": return text.toLowerCase(); case "sentence": return kuToSentenceCase(text); case "title": return kuToTitleCase(text); default: return text; } }; function getLinkifyTool() { return { type: "button", action: { type: "callback", execute: function () { mw.loader.using("jquery.textSelection", function () { var selection = $("#wpTextbox1").textSelection("getSelection"); $.kuLinkify(selection, function (linkedText) { if (!linkedText) return; $("#wpTextbox1").textSelection("encapsulateSelection", { peri: linkedText, replace: true }); }, $.kuLinkify_debug); }); } }, label: getMessage("toolbarButtonName"), icon: "//upload.wikimedia.org/wikipedia/commons/b/ba/Norwegian_link_sign.png" }; } // Two link segments with a diagonal strike through them -- distinct from // the linkify tool's chain-link icon, but still visually "link-related" so // its relationship to the linkify button is obvious. Defined as an inline // SVG data URI rather than a Commons file reference, so the icon can't // silently break if a filename on Commons is ever renamed or deleted. var delinkifyIcon = "data:image/svg+xml;utf8," + encodeURIComponent( '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" width="20" height="20">' + '<rect x="2" y="7" width="7" height="6" rx="3" fill="none" stroke="#333" stroke-width="2"/>' + '<rect x="11" y="7" width="7" height="6" rx="3" fill="none" stroke="#333" stroke-width="2"/>' + '<line x1="2" y1="2" x2="18" y2="18" stroke="#d33" stroke-width="2.2" stroke-linecap="round"/>' + '</svg>' ); function getDelinkifyTool() { return { type: "button", action: { type: "callback", execute: function () { mw.loader.using("jquery.textSelection", function () { var selection = $("#wpTextbox1").textSelection("getSelection"); var plainText = $.kuDelinkify(selection); if (plainText === selection) return; $("#wpTextbox1").textSelection("encapsulateSelection", { peri: plainText, replace: true }); }); } }, label: getMessage("delinkifyButtonName"), icon: delinkifyIcon }; } // Applies a case transform to the current textbox selection and writes the // result back in place. Shared by every option in the case-change dropdown. function applyCaseToSelection(form) { mw.loader.using("jquery.textSelection", function () { var selection = $("#wpTextbox1").textSelection("getSelection"); if (!selection) return; var converted = $.kuApplyCase(selection, form); if (converted === selection) return; $("#wpTextbox1").textSelection("encapsulateSelection", { peri: converted, replace: true }); }); } // The built-in wikiEditor "select" tool type (used for e.g. the core // "heading" dropdown) is supposed to close itself both on selecting an // option and on re-clicking its label, but that toggle lives entirely // inside jquery.wikiEditor.toolbar.js and isn't something a gadget can // patch if it misbehaves on a given wiki's deployed version. To make the // close behavior actually reliable, this builds the dropdown by hand as a // wikiEditor "element" tool (a raw DOM element wikiEditor just drops into // the toolbar) and manages its own open/closed state directly, while still // reusing wikiEditor's existing tool-select/label/menu/options/option CSS // classes so it looks identical to a native dropdown. function buildCaseChangeElement() { var forms = [ { key: "upper", label: getMessage("caseUpperLabel") }, { key: "lower", label: getMessage("caseLowerLabel") }, { key: "sentence", label: getMessage("caseSentenceLabel") }, { key: "title", label: getMessage("caseTitleLabel") } ]; var $select = $("<div>").addClass("tool tool-select").attr("rel", "caseChange"); var $options = $("<div>").addClass("options"); var $menu = $("<div>").addClass("menu").append($options).hide(); // Toggling both the class (for anyone's CSS keyed off .options-shown) // and an explicit .show()/.hide() (so the menu is guaranteed to // actually disappear even if that CSS rule is missing or overridden). function closeMenu() { $select.removeClass("options-shown"); $menu.hide(); $label.attr("aria-expanded", "false"); } function openMenu() { // Only one such dropdown open at a time. $(".tool-select").not($select).removeClass("options-shown").find(".menu").hide(); $select.addClass("options-shown"); $menu.show(); $label.attr("aria-expanded", "true"); } $.each(forms, function (i, form) { $("<a>") .addClass("option") .attr({ rel: form.key, tabindex: 0, role: "menuitem" }) .text(form.label) .on("mousedown", function (e) { e.preventDefault(); return false; }) .on("click keydown", function (e) { if (e.type === "click" || (e.type === "keydown" && e.key === "Enter")) { applyCaseToSelection(form.key); closeMenu(); e.preventDefault(); return false; } }) .appendTo($options); }); var $label = $("<a>") .addClass("label skin-invert") .text(getMessage("caseChangeLabel")) .attr({ role: "button", tabindex: 0, "aria-expanded": "false", "aria-haspopup": "menu" }) .on("mousedown", function (e) { e.preventDefault(); return false; }) .on("click keydown", function (e) { if (e.type === "click" || (e.type === "keydown" && e.key === "Enter")) { if ($select.hasClass("options-shown")) { closeMenu(); } else { openMenu(); } e.preventDefault(); return false; } }); $select.append($label, $menu); // Close on any click elsewhere on the page. Namespaced and re-bound // via .off() first so re-registering this tool never stacks up // duplicate document-level handlers. $(document).off("mousedown.kuCaseChange").on("mousedown.kuCaseChange", function (e) { if (!$(e.target).closest($select).length) { closeMenu(); } }); return $select; } function getCaseChangeTool() { return { type: "element", element: buildCaseChangeElement }; } function addLinkifyButton() { var $textbox = $("#wpTextbox1"); // Nothing to attach to on this page (VisualEditor, 2017 editor, non-edit // pages, etc.) — bail out instead of silently binding to an empty set. if (!$textbox.length) return; if ($.kuLinkify) { $textbox.after($(mw.html.element("div", { id: "linkify-progress", title: getMessage("toolbarButtonName") })).hide()); } // A single source of truth for the three tools, so both registration // paths below build identical (but never duplicate) tool objects. function buildTools() { return { linkify: getLinkifyTool(), delinkify: getDelinkifyTool(), caseChange: getCaseChangeTool() }; } // Sends the toolbar-build event and the mw.loader.using("ext.wikiEditor") // callback below race each other -- either the event can fire before // ext.wikiEditor resolves, or (very rarely) the main section can already // be built by the time ext.wikiEditor resolves, having fired and gone // before this script even attached its listener. Exactly one of the two // paths should end up adding the tools; without this flag, both were // firing on ordinary page loads (the event fires during the normal // build, and by the time the mw.loader.using callback runs afterward // context.modules.toolbar already exists too, since it always will once // the toolbar has finished building) -- silently doubling every tool in // the group. var toolsAdded = false; // Bind the listener immediately, synchronously, rather than inside the // mw.loader.using("ext.wikiEditor", ...) callback. If we wait for that // callback to fire before attaching the listener, ext.wikiEditor may // already be loaded and may have already built (and fired the event for) // the main toolbar section by the time our callback runs -- in which case // the event has already come and gone and our button never gets added. // Attaching the listener up front means we won't miss the event even if // ext.wikiEditor resolves "instantly" (e.g. already cached/loaded). $textbox.on('wikiEditor-toolbar-buildSection-main', function (evt, section) { $.extend(section.groups.insert.tools, buildTools()); toolsAdded = true; }); mw.loader.using("ext.wikiEditor", function () { // If the event above already fired (the normal case on every // ordinary page load), the tools are already in place -- don't add // them again. if (toolsAdded) return; // Fallback for the case where the toolbar's main section was already // built (and the event already fired and gone) before this gadget's // script even started executing -- e.g. another gadget loaded // ext.wikiEditor earlier and the toolbar finished initializing // first. In that case the listener above is too late, so we check // whether the toolbar context already exists and, if so, add the // tools directly via the public addToToolbar API instead of waiting // for an event that has already happened. var context = $textbox.data("wikiEditor-context"); if (context && context.modules && context.modules.toolbar) { $textbox.wikiEditor("addToToolbar", { section: "main", group: "insert", tools: buildTools() }); toolsAdded = true; } }); }; // Only try to add the button on pages that actually have an edit form -- // running unconditionally on every page load (including view/history/etc. // pages where #wpTextbox1 never exists) wastes a mw.loader.using round trip // and can look like "sometimes nothing happens" if a user doesn't realize // they weren't on an edit screen. if ($.inArray(mw.config.get("wgAction"), ["edit", "submit"]) !== -1) { addLinkifyButton(); } })(jQuery); leu8n2p5bsf1wwik1tozm8ip1j9whee 6265723 6265722 2026-07-20T01:45:57Z Wikihez 7344 6265723 javascript text/javascript // MediaWiki gadget: automatically link selected text to existing wiktionary entries (function ($) { var messages = { ku: { toolbarButtonName: "Li nivîsa bijartî bi otomatîkî girêdan lê zêde bike", delinkifyButtonName: "Ji nivîsa bijartî girêdanan rake", caseChangeLabel: "Herf biguhêre", caseUpperLabel: "MEZIN (UPPERCASE)", caseLowerLabel: "biçûk (lowercase)", caseSentenceLabel: "Cimle (Sentence case)", caseTitleLabel: "Her Kelîme Mezin (Title Case)" }, en: { toolbarButtonName: "Automatically link selected text", delinkifyButtonName: "Remove links from selected text", caseChangeLabel: "Change letter case", caseUpperLabel: "UPPERCASE", caseLowerLabel: "lowercase", caseSentenceLabel: "Sentence case", caseTitleLabel: "Title Case" }, es: { toolbarButtonName: "Automáticamente insertar enlaces en la selección", delinkifyButtonName: "Quitar enlaces del texto seleccionado", caseChangeLabel: "Cambiar mayúsculas/minúsculas", caseUpperLabel: "MAYÚSCULAS", caseLowerLabel: "minúsculas", caseSentenceLabel: "Case de oración", caseTitleLabel: "Case de Título" } }; // Kurmanji function words (prepositions, conjunctions, pronouns, particles, // demonstratives, copula/negation forms) that should never be turned into // links on their own, even though they're short enough to match compound // candidates during scanning. Also includes all 8 bare Kurmanji vowels // (a, e, ê, i, î, o, u, û) on their own, since a lone vowel is never a // meaningful link target even if it happens to match part of a scan. var ignoredWordList = ( "a|an|ba|bê|bi|çi|çu|çû|da|de|dê|dî|di|e|ê|ên|erê|ev|ew|em|gel|ha|hê|her|" + "hûn|i|î|jê|jî|ka|kî|ku|kû|lê|li|me|min|na|ne|o|pê|re|ra|ti|te|tê|" + "tu|u|û|va|van|ve|vê|vî|wan|we|wê|wî|wir|vir|ya|yan|yê|yên" ).split("|"); var ignoredWords = {}; $.each(ignoredWordList, function (i, word) { ignoredWords[word] = true; }); /** * One less than the maximum number of syllables to be considered as a compound * word. */ var lookahead = 2; // Tokenizer boundary class: standard uppercase Latin A-Z plus the Kurmanji // Latin alphabet's diacritic letters (both cases: Ç ç, Ê ê, Î î, Ş ş, Û û), // combining diacritical marks, and wiki markup delimiters. var tokenRE = /(\s*(?:<!--[\s\S]+?-->|\{\{[\s\S]+?\}\}|\[\[.+?\]\]|[^A-ZÇÊÎŞÛçêîşû\u0300-\u036F{[< ]+|[{[<])\s*)/i; String.prototype.linkifyUncapitalize = function () { return this[0].toLowerCase() + this.substr(1); }; // Common Kurmanji noun-declension suffixes (indefinite/definite, // nominative/construct/oblique/vocative -- see Module:ku-nouns' // declSimpleNoun), longest first so the greedy match below prefers the // most specific ending (e.g. "eke" before a bare "e"). // // This list is intentionally generous rather than grammatically precise: // unlike declSimpleNoun, the gadget doesn't know a word's gender or its // exact stem class when scanning arbitrary running text, so it can't // reproduce that branching logic exactly. Instead, every candidate root // produced here is verified against real wiktionary entries via the API // before it's ever used (see the "stems" check below) -- so an // over-aggressive strip that doesn't correspond to a genuine entry is // simply discarded, never turned into a bad link. var nounSuffixes = [ "iyekî", "iyekê", "iyeke", "iyinan", "iyino", "yekî", "yekê", "yeke", "yinan", "yino", "ekî", "ekê", "eke", "inan", "ine", "ino", "iyên", "iyan", "iyek", "iyin", "iyo", "iyî", "iyê", "iya", "yên", "yan", "yek", "yin", "yo", "yî", "yê", "ya", "ek", "ên", "an", "in", "a", "ê", "î", "o" ]; /** * Given a lowercase surface word, returns candidate noun roots obtained by * stripping a known declension suffix -- e.g. "rûpeleke" -> ["rûpel"]. * Candidates are ordered from least- to most-aggressively stripped (longest * remaining root first), so that when several candidates turn out to match * real entries, the safer/more specific one wins. */ function getNounStemCandidates(word) { var candidates = []; for (var i = 0; i < nounSuffixes.length; i++) { var suf = nounSuffixes[i]; // Require at least a 2-character root left over, so we don't // generate degenerate single-letter "roots". if (word.length > suf.length + 1 && word.slice(-suf.length) === suf) { candidates.push(word.slice(0, -suf.length)); } } // Orthographic correction: a root ending in î drops its circumflex when // it meets a glide suffix starting with y -- "giranî" + "yê" spells as // "giraniyê", not "giranîyê". Stripping the short suffix "yê" from that // surface form literally gives "girani" (bare i); stripping the longer // "iyê" suffix instead gives the shorter, unrelated root "giran". Since // the î-final noun is the actual root in this pattern, also offer the // î-restored form as a candidate for any stripped result ending in a // bare "i" -- e.g. "girani" -> "giranî". Because it's one character // longer than the "iyê"-derived candidate, the length-based sort below // naturally tries it first. var restored = []; $.each(candidates, function (idx, root) { if (root.length > 1 && root.slice(-1) === "i") { restored.push(root.slice(0, -1) + "î"); } }); candidates = candidates.concat(restored); candidates.sort(function (a, b) { return b.length - a.length; }); return candidates; } var userLang = mw.config.get("wgUserLanguage"); function getMessage(name) { return (messages[userLang] || messages.ku)[name] || messages.ku[name]; } $.kuLinkify = function (text, callback, debug) { var tokens = text.split(tokenRE); var displayTokens = []; var words = {}; var existingLinks = {}; // Maps a surface word (as typed, and its lowercase form) to candidate // noun roots -- e.g. stemCandidates["rûpeleke"] = ["rûpel"]. Filled in // below and consulted during reconstruction so an inflected word whose // exact surface form has no entry can still be linked to its root. var stemCandidates = {}; $.each(tokens, function (i, token) { if (debug) displayTokens.push(mw.html.escape(token)); var tokenLinks = token.match(/\[\[.+?(?:\|.+?)?\]\]/g); $.each(tokenLinks || [], function () { existingLinks[this.match(/\[\[(.+?)(?:\|.+?)?\]\]/)[1]] = true; }); if (!token || token.match(tokenRE)) return; var tokenWords = token.split(" "); $.each(tokenWords, function (j, word) { for (var k = 0; k < lookahead + 1 && tokenWords[j + k]; k++) { if (k) word += " " + tokenWords[j + k]; if (!ignoredWords[word]) words[word] = true; if (word[0] != word[0].toLowerCase()) { var lowerWord = word.linkifyUncapitalize(); if (!ignoredWords[lowerWord]) { words[lowerWord] = true; } } } }); // Also collect candidate noun roots for every individual word (not // multi-word compounds -- declension endings attach to a single // word), so inflected forms like "rûpeleke" can still be linked to // an existing root entry like "rûpel" even when the inflected form // itself has no entry. $.each(tokenWords, function (j, word) { if (!word) return; var lower = word.linkifyUncapitalize(); var stems = getNounStemCandidates(lower); if (stems.length) { stemCandidates[word] = stems; $.each(stems, function (s, stem) { if (!ignoredWords[stem]) words[stem] = true; }); } }); if (debug) { displayTokens[i] = "<b style='border: 1px solid gray;'>" + mw.html.escape(token) + "</b>"; } }); var uniqueWords = []; $.each(words, function (word) { if (!ignoredWords[word]) uniqueWords.push(word); }); if (debug) { var uniqueLinks = []; $.each(existingLinks, function (link) { uniqueLinks.push(link); }); var list = "<pre id='linkify-tokens'>\n" + displayTokens.join("") + "\n</pre>"; list += "<hr /><p>Words to search for:</p><p>" + uniqueWords + "</p>"; list += "<hr /><p>Words that already have links:</p><p>" + uniqueLinks + "</p>"; $("#linkify-progress").html(list).dialog({modal: true}); } if (!uniqueWords.length) return; mw.loader.using("mediawiki.api", function () { var api = new mw.Api(); api.get({ action: "parse", text: "[[" + uniqueWords.join("]] [[") + "]]", prop: "links" }).done(function (results) { $("#linkify-progress").append("<hr />"); var displayLinks = []; var links = {}; $.each(results.parse.links, function () { if (debug && "exists" in this) displayLinks.push(this["*"]); if ("exists" in this) links[this["*"]] = true; }); if (debug) { $("#linkify-progress").append("<p>Existing entries:</p><p>" + displayLinks + "</p>"); } $.each(tokens, function (i, token) { if (!token || token.match(tokenRE)) return; var tokenWords = token.split(" "); for (var j = 0; j < tokenWords.length; j++) { var word = []; for (var k = 0; k < lookahead + 1; k++) { word.push(tokenWords[j + k]); } for (var k = lookahead; k >= 0; k--) { var compoundWord = word.join(" "); if (k === 0) { var lowerSingle = compoundWord.linkifyUncapitalize(); // 1. Prefer linking to the declension root (lemma) // over the inflected surface form's own page -- // e.g. link "pîvana" as [[pîvan|pîvana]] rather // than [[pîvana]], since wiktionary entries for // inflected forms are usually secondary "form of" // pages rather than the main lemma readers want. var stems = stemCandidates[compoundWord] || stemCandidates[lowerSingle] || []; var stemLinked = false; for (var s = 0; s < stems.length; s++) { var stem = stems[s]; if ((stem in links) && !(stem in existingLinks) && !ignoredWords[stem]) { existingLinks[stem] = true; tokenWords[j] = "[[" + stem + "|" + tokenWords[j] + "]]"; stemLinked = true; break; } } if (stemLinked) break; if (!ignoredWords[compoundWord] && !ignoredWords[lowerSingle]) { // 2. No usable root. If the word (or its // lowercase form) is itself a confirmed // entry, link it normally -- this is a real // match, not a guess. Otherwise, only add a // speculative self-link -- always piped // (target|display), even though target and // display are identical text, so a reader // who spots a wrong link can simply edit the // part before the "|" -- when the word's // shape actually looks like an inflected // noun (it matched at least two different // candidate declension suffixes). A word // that matched zero or only one suffix isn't // strong enough evidence that it's inflected // at all, so it's left unlinked rather than // guessed at. var target = null; if (compoundWord in links) { target = compoundWord; } else if (lowerSingle in links) { target = lowerSingle; } else if (stems.length >= 2) { target = compoundWord; } if (target && !(target in existingLinks)) { existingLinks[target] = true; tokenWords[j] = "[[" + target + "|" + tokenWords[j] + "]]"; } } break; } if (compoundWord in links) { if ((compoundWord in existingLinks) || ignoredWords[compoundWord]) { j += k; break; } existingLinks[compoundWord] = true; tokenWords[j] = "[[" + tokenWords[j]; tokenWords[j + k] += "]]"; j += k; break; } var lowerWord = compoundWord.linkifyUncapitalize(); if (lowerWord in links) { if ((lowerWord in existingLinks) || ignoredWords[lowerWord]) { j += k; break; } existingLinks[lowerWord] = true; tokenWords[j] = "[[" + lowerWord + "|" + tokenWords[j]; tokenWords[j + k] += "]]"; j += k; break; } word.splice(-1, 1); } } tokens[i] = tokenWords.join(" "); if (debug) { displayTokens[i] = "<b style='border: 1px solid gray;'>" + mw.html.escape(tokens[i]) + "</b>"; } }); if (debug) { $("#linkify-tokens").html("\n" + displayTokens.join("") + "\n"); } callback(tokens.join("")); }).fail(function (error) { console.warn(error); callback(); }); }); } // Regex for a single wikilink: [[target]] or [[target|display]]. Also // matches file/category-style links (e.g. [[File:...]]) the same way as any // other link -- this gadget doesn't try to special-case those, since a user // invoking "remove links" on a stretch of text presumably wants every // [[...]] construct in that stretch unwrapped, not just plain word links. var wikilinkRE = /\[\[([^\]|]*)\|([^\]]*)\]\]|\[\[([^\]|]*)\]\]/g; /** * Strips wikilink markup from text, keeping only the reader-facing text. * [[target|display]] -> display * [[target]] -> target * Unlike $.kuLinkify, this needs no API round-trip: removing markup that's * already there doesn't require checking whether any page exists. */ $.kuDelinkify = function (text) { return text.replace(wikilinkRE, function (match, pipedTarget, pipedDisplay, bareTarget) { return pipedDisplay !== undefined ? pipedDisplay : bareTarget; }); }; // --------------------------------------------------------------- // Letter-case conversion (UPPERCASE / lowercase / Sentence case / // Title Case), adapted from the herfguhartin.js gadget's ku-locale // logic. Unlike that gadget, this one only ever deals with Kurmanji // text, so there's no per-language dotted/dotless-i handling to worry // about -- plain JS toUpperCase()/toLowerCase() already do the right // thing for Kurmanji's Latin letters (a e ê i î o u û plus ç ş, etc). // // For Title Case, this reuses the gadget's own `ignoredWords` list // (the Kurmanji function words already excluded from auto-linking) // as the set of small grammatical words that should stay lowercase, // rather than keeping a second, separately-maintained stopword list. // --------------------------------------------------------------- var KU_LETTER_CLASS = "a-zA-ZçêîşûÇÊÎŞÛ"; var kuNonLetterLeadingRE = new RegExp("^[^" + KU_LETTER_CLASS + "]*"); var kuNonLetterTrailingRE = new RegExp("[^" + KU_LETTER_CLASS + "]*$"); var kuSentenceBreakRE = new RegExp( "(^\\s*[a-zçêîşû]|[.!?][\"'\\)\\]]*\\s+[a-zçêîşû])", "gi" ); function kuCapitalizeFirstLetter(word) { if (word === "") return word; var lowered = word.toLowerCase(); return lowered.charAt(0).toUpperCase() + lowered.slice(1); } function kuToSentenceCase(text) { var lowered = text.toLowerCase(); return lowered.replace(kuSentenceBreakRE, function (match) { var idx = match.length - 1; return match.slice(0, idx) + match.charAt(idx).toUpperCase(); }); } // Capitalizes one "word chunk": handles leading/trailing punctuation // ("(çîroka" -> "(Çîroka"), hyphenated compounds ("kurdî-gerşûnî" -> // "Kurdî-Gerşûnî"), and keeps ignoredWords entries lowercase unless // forced (first word of the text, or right after an opening // bracket/quote). function kuCapitalizeWordChunk(chunk, forceCapitalize) { var leading = (chunk.match(kuNonLetterLeadingRE) || [""])[0]; var trailing = (chunk.match(kuNonLetterTrailingRE) || [""])[0]; var core = chunk.slice(leading.length, chunk.length - trailing.length); if (core === "") return chunk; if (/[(["'‘“]/.test(leading)) forceCapitalize = true; var loweredCore = core.toLowerCase(); var isStopWord = !forceCapitalize && ignoredWords[loweredCore]; var newCore; if (isStopWord) { newCore = loweredCore; } else { newCore = core.split("-").map(function (part) { return kuCapitalizeFirstLetter(part); }).join("-"); } return leading + newCore + trailing; } function kuToTitleCase(text) { var wordIndex = 0; return text.split(/(\s+)/).map(function (chunk) { if (chunk === "" || /^\s+$/.test(chunk)) return chunk; var isFirstWord = wordIndex === 0; wordIndex++; return kuCapitalizeWordChunk(chunk, isFirstWord); }).join(""); } $.kuApplyCase = function (text, form) { switch (form) { case "upper": return text.toUpperCase(); case "lower": return text.toLowerCase(); case "sentence": return kuToSentenceCase(text); case "title": return kuToTitleCase(text); default: return text; } }; function getLinkifyTool() { return { type: "button", action: { type: "callback", execute: function () { mw.loader.using("jquery.textSelection", function () { var selection = $("#wpTextbox1").textSelection("getSelection"); $.kuLinkify(selection, function (linkedText) { if (!linkedText) return; $("#wpTextbox1").textSelection("encapsulateSelection", { peri: linkedText, replace: true }); }, $.kuLinkify_debug); }); } }, label: getMessage("toolbarButtonName"), icon: "//upload.wikimedia.org/wikipedia/commons/b/ba/Norwegian_link_sign.png" }; } // Two link segments with a diagonal strike through them -- distinct from // the linkify tool's chain-link icon, but still visually "link-related" so // its relationship to the linkify button is obvious. Defined as an inline // SVG data URI rather than a Commons file reference, so the icon can't // silently break if a filename on Commons is ever renamed or deleted. var delinkifyIcon = "data:image/svg+xml;utf8," + encodeURIComponent( '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" width="20" height="20">' + '<rect x="2" y="7" width="7" height="6" rx="3" fill="none" stroke="#333" stroke-width="2"/>' + '<rect x="11" y="7" width="7" height="6" rx="3" fill="none" stroke="#333" stroke-width="2"/>' + '<line x1="2" y1="2" x2="18" y2="18" stroke="#d33" stroke-width="2.2" stroke-linecap="round"/>' + '</svg>' ); function getDelinkifyTool() { return { type: "button", action: { type: "callback", execute: function () { mw.loader.using("jquery.textSelection", function () { var selection = $("#wpTextbox1").textSelection("getSelection"); var plainText = $.kuDelinkify(selection); if (plainText === selection) return; $("#wpTextbox1").textSelection("encapsulateSelection", { peri: plainText, replace: true }); }); } }, label: getMessage("delinkifyButtonName"), icon: delinkifyIcon }; } // Applies a case transform to the current textbox selection and writes the // result back in place. Shared by every option in the case-change dropdown. function applyCaseToSelection(form) { mw.loader.using("jquery.textSelection", function () { var selection = $("#wpTextbox1").textSelection("getSelection"); if (!selection) return; var converted = $.kuApplyCase(selection, form); if (converted === selection) return; $("#wpTextbox1").textSelection("encapsulateSelection", { peri: converted, replace: true }); }); } // The built-in wikiEditor "select" tool type (used for e.g. the core // "heading" dropdown) is supposed to close itself both on selecting an // option and on re-clicking its label, but that toggle lives entirely // inside jquery.wikiEditor.toolbar.js and isn't something a gadget can // patch if it misbehaves on a given wiki's deployed version. To make the // close behavior actually reliable, this builds the dropdown by hand as a // wikiEditor "element" tool (a raw DOM element wikiEditor just drops into // the toolbar) and manages its own open/closed state directly, while still // reusing wikiEditor's existing tool-select/label/menu/options/option CSS // classes so it looks identical to a native dropdown. function buildCaseChangeElement() { var forms = [ { key: "upper", label: getMessage("caseUpperLabel") }, { key: "lower", label: getMessage("caseLowerLabel") }, { key: "sentence", label: getMessage("caseSentenceLabel") }, { key: "title", label: getMessage("caseTitleLabel") } ]; var $select = $("<div>").addClass("tool tool-select").attr("rel", "caseChange"); var $options = $("<div>").addClass("options"); var $menu = $("<div>").addClass("menu").append($options).hide(); // Toggling both the class (for anyone's CSS keyed off .options-shown) // and an explicit .show()/.hide() (so the menu is guaranteed to // actually disappear even if that CSS rule is missing or overridden). function closeMenu() { $select.removeClass("options-shown"); $menu.hide(); $label.attr("aria-expanded", "false"); } function openMenu() { // Only one such dropdown open at a time. $(".tool-select").not($select).removeClass("options-shown").find(".menu").hide(); $select.addClass("options-shown"); $menu.show(); $label.attr("aria-expanded", "true"); } $.each(forms, function (i, form) { $("<a>") .addClass("option") .attr({ rel: form.key, tabindex: 0, role: "menuitem" }) .text(form.label) .on("mousedown", function (e) { e.preventDefault(); return false; }) .on("click keydown", function (e) { if (e.type === "click" || (e.type === "keydown" && e.key === "Enter")) { applyCaseToSelection(form.key); closeMenu(); e.preventDefault(); return false; } }) .appendTo($options); }); var $label = $("<a>") .addClass("label skin-invert") .text(getMessage("caseChangeLabel")) .attr({ role: "button", tabindex: 0, "aria-expanded": "false", "aria-haspopup": "menu" }) .on("mousedown", function (e) { e.preventDefault(); return false; }) .on("click keydown", function (e) { if (e.type === "click" || (e.type === "keydown" && e.key === "Enter")) { if ($select.hasClass("options-shown")) { closeMenu(); } else { openMenu(); } e.preventDefault(); return false; } }); $select.append($label, $menu); // Close on any click elsewhere on the page. Namespaced and re-bound // via .off() first so re-registering this tool never stacks up // duplicate document-level handlers. $(document).off("mousedown.kuCaseChange").on("mousedown.kuCaseChange", function (e) { if (!$(e.target).closest($select).length) { closeMenu(); } }); return $select; } function getCaseChangeTool() { return { type: "element", element: buildCaseChangeElement }; } function addLinkifyButton() { var $textbox = $("#wpTextbox1"); // Nothing to attach to on this page (VisualEditor, 2017 editor, non-edit // pages, etc.) — bail out instead of silently binding to an empty set. if (!$textbox.length) return; if ($.kuLinkify) { $textbox.after($(mw.html.element("div", { id: "linkify-progress", title: getMessage("toolbarButtonName") })).hide()); } // A single source of truth for the three tools, so both registration // paths below build identical (but never duplicate) tool objects. function buildTools() { return { linkify: getLinkifyTool(), delinkify: getDelinkifyTool(), caseChange: getCaseChangeTool() }; } // Sends the toolbar-build event and the mw.loader.using("ext.wikiEditor") // callback below race each other -- either the event can fire before // ext.wikiEditor resolves, or (very rarely) the main section can already // be built by the time ext.wikiEditor resolves, having fired and gone // before this script even attached its listener. Exactly one of the two // paths should end up adding the tools; without this flag, both were // firing on ordinary page loads (the event fires during the normal // build, and by the time the mw.loader.using callback runs afterward // context.modules.toolbar already exists too, since it always will once // the toolbar has finished building) -- silently doubling every tool in // the group. var toolsAdded = false; // Bind the listener immediately, synchronously, rather than inside the // mw.loader.using("ext.wikiEditor", ...) callback. If we wait for that // callback to fire before attaching the listener, ext.wikiEditor may // already be loaded and may have already built (and fired the event for) // the main toolbar section by the time our callback runs -- in which case // the event has already come and gone and our button never gets added. // Attaching the listener up front means we won't miss the event even if // ext.wikiEditor resolves "instantly" (e.g. already cached/loaded). $textbox.on('wikiEditor-toolbar-buildSection-main', function (evt, section) { $.extend(section.groups.insert.tools, buildTools()); toolsAdded = true; }); mw.loader.using("ext.wikiEditor", function () { // If the event above already fired (the normal case on every // ordinary page load), the tools are already in place -- don't add // them again. if (toolsAdded) return; // Fallback for the case where the toolbar's main section was already // built (and the event already fired and gone) before this gadget's // script even started executing -- e.g. another gadget loaded // ext.wikiEditor earlier and the toolbar finished initializing // first. In that case the listener above is too late, so we check // whether the toolbar context already exists and, if so, add the // tools directly via the public addToToolbar API instead of waiting // for an event that has already happened. var context = $textbox.data("wikiEditor-context"); if (context && context.modules && context.modules.toolbar) { $textbox.wikiEditor("addToToolbar", { section: "main", group: "insert", tools: buildTools() }); toolsAdded = true; } }); }; // Only try to add the button on pages that actually have an edit form -- // running unconditionally on every page load (including view/history/etc. // pages where #wpTextbox1 never exists) wastes a mw.loader.using round trip // and can look like "sometimes nothing happens" if a user doesn't realize // they weren't on an edit screen. if ($.inArray(mw.config.get("wgAction"), ["edit", "submit"]) !== -1) { addLinkifyButton(); } })(jQuery); iezq9ya6cvrpz78ji2645a0wtia4yuy 6265724 6265723 2026-07-20T05:16:34Z Wikihez 7344 6265724 javascript text/javascript // MediaWiki gadget: automatically link selected text to existing wiktionary entries (function ($) { var messages = { ku: { toolbarButtonName: "Li nivîsa bijartî bi otomatîkî girêdan lê zêde bike", delinkifyButtonName: "Ji nivîsa bijartî girêdanan rake", caseChangeLabel: "Herf biguhêre", caseUpperLabel: "MEZIN (UPPERCASE)", caseLowerLabel: "biçûk (lowercase)", caseSentenceLabel: "Cimle (Sentence case)", caseTitleLabel: "Her Kelîme Mezin (Title Case)" }, en: { toolbarButtonName: "Automatically link selected text", delinkifyButtonName: "Remove links from selected text", caseChangeLabel: "Change letter case", caseUpperLabel: "UPPERCASE", caseLowerLabel: "lowercase", caseSentenceLabel: "Sentence case", caseTitleLabel: "Title Case" }, es: { toolbarButtonName: "Automáticamente insertar enlaces en la selección", delinkifyButtonName: "Quitar enlaces del texto seleccionado", caseChangeLabel: "Cambiar mayúsculas/minúsculas", caseUpperLabel: "MAYÚSCULAS", caseLowerLabel: "minúsculas", caseSentenceLabel: "Case de oración", caseTitleLabel: "Case de Título" } }; // Kurmanji function words (prepositions, conjunctions, pronouns, particles, // demonstratives, copula/negation forms) that should never be turned into // links on their own, even though they're short enough to match compound // candidates during scanning. Also includes all 8 bare Kurmanji vowels // (a, e, ê, i, î, o, u, û) on their own, since a lone vowel is never a // meaningful link target even if it happens to match part of a scan. var ignoredWordList = ( "a|an|ba|bê|bi|çi|çu|çû|da|de|dê|dî|di|e|ê|ên|erê|ev|ew|em|gel|ha|hê|her|" + "hûn|i|î|jê|jî|ka|kî|ku|kû|lê|li|me|min|na|ne|o|pê|re|ra|ti|te|tê|" + "tu|u|û|va|van|ve|vê|vî|wan|we|wê|wî|wir|vir|ya|yan|yê|yên" ).split("|"); var ignoredWords = {}; $.each(ignoredWordList, function (i, word) { ignoredWords[word] = true; }); /** * One less than the maximum number of syllables to be considered as a compound * word. */ var lookahead = 2; // Tokenizer boundary class: standard uppercase Latin A-Z plus the Kurmanji // Latin alphabet's diacritic letters (both cases: Ç ç, Ê ê, Î î, Ş ş, Û û), // combining diacritical marks, and wiki markup delimiters. var tokenRE = /(\s*(?:<!--[\s\S]+?-->|\{\{[\s\S]+?\}\}|\[\[.+?\]\]|[^A-ZÇÊÎŞÛçêîşû\u0300-\u036F{[< ]+|[{[<])\s*)/i; String.prototype.linkifyUncapitalize = function () { return this[0].toLowerCase() + this.substr(1); }; // Common Kurmanji noun-declension suffixes (indefinite/definite, // nominative/construct/oblique/vocative -- see Module:ku-nouns' // declSimpleNoun), longest first so the greedy match below prefers the // most specific ending (e.g. "eke" before a bare "e"). // // This list is intentionally generous rather than grammatically precise: // unlike declSimpleNoun, the gadget doesn't know a word's gender or its // exact stem class when scanning arbitrary running text, so it can't // reproduce that branching logic exactly. Instead, every candidate root // produced here is verified against real wiktionary entries via the API // before it's ever used (see the "stems" check below) -- so an // over-aggressive strip that doesn't correspond to a genuine entry is // simply discarded, never turned into a bad link. var nounSuffixes = [ "iyekî", "iyekê", "iyeke", "iyinan", "iyino", "yekî", "yekê", "yeke", "yinan", "yino", "ekî", "ekê", "eke", "inan", "ine", "ino", "iyên", "iyan", "iyek", "iyin", "iyo", "iyî", "iyê", "iya", "yên", "yan", "yek", "yin", "yo", "yî", "yê", "ya", "ek", "ên", "an", "in", "a", "ê", "î", "o" ]; /** * Given a lowercase surface word, returns candidate noun roots obtained by * stripping a known declension suffix -- e.g. "rûpeleke" -> ["rûpel"]. * Candidates are ordered from least- to most-aggressively stripped (longest * remaining root first), so that when several candidates turn out to match * real entries, the safer/more specific one wins. */ function getNounStemCandidates(word) { var candidates = []; for (var i = 0; i < nounSuffixes.length; i++) { var suf = nounSuffixes[i]; // Require at least a 2-character root left over, so we don't // generate degenerate single-letter "roots". if (word.length > suf.length + 1 && word.slice(-suf.length) === suf) { candidates.push(word.slice(0, -suf.length)); } } // Orthographic correction: a root ending in î drops its circumflex when // it meets a glide suffix starting with y -- "giranî" + "yê" spells as // "giraniyê", not "giranîyê". Stripping the short suffix "yê" from that // surface form literally gives "girani" (bare i); stripping the longer // "iyê" suffix instead gives the shorter, unrelated root "giran". Since // the î-final noun is the actual root in this pattern, also offer the // î-restored form as a candidate for any stripped result ending in a // bare "i" -- e.g. "girani" -> "giranî". Because it's one character // longer than the "iyê"-derived candidate, the length-based sort below // naturally tries it first. var restored = []; $.each(candidates, function (idx, root) { if (root.length > 1 && root.slice(-1) === "i") { restored.push(root.slice(0, -1) + "î"); } }); candidates = candidates.concat(restored); candidates.sort(function (a, b) { return b.length - a.length; }); return candidates; } var userLang = mw.config.get("wgUserLanguage"); function getMessage(name) { return (messages[userLang] || messages.ku)[name] || messages.ku[name]; } $.kuLinkify = function (text, callback, debug) { var tokens = text.split(tokenRE); var displayTokens = []; var words = {}; var existingLinks = {}; // Maps a surface word (as typed, and its lowercase form) to candidate // noun roots -- e.g. stemCandidates["rûpeleke"] = ["rûpel"]. Filled in // below and consulted during reconstruction so an inflected word whose // exact surface form has no entry can still be linked to its root. var stemCandidates = {}; $.each(tokens, function (i, token) { if (debug) displayTokens.push(mw.html.escape(token)); var tokenLinks = token.match(/\[\[.+?(?:\|.+?)?\]\]/g); $.each(tokenLinks || [], function () { existingLinks[this.match(/\[\[(.+?)(?:\|.+?)?\]\]/)[1]] = true; }); if (!token || token.match(tokenRE)) return; var tokenWords = token.split(" "); $.each(tokenWords, function (j, word) { for (var k = 0; k < lookahead + 1 && tokenWords[j + k]; k++) { if (k) word += " " + tokenWords[j + k]; if (!ignoredWords[word]) words[word] = true; if (word[0] != word[0].toLowerCase()) { var lowerWord = word.linkifyUncapitalize(); if (!ignoredWords[lowerWord]) { words[lowerWord] = true; } } } }); // Also collect candidate noun roots for every individual word (not // multi-word compounds -- declension endings attach to a single // word), so inflected forms like "rûpeleke" can still be linked to // an existing root entry like "rûpel" even when the inflected form // itself has no entry. $.each(tokenWords, function (j, word) { if (!word) return; var lower = word.linkifyUncapitalize(); var stems = getNounStemCandidates(lower); if (stems.length) { stemCandidates[word] = stems; $.each(stems, function (s, stem) { if (!ignoredWords[stem]) words[stem] = true; }); } }); if (debug) { displayTokens[i] = "<b style='border: 1px solid gray;'>" + mw.html.escape(token) + "</b>"; } }); var uniqueWords = []; $.each(words, function (word) { if (!ignoredWords[word]) uniqueWords.push(word); }); if (debug) { var uniqueLinks = []; $.each(existingLinks, function (link) { uniqueLinks.push(link); }); var list = "<pre id='linkify-tokens'>\n" + displayTokens.join("") + "\n</pre>"; list += "<hr /><p>Words to search for:</p><p>" + uniqueWords + "</p>"; list += "<hr /><p>Words that already have links:</p><p>" + uniqueLinks + "</p>"; $("#linkify-progress").html(list).dialog({modal: true}); } if (!uniqueWords.length) return; mw.loader.using("mediawiki.api", function () { var api = new mw.Api(); api.get({ action: "parse", text: "[[" + uniqueWords.join("]] [[") + "]]", prop: "links" }).done(function (results) { $("#linkify-progress").append("<hr />"); var displayLinks = []; var links = {}; $.each(results.parse.links, function () { if (debug && "exists" in this) displayLinks.push(this["*"]); if ("exists" in this) links[this["*"]] = true; }); if (debug) { $("#linkify-progress").append("<p>Existing entries:</p><p>" + displayLinks + "</p>"); } $.each(tokens, function (i, token) { if (!token || token.match(tokenRE)) return; var tokenWords = token.split(" "); for (var j = 0; j < tokenWords.length; j++) { var word = []; for (var k = 0; k < lookahead + 1; k++) { word.push(tokenWords[j + k]); } for (var k = lookahead; k >= 0; k--) { var compoundWord = word.join(" "); if (k === 0) { var lowerSingle = compoundWord.linkifyUncapitalize(); // 1. Prefer linking to the declension root (lemma) // over the inflected surface form's own page -- // e.g. link "pîvana" as [[pîvan|pîvana]] rather // than [[pîvana]], since wiktionary entries for // inflected forms are usually secondary "form of" // pages rather than the main lemma readers want. var stems = stemCandidates[compoundWord] || stemCandidates[lowerSingle] || []; var stemLinked = false; for (var s = 0; s < stems.length; s++) { var stem = stems[s]; if ((stem in links) && !(stem in existingLinks) && !ignoredWords[stem]) { existingLinks[stem] = true; tokenWords[j] = "[[" + stem + "|" + tokenWords[j] + "]]"; stemLinked = true; break; } } if (stemLinked) break; if (!ignoredWords[compoundWord] && !ignoredWords[lowerSingle]) { // 2. No usable root. If the word (or its // lowercase form) is itself a confirmed // entry, link it normally -- this is a real // match, not a guess. Otherwise, only add a // speculative self-link -- always piped // (target|display), even though target and // display are identical text, so a reader // who spots a wrong link can simply edit the // part before the "|" -- when the word's // shape actually looks like an inflected // noun (it matched at least two different // candidate declension suffixes). A word // that matched zero or only one suffix isn't // strong enough evidence that it's inflected // at all, so it's left unlinked rather than // guessed at. var target = null; if (compoundWord in links) { target = compoundWord; } else if (lowerSingle in links) { target = lowerSingle; } else if (stems.length >= 2) { target = compoundWord; } if (target && !(target in existingLinks)) { existingLinks[target] = true; tokenWords[j] = "[[" + target + "|" + tokenWords[j] + "]]"; } } break; } if (compoundWord in links) { if ((compoundWord in existingLinks) || ignoredWords[compoundWord]) { j += k; break; } existingLinks[compoundWord] = true; tokenWords[j] = "[[" + tokenWords[j]; tokenWords[j + k] += "]]"; j += k; break; } var lowerWord = compoundWord.linkifyUncapitalize(); if (lowerWord in links) { if ((lowerWord in existingLinks) || ignoredWords[lowerWord]) { j += k; break; } existingLinks[lowerWord] = true; tokenWords[j] = "[[" + lowerWord + "|" + tokenWords[j]; tokenWords[j + k] += "]]"; j += k; break; } word.splice(-1, 1); } } tokens[i] = tokenWords.join(" "); if (debug) { displayTokens[i] = "<b style='border: 1px solid gray;'>" + mw.html.escape(tokens[i]) + "</b>"; } }); if (debug) { $("#linkify-tokens").html("\n" + displayTokens.join("") + "\n"); } callback(tokens.join("")); }).fail(function (error) { console.warn(error); callback(); }); }); } // Regex for a single wikilink: [[target]] or [[target|display]]. Also // matches file/category-style links (e.g. [[File:...]]) the same way as any // other link -- this gadget doesn't try to special-case those, since a user // invoking "remove links" on a stretch of text presumably wants every // [[...]] construct in that stretch unwrapped, not just plain word links. var wikilinkRE = /\[\[([^\]|]*)\|([^\]]*)\]\]|\[\[([^\]|]*)\]\]/g; /** * Strips wikilink markup from text, keeping only the reader-facing text. * [[target|display]] -> display * [[target]] -> target * Unlike $.kuLinkify, this needs no API round-trip: removing markup that's * already there doesn't require checking whether any page exists. */ $.kuDelinkify = function (text) { return text.replace(wikilinkRE, function (match, pipedTarget, pipedDisplay, bareTarget) { return pipedDisplay !== undefined ? pipedDisplay : bareTarget; }); }; // --------------------------------------------------------------- // Letter-case conversion (UPPERCASE / lowercase / Sentence case / // Title Case), adapted from the herfguhartin.js gadget's ku-locale // logic. Unlike that gadget, this one only ever deals with Kurmanji // text, so there's no per-language dotted/dotless-i handling to worry // about -- plain JS toUpperCase()/toLowerCase() already do the right // thing for Kurmanji's Latin letters (a e ê i î o u û plus ç ş, etc). // // For Title Case, this reuses the gadget's own `ignoredWords` list // (the Kurmanji function words already excluded from auto-linking) // as the set of small grammatical words that should stay lowercase, // rather than keeping a second, separately-maintained stopword list. // --------------------------------------------------------------- var KU_LETTER_CLASS = "a-zA-ZçêîşûÇÊÎŞÛ"; var kuNonLetterLeadingRE = new RegExp("^[^" + KU_LETTER_CLASS + "]*"); var kuNonLetterTrailingRE = new RegExp("[^" + KU_LETTER_CLASS + "]*$"); var kuSentenceBreakRE = new RegExp( "(^\\s*[a-zçêîşû]|[.!?][\"'\\)\\]]*\\s+[a-zçêîşû])", "gi" ); function kuCapitalizeFirstLetter(word) { if (word === "") return word; var lowered = word.toLowerCase(); return lowered.charAt(0).toUpperCase() + lowered.slice(1); } function kuToSentenceCase(text) { var lowered = text.toLowerCase(); return lowered.replace(kuSentenceBreakRE, function (match) { var idx = match.length - 1; return match.slice(0, idx) + match.charAt(idx).toUpperCase(); }); } // Capitalizes one "word chunk": handles leading/trailing punctuation // ("(çîroka" -> "(Çîroka"), hyphenated compounds ("kurdî-gerşûnî" -> // "Kurdî-Gerşûnî"), and keeps ignoredWords entries lowercase unless // forced (first word of the text, or right after an opening // bracket/quote). function kuCapitalizeWordChunk(chunk, forceCapitalize) { var leading = (chunk.match(kuNonLetterLeadingRE) || [""])[0]; var trailing = (chunk.match(kuNonLetterTrailingRE) || [""])[0]; var core = chunk.slice(leading.length, chunk.length - trailing.length); if (core === "") return chunk; if (/[(["'‘“]/.test(leading)) forceCapitalize = true; var loweredCore = core.toLowerCase(); var isStopWord = !forceCapitalize && ignoredWords[loweredCore]; var newCore; if (isStopWord) { newCore = loweredCore; } else { newCore = core.split("-").map(function (part) { return kuCapitalizeFirstLetter(part); }).join("-"); } return leading + newCore + trailing; } function kuToTitleCase(text) { var wordIndex = 0; return text.split(/(\s+)/).map(function (chunk) { if (chunk === "" || /^\s+$/.test(chunk)) return chunk; var isFirstWord = wordIndex === 0; wordIndex++; return kuCapitalizeWordChunk(chunk, isFirstWord); }).join(""); } $.kuApplyCase = function (text, form) { switch (form) { case "upper": return text.toUpperCase(); case "lower": return text.toLowerCase(); case "sentence": return kuToSentenceCase(text); case "title": return kuToTitleCase(text); default: return text; } }; function getLinkifyTool() { return { type: "button", action: { type: "callback", execute: function () { mw.loader.using("jquery.textSelection", function () { var selection = $("#wpTextbox1").textSelection("getSelection"); $.kuLinkify(selection, function (linkedText) { if (!linkedText) return; $("#wpTextbox1").textSelection("encapsulateSelection", { peri: linkedText, replace: true }); }, $.kuLinkify_debug); }); } }, label: getMessage("toolbarButtonName"), icon: "//upload.wikimedia.org/wikipedia/commons/b/ba/Norwegian_link_sign.png" }; } var delinkifyIcon = "//upload.wikimedia.org/wikipedia/commons/b/ba/UI Icon Dewikify.svg"; function getDelinkifyTool() { return { type: "button", action: { type: "callback", execute: function () { mw.loader.using("jquery.textSelection", function () { var selection = $("#wpTextbox1").textSelection("getSelection"); var plainText = $.kuDelinkify(selection); if (plainText === selection) return; $("#wpTextbox1").textSelection("encapsulateSelection", { peri: plainText, replace: true }); }); } }, label: getMessage("delinkifyButtonName"), icon: delinkifyIcon }; } // Applies a case transform to the current textbox selection and writes the // result back in place. Shared by every option in the case-change dropdown. function applyCaseToSelection(form) { mw.loader.using("jquery.textSelection", function () { var selection = $("#wpTextbox1").textSelection("getSelection"); if (!selection) return; var converted = $.kuApplyCase(selection, form); if (converted === selection) return; $("#wpTextbox1").textSelection("encapsulateSelection", { peri: converted, replace: true }); }); } // The built-in wikiEditor "select" tool type (used for e.g. the core // "heading" dropdown) is supposed to close itself both on selecting an // option and on re-clicking its label, but that toggle lives entirely // inside jquery.wikiEditor.toolbar.js and isn't something a gadget can // patch if it misbehaves on a given wiki's deployed version. To make the // close behavior actually reliable, this builds the dropdown by hand as a // wikiEditor "element" tool (a raw DOM element wikiEditor just drops into // the toolbar) and manages its own open/closed state directly, while still // reusing wikiEditor's existing tool-select/label/menu/options/option CSS // classes so it looks identical to a native dropdown. function buildCaseChangeElement() { var forms = [ { key: "upper", label: getMessage("caseUpperLabel") }, { key: "lower", label: getMessage("caseLowerLabel") }, { key: "sentence", label: getMessage("caseSentenceLabel") }, { key: "title", label: getMessage("caseTitleLabel") } ]; var $select = $("<div>").addClass("tool tool-select").attr("rel", "caseChange"); var $options = $("<div>").addClass("options"); var $menu = $("<div>").addClass("menu").append($options).hide(); // Toggling both the class (for anyone's CSS keyed off .options-shown) // and an explicit .show()/.hide() (so the menu is guaranteed to // actually disappear even if that CSS rule is missing or overridden). function closeMenu() { $select.removeClass("options-shown"); $menu.hide(); $label.attr("aria-expanded", "false"); } function openMenu() { // Only one such dropdown open at a time. $(".tool-select").not($select).removeClass("options-shown").find(".menu").hide(); $select.addClass("options-shown"); $menu.show(); $label.attr("aria-expanded", "true"); } $.each(forms, function (i, form) { $("<a>") .addClass("option") .attr({ rel: form.key, tabindex: 0, role: "menuitem" }) .text(form.label) .on("mousedown", function (e) { e.preventDefault(); return false; }) .on("click keydown", function (e) { if (e.type === "click" || (e.type === "keydown" && e.key === "Enter")) { applyCaseToSelection(form.key); closeMenu(); e.preventDefault(); return false; } }) .appendTo($options); }); var $label = $("<a>") .addClass("label skin-invert") .text(getMessage("caseChangeLabel")) .attr({ role: "button", tabindex: 0, "aria-expanded": "false", "aria-haspopup": "menu" }) .on("mousedown", function (e) { e.preventDefault(); return false; }) .on("click keydown", function (e) { if (e.type === "click" || (e.type === "keydown" && e.key === "Enter")) { if ($select.hasClass("options-shown")) { closeMenu(); } else { openMenu(); } e.preventDefault(); return false; } }); $select.append($label, $menu); // Close on any click elsewhere on the page. Namespaced and re-bound // via .off() first so re-registering this tool never stacks up // duplicate document-level handlers. $(document).off("mousedown.kuCaseChange").on("mousedown.kuCaseChange", function (e) { if (!$(e.target).closest($select).length) { closeMenu(); } }); return $select; } function getCaseChangeTool() { return { type: "element", element: buildCaseChangeElement }; } function addLinkifyButton() { var $textbox = $("#wpTextbox1"); // Nothing to attach to on this page (VisualEditor, 2017 editor, non-edit // pages, etc.) — bail out instead of silently binding to an empty set. if (!$textbox.length) return; if ($.kuLinkify) { $textbox.after($(mw.html.element("div", { id: "linkify-progress", title: getMessage("toolbarButtonName") })).hide()); } // A single source of truth for the three tools, so both registration // paths below build identical (but never duplicate) tool objects. function buildTools() { return { linkify: getLinkifyTool(), delinkify: getDelinkifyTool(), caseChange: getCaseChangeTool() }; } // Sends the toolbar-build event and the mw.loader.using("ext.wikiEditor") // callback below race each other -- either the event can fire before // ext.wikiEditor resolves, or (very rarely) the main section can already // be built by the time ext.wikiEditor resolves, having fired and gone // before this script even attached its listener. Exactly one of the two // paths should end up adding the tools; without this flag, both were // firing on ordinary page loads (the event fires during the normal // build, and by the time the mw.loader.using callback runs afterward // context.modules.toolbar already exists too, since it always will once // the toolbar has finished building) -- silently doubling every tool in // the group. var toolsAdded = false; // Bind the listener immediately, synchronously, rather than inside the // mw.loader.using("ext.wikiEditor", ...) callback. If we wait for that // callback to fire before attaching the listener, ext.wikiEditor may // already be loaded and may have already built (and fired the event for) // the main toolbar section by the time our callback runs -- in which case // the event has already come and gone and our button never gets added. // Attaching the listener up front means we won't miss the event even if // ext.wikiEditor resolves "instantly" (e.g. already cached/loaded). $textbox.on('wikiEditor-toolbar-buildSection-main', function (evt, section) { $.extend(section.groups.insert.tools, buildTools()); toolsAdded = true; }); mw.loader.using("ext.wikiEditor", function () { // If the event above already fired (the normal case on every // ordinary page load), the tools are already in place -- don't add // them again. if (toolsAdded) return; // Fallback for the case where the toolbar's main section was already // built (and the event already fired and gone) before this gadget's // script even started executing -- e.g. another gadget loaded // ext.wikiEditor earlier and the toolbar finished initializing // first. In that case the listener above is too late, so we check // whether the toolbar context already exists and, if so, add the // tools directly via the public addToToolbar API instead of waiting // for an event that has already happened. var context = $textbox.data("wikiEditor-context"); if (context && context.modules && context.modules.toolbar) { $textbox.wikiEditor("addToToolbar", { section: "main", group: "insert", tools: buildTools() }); toolsAdded = true; } }); }; // Only try to add the button on pages that actually have an edit form -- // running unconditionally on every page load (including view/history/etc. // pages where #wpTextbox1 never exists) wastes a mw.loader.using round trip // and can look like "sometimes nothing happens" if a user doesn't realize // they weren't on an edit screen. if ($.inArray(mw.config.get("wgAction"), ["edit", "submit"]) !== -1) { addLinkifyButton(); } })(jQuery); 5kd8ny2v0d6b20uf652fodn6c1vl85o 6265725 6265724 2026-07-20T05:25:25Z Wikihez 7344 6265725 javascript text/javascript // MediaWiki gadget: automatically link selected text to existing wiktionary entries (function ($) { var messages = { ku: { toolbarButtonName: "Li nivîsa bijartî bi otomatîkî girêdan lê zêde bike", delinkifyButtonName: "Ji nivîsa bijartî girêdanan rake", caseChangeLabel: "Herf biguhêre", caseUpperLabel: "MEZIN (UPPERCASE)", caseLowerLabel: "biçûk (lowercase)", caseSentenceLabel: "Cimle (Sentence case)", caseTitleLabel: "Her Kelîme Mezin (Title Case)" }, en: { toolbarButtonName: "Automatically link selected text", delinkifyButtonName: "Remove links from selected text", caseChangeLabel: "Change letter case", caseUpperLabel: "UPPERCASE", caseLowerLabel: "lowercase", caseSentenceLabel: "Sentence case", caseTitleLabel: "Title Case" }, es: { toolbarButtonName: "Automáticamente insertar enlaces en la selección", delinkifyButtonName: "Quitar enlaces del texto seleccionado", caseChangeLabel: "Cambiar mayúsculas/minúsculas", caseUpperLabel: "MAYÚSCULAS", caseLowerLabel: "minúsculas", caseSentenceLabel: "Case de oración", caseTitleLabel: "Case de Título" } }; // Kurmanji function words (prepositions, conjunctions, pronouns, particles, // demonstratives, copula/negation forms) that should never be turned into // links on their own, even though they're short enough to match compound // candidates during scanning. Also includes all 8 bare Kurmanji vowels // (a, e, ê, i, î, o, u, û) on their own, since a lone vowel is never a // meaningful link target even if it happens to match part of a scan. var ignoredWordList = ( "a|an|ba|bê|bi|çi|çu|çû|da|de|dê|dî|di|e|ê|ên|erê|ev|ew|em|gel|ha|hê|her|" + "hûn|i|î|jê|jî|ka|kî|ku|kû|lê|li|me|min|na|ne|o|pê|re|ra|ti|te|tê|" + "tu|u|û|va|van|ve|vê|vî|wan|we|wê|wî|wir|vir|ya|yan|yê|yên" ).split("|"); var ignoredWords = {}; $.each(ignoredWordList, function (i, word) { ignoredWords[word] = true; }); /** * One less than the maximum number of syllables to be considered as a compound * word. */ var lookahead = 2; // Tokenizer boundary class: standard uppercase Latin A-Z plus the Kurmanji // Latin alphabet's diacritic letters (both cases: Ç ç, Ê ê, Î î, Ş ş, Û û), // combining diacritical marks, and wiki markup delimiters. var tokenRE = /(\s*(?:<!--[\s\S]+?-->|\{\{[\s\S]+?\}\}|\[\[.+?\]\]|[^A-ZÇÊÎŞÛçêîşû\u0300-\u036F{[< ]+|[{[<])\s*)/i; String.prototype.linkifyUncapitalize = function () { return this[0].toLowerCase() + this.substr(1); }; // Common Kurmanji noun-declension suffixes (indefinite/definite, // nominative/construct/oblique/vocative -- see Module:ku-nouns' // declSimpleNoun), longest first so the greedy match below prefers the // most specific ending (e.g. "eke" before a bare "e"). // // This list is intentionally generous rather than grammatically precise: // unlike declSimpleNoun, the gadget doesn't know a word's gender or its // exact stem class when scanning arbitrary running text, so it can't // reproduce that branching logic exactly. Instead, every candidate root // produced here is verified against real wiktionary entries via the API // before it's ever used (see the "stems" check below) -- so an // over-aggressive strip that doesn't correspond to a genuine entry is // simply discarded, never turned into a bad link. var nounSuffixes = [ "iyekî", "iyekê", "iyeke", "iyinan", "iyino", "yekî", "yekê", "yeke", "yinan", "yino", "ekî", "ekê", "eke", "inan", "ine", "ino", "iyên", "iyan", "iyek", "iyin", "iyo", "iyî", "iyê", "iya", "yên", "yan", "yek", "yin", "yo", "yî", "yê", "ya", "ek", "ên", "an", "in", "a", "ê", "î", "o" ]; /** * Given a lowercase surface word, returns candidate noun roots obtained by * stripping a known declension suffix -- e.g. "rûpeleke" -> ["rûpel"]. * Candidates are ordered from least- to most-aggressively stripped (longest * remaining root first), so that when several candidates turn out to match * real entries, the safer/more specific one wins. */ function getNounStemCandidates(word) { var candidates = []; for (var i = 0; i < nounSuffixes.length; i++) { var suf = nounSuffixes[i]; // Require at least a 2-character root left over, so we don't // generate degenerate single-letter "roots". if (word.length > suf.length + 1 && word.slice(-suf.length) === suf) { candidates.push(word.slice(0, -suf.length)); } } // Orthographic correction: a root ending in î drops its circumflex when // it meets a glide suffix starting with y -- "giranî" + "yê" spells as // "giraniyê", not "giranîyê". Stripping the short suffix "yê" from that // surface form literally gives "girani" (bare i); stripping the longer // "iyê" suffix instead gives the shorter, unrelated root "giran". Since // the î-final noun is the actual root in this pattern, also offer the // î-restored form as a candidate for any stripped result ending in a // bare "i" -- e.g. "girani" -> "giranî". Because it's one character // longer than the "iyê"-derived candidate, the length-based sort below // naturally tries it first. var restored = []; $.each(candidates, function (idx, root) { if (root.length > 1 && root.slice(-1) === "i") { restored.push(root.slice(0, -1) + "î"); } }); candidates = candidates.concat(restored); candidates.sort(function (a, b) { return b.length - a.length; }); return candidates; } var userLang = mw.config.get("wgUserLanguage"); function getMessage(name) { return (messages[userLang] || messages.ku)[name] || messages.ku[name]; } $.kuLinkify = function (text, callback, debug) { var tokens = text.split(tokenRE); var displayTokens = []; var words = {}; var existingLinks = {}; // Maps a surface word (as typed, and its lowercase form) to candidate // noun roots -- e.g. stemCandidates["rûpeleke"] = ["rûpel"]. Filled in // below and consulted during reconstruction so an inflected word whose // exact surface form has no entry can still be linked to its root. var stemCandidates = {}; $.each(tokens, function (i, token) { if (debug) displayTokens.push(mw.html.escape(token)); var tokenLinks = token.match(/\[\[.+?(?:\|.+?)?\]\]/g); $.each(tokenLinks || [], function () { existingLinks[this.match(/\[\[(.+?)(?:\|.+?)?\]\]/)[1]] = true; }); if (!token || token.match(tokenRE)) return; var tokenWords = token.split(" "); $.each(tokenWords, function (j, word) { for (var k = 0; k < lookahead + 1 && tokenWords[j + k]; k++) { if (k) word += " " + tokenWords[j + k]; if (!ignoredWords[word]) words[word] = true; if (word[0] != word[0].toLowerCase()) { var lowerWord = word.linkifyUncapitalize(); if (!ignoredWords[lowerWord]) { words[lowerWord] = true; } } } }); // Also collect candidate noun roots for every individual word (not // multi-word compounds -- declension endings attach to a single // word), so inflected forms like "rûpeleke" can still be linked to // an existing root entry like "rûpel" even when the inflected form // itself has no entry. $.each(tokenWords, function (j, word) { if (!word) return; var lower = word.linkifyUncapitalize(); var stems = getNounStemCandidates(lower); if (stems.length) { stemCandidates[word] = stems; $.each(stems, function (s, stem) { if (!ignoredWords[stem]) words[stem] = true; }); } }); if (debug) { displayTokens[i] = "<b style='border: 1px solid gray;'>" + mw.html.escape(token) + "</b>"; } }); var uniqueWords = []; $.each(words, function (word) { if (!ignoredWords[word]) uniqueWords.push(word); }); if (debug) { var uniqueLinks = []; $.each(existingLinks, function (link) { uniqueLinks.push(link); }); var list = "<pre id='linkify-tokens'>\n" + displayTokens.join("") + "\n</pre>"; list += "<hr /><p>Words to search for:</p><p>" + uniqueWords + "</p>"; list += "<hr /><p>Words that already have links:</p><p>" + uniqueLinks + "</p>"; $("#linkify-progress").html(list).dialog({modal: true}); } if (!uniqueWords.length) return; mw.loader.using("mediawiki.api", function () { var api = new mw.Api(); api.get({ action: "parse", text: "[[" + uniqueWords.join("]] [[") + "]]", prop: "links" }).done(function (results) { $("#linkify-progress").append("<hr />"); var displayLinks = []; var links = {}; $.each(results.parse.links, function () { if (debug && "exists" in this) displayLinks.push(this["*"]); if ("exists" in this) links[this["*"]] = true; }); if (debug) { $("#linkify-progress").append("<p>Existing entries:</p><p>" + displayLinks + "</p>"); } $.each(tokens, function (i, token) { if (!token || token.match(tokenRE)) return; var tokenWords = token.split(" "); for (var j = 0; j < tokenWords.length; j++) { var word = []; for (var k = 0; k < lookahead + 1; k++) { word.push(tokenWords[j + k]); } for (var k = lookahead; k >= 0; k--) { var compoundWord = word.join(" "); if (k === 0) { var lowerSingle = compoundWord.linkifyUncapitalize(); // 1. Prefer linking to the declension root (lemma) // over the inflected surface form's own page -- // e.g. link "pîvana" as [[pîvan|pîvana]] rather // than [[pîvana]], since wiktionary entries for // inflected forms are usually secondary "form of" // pages rather than the main lemma readers want. var stems = stemCandidates[compoundWord] || stemCandidates[lowerSingle] || []; var stemLinked = false; for (var s = 0; s < stems.length; s++) { var stem = stems[s]; if ((stem in links) && !(stem in existingLinks) && !ignoredWords[stem]) { existingLinks[stem] = true; tokenWords[j] = "[[" + stem + "|" + tokenWords[j] + "]]"; stemLinked = true; break; } } if (stemLinked) break; if (!ignoredWords[compoundWord] && !ignoredWords[lowerSingle]) { // 2. No usable root. If the word (or its // lowercase form) is itself a confirmed // entry, link it normally -- this is a real // match, not a guess. Otherwise, only add a // speculative self-link -- always piped // (target|display), even though target and // display are identical text, so a reader // who spots a wrong link can simply edit the // part before the "|" -- when the word's // shape actually looks like an inflected // noun (it matched at least two different // candidate declension suffixes). A word // that matched zero or only one suffix isn't // strong enough evidence that it's inflected // at all, so it's left unlinked rather than // guessed at. var target = null; if (compoundWord in links) { target = compoundWord; } else if (lowerSingle in links) { target = lowerSingle; } else if (stems.length >= 2) { target = compoundWord; } if (target && !(target in existingLinks)) { existingLinks[target] = true; tokenWords[j] = "[[" + target + "|" + tokenWords[j] + "]]"; } } break; } if (compoundWord in links) { if ((compoundWord in existingLinks) || ignoredWords[compoundWord]) { j += k; break; } existingLinks[compoundWord] = true; tokenWords[j] = "[[" + tokenWords[j]; tokenWords[j + k] += "]]"; j += k; break; } var lowerWord = compoundWord.linkifyUncapitalize(); if (lowerWord in links) { if ((lowerWord in existingLinks) || ignoredWords[lowerWord]) { j += k; break; } existingLinks[lowerWord] = true; tokenWords[j] = "[[" + lowerWord + "|" + tokenWords[j]; tokenWords[j + k] += "]]"; j += k; break; } word.splice(-1, 1); } } tokens[i] = tokenWords.join(" "); if (debug) { displayTokens[i] = "<b style='border: 1px solid gray;'>" + mw.html.escape(tokens[i]) + "</b>"; } }); if (debug) { $("#linkify-tokens").html("\n" + displayTokens.join("") + "\n"); } callback(tokens.join("")); }).fail(function (error) { console.warn(error); callback(); }); }); } // Regex for a single wikilink: [[target]] or [[target|display]]. Also // matches file/category-style links (e.g. [[File:...]]) the same way as any // other link -- this gadget doesn't try to special-case those, since a user // invoking "remove links" on a stretch of text presumably wants every // [[...]] construct in that stretch unwrapped, not just plain word links. var wikilinkRE = /\[\[([^\]|]*)\|([^\]]*)\]\]|\[\[([^\]|]*)\]\]/g; /** * Strips wikilink markup from text, keeping only the reader-facing text. * [[target|display]] -> display * [[target]] -> target * Unlike $.kuLinkify, this needs no API round-trip: removing markup that's * already there doesn't require checking whether any page exists. */ $.kuDelinkify = function (text) { return text.replace(wikilinkRE, function (match, pipedTarget, pipedDisplay, bareTarget) { return pipedDisplay !== undefined ? pipedDisplay : bareTarget; }); }; // --------------------------------------------------------------- // Letter-case conversion (UPPERCASE / lowercase / Sentence case / // Title Case), adapted from the herfguhartin.js gadget's ku-locale // logic. Unlike that gadget, this one only ever deals with Kurmanji // text, so there's no per-language dotted/dotless-i handling to worry // about -- plain JS toUpperCase()/toLowerCase() already do the right // thing for Kurmanji's Latin letters (a e ê i î o u û plus ç ş, etc). // // For Title Case, this reuses the gadget's own `ignoredWords` list // (the Kurmanji function words already excluded from auto-linking) // as the set of small grammatical words that should stay lowercase, // rather than keeping a second, separately-maintained stopword list. // --------------------------------------------------------------- var KU_LETTER_CLASS = "a-zA-ZçêîşûÇÊÎŞÛ"; var kuNonLetterLeadingRE = new RegExp("^[^" + KU_LETTER_CLASS + "]*"); var kuNonLetterTrailingRE = new RegExp("[^" + KU_LETTER_CLASS + "]*$"); var kuSentenceBreakRE = new RegExp( "(^\\s*[a-zçêîşû]|[.!?][\"'\\)\\]]*\\s+[a-zçêîşû])", "gi" ); function kuCapitalizeFirstLetter(word) { if (word === "") return word; var lowered = word.toLowerCase(); return lowered.charAt(0).toUpperCase() + lowered.slice(1); } function kuToSentenceCase(text) { var lowered = text.toLowerCase(); return lowered.replace(kuSentenceBreakRE, function (match) { var idx = match.length - 1; return match.slice(0, idx) + match.charAt(idx).toUpperCase(); }); } // Capitalizes one "word chunk": handles leading/trailing punctuation // ("(çîroka" -> "(Çîroka"), hyphenated compounds ("kurdî-gerşûnî" -> // "Kurdî-Gerşûnî"), and keeps ignoredWords entries lowercase unless // forced (first word of the text, or right after an opening // bracket/quote). function kuCapitalizeWordChunk(chunk, forceCapitalize) { var leading = (chunk.match(kuNonLetterLeadingRE) || [""])[0]; var trailing = (chunk.match(kuNonLetterTrailingRE) || [""])[0]; var core = chunk.slice(leading.length, chunk.length - trailing.length); if (core === "") return chunk; if (/[(["'‘“]/.test(leading)) forceCapitalize = true; var loweredCore = core.toLowerCase(); var isStopWord = !forceCapitalize && ignoredWords[loweredCore]; var newCore; if (isStopWord) { newCore = loweredCore; } else { newCore = core.split("-").map(function (part) { return kuCapitalizeFirstLetter(part); }).join("-"); } return leading + newCore + trailing; } function kuToTitleCase(text) { var wordIndex = 0; return text.split(/(\s+)/).map(function (chunk) { if (chunk === "" || /^\s+$/.test(chunk)) return chunk; var isFirstWord = wordIndex === 0; wordIndex++; return kuCapitalizeWordChunk(chunk, isFirstWord); }).join(""); } $.kuApplyCase = function (text, form) { switch (form) { case "upper": return text.toUpperCase(); case "lower": return text.toLowerCase(); case "sentence": return kuToSentenceCase(text); case "title": return kuToTitleCase(text); default: return text; } }; function getLinkifyTool() { return { type: "button", action: { type: "callback", execute: function () { mw.loader.using("jquery.textSelection", function () { var selection = $("#wpTextbox1").textSelection("getSelection"); $.kuLinkify(selection, function (linkedText) { if (!linkedText) return; $("#wpTextbox1").textSelection("encapsulateSelection", { peri: linkedText, replace: true }); }, $.kuLinkify_debug); }); } }, label: getMessage("toolbarButtonName"), icon: "//upload.wikimedia.org/wikipedia/commons/b/ba/Norwegian_link_sign.png" }; } var delinkifyIcon = "//upload.wikimedia.org/wikipedia/commons/b/ba/工具欄不使用維基標記的符號.png"; function getDelinkifyTool() { return { type: "button", action: { type: "callback", execute: function () { mw.loader.using("jquery.textSelection", function () { var selection = $("#wpTextbox1").textSelection("getSelection"); var plainText = $.kuDelinkify(selection); if (plainText === selection) return; $("#wpTextbox1").textSelection("encapsulateSelection", { peri: plainText, replace: true }); }); } }, label: getMessage("delinkifyButtonName"), icon: delinkifyIcon }; } // Applies a case transform to the current textbox selection and writes the // result back in place. Shared by every option in the case-change dropdown. function applyCaseToSelection(form) { mw.loader.using("jquery.textSelection", function () { var selection = $("#wpTextbox1").textSelection("getSelection"); if (!selection) return; var converted = $.kuApplyCase(selection, form); if (converted === selection) return; $("#wpTextbox1").textSelection("encapsulateSelection", { peri: converted, replace: true }); }); } // The built-in wikiEditor "select" tool type (used for e.g. the core // "heading" dropdown) is supposed to close itself both on selecting an // option and on re-clicking its label, but that toggle lives entirely // inside jquery.wikiEditor.toolbar.js and isn't something a gadget can // patch if it misbehaves on a given wiki's deployed version. To make the // close behavior actually reliable, this builds the dropdown by hand as a // wikiEditor "element" tool (a raw DOM element wikiEditor just drops into // the toolbar) and manages its own open/closed state directly, while still // reusing wikiEditor's existing tool-select/label/menu/options/option CSS // classes so it looks identical to a native dropdown. function buildCaseChangeElement() { var forms = [ { key: "upper", label: getMessage("caseUpperLabel") }, { key: "lower", label: getMessage("caseLowerLabel") }, { key: "sentence", label: getMessage("caseSentenceLabel") }, { key: "title", label: getMessage("caseTitleLabel") } ]; var $select = $("<div>").addClass("tool tool-select").attr("rel", "caseChange"); var $options = $("<div>").addClass("options"); var $menu = $("<div>").addClass("menu").append($options).hide(); // Toggling both the class (for anyone's CSS keyed off .options-shown) // and an explicit .show()/.hide() (so the menu is guaranteed to // actually disappear even if that CSS rule is missing or overridden). function closeMenu() { $select.removeClass("options-shown"); $menu.hide(); $label.attr("aria-expanded", "false"); } function openMenu() { // Only one such dropdown open at a time. $(".tool-select").not($select).removeClass("options-shown").find(".menu").hide(); $select.addClass("options-shown"); $menu.show(); $label.attr("aria-expanded", "true"); } $.each(forms, function (i, form) { $("<a>") .addClass("option") .attr({ rel: form.key, tabindex: 0, role: "menuitem" }) .text(form.label) .on("mousedown", function (e) { e.preventDefault(); return false; }) .on("click keydown", function (e) { if (e.type === "click" || (e.type === "keydown" && e.key === "Enter")) { applyCaseToSelection(form.key); closeMenu(); e.preventDefault(); return false; } }) .appendTo($options); }); var $label = $("<a>") .addClass("label skin-invert") .text(getMessage("caseChangeLabel")) .attr({ role: "button", tabindex: 0, "aria-expanded": "false", "aria-haspopup": "menu" }) .on("mousedown", function (e) { e.preventDefault(); return false; }) .on("click keydown", function (e) { if (e.type === "click" || (e.type === "keydown" && e.key === "Enter")) { if ($select.hasClass("options-shown")) { closeMenu(); } else { openMenu(); } e.preventDefault(); return false; } }); $select.append($label, $menu); // Close on any click elsewhere on the page. Namespaced and re-bound // via .off() first so re-registering this tool never stacks up // duplicate document-level handlers. $(document).off("mousedown.kuCaseChange").on("mousedown.kuCaseChange", function (e) { if (!$(e.target).closest($select).length) { closeMenu(); } }); return $select; } function getCaseChangeTool() { return { type: "element", element: buildCaseChangeElement }; } function addLinkifyButton() { var $textbox = $("#wpTextbox1"); // Nothing to attach to on this page (VisualEditor, 2017 editor, non-edit // pages, etc.) — bail out instead of silently binding to an empty set. if (!$textbox.length) return; if ($.kuLinkify) { $textbox.after($(mw.html.element("div", { id: "linkify-progress", title: getMessage("toolbarButtonName") })).hide()); } // A single source of truth for the three tools, so both registration // paths below build identical (but never duplicate) tool objects. function buildTools() { return { linkify: getLinkifyTool(), delinkify: getDelinkifyTool(), caseChange: getCaseChangeTool() }; } // Sends the toolbar-build event and the mw.loader.using("ext.wikiEditor") // callback below race each other -- either the event can fire before // ext.wikiEditor resolves, or (very rarely) the main section can already // be built by the time ext.wikiEditor resolves, having fired and gone // before this script even attached its listener. Exactly one of the two // paths should end up adding the tools; without this flag, both were // firing on ordinary page loads (the event fires during the normal // build, and by the time the mw.loader.using callback runs afterward // context.modules.toolbar already exists too, since it always will once // the toolbar has finished building) -- silently doubling every tool in // the group. var toolsAdded = false; // Bind the listener immediately, synchronously, rather than inside the // mw.loader.using("ext.wikiEditor", ...) callback. If we wait for that // callback to fire before attaching the listener, ext.wikiEditor may // already be loaded and may have already built (and fired the event for) // the main toolbar section by the time our callback runs -- in which case // the event has already come and gone and our button never gets added. // Attaching the listener up front means we won't miss the event even if // ext.wikiEditor resolves "instantly" (e.g. already cached/loaded). $textbox.on('wikiEditor-toolbar-buildSection-main', function (evt, section) { $.extend(section.groups.insert.tools, buildTools()); toolsAdded = true; }); mw.loader.using("ext.wikiEditor", function () { // If the event above already fired (the normal case on every // ordinary page load), the tools are already in place -- don't add // them again. if (toolsAdded) return; // Fallback for the case where the toolbar's main section was already // built (and the event already fired and gone) before this gadget's // script even started executing -- e.g. another gadget loaded // ext.wikiEditor earlier and the toolbar finished initializing // first. In that case the listener above is too late, so we check // whether the toolbar context already exists and, if so, add the // tools directly via the public addToToolbar API instead of waiting // for an event that has already happened. var context = $textbox.data("wikiEditor-context"); if (context && context.modules && context.modules.toolbar) { $textbox.wikiEditor("addToToolbar", { section: "main", group: "insert", tools: buildTools() }); toolsAdded = true; } }); }; // Only try to add the button on pages that actually have an edit form -- // running unconditionally on every page load (including view/history/etc. // pages where #wpTextbox1 never exists) wastes a mw.loader.using round trip // and can look like "sometimes nothing happens" if a user doesn't realize // they weren't on an edit screen. if ($.inArray(mw.config.get("wgAction"), ["edit", "submit"]) !== -1) { addLinkifyButton(); } })(jQuery); 8j7445c8ie34pjhbg335xcopoklz9x8 6265726 6265725 2026-07-20T05:28:59Z Wikihez 7344 6265726 javascript text/javascript // MediaWiki gadget: automatically link selected text to existing wiktionary entries (function ($) { var messages = { ku: { toolbarButtonName: "Li nivîsa bijartî bi otomatîkî girêdan lê zêde bike", delinkifyButtonName: "Ji nivîsa bijartî girêdanan rake", caseChangeLabel: "Herf biguhêre", caseUpperLabel: "MEZIN (UPPERCASE)", caseLowerLabel: "biçûk (lowercase)", caseSentenceLabel: "Cimle (Sentence case)", caseTitleLabel: "Her Kelîme Mezin (Title Case)" }, en: { toolbarButtonName: "Automatically link selected text", delinkifyButtonName: "Remove links from selected text", caseChangeLabel: "Change letter case", caseUpperLabel: "UPPERCASE", caseLowerLabel: "lowercase", caseSentenceLabel: "Sentence case", caseTitleLabel: "Title Case" }, es: { toolbarButtonName: "Automáticamente insertar enlaces en la selección", delinkifyButtonName: "Quitar enlaces del texto seleccionado", caseChangeLabel: "Cambiar mayúsculas/minúsculas", caseUpperLabel: "MAYÚSCULAS", caseLowerLabel: "minúsculas", caseSentenceLabel: "Case de oración", caseTitleLabel: "Case de Título" } }; // Kurmanji function words (prepositions, conjunctions, pronouns, particles, // demonstratives, copula/negation forms) that should never be turned into // links on their own, even though they're short enough to match compound // candidates during scanning. Also includes all 8 bare Kurmanji vowels // (a, e, ê, i, î, o, u, û) on their own, since a lone vowel is never a // meaningful link target even if it happens to match part of a scan. var ignoredWordList = ( "a|an|ba|bê|bi|çi|çu|çû|da|de|dê|dî|di|e|ê|ên|erê|ev|ew|em|gel|ha|hê|her|" + "hûn|i|î|jê|jî|ka|kî|ku|kû|lê|li|me|min|na|ne|o|pê|re|ra|ti|te|tê|" + "tu|u|û|va|van|ve|vê|vî|wan|we|wê|wî|wir|vir|ya|yan|yê|yên" ).split("|"); var ignoredWords = {}; $.each(ignoredWordList, function (i, word) { ignoredWords[word] = true; }); /** * One less than the maximum number of syllables to be considered as a compound * word. */ var lookahead = 2; // Tokenizer boundary class: standard uppercase Latin A-Z plus the Kurmanji // Latin alphabet's diacritic letters (both cases: Ç ç, Ê ê, Î î, Ş ş, Û û), // combining diacritical marks, and wiki markup delimiters. var tokenRE = /(\s*(?:<!--[\s\S]+?-->|\{\{[\s\S]+?\}\}|\[\[.+?\]\]|[^A-ZÇÊÎŞÛçêîşû\u0300-\u036F{[< ]+|[{[<])\s*)/i; String.prototype.linkifyUncapitalize = function () { return this[0].toLowerCase() + this.substr(1); }; // Common Kurmanji noun-declension suffixes (indefinite/definite, // nominative/construct/oblique/vocative -- see Module:ku-nouns' // declSimpleNoun), longest first so the greedy match below prefers the // most specific ending (e.g. "eke" before a bare "e"). // // This list is intentionally generous rather than grammatically precise: // unlike declSimpleNoun, the gadget doesn't know a word's gender or its // exact stem class when scanning arbitrary running text, so it can't // reproduce that branching logic exactly. Instead, every candidate root // produced here is verified against real wiktionary entries via the API // before it's ever used (see the "stems" check below) -- so an // over-aggressive strip that doesn't correspond to a genuine entry is // simply discarded, never turned into a bad link. var nounSuffixes = [ "iyekî", "iyekê", "iyeke", "iyinan", "iyino", "yekî", "yekê", "yeke", "yinan", "yino", "ekî", "ekê", "eke", "inan", "ine", "ino", "iyên", "iyan", "iyek", "iyin", "iyo", "iyî", "iyê", "iya", "yên", "yan", "yek", "yin", "yo", "yî", "yê", "ya", "ek", "ên", "an", "in", "a", "ê", "î", "o" ]; /** * Given a lowercase surface word, returns candidate noun roots obtained by * stripping a known declension suffix -- e.g. "rûpeleke" -> ["rûpel"]. * Candidates are ordered from least- to most-aggressively stripped (longest * remaining root first), so that when several candidates turn out to match * real entries, the safer/more specific one wins. */ function getNounStemCandidates(word) { var candidates = []; for (var i = 0; i < nounSuffixes.length; i++) { var suf = nounSuffixes[i]; // Require at least a 2-character root left over, so we don't // generate degenerate single-letter "roots". if (word.length > suf.length + 1 && word.slice(-suf.length) === suf) { candidates.push(word.slice(0, -suf.length)); } } // Orthographic correction: a root ending in î drops its circumflex when // it meets a glide suffix starting with y -- "giranî" + "yê" spells as // "giraniyê", not "giranîyê". Stripping the short suffix "yê" from that // surface form literally gives "girani" (bare i); stripping the longer // "iyê" suffix instead gives the shorter, unrelated root "giran". Since // the î-final noun is the actual root in this pattern, also offer the // î-restored form as a candidate for any stripped result ending in a // bare "i" -- e.g. "girani" -> "giranî". Because it's one character // longer than the "iyê"-derived candidate, the length-based sort below // naturally tries it first. var restored = []; $.each(candidates, function (idx, root) { if (root.length > 1 && root.slice(-1) === "i") { restored.push(root.slice(0, -1) + "î"); } }); candidates = candidates.concat(restored); candidates.sort(function (a, b) { return b.length - a.length; }); return candidates; } var userLang = mw.config.get("wgUserLanguage"); function getMessage(name) { return (messages[userLang] || messages.ku)[name] || messages.ku[name]; } $.kuLinkify = function (text, callback, debug) { var tokens = text.split(tokenRE); var displayTokens = []; var words = {}; var existingLinks = {}; // Maps a surface word (as typed, and its lowercase form) to candidate // noun roots -- e.g. stemCandidates["rûpeleke"] = ["rûpel"]. Filled in // below and consulted during reconstruction so an inflected word whose // exact surface form has no entry can still be linked to its root. var stemCandidates = {}; $.each(tokens, function (i, token) { if (debug) displayTokens.push(mw.html.escape(token)); var tokenLinks = token.match(/\[\[.+?(?:\|.+?)?\]\]/g); $.each(tokenLinks || [], function () { existingLinks[this.match(/\[\[(.+?)(?:\|.+?)?\]\]/)[1]] = true; }); if (!token || token.match(tokenRE)) return; var tokenWords = token.split(" "); $.each(tokenWords, function (j, word) { for (var k = 0; k < lookahead + 1 && tokenWords[j + k]; k++) { if (k) word += " " + tokenWords[j + k]; if (!ignoredWords[word]) words[word] = true; if (word[0] != word[0].toLowerCase()) { var lowerWord = word.linkifyUncapitalize(); if (!ignoredWords[lowerWord]) { words[lowerWord] = true; } } } }); // Also collect candidate noun roots for every individual word (not // multi-word compounds -- declension endings attach to a single // word), so inflected forms like "rûpeleke" can still be linked to // an existing root entry like "rûpel" even when the inflected form // itself has no entry. $.each(tokenWords, function (j, word) { if (!word) return; var lower = word.linkifyUncapitalize(); var stems = getNounStemCandidates(lower); if (stems.length) { stemCandidates[word] = stems; $.each(stems, function (s, stem) { if (!ignoredWords[stem]) words[stem] = true; }); } }); if (debug) { displayTokens[i] = "<b style='border: 1px solid gray;'>" + mw.html.escape(token) + "</b>"; } }); var uniqueWords = []; $.each(words, function (word) { if (!ignoredWords[word]) uniqueWords.push(word); }); if (debug) { var uniqueLinks = []; $.each(existingLinks, function (link) { uniqueLinks.push(link); }); var list = "<pre id='linkify-tokens'>\n" + displayTokens.join("") + "\n</pre>"; list += "<hr /><p>Words to search for:</p><p>" + uniqueWords + "</p>"; list += "<hr /><p>Words that already have links:</p><p>" + uniqueLinks + "</p>"; $("#linkify-progress").html(list).dialog({modal: true}); } if (!uniqueWords.length) return; mw.loader.using("mediawiki.api", function () { var api = new mw.Api(); api.get({ action: "parse", text: "[[" + uniqueWords.join("]] [[") + "]]", prop: "links" }).done(function (results) { $("#linkify-progress").append("<hr />"); var displayLinks = []; var links = {}; $.each(results.parse.links, function () { if (debug && "exists" in this) displayLinks.push(this["*"]); if ("exists" in this) links[this["*"]] = true; }); if (debug) { $("#linkify-progress").append("<p>Existing entries:</p><p>" + displayLinks + "</p>"); } $.each(tokens, function (i, token) { if (!token || token.match(tokenRE)) return; var tokenWords = token.split(" "); for (var j = 0; j < tokenWords.length; j++) { var word = []; for (var k = 0; k < lookahead + 1; k++) { word.push(tokenWords[j + k]); } for (var k = lookahead; k >= 0; k--) { var compoundWord = word.join(" "); if (k === 0) { var lowerSingle = compoundWord.linkifyUncapitalize(); // 1. Prefer linking to the declension root (lemma) // over the inflected surface form's own page -- // e.g. link "pîvana" as [[pîvan|pîvana]] rather // than [[pîvana]], since wiktionary entries for // inflected forms are usually secondary "form of" // pages rather than the main lemma readers want. var stems = stemCandidates[compoundWord] || stemCandidates[lowerSingle] || []; var stemLinked = false; for (var s = 0; s < stems.length; s++) { var stem = stems[s]; if ((stem in links) && !(stem in existingLinks) && !ignoredWords[stem]) { existingLinks[stem] = true; tokenWords[j] = "[[" + stem + "|" + tokenWords[j] + "]]"; stemLinked = true; break; } } if (stemLinked) break; if (!ignoredWords[compoundWord] && !ignoredWords[lowerSingle]) { // 2. No usable root. If the word (or its // lowercase form) is itself a confirmed // entry, link it normally -- this is a real // match, not a guess. Otherwise, only add a // speculative self-link -- always piped // (target|display), even though target and // display are identical text, so a reader // who spots a wrong link can simply edit the // part before the "|" -- when the word's // shape actually looks like an inflected // noun (it matched at least two different // candidate declension suffixes). A word // that matched zero or only one suffix isn't // strong enough evidence that it's inflected // at all, so it's left unlinked rather than // guessed at. var target = null; if (compoundWord in links) { target = compoundWord; } else if (lowerSingle in links) { target = lowerSingle; } else if (stems.length >= 2) { target = compoundWord; } if (target && !(target in existingLinks)) { existingLinks[target] = true; tokenWords[j] = "[[" + target + "|" + tokenWords[j] + "]]"; } } break; } if (compoundWord in links) { if ((compoundWord in existingLinks) || ignoredWords[compoundWord]) { j += k; break; } existingLinks[compoundWord] = true; tokenWords[j] = "[[" + tokenWords[j]; tokenWords[j + k] += "]]"; j += k; break; } var lowerWord = compoundWord.linkifyUncapitalize(); if (lowerWord in links) { if ((lowerWord in existingLinks) || ignoredWords[lowerWord]) { j += k; break; } existingLinks[lowerWord] = true; tokenWords[j] = "[[" + lowerWord + "|" + tokenWords[j]; tokenWords[j + k] += "]]"; j += k; break; } word.splice(-1, 1); } } tokens[i] = tokenWords.join(" "); if (debug) { displayTokens[i] = "<b style='border: 1px solid gray;'>" + mw.html.escape(tokens[i]) + "</b>"; } }); if (debug) { $("#linkify-tokens").html("\n" + displayTokens.join("") + "\n"); } callback(tokens.join("")); }).fail(function (error) { console.warn(error); callback(); }); }); } // Regex for a single wikilink: [[target]] or [[target|display]]. Also // matches file/category-style links (e.g. [[File:...]]) the same way as any // other link -- this gadget doesn't try to special-case those, since a user // invoking "remove links" on a stretch of text presumably wants every // [[...]] construct in that stretch unwrapped, not just plain word links. var wikilinkRE = /\[\[([^\]|]*)\|([^\]]*)\]\]|\[\[([^\]|]*)\]\]/g; /** * Strips wikilink markup from text, keeping only the reader-facing text. * [[target|display]] -> display * [[target]] -> target * Unlike $.kuLinkify, this needs no API round-trip: removing markup that's * already there doesn't require checking whether any page exists. */ $.kuDelinkify = function (text) { return text.replace(wikilinkRE, function (match, pipedTarget, pipedDisplay, bareTarget) { return pipedDisplay !== undefined ? pipedDisplay : bareTarget; }); }; // --------------------------------------------------------------- // Letter-case conversion (UPPERCASE / lowercase / Sentence case / // Title Case), adapted from the herfguhartin.js gadget's ku-locale // logic. Unlike that gadget, this one only ever deals with Kurmanji // text, so there's no per-language dotted/dotless-i handling to worry // about -- plain JS toUpperCase()/toLowerCase() already do the right // thing for Kurmanji's Latin letters (a e ê i î o u û plus ç ş, etc). // // For Title Case, this reuses the gadget's own `ignoredWords` list // (the Kurmanji function words already excluded from auto-linking) // as the set of small grammatical words that should stay lowercase, // rather than keeping a second, separately-maintained stopword list. // --------------------------------------------------------------- var KU_LETTER_CLASS = "a-zA-ZçêîşûÇÊÎŞÛ"; var kuNonLetterLeadingRE = new RegExp("^[^" + KU_LETTER_CLASS + "]*"); var kuNonLetterTrailingRE = new RegExp("[^" + KU_LETTER_CLASS + "]*$"); var kuSentenceBreakRE = new RegExp( "(^\\s*[a-zçêîşû]|[.!?][\"'\\)\\]]*\\s+[a-zçêîşû])", "gi" ); function kuCapitalizeFirstLetter(word) { if (word === "") return word; var lowered = word.toLowerCase(); return lowered.charAt(0).toUpperCase() + lowered.slice(1); } function kuToSentenceCase(text) { var lowered = text.toLowerCase(); return lowered.replace(kuSentenceBreakRE, function (match) { var idx = match.length - 1; return match.slice(0, idx) + match.charAt(idx).toUpperCase(); }); } // Capitalizes one "word chunk": handles leading/trailing punctuation // ("(çîroka" -> "(Çîroka"), hyphenated compounds ("kurdî-gerşûnî" -> // "Kurdî-Gerşûnî"), and keeps ignoredWords entries lowercase unless // forced (first word of the text, or right after an opening // bracket/quote). function kuCapitalizeWordChunk(chunk, forceCapitalize) { var leading = (chunk.match(kuNonLetterLeadingRE) || [""])[0]; var trailing = (chunk.match(kuNonLetterTrailingRE) || [""])[0]; var core = chunk.slice(leading.length, chunk.length - trailing.length); if (core === "") return chunk; if (/[(["'‘“]/.test(leading)) forceCapitalize = true; var loweredCore = core.toLowerCase(); var isStopWord = !forceCapitalize && ignoredWords[loweredCore]; var newCore; if (isStopWord) { newCore = loweredCore; } else { newCore = core.split("-").map(function (part) { return kuCapitalizeFirstLetter(part); }).join("-"); } return leading + newCore + trailing; } function kuToTitleCase(text) { var wordIndex = 0; return text.split(/(\s+)/).map(function (chunk) { if (chunk === "" || /^\s+$/.test(chunk)) return chunk; var isFirstWord = wordIndex === 0; wordIndex++; return kuCapitalizeWordChunk(chunk, isFirstWord); }).join(""); } $.kuApplyCase = function (text, form) { switch (form) { case "upper": return text.toUpperCase(); case "lower": return text.toLowerCase(); case "sentence": return kuToSentenceCase(text); case "title": return kuToTitleCase(text); default: return text; } }; function getLinkifyTool() { return { type: "button", action: { type: "callback", execute: function () { mw.loader.using("jquery.textSelection", function () { var selection = $("#wpTextbox1").textSelection("getSelection"); $.kuLinkify(selection, function (linkedText) { if (!linkedText) return; $("#wpTextbox1").textSelection("encapsulateSelection", { peri: linkedText, replace: true }); }, $.kuLinkify_debug); }); } }, label: getMessage("toolbarButtonName"), icon: "//upload.wikimedia.org/wikipedia/commons/b/ba/Norwegian_link_sign.png" }; } var delinkifyIcon = "//upload.wikimedia.org/wikipedia/commons/8/8c/OOjs_UI_icon_noWikiText-rtl.svg"; function getDelinkifyTool() { return { type: "button", action: { type: "callback", execute: function () { mw.loader.using("jquery.textSelection", function () { var selection = $("#wpTextbox1").textSelection("getSelection"); var plainText = $.kuDelinkify(selection); if (plainText === selection) return; $("#wpTextbox1").textSelection("encapsulateSelection", { peri: plainText, replace: true }); }); } }, label: getMessage("delinkifyButtonName"), icon: delinkifyIcon }; } // Applies a case transform to the current textbox selection and writes the // result back in place. Shared by every option in the case-change dropdown. function applyCaseToSelection(form) { mw.loader.using("jquery.textSelection", function () { var selection = $("#wpTextbox1").textSelection("getSelection"); if (!selection) return; var converted = $.kuApplyCase(selection, form); if (converted === selection) return; $("#wpTextbox1").textSelection("encapsulateSelection", { peri: converted, replace: true }); }); } // The built-in wikiEditor "select" tool type (used for e.g. the core // "heading" dropdown) is supposed to close itself both on selecting an // option and on re-clicking its label, but that toggle lives entirely // inside jquery.wikiEditor.toolbar.js and isn't something a gadget can // patch if it misbehaves on a given wiki's deployed version. To make the // close behavior actually reliable, this builds the dropdown by hand as a // wikiEditor "element" tool (a raw DOM element wikiEditor just drops into // the toolbar) and manages its own open/closed state directly, while still // reusing wikiEditor's existing tool-select/label/menu/options/option CSS // classes so it looks identical to a native dropdown. function buildCaseChangeElement() { var forms = [ { key: "upper", label: getMessage("caseUpperLabel") }, { key: "lower", label: getMessage("caseLowerLabel") }, { key: "sentence", label: getMessage("caseSentenceLabel") }, { key: "title", label: getMessage("caseTitleLabel") } ]; var $select = $("<div>").addClass("tool tool-select").attr("rel", "caseChange"); var $options = $("<div>").addClass("options"); var $menu = $("<div>").addClass("menu").append($options).hide(); // Toggling both the class (for anyone's CSS keyed off .options-shown) // and an explicit .show()/.hide() (so the menu is guaranteed to // actually disappear even if that CSS rule is missing or overridden). function closeMenu() { $select.removeClass("options-shown"); $menu.hide(); $label.attr("aria-expanded", "false"); } function openMenu() { // Only one such dropdown open at a time. $(".tool-select").not($select).removeClass("options-shown").find(".menu").hide(); $select.addClass("options-shown"); $menu.show(); $label.attr("aria-expanded", "true"); } $.each(forms, function (i, form) { $("<a>") .addClass("option") .attr({ rel: form.key, tabindex: 0, role: "menuitem" }) .text(form.label) .on("mousedown", function (e) { e.preventDefault(); return false; }) .on("click keydown", function (e) { if (e.type === "click" || (e.type === "keydown" && e.key === "Enter")) { applyCaseToSelection(form.key); closeMenu(); e.preventDefault(); return false; } }) .appendTo($options); }); var $label = $("<a>") .addClass("label skin-invert") .text(getMessage("caseChangeLabel")) .attr({ role: "button", tabindex: 0, "aria-expanded": "false", "aria-haspopup": "menu" }) .on("mousedown", function (e) { e.preventDefault(); return false; }) .on("click keydown", function (e) { if (e.type === "click" || (e.type === "keydown" && e.key === "Enter")) { if ($select.hasClass("options-shown")) { closeMenu(); } else { openMenu(); } e.preventDefault(); return false; } }); $select.append($label, $menu); // Close on any click elsewhere on the page. Namespaced and re-bound // via .off() first so re-registering this tool never stacks up // duplicate document-level handlers. $(document).off("mousedown.kuCaseChange").on("mousedown.kuCaseChange", function (e) { if (!$(e.target).closest($select).length) { closeMenu(); } }); return $select; } function getCaseChangeTool() { return { type: "element", element: buildCaseChangeElement }; } function addLinkifyButton() { var $textbox = $("#wpTextbox1"); // Nothing to attach to on this page (VisualEditor, 2017 editor, non-edit // pages, etc.) — bail out instead of silently binding to an empty set. if (!$textbox.length) return; if ($.kuLinkify) { $textbox.after($(mw.html.element("div", { id: "linkify-progress", title: getMessage("toolbarButtonName") })).hide()); } // A single source of truth for the three tools, so both registration // paths below build identical (but never duplicate) tool objects. function buildTools() { return { linkify: getLinkifyTool(), delinkify: getDelinkifyTool(), caseChange: getCaseChangeTool() }; } // Sends the toolbar-build event and the mw.loader.using("ext.wikiEditor") // callback below race each other -- either the event can fire before // ext.wikiEditor resolves, or (very rarely) the main section can already // be built by the time ext.wikiEditor resolves, having fired and gone // before this script even attached its listener. Exactly one of the two // paths should end up adding the tools; without this flag, both were // firing on ordinary page loads (the event fires during the normal // build, and by the time the mw.loader.using callback runs afterward // context.modules.toolbar already exists too, since it always will once // the toolbar has finished building) -- silently doubling every tool in // the group. var toolsAdded = false; // Bind the listener immediately, synchronously, rather than inside the // mw.loader.using("ext.wikiEditor", ...) callback. If we wait for that // callback to fire before attaching the listener, ext.wikiEditor may // already be loaded and may have already built (and fired the event for) // the main toolbar section by the time our callback runs -- in which case // the event has already come and gone and our button never gets added. // Attaching the listener up front means we won't miss the event even if // ext.wikiEditor resolves "instantly" (e.g. already cached/loaded). $textbox.on('wikiEditor-toolbar-buildSection-main', function (evt, section) { $.extend(section.groups.insert.tools, buildTools()); toolsAdded = true; }); mw.loader.using("ext.wikiEditor", function () { // If the event above already fired (the normal case on every // ordinary page load), the tools are already in place -- don't add // them again. if (toolsAdded) return; // Fallback for the case where the toolbar's main section was already // built (and the event already fired and gone) before this gadget's // script even started executing -- e.g. another gadget loaded // ext.wikiEditor earlier and the toolbar finished initializing // first. In that case the listener above is too late, so we check // whether the toolbar context already exists and, if so, add the // tools directly via the public addToToolbar API instead of waiting // for an event that has already happened. var context = $textbox.data("wikiEditor-context"); if (context && context.modules && context.modules.toolbar) { $textbox.wikiEditor("addToToolbar", { section: "main", group: "insert", tools: buildTools() }); toolsAdded = true; } }); }; // Only try to add the button on pages that actually have an edit form -- // running unconditionally on every page load (including view/history/etc. // pages where #wpTextbox1 never exists) wastes a mw.loader.using round trip // and can look like "sometimes nothing happens" if a user doesn't realize // they weren't on an edit screen. if ($.inArray(mw.config.get("wgAction"), ["edit", "submit"]) !== -1) { addLinkifyButton(); } })(jQuery); 77d2c6jcburmgpbxoq8mtbmlajud05i 6265727 6265726 2026-07-20T05:30:28Z Wikihez 7344 6265727 javascript text/javascript // MediaWiki gadget: automatically link selected text to existing wiktionary entries (function ($) { var messages = { ku: { toolbarButtonName: "Li nivîsa bijartî bi otomatîkî girêdan lê zêde bike", delinkifyButtonName: "Ji nivîsa bijartî girêdanan rake", caseChangeLabel: "Herf biguhêre", caseUpperLabel: "MEZIN (UPPERCASE)", caseLowerLabel: "biçûk (lowercase)", caseSentenceLabel: "Cimle (Sentence case)", caseTitleLabel: "Her Kelîme Mezin (Title Case)" }, en: { toolbarButtonName: "Automatically link selected text", delinkifyButtonName: "Remove links from selected text", caseChangeLabel: "Change letter case", caseUpperLabel: "UPPERCASE", caseLowerLabel: "lowercase", caseSentenceLabel: "Sentence case", caseTitleLabel: "Title Case" }, es: { toolbarButtonName: "Automáticamente insertar enlaces en la selección", delinkifyButtonName: "Quitar enlaces del texto seleccionado", caseChangeLabel: "Cambiar mayúsculas/minúsculas", caseUpperLabel: "MAYÚSCULAS", caseLowerLabel: "minúsculas", caseSentenceLabel: "Case de oración", caseTitleLabel: "Case de Título" } }; // Kurmanji function words (prepositions, conjunctions, pronouns, particles, // demonstratives, copula/negation forms) that should never be turned into // links on their own, even though they're short enough to match compound // candidates during scanning. Also includes all 8 bare Kurmanji vowels // (a, e, ê, i, î, o, u, û) on their own, since a lone vowel is never a // meaningful link target even if it happens to match part of a scan. var ignoredWordList = ( "a|an|ba|bê|bi|çi|çu|çû|da|de|dê|dî|di|e|ê|ên|erê|ev|ew|em|gel|ha|hê|her|" + "hûn|i|î|jê|jî|ka|kî|ku|kû|lê|li|me|min|na|ne|o|pê|re|ra|ti|te|tê|" + "tu|u|û|va|van|ve|vê|vî|wan|we|wê|wî|wir|vir|ya|yan|yê|yên" ).split("|"); var ignoredWords = {}; $.each(ignoredWordList, function (i, word) { ignoredWords[word] = true; }); /** * One less than the maximum number of syllables to be considered as a compound * word. */ var lookahead = 2; // Tokenizer boundary class: standard uppercase Latin A-Z plus the Kurmanji // Latin alphabet's diacritic letters (both cases: Ç ç, Ê ê, Î î, Ş ş, Û û), // combining diacritical marks, and wiki markup delimiters. var tokenRE = /(\s*(?:<!--[\s\S]+?-->|\{\{[\s\S]+?\}\}|\[\[.+?\]\]|[^A-ZÇÊÎŞÛçêîşû\u0300-\u036F{[< ]+|[{[<])\s*)/i; String.prototype.linkifyUncapitalize = function () { return this[0].toLowerCase() + this.substr(1); }; // Common Kurmanji noun-declension suffixes (indefinite/definite, // nominative/construct/oblique/vocative -- see Module:ku-nouns' // declSimpleNoun), longest first so the greedy match below prefers the // most specific ending (e.g. "eke" before a bare "e"). // // This list is intentionally generous rather than grammatically precise: // unlike declSimpleNoun, the gadget doesn't know a word's gender or its // exact stem class when scanning arbitrary running text, so it can't // reproduce that branching logic exactly. Instead, every candidate root // produced here is verified against real wiktionary entries via the API // before it's ever used (see the "stems" check below) -- so an // over-aggressive strip that doesn't correspond to a genuine entry is // simply discarded, never turned into a bad link. var nounSuffixes = [ "iyekî", "iyekê", "iyeke", "iyinan", "iyino", "yekî", "yekê", "yeke", "yinan", "yino", "ekî", "ekê", "eke", "inan", "ine", "ino", "iyên", "iyan", "iyek", "iyin", "iyo", "iyî", "iyê", "iya", "yên", "yan", "yek", "yin", "yo", "yî", "yê", "ya", "ek", "ên", "an", "in", "a", "ê", "î", "o" ]; /** * Given a lowercase surface word, returns candidate noun roots obtained by * stripping a known declension suffix -- e.g. "rûpeleke" -> ["rûpel"]. * Candidates are ordered from least- to most-aggressively stripped (longest * remaining root first), so that when several candidates turn out to match * real entries, the safer/more specific one wins. */ function getNounStemCandidates(word) { var candidates = []; for (var i = 0; i < nounSuffixes.length; i++) { var suf = nounSuffixes[i]; // Require at least a 2-character root left over, so we don't // generate degenerate single-letter "roots". if (word.length > suf.length + 1 && word.slice(-suf.length) === suf) { candidates.push(word.slice(0, -suf.length)); } } // Orthographic correction: a root ending in î drops its circumflex when // it meets a glide suffix starting with y -- "giranî" + "yê" spells as // "giraniyê", not "giranîyê". Stripping the short suffix "yê" from that // surface form literally gives "girani" (bare i); stripping the longer // "iyê" suffix instead gives the shorter, unrelated root "giran". Since // the î-final noun is the actual root in this pattern, also offer the // î-restored form as a candidate for any stripped result ending in a // bare "i" -- e.g. "girani" -> "giranî". Because it's one character // longer than the "iyê"-derived candidate, the length-based sort below // naturally tries it first. var restored = []; $.each(candidates, function (idx, root) { if (root.length > 1 && root.slice(-1) === "i") { restored.push(root.slice(0, -1) + "î"); } }); candidates = candidates.concat(restored); candidates.sort(function (a, b) { return b.length - a.length; }); return candidates; } var userLang = mw.config.get("wgUserLanguage"); function getMessage(name) { return (messages[userLang] || messages.ku)[name] || messages.ku[name]; } $.kuLinkify = function (text, callback, debug) { var tokens = text.split(tokenRE); var displayTokens = []; var words = {}; var existingLinks = {}; // Maps a surface word (as typed, and its lowercase form) to candidate // noun roots -- e.g. stemCandidates["rûpeleke"] = ["rûpel"]. Filled in // below and consulted during reconstruction so an inflected word whose // exact surface form has no entry can still be linked to its root. var stemCandidates = {}; $.each(tokens, function (i, token) { if (debug) displayTokens.push(mw.html.escape(token)); var tokenLinks = token.match(/\[\[.+?(?:\|.+?)?\]\]/g); $.each(tokenLinks || [], function () { existingLinks[this.match(/\[\[(.+?)(?:\|.+?)?\]\]/)[1]] = true; }); if (!token || token.match(tokenRE)) return; var tokenWords = token.split(" "); $.each(tokenWords, function (j, word) { for (var k = 0; k < lookahead + 1 && tokenWords[j + k]; k++) { if (k) word += " " + tokenWords[j + k]; if (!ignoredWords[word]) words[word] = true; if (word[0] != word[0].toLowerCase()) { var lowerWord = word.linkifyUncapitalize(); if (!ignoredWords[lowerWord]) { words[lowerWord] = true; } } } }); // Also collect candidate noun roots for every individual word (not // multi-word compounds -- declension endings attach to a single // word), so inflected forms like "rûpeleke" can still be linked to // an existing root entry like "rûpel" even when the inflected form // itself has no entry. $.each(tokenWords, function (j, word) { if (!word) return; var lower = word.linkifyUncapitalize(); var stems = getNounStemCandidates(lower); if (stems.length) { stemCandidates[word] = stems; $.each(stems, function (s, stem) { if (!ignoredWords[stem]) words[stem] = true; }); } }); if (debug) { displayTokens[i] = "<b style='border: 1px solid gray;'>" + mw.html.escape(token) + "</b>"; } }); var uniqueWords = []; $.each(words, function (word) { if (!ignoredWords[word]) uniqueWords.push(word); }); if (debug) { var uniqueLinks = []; $.each(existingLinks, function (link) { uniqueLinks.push(link); }); var list = "<pre id='linkify-tokens'>\n" + displayTokens.join("") + "\n</pre>"; list += "<hr /><p>Words to search for:</p><p>" + uniqueWords + "</p>"; list += "<hr /><p>Words that already have links:</p><p>" + uniqueLinks + "</p>"; $("#linkify-progress").html(list).dialog({modal: true}); } if (!uniqueWords.length) return; mw.loader.using("mediawiki.api", function () { var api = new mw.Api(); api.get({ action: "parse", text: "[[" + uniqueWords.join("]] [[") + "]]", prop: "links" }).done(function (results) { $("#linkify-progress").append("<hr />"); var displayLinks = []; var links = {}; $.each(results.parse.links, function () { if (debug && "exists" in this) displayLinks.push(this["*"]); if ("exists" in this) links[this["*"]] = true; }); if (debug) { $("#linkify-progress").append("<p>Existing entries:</p><p>" + displayLinks + "</p>"); } $.each(tokens, function (i, token) { if (!token || token.match(tokenRE)) return; var tokenWords = token.split(" "); for (var j = 0; j < tokenWords.length; j++) { var word = []; for (var k = 0; k < lookahead + 1; k++) { word.push(tokenWords[j + k]); } for (var k = lookahead; k >= 0; k--) { var compoundWord = word.join(" "); if (k === 0) { var lowerSingle = compoundWord.linkifyUncapitalize(); // 1. Prefer linking to the declension root (lemma) // over the inflected surface form's own page -- // e.g. link "pîvana" as [[pîvan|pîvana]] rather // than [[pîvana]], since wiktionary entries for // inflected forms are usually secondary "form of" // pages rather than the main lemma readers want. var stems = stemCandidates[compoundWord] || stemCandidates[lowerSingle] || []; var stemLinked = false; for (var s = 0; s < stems.length; s++) { var stem = stems[s]; if ((stem in links) && !(stem in existingLinks) && !ignoredWords[stem]) { existingLinks[stem] = true; tokenWords[j] = "[[" + stem + "|" + tokenWords[j] + "]]"; stemLinked = true; break; } } if (stemLinked) break; if (!ignoredWords[compoundWord] && !ignoredWords[lowerSingle]) { // 2. No usable root. If the word (or its // lowercase form) is itself a confirmed // entry, link it normally -- this is a real // match, not a guess. Otherwise, only add a // speculative self-link -- always piped // (target|display), even though target and // display are identical text, so a reader // who spots a wrong link can simply edit the // part before the "|" -- when the word's // shape actually looks like an inflected // noun (it matched at least two different // candidate declension suffixes). A word // that matched zero or only one suffix isn't // strong enough evidence that it's inflected // at all, so it's left unlinked rather than // guessed at. var target = null; if (compoundWord in links) { target = compoundWord; } else if (lowerSingle in links) { target = lowerSingle; } else if (stems.length >= 2) { target = compoundWord; } if (target && !(target in existingLinks)) { existingLinks[target] = true; tokenWords[j] = "[[" + target + "|" + tokenWords[j] + "]]"; } } break; } if (compoundWord in links) { if ((compoundWord in existingLinks) || ignoredWords[compoundWord]) { j += k; break; } existingLinks[compoundWord] = true; tokenWords[j] = "[[" + tokenWords[j]; tokenWords[j + k] += "]]"; j += k; break; } var lowerWord = compoundWord.linkifyUncapitalize(); if (lowerWord in links) { if ((lowerWord in existingLinks) || ignoredWords[lowerWord]) { j += k; break; } existingLinks[lowerWord] = true; tokenWords[j] = "[[" + lowerWord + "|" + tokenWords[j]; tokenWords[j + k] += "]]"; j += k; break; } word.splice(-1, 1); } } tokens[i] = tokenWords.join(" "); if (debug) { displayTokens[i] = "<b style='border: 1px solid gray;'>" + mw.html.escape(tokens[i]) + "</b>"; } }); if (debug) { $("#linkify-tokens").html("\n" + displayTokens.join("") + "\n"); } callback(tokens.join("")); }).fail(function (error) { console.warn(error); callback(); }); }); } // Regex for a single wikilink: [[target]] or [[target|display]]. Also // matches file/category-style links (e.g. [[File:...]]) the same way as any // other link -- this gadget doesn't try to special-case those, since a user // invoking "remove links" on a stretch of text presumably wants every // [[...]] construct in that stretch unwrapped, not just plain word links. var wikilinkRE = /\[\[([^\]|]*)\|([^\]]*)\]\]|\[\[([^\]|]*)\]\]/g; /** * Strips wikilink markup from text, keeping only the reader-facing text. * [[target|display]] -> display * [[target]] -> target * Unlike $.kuLinkify, this needs no API round-trip: removing markup that's * already there doesn't require checking whether any page exists. */ $.kuDelinkify = function (text) { return text.replace(wikilinkRE, function (match, pipedTarget, pipedDisplay, bareTarget) { return pipedDisplay !== undefined ? pipedDisplay : bareTarget; }); }; // --------------------------------------------------------------- // Letter-case conversion (UPPERCASE / lowercase / Sentence case / // Title Case), adapted from the herfguhartin.js gadget's ku-locale // logic. Unlike that gadget, this one only ever deals with Kurmanji // text, so there's no per-language dotted/dotless-i handling to worry // about -- plain JS toUpperCase()/toLowerCase() already do the right // thing for Kurmanji's Latin letters (a e ê i î o u û plus ç ş, etc). // // For Title Case, this reuses the gadget's own `ignoredWords` list // (the Kurmanji function words already excluded from auto-linking) // as the set of small grammatical words that should stay lowercase, // rather than keeping a second, separately-maintained stopword list. // --------------------------------------------------------------- var KU_LETTER_CLASS = "a-zA-ZçêîşûÇÊÎŞÛ"; var kuNonLetterLeadingRE = new RegExp("^[^" + KU_LETTER_CLASS + "]*"); var kuNonLetterTrailingRE = new RegExp("[^" + KU_LETTER_CLASS + "]*$"); var kuSentenceBreakRE = new RegExp( "(^\\s*[a-zçêîşû]|[.!?][\"'\\)\\]]*\\s+[a-zçêîşû])", "gi" ); function kuCapitalizeFirstLetter(word) { if (word === "") return word; var lowered = word.toLowerCase(); return lowered.charAt(0).toUpperCase() + lowered.slice(1); } function kuToSentenceCase(text) { var lowered = text.toLowerCase(); return lowered.replace(kuSentenceBreakRE, function (match) { var idx = match.length - 1; return match.slice(0, idx) + match.charAt(idx).toUpperCase(); }); } // Capitalizes one "word chunk": handles leading/trailing punctuation // ("(çîroka" -> "(Çîroka"), hyphenated compounds ("kurdî-gerşûnî" -> // "Kurdî-Gerşûnî"), and keeps ignoredWords entries lowercase unless // forced (first word of the text, or right after an opening // bracket/quote). function kuCapitalizeWordChunk(chunk, forceCapitalize) { var leading = (chunk.match(kuNonLetterLeadingRE) || [""])[0]; var trailing = (chunk.match(kuNonLetterTrailingRE) || [""])[0]; var core = chunk.slice(leading.length, chunk.length - trailing.length); if (core === "") return chunk; if (/[(["'‘“]/.test(leading)) forceCapitalize = true; var loweredCore = core.toLowerCase(); var isStopWord = !forceCapitalize && ignoredWords[loweredCore]; var newCore; if (isStopWord) { newCore = loweredCore; } else { newCore = core.split("-").map(function (part) { return kuCapitalizeFirstLetter(part); }).join("-"); } return leading + newCore + trailing; } function kuToTitleCase(text) { var wordIndex = 0; return text.split(/(\s+)/).map(function (chunk) { if (chunk === "" || /^\s+$/.test(chunk)) return chunk; var isFirstWord = wordIndex === 0; wordIndex++; return kuCapitalizeWordChunk(chunk, isFirstWord); }).join(""); } $.kuApplyCase = function (text, form) { switch (form) { case "upper": return text.toUpperCase(); case "lower": return text.toLowerCase(); case "sentence": return kuToSentenceCase(text); case "title": return kuToTitleCase(text); default: return text; } }; function getLinkifyTool() { return { type: "button", action: { type: "callback", execute: function () { mw.loader.using("jquery.textSelection", function () { var selection = $("#wpTextbox1").textSelection("getSelection"); $.kuLinkify(selection, function (linkedText) { if (!linkedText) return; $("#wpTextbox1").textSelection("encapsulateSelection", { peri: linkedText, replace: true }); }, $.kuLinkify_debug); }); } }, label: getMessage("toolbarButtonName"), icon: "//upload.wikimedia.org/wikipedia/commons/b/ba/Norwegian_link_sign.png" }; } var delinkifyIcon = "//upload.wikimedia.org/wikipedia/commons/9/9d/OOjs_UI_icon_noWikiText-ltr-progressive.svg"; function getDelinkifyTool() { return { type: "button", action: { type: "callback", execute: function () { mw.loader.using("jquery.textSelection", function () { var selection = $("#wpTextbox1").textSelection("getSelection"); var plainText = $.kuDelinkify(selection); if (plainText === selection) return; $("#wpTextbox1").textSelection("encapsulateSelection", { peri: plainText, replace: true }); }); } }, label: getMessage("delinkifyButtonName"), icon: delinkifyIcon }; } // Applies a case transform to the current textbox selection and writes the // result back in place. Shared by every option in the case-change dropdown. function applyCaseToSelection(form) { mw.loader.using("jquery.textSelection", function () { var selection = $("#wpTextbox1").textSelection("getSelection"); if (!selection) return; var converted = $.kuApplyCase(selection, form); if (converted === selection) return; $("#wpTextbox1").textSelection("encapsulateSelection", { peri: converted, replace: true }); }); } // The built-in wikiEditor "select" tool type (used for e.g. the core // "heading" dropdown) is supposed to close itself both on selecting an // option and on re-clicking its label, but that toggle lives entirely // inside jquery.wikiEditor.toolbar.js and isn't something a gadget can // patch if it misbehaves on a given wiki's deployed version. To make the // close behavior actually reliable, this builds the dropdown by hand as a // wikiEditor "element" tool (a raw DOM element wikiEditor just drops into // the toolbar) and manages its own open/closed state directly, while still // reusing wikiEditor's existing tool-select/label/menu/options/option CSS // classes so it looks identical to a native dropdown. function buildCaseChangeElement() { var forms = [ { key: "upper", label: getMessage("caseUpperLabel") }, { key: "lower", label: getMessage("caseLowerLabel") }, { key: "sentence", label: getMessage("caseSentenceLabel") }, { key: "title", label: getMessage("caseTitleLabel") } ]; var $select = $("<div>").addClass("tool tool-select").attr("rel", "caseChange"); var $options = $("<div>").addClass("options"); var $menu = $("<div>").addClass("menu").append($options).hide(); // Toggling both the class (for anyone's CSS keyed off .options-shown) // and an explicit .show()/.hide() (so the menu is guaranteed to // actually disappear even if that CSS rule is missing or overridden). function closeMenu() { $select.removeClass("options-shown"); $menu.hide(); $label.attr("aria-expanded", "false"); } function openMenu() { // Only one such dropdown open at a time. $(".tool-select").not($select).removeClass("options-shown").find(".menu").hide(); $select.addClass("options-shown"); $menu.show(); $label.attr("aria-expanded", "true"); } $.each(forms, function (i, form) { $("<a>") .addClass("option") .attr({ rel: form.key, tabindex: 0, role: "menuitem" }) .text(form.label) .on("mousedown", function (e) { e.preventDefault(); return false; }) .on("click keydown", function (e) { if (e.type === "click" || (e.type === "keydown" && e.key === "Enter")) { applyCaseToSelection(form.key); closeMenu(); e.preventDefault(); return false; } }) .appendTo($options); }); var $label = $("<a>") .addClass("label skin-invert") .text(getMessage("caseChangeLabel")) .attr({ role: "button", tabindex: 0, "aria-expanded": "false", "aria-haspopup": "menu" }) .on("mousedown", function (e) { e.preventDefault(); return false; }) .on("click keydown", function (e) { if (e.type === "click" || (e.type === "keydown" && e.key === "Enter")) { if ($select.hasClass("options-shown")) { closeMenu(); } else { openMenu(); } e.preventDefault(); return false; } }); $select.append($label, $menu); // Close on any click elsewhere on the page. Namespaced and re-bound // via .off() first so re-registering this tool never stacks up // duplicate document-level handlers. $(document).off("mousedown.kuCaseChange").on("mousedown.kuCaseChange", function (e) { if (!$(e.target).closest($select).length) { closeMenu(); } }); return $select; } function getCaseChangeTool() { return { type: "element", element: buildCaseChangeElement }; } function addLinkifyButton() { var $textbox = $("#wpTextbox1"); // Nothing to attach to on this page (VisualEditor, 2017 editor, non-edit // pages, etc.) — bail out instead of silently binding to an empty set. if (!$textbox.length) return; if ($.kuLinkify) { $textbox.after($(mw.html.element("div", { id: "linkify-progress", title: getMessage("toolbarButtonName") })).hide()); } // A single source of truth for the three tools, so both registration // paths below build identical (but never duplicate) tool objects. function buildTools() { return { linkify: getLinkifyTool(), delinkify: getDelinkifyTool(), caseChange: getCaseChangeTool() }; } // Sends the toolbar-build event and the mw.loader.using("ext.wikiEditor") // callback below race each other -- either the event can fire before // ext.wikiEditor resolves, or (very rarely) the main section can already // be built by the time ext.wikiEditor resolves, having fired and gone // before this script even attached its listener. Exactly one of the two // paths should end up adding the tools; without this flag, both were // firing on ordinary page loads (the event fires during the normal // build, and by the time the mw.loader.using callback runs afterward // context.modules.toolbar already exists too, since it always will once // the toolbar has finished building) -- silently doubling every tool in // the group. var toolsAdded = false; // Bind the listener immediately, synchronously, rather than inside the // mw.loader.using("ext.wikiEditor", ...) callback. If we wait for that // callback to fire before attaching the listener, ext.wikiEditor may // already be loaded and may have already built (and fired the event for) // the main toolbar section by the time our callback runs -- in which case // the event has already come and gone and our button never gets added. // Attaching the listener up front means we won't miss the event even if // ext.wikiEditor resolves "instantly" (e.g. already cached/loaded). $textbox.on('wikiEditor-toolbar-buildSection-main', function (evt, section) { $.extend(section.groups.insert.tools, buildTools()); toolsAdded = true; }); mw.loader.using("ext.wikiEditor", function () { // If the event above already fired (the normal case on every // ordinary page load), the tools are already in place -- don't add // them again. if (toolsAdded) return; // Fallback for the case where the toolbar's main section was already // built (and the event already fired and gone) before this gadget's // script even started executing -- e.g. another gadget loaded // ext.wikiEditor earlier and the toolbar finished initializing // first. In that case the listener above is too late, so we check // whether the toolbar context already exists and, if so, add the // tools directly via the public addToToolbar API instead of waiting // for an event that has already happened. var context = $textbox.data("wikiEditor-context"); if (context && context.modules && context.modules.toolbar) { $textbox.wikiEditor("addToToolbar", { section: "main", group: "insert", tools: buildTools() }); toolsAdded = true; } }); }; // Only try to add the button on pages that actually have an edit form -- // running unconditionally on every page load (including view/history/etc. // pages where #wpTextbox1 never exists) wastes a mw.loader.using round trip // and can look like "sometimes nothing happens" if a user doesn't realize // they weren't on an edit screen. if ($.inArray(mw.config.get("wgAction"), ["edit", "submit"]) !== -1) { addLinkifyButton(); } })(jQuery); 923251lqs90w0d8ep6vhymlfocpknxk 6265728 6265727 2026-07-20T05:33:29Z Wikihez 7344 6265728 javascript text/javascript // MediaWiki gadget: automatically link selected text to existing wiktionary entries (function ($) { var messages = { ku: { toolbarButtonName: "Li nivîsa bijartî bi otomatîkî girêdan lê zêde bike", delinkifyButtonName: "Ji nivîsa bijartî girêdanan rake", caseChangeLabel: "Herf biguhêre", caseUpperLabel: "MEZIN (UPPERCASE)", caseLowerLabel: "biçûk (lowercase)", caseSentenceLabel: "Cimle (Sentence case)", caseTitleLabel: "Her Kelîme Mezin (Title Case)" }, en: { toolbarButtonName: "Automatically link selected text", delinkifyButtonName: "Remove links from selected text", caseChangeLabel: "Change letter case", caseUpperLabel: "UPPERCASE", caseLowerLabel: "lowercase", caseSentenceLabel: "Sentence case", caseTitleLabel: "Title Case" }, es: { toolbarButtonName: "Automáticamente insertar enlaces en la selección", delinkifyButtonName: "Quitar enlaces del texto seleccionado", caseChangeLabel: "Cambiar mayúsculas/minúsculas", caseUpperLabel: "MAYÚSCULAS", caseLowerLabel: "minúsculas", caseSentenceLabel: "Case de oración", caseTitleLabel: "Case de Título" } }; // Kurmanji function words (prepositions, conjunctions, pronouns, particles, // demonstratives, copula/negation forms) that should never be turned into // links on their own, even though they're short enough to match compound // candidates during scanning. Also includes all 8 bare Kurmanji vowels // (a, e, ê, i, î, o, u, û) on their own, since a lone vowel is never a // meaningful link target even if it happens to match part of a scan. var ignoredWordList = ( "a|an|ba|bê|bi|çi|çu|çû|da|de|dê|dî|di|e|ê|ên|erê|ev|ew|em|gel|ha|hê|her|" + "hûn|i|î|jê|jî|ka|kî|ku|kû|lê|li|me|min|na|ne|o|pê|re|ra|ti|te|tê|" + "tu|u|û|va|van|ve|vê|vî|wan|we|wê|wî|wir|vir|ya|yan|yê|yên" ).split("|"); var ignoredWords = {}; $.each(ignoredWordList, function (i, word) { ignoredWords[word] = true; }); /** * One less than the maximum number of syllables to be considered as a compound * word. */ var lookahead = 2; // Tokenizer boundary class: standard uppercase Latin A-Z plus the Kurmanji // Latin alphabet's diacritic letters (both cases: Ç ç, Ê ê, Î î, Ş ş, Û û), // combining diacritical marks, and wiki markup delimiters. var tokenRE = /(\s*(?:<!--[\s\S]+?-->|\{\{[\s\S]+?\}\}|\[\[.+?\]\]|[^A-ZÇÊÎŞÛçêîşû\u0300-\u036F{[< ]+|[{[<])\s*)/i; String.prototype.linkifyUncapitalize = function () { return this[0].toLowerCase() + this.substr(1); }; // Common Kurmanji noun-declension suffixes (indefinite/definite, // nominative/construct/oblique/vocative -- see Module:ku-nouns' // declSimpleNoun), longest first so the greedy match below prefers the // most specific ending (e.g. "eke" before a bare "e"). // // This list is intentionally generous rather than grammatically precise: // unlike declSimpleNoun, the gadget doesn't know a word's gender or its // exact stem class when scanning arbitrary running text, so it can't // reproduce that branching logic exactly. Instead, every candidate root // produced here is verified against real wiktionary entries via the API // before it's ever used (see the "stems" check below) -- so an // over-aggressive strip that doesn't correspond to a genuine entry is // simply discarded, never turned into a bad link. var nounSuffixes = [ "iyekî", "iyekê", "iyeke", "iyinan", "iyino", "yekî", "yekê", "yeke", "yinan", "yino", "ekî", "ekê", "eke", "inan", "ine", "ino", "iyên", "iyan", "iyek", "iyin", "iyo", "iyî", "iyê", "iya", "yên", "yan", "yek", "yin", "yo", "yî", "yê", "ya", "ek", "ên", "an", "in", "a", "ê", "î", "o" ]; /** * Given a lowercase surface word, returns candidate noun roots obtained by * stripping a known declension suffix -- e.g. "rûpeleke" -> ["rûpel"]. * Candidates are ordered from least- to most-aggressively stripped (longest * remaining root first), so that when several candidates turn out to match * real entries, the safer/more specific one wins. */ function getNounStemCandidates(word) { var candidates = []; for (var i = 0; i < nounSuffixes.length; i++) { var suf = nounSuffixes[i]; // Require at least a 2-character root left over, so we don't // generate degenerate single-letter "roots". if (word.length > suf.length + 1 && word.slice(-suf.length) === suf) { candidates.push(word.slice(0, -suf.length)); } } // Orthographic correction: a root ending in î drops its circumflex when // it meets a glide suffix starting with y -- "giranî" + "yê" spells as // "giraniyê", not "giranîyê". Stripping the short suffix "yê" from that // surface form literally gives "girani" (bare i); stripping the longer // "iyê" suffix instead gives the shorter, unrelated root "giran". Since // the î-final noun is the actual root in this pattern, also offer the // î-restored form as a candidate for any stripped result ending in a // bare "i" -- e.g. "girani" -> "giranî". Because it's one character // longer than the "iyê"-derived candidate, the length-based sort below // naturally tries it first. var restored = []; $.each(candidates, function (idx, root) { if (root.length > 1 && root.slice(-1) === "i") { restored.push(root.slice(0, -1) + "î"); } }); candidates = candidates.concat(restored); candidates.sort(function (a, b) { return b.length - a.length; }); return candidates; } var userLang = mw.config.get("wgUserLanguage"); function getMessage(name) { return (messages[userLang] || messages.ku)[name] || messages.ku[name]; } $.kuLinkify = function (text, callback, debug) { var tokens = text.split(tokenRE); var displayTokens = []; var words = {}; var existingLinks = {}; // Maps a surface word (as typed, and its lowercase form) to candidate // noun roots -- e.g. stemCandidates["rûpeleke"] = ["rûpel"]. Filled in // below and consulted during reconstruction so an inflected word whose // exact surface form has no entry can still be linked to its root. var stemCandidates = {}; $.each(tokens, function (i, token) { if (debug) displayTokens.push(mw.html.escape(token)); var tokenLinks = token.match(/\[\[.+?(?:\|.+?)?\]\]/g); $.each(tokenLinks || [], function () { existingLinks[this.match(/\[\[(.+?)(?:\|.+?)?\]\]/)[1]] = true; }); if (!token || token.match(tokenRE)) return; var tokenWords = token.split(" "); $.each(tokenWords, function (j, word) { for (var k = 0; k < lookahead + 1 && tokenWords[j + k]; k++) { if (k) word += " " + tokenWords[j + k]; if (!ignoredWords[word]) words[word] = true; if (word[0] != word[0].toLowerCase()) { var lowerWord = word.linkifyUncapitalize(); if (!ignoredWords[lowerWord]) { words[lowerWord] = true; } } } }); // Also collect candidate noun roots for every individual word (not // multi-word compounds -- declension endings attach to a single // word), so inflected forms like "rûpeleke" can still be linked to // an existing root entry like "rûpel" even when the inflected form // itself has no entry. $.each(tokenWords, function (j, word) { if (!word) return; var lower = word.linkifyUncapitalize(); var stems = getNounStemCandidates(lower); if (stems.length) { stemCandidates[word] = stems; $.each(stems, function (s, stem) { if (!ignoredWords[stem]) words[stem] = true; }); } }); if (debug) { displayTokens[i] = "<b style='border: 1px solid gray;'>" + mw.html.escape(token) + "</b>"; } }); var uniqueWords = []; $.each(words, function (word) { if (!ignoredWords[word]) uniqueWords.push(word); }); if (debug) { var uniqueLinks = []; $.each(existingLinks, function (link) { uniqueLinks.push(link); }); var list = "<pre id='linkify-tokens'>\n" + displayTokens.join("") + "\n</pre>"; list += "<hr /><p>Words to search for:</p><p>" + uniqueWords + "</p>"; list += "<hr /><p>Words that already have links:</p><p>" + uniqueLinks + "</p>"; $("#linkify-progress").html(list).dialog({modal: true}); } if (!uniqueWords.length) return; mw.loader.using("mediawiki.api", function () { var api = new mw.Api(); api.get({ action: "parse", text: "[[" + uniqueWords.join("]] [[") + "]]", prop: "links" }).done(function (results) { $("#linkify-progress").append("<hr />"); var displayLinks = []; var links = {}; $.each(results.parse.links, function () { if (debug && "exists" in this) displayLinks.push(this["*"]); if ("exists" in this) links[this["*"]] = true; }); if (debug) { $("#linkify-progress").append("<p>Existing entries:</p><p>" + displayLinks + "</p>"); } $.each(tokens, function (i, token) { if (!token || token.match(tokenRE)) return; var tokenWords = token.split(" "); for (var j = 0; j < tokenWords.length; j++) { var word = []; for (var k = 0; k < lookahead + 1; k++) { word.push(tokenWords[j + k]); } for (var k = lookahead; k >= 0; k--) { var compoundWord = word.join(" "); if (k === 0) { var lowerSingle = compoundWord.linkifyUncapitalize(); // 1. Prefer linking to the declension root (lemma) // over the inflected surface form's own page -- // e.g. link "pîvana" as [[pîvan|pîvana]] rather // than [[pîvana]], since wiktionary entries for // inflected forms are usually secondary "form of" // pages rather than the main lemma readers want. var stems = stemCandidates[compoundWord] || stemCandidates[lowerSingle] || []; var stemLinked = false; for (var s = 0; s < stems.length; s++) { var stem = stems[s]; if ((stem in links) && !(stem in existingLinks) && !ignoredWords[stem]) { existingLinks[stem] = true; tokenWords[j] = "[[" + stem + "|" + tokenWords[j] + "]]"; stemLinked = true; break; } } if (stemLinked) break; if (!ignoredWords[compoundWord] && !ignoredWords[lowerSingle]) { // 2. No usable root. If the word (or its // lowercase form) is itself a confirmed // entry, link it normally -- this is a real // match, not a guess. Otherwise, only add a // speculative self-link -- always piped // (target|display), even though target and // display are identical text, so a reader // who spots a wrong link can simply edit the // part before the "|" -- when the word's // shape actually looks like an inflected // noun (it matched at least two different // candidate declension suffixes). A word // that matched zero or only one suffix isn't // strong enough evidence that it's inflected // at all, so it's left unlinked rather than // guessed at. var target = null; if (compoundWord in links) { target = compoundWord; } else if (lowerSingle in links) { target = lowerSingle; } else if (stems.length >= 2) { target = compoundWord; } if (target && !(target in existingLinks)) { existingLinks[target] = true; tokenWords[j] = "[[" + target + "|" + tokenWords[j] + "]]"; } } break; } if (compoundWord in links) { if ((compoundWord in existingLinks) || ignoredWords[compoundWord]) { j += k; break; } existingLinks[compoundWord] = true; tokenWords[j] = "[[" + tokenWords[j]; tokenWords[j + k] += "]]"; j += k; break; } var lowerWord = compoundWord.linkifyUncapitalize(); if (lowerWord in links) { if ((lowerWord in existingLinks) || ignoredWords[lowerWord]) { j += k; break; } existingLinks[lowerWord] = true; tokenWords[j] = "[[" + lowerWord + "|" + tokenWords[j]; tokenWords[j + k] += "]]"; j += k; break; } word.splice(-1, 1); } } tokens[i] = tokenWords.join(" "); if (debug) { displayTokens[i] = "<b style='border: 1px solid gray;'>" + mw.html.escape(tokens[i]) + "</b>"; } }); if (debug) { $("#linkify-tokens").html("\n" + displayTokens.join("") + "\n"); } callback(tokens.join("")); }).fail(function (error) { console.warn(error); callback(); }); }); } // Regex for a single wikilink: [[target]] or [[target|display]]. Also // matches file/category-style links (e.g. [[File:...]]) the same way as any // other link -- this gadget doesn't try to special-case those, since a user // invoking "remove links" on a stretch of text presumably wants every // [[...]] construct in that stretch unwrapped, not just plain word links. var wikilinkRE = /\[\[([^\]|]*)\|([^\]]*)\]\]|\[\[([^\]|]*)\]\]/g; /** * Strips wikilink markup from text, keeping only the reader-facing text. * [[target|display]] -> display * [[target]] -> target * Unlike $.kuLinkify, this needs no API round-trip: removing markup that's * already there doesn't require checking whether any page exists. */ $.kuDelinkify = function (text) { return text.replace(wikilinkRE, function (match, pipedTarget, pipedDisplay, bareTarget) { return pipedDisplay !== undefined ? pipedDisplay : bareTarget; }); }; // --------------------------------------------------------------- // Letter-case conversion (UPPERCASE / lowercase / Sentence case / // Title Case), adapted from the herfguhartin.js gadget's ku-locale // logic. Unlike that gadget, this one only ever deals with Kurmanji // text, so there's no per-language dotted/dotless-i handling to worry // about -- plain JS toUpperCase()/toLowerCase() already do the right // thing for Kurmanji's Latin letters (a e ê i î o u û plus ç ş, etc). // // For Title Case, this reuses the gadget's own `ignoredWords` list // (the Kurmanji function words already excluded from auto-linking) // as the set of small grammatical words that should stay lowercase, // rather than keeping a second, separately-maintained stopword list. // --------------------------------------------------------------- var KU_LETTER_CLASS = "a-zA-ZçêîşûÇÊÎŞÛ"; var kuNonLetterLeadingRE = new RegExp("^[^" + KU_LETTER_CLASS + "]*"); var kuNonLetterTrailingRE = new RegExp("[^" + KU_LETTER_CLASS + "]*$"); var kuSentenceBreakRE = new RegExp( "(^\\s*[a-zçêîşû]|[.!?][\"'\\)\\]]*\\s+[a-zçêîşû])", "gi" ); function kuCapitalizeFirstLetter(word) { if (word === "") return word; var lowered = word.toLowerCase(); return lowered.charAt(0).toUpperCase() + lowered.slice(1); } function kuToSentenceCase(text) { var lowered = text.toLowerCase(); return lowered.replace(kuSentenceBreakRE, function (match) { var idx = match.length - 1; return match.slice(0, idx) + match.charAt(idx).toUpperCase(); }); } // Capitalizes one "word chunk": handles leading/trailing punctuation // ("(çîroka" -> "(Çîroka"), hyphenated compounds ("kurdî-gerşûnî" -> // "Kurdî-Gerşûnî"), and keeps ignoredWords entries lowercase unless // forced (first word of the text, or right after an opening // bracket/quote). function kuCapitalizeWordChunk(chunk, forceCapitalize) { var leading = (chunk.match(kuNonLetterLeadingRE) || [""])[0]; var trailing = (chunk.match(kuNonLetterTrailingRE) || [""])[0]; var core = chunk.slice(leading.length, chunk.length - trailing.length); if (core === "") return chunk; if (/[(["'‘“]/.test(leading)) forceCapitalize = true; var loweredCore = core.toLowerCase(); var isStopWord = !forceCapitalize && ignoredWords[loweredCore]; var newCore; if (isStopWord) { newCore = loweredCore; } else { newCore = core.split("-").map(function (part) { return kuCapitalizeFirstLetter(part); }).join("-"); } return leading + newCore + trailing; } function kuToTitleCase(text) { var wordIndex = 0; return text.split(/(\s+)/).map(function (chunk) { if (chunk === "" || /^\s+$/.test(chunk)) return chunk; var isFirstWord = wordIndex === 0; wordIndex++; return kuCapitalizeWordChunk(chunk, isFirstWord); }).join(""); } $.kuApplyCase = function (text, form) { switch (form) { case "upper": return text.toUpperCase(); case "lower": return text.toLowerCase(); case "sentence": return kuToSentenceCase(text); case "title": return kuToTitleCase(text); default: return text; } }; function getLinkifyTool() { return { type: "button", action: { type: "callback", execute: function () { mw.loader.using("jquery.textSelection", function () { var selection = $("#wpTextbox1").textSelection("getSelection"); $.kuLinkify(selection, function (linkedText) { if (!linkedText) return; $("#wpTextbox1").textSelection("encapsulateSelection", { peri: linkedText, replace: true }); }, $.kuLinkify_debug); }); } }, label: getMessage("toolbarButtonName"), icon: "//upload.wikimedia.org/wikipedia/commons/8/8f/OOjs_UI_icon_wikiText-progressive.svg" }; } function getDelinkifyTool() { return { type: "button", action: { type: "callback", execute: function () { mw.loader.using("jquery.textSelection", function () { var selection = $("#wpTextbox1").textSelection("getSelection"); var plainText = $.kuDelinkify(selection); if (plainText === selection) return; $("#wpTextbox1").textSelection("encapsulateSelection", { peri: plainText, replace: true }); }); } }, label: getMessage("delinkifyButtonName"), icon: "//upload.wikimedia.org/wikipedia/commons/e/eb/OOjs_UI_icon_noWikiText-rtl-progressive.svg" }; } // Applies a case transform to the current textbox selection and writes the // result back in place. Shared by every option in the case-change dropdown. function applyCaseToSelection(form) { mw.loader.using("jquery.textSelection", function () { var selection = $("#wpTextbox1").textSelection("getSelection"); if (!selection) return; var converted = $.kuApplyCase(selection, form); if (converted === selection) return; $("#wpTextbox1").textSelection("encapsulateSelection", { peri: converted, replace: true }); }); } // The built-in wikiEditor "select" tool type (used for e.g. the core // "heading" dropdown) is supposed to close itself both on selecting an // option and on re-clicking its label, but that toggle lives entirely // inside jquery.wikiEditor.toolbar.js and isn't something a gadget can // patch if it misbehaves on a given wiki's deployed version. To make the // close behavior actually reliable, this builds the dropdown by hand as a // wikiEditor "element" tool (a raw DOM element wikiEditor just drops into // the toolbar) and manages its own open/closed state directly, while still // reusing wikiEditor's existing tool-select/label/menu/options/option CSS // classes so it looks identical to a native dropdown. function buildCaseChangeElement() { var forms = [ { key: "upper", label: getMessage("caseUpperLabel") }, { key: "lower", label: getMessage("caseLowerLabel") }, { key: "sentence", label: getMessage("caseSentenceLabel") }, { key: "title", label: getMessage("caseTitleLabel") } ]; var $select = $("<div>").addClass("tool tool-select").attr("rel", "caseChange"); var $options = $("<div>").addClass("options"); var $menu = $("<div>").addClass("menu").append($options).hide(); // Toggling both the class (for anyone's CSS keyed off .options-shown) // and an explicit .show()/.hide() (so the menu is guaranteed to // actually disappear even if that CSS rule is missing or overridden). function closeMenu() { $select.removeClass("options-shown"); $menu.hide(); $label.attr("aria-expanded", "false"); } function openMenu() { // Only one such dropdown open at a time. $(".tool-select").not($select).removeClass("options-shown").find(".menu").hide(); $select.addClass("options-shown"); $menu.show(); $label.attr("aria-expanded", "true"); } $.each(forms, function (i, form) { $("<a>") .addClass("option") .attr({ rel: form.key, tabindex: 0, role: "menuitem" }) .text(form.label) .on("mousedown", function (e) { e.preventDefault(); return false; }) .on("click keydown", function (e) { if (e.type === "click" || (e.type === "keydown" && e.key === "Enter")) { applyCaseToSelection(form.key); closeMenu(); e.preventDefault(); return false; } }) .appendTo($options); }); var $label = $("<a>") .addClass("label skin-invert") .text(getMessage("caseChangeLabel")) .attr({ role: "button", tabindex: 0, "aria-expanded": "false", "aria-haspopup": "menu" }) .on("mousedown", function (e) { e.preventDefault(); return false; }) .on("click keydown", function (e) { if (e.type === "click" || (e.type === "keydown" && e.key === "Enter")) { if ($select.hasClass("options-shown")) { closeMenu(); } else { openMenu(); } e.preventDefault(); return false; } }); $select.append($label, $menu); // Close on any click elsewhere on the page. Namespaced and re-bound // via .off() first so re-registering this tool never stacks up // duplicate document-level handlers. $(document).off("mousedown.kuCaseChange").on("mousedown.kuCaseChange", function (e) { if (!$(e.target).closest($select).length) { closeMenu(); } }); return $select; } function getCaseChangeTool() { return { type: "element", element: buildCaseChangeElement }; } function addLinkifyButton() { var $textbox = $("#wpTextbox1"); // Nothing to attach to on this page (VisualEditor, 2017 editor, non-edit // pages, etc.) — bail out instead of silently binding to an empty set. if (!$textbox.length) return; if ($.kuLinkify) { $textbox.after($(mw.html.element("div", { id: "linkify-progress", title: getMessage("toolbarButtonName") })).hide()); } // A single source of truth for the three tools, so both registration // paths below build identical (but never duplicate) tool objects. function buildTools() { return { linkify: getLinkifyTool(), delinkify: getDelinkifyTool(), caseChange: getCaseChangeTool() }; } // Sends the toolbar-build event and the mw.loader.using("ext.wikiEditor") // callback below race each other -- either the event can fire before // ext.wikiEditor resolves, or (very rarely) the main section can already // be built by the time ext.wikiEditor resolves, having fired and gone // before this script even attached its listener. Exactly one of the two // paths should end up adding the tools; without this flag, both were // firing on ordinary page loads (the event fires during the normal // build, and by the time the mw.loader.using callback runs afterward // context.modules.toolbar already exists too, since it always will once // the toolbar has finished building) -- silently doubling every tool in // the group. var toolsAdded = false; // Bind the listener immediately, synchronously, rather than inside the // mw.loader.using("ext.wikiEditor", ...) callback. If we wait for that // callback to fire before attaching the listener, ext.wikiEditor may // already be loaded and may have already built (and fired the event for) // the main toolbar section by the time our callback runs -- in which case // the event has already come and gone and our button never gets added. // Attaching the listener up front means we won't miss the event even if // ext.wikiEditor resolves "instantly" (e.g. already cached/loaded). $textbox.on('wikiEditor-toolbar-buildSection-main', function (evt, section) { $.extend(section.groups.insert.tools, buildTools()); toolsAdded = true; }); mw.loader.using("ext.wikiEditor", function () { // If the event above already fired (the normal case on every // ordinary page load), the tools are already in place -- don't add // them again. if (toolsAdded) return; // Fallback for the case where the toolbar's main section was already // built (and the event already fired and gone) before this gadget's // script even started executing -- e.g. another gadget loaded // ext.wikiEditor earlier and the toolbar finished initializing // first. In that case the listener above is too late, so we check // whether the toolbar context already exists and, if so, add the // tools directly via the public addToToolbar API instead of waiting // for an event that has already happened. var context = $textbox.data("wikiEditor-context"); if (context && context.modules && context.modules.toolbar) { $textbox.wikiEditor("addToToolbar", { section: "main", group: "insert", tools: buildTools() }); toolsAdded = true; } }); }; // Only try to add the button on pages that actually have an edit form -- // running unconditionally on every page load (including view/history/etc. // pages where #wpTextbox1 never exists) wastes a mw.loader.using round trip // and can look like "sometimes nothing happens" if a user doesn't realize // they weren't on an edit screen. if ($.inArray(mw.config.get("wgAction"), ["edit", "submit"]) !== -1) { addLinkifyButton(); } })(jQuery); 4pxmj5q7gh2fopboktblj8tzgg2oy70 Bikarhêner:Wikihez/Gadget-start.js 2 974484 6265553 6265457 2026-07-19T12:17:38Z Wikihez 7344 6265553 javascript text/javascript // Li ser [[vi:MediaWiki:Gadget-start.js]] hatiye refaktorkirin. //<nowiki> $(function () { var ns = mw.config.get("wgNamespaceNumber"); if (ns && !(ns === 2 && mw.config.get("wgPageName").match(/\/ceribandin$|\/test$/))) { return; } var action = mw.config.get("wgAction"); var pageExists = !!mw.config.get("wgArticleId"); // "Zimanek lê zêde bike" mode: triggered from the portlet link below. // Runs the same wizard on an EXISTING page's edit form, but appends the // generated section instead of replacing the textarea's content. var addLangMode = pageExists && mw.util.getParamValue("wiktkuaddlang") === "1"; // On a normal page view of an existing page, just add the portlet link // that takes the user into addLangMode; don't build anything else here. if (action === "view" && pageExists) { mw.util.addPortletLink("p-views", mw.util.getUrl(mw.config.get("wgPageName"), { action: "submit", wiktkuaddlang: "1" }), "+Ziman/beşeke din", "ca-wiktku-addlang", "Ji vê rûpelê re zimanekî nû zêde bike"); return; } if (!(action === "edit" || action === "submit")) { return; } if (!addLangMode && !$(".mw-newarticletext, .mw-newarticletextanon").length) { return; } if (window.location.href.includes("editintro=User:Wikihez/creation/intro")) { return; // Do not run the script wextê WF:Bilez dişuxile } function capitalize(str) { if (!str) return str; return str[0].toUpperCase() + str.substr(1); } function decapitalize(str) { if (!str) return str; return str[0].toLowerCase() + str.substr(1); } function escapeRegExp(str) { return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); } function stripWikilinks(str) { return str.replace(/\[\[([^\]|]+)(?:\|([^\]]+))?\]\]/g, function (m, target, display) { return display || target; }); } function insertAtCursor(el, text) { var start = el.selectionStart; var end = el.selectionEnd; var val = el.value; el.value = val.slice(0, start) + text + val.slice(end); var pos = start + text.length; el.selectionStart = el.selectionEnd = pos; } var pageName = mw.config.get("wgPageName").replaceAll(/_/g, " "); if (ns) pageName = pageName.replace(/.*\//, ""); var pageNameRe = escapeRegExp(pageName); var userLang = mw.config.get("wgUserLanguage"); // Mobile detection: MobileFrontend sets wgMFMode, or fall back to touch check. var isMobile = !!mw.config.get("wgMFMode") || window.matchMedia("(pointer: coarse)").matches; var chosenOptions = { width: "20em", disable_search_threshold: 0, placeholder_text_single: "Yekî hilbijêre", placeholder_text_multiple: "Hilbijêre", no_results_text: "Nehat dîtin", enable_split_word_search: true, search_contains: true }; function wrapNativeSelect(select) { var placeholder = select.attr("data-placeholder") || "Lê bigere…"; // Hide the native select — we drive it programmatically. select.hide(); var wrapper = $("<span class='wiktku-native-select-wrap'></span>"); var textInput = $("<input type='search' autocomplete='off'>") .attr("placeholder", placeholder) .addClass("wiktku-start-narrow wiktku-ac-input"); var resultsList = $("<ul class='wiktku-ac-results'></ul>").hide(); // Full option cache — rebuilt when chosen:updated fires. var allOptions = []; function cacheOptions() { allOptions = []; select.find("option").each(function () { var v = $(this).val(); if (!v) return; // skip the empty placeholder option allOptions.push({ value: v, text: $(this).text(), disabled: $(this).prop("disabled") }); }); } cacheOptions(); function showResults(query) { var q = query.trim().toLowerCase(); resultsList.empty(); var matched; if (q) { matched = []; $.each(allOptions, function (_, o) { if (o.disabled) return; var codeMatch = o.value.toLowerCase().indexOf(q) !== -1; var nameMatch = o.text.toLowerCase().indexOf(q) !== -1; if (codeMatch || nameMatch) { matched.push({ opt: o, codeMatch: codeMatch }); } }); // Code matches (especially prefix matches) come first. matched.sort(function (a, b) { var aCode = a.opt.value.toLowerCase(); var bCode = b.opt.value.toLowerCase(); var aPrefix = aCode.indexOf(q) === 0; var bPrefix = bCode.indexOf(q) === 0; if (aPrefix !== bPrefix) return aPrefix ? -1 : 1; if (a.codeMatch !== b.codeMatch) return a.codeMatch ? -1 : 1; return 0; }); matched = matched.map(function (item) { return item.opt; }); } else { matched = allOptions.filter(function (o) { return !o.disabled; }); } if (!matched.length) { resultsList.hide(); return; } $.each(matched.slice(0, 50), function (_, opt) { var li = $("<li></li>").text(opt.text).attr("data-value", opt.value); // Use touchend instead of touchstart so that a scroll gesture does // not accidentally select an item. We track whether the finger moved // between touchstart and touchend — if it did, it was a scroll. var touchMoved = false; li.on("touchstart", function () { touchMoved = false; }); li.on("touchmove", function () { touchMoved = true; }); li.on("touchend", function (e) { if (touchMoved) return; // was a scroll, not a tap e.preventDefault(); selectOption(opt.value, opt.text); }); // Keep mousedown for desktop fallback. li.on("mousedown", function (e) { e.preventDefault(); selectOption(opt.value, opt.text); }); resultsList.append(li); }); // Position the list above or below depending on available viewport space. var inputRect = textInput[0].getBoundingClientRect(); var viewportH = window.innerHeight; var spaceBelow = viewportH - inputRect.bottom - 8; var spaceAbove = inputRect.top - 8; var maxH = Math.min(224, Math.max(spaceBelow, spaceAbove)); // 224px ≈ 14em resultsList.css({ "max-height": maxH + "px", "top": spaceBelow >= spaceAbove ? "100%" : "auto", "bottom": spaceBelow >= spaceAbove ? "auto" : "100%" }); resultsList.show(); } function selectOption(value, text) { textInput.val(text); select.val(value); resultsList.hide(); select.trigger("change"); } textInput.on("input focus", function () { showResults($(this).val()); }); textInput.on("blur", function () { // Short delay so a touchstart on a result item fires first. setTimeout(function () { resultsList.hide(); }, 200); }); // chosen:updated → re-cache (called after ziman.json loads). select.on("chosen:updated", function () { cacheOptions(); // If a value is already selected, keep the display text in sync. var cur = select.val(); if (cur) { var match = $.grep(allOptions, function (o) { return o.value === cur; })[0]; if (match) textInput.val(match.text); } }); // No-op .chosen() so desktop call-sites don't need guarding. select.chosen = function () { return select; }; wrapper.append(textInput).append(resultsList).append(select); return wrapper; } var langsByCode = {}; // Populated from [[MediaWiki:Gadget-start.js/data.json]] at runtime. var metadata = {}; // Zaravayên kurdî yên ku di beşa "Bi zaravayên din" de tên pêşkêşkirin — // ev kod ji beşa Werger têne derxistin daku heman zimên du caran neyê xwendin. var ZARAVA_LANG_CODES = ["ckb", "sdh", "lki", "hac", "zza"]; function getZaravaKeys(choices) { var byCode = {}; $.each(choices || [], function (_, c) { byCode[c[0]] = c; }); var result = []; $.each(ZARAVA_LANG_CODES, function (_, code) { if (byCode[code]) result.push(byCode[code]); }); return result; } function needsTransliteration(langCode) { var meta = metadata[langCode]; if (!meta || !meta.sc) return false; var scripts = Array.isArray(meta.sc) ? meta.sc : [meta.sc]; return scripts.length > 0 && scripts[0] !== "Latn"; } // Kodên cinsiyetê yên di metadata.g de var GENDER_BASE_LABELS = { m: "mê", n: "nêr", nt: "nêtar", mn: "mê û nêr", mnmane: "mê yan nêr li gorî maneyê", g: "giştî", y: "yekjimar", p: "pirjimar" }; // Sub-lists that only make sense for a plain (non-şablon) sense — hidden // when a şablon (e.g. {{guharto|…}}) is chosen for that sense, since a // template-based sense has no "own" gloss for alternate forms, synonyms, // antonyms, coordinate terms, hypernyms or hyponyms to attach to. Etîket, // Nimûne and Jêgirtin stay visible either way. var HIDDEN_ON_TPL_GROUPS = [ "wiktku-dfn-alternativ", "wiktku-dfn-hevmane", "wiktku-dfn-dijmane", "wiktku-dfn-koordine", "wiktku-dfn-jornav", "wiktku-dfn-jernav" ]; function genderLabel(code) { if (code === "p") return "Pirjimar"; var pluralMatch = code.match(/^(.+)-p$/); if (pluralMatch && GENDER_BASE_LABELS[pluralMatch[1]]) { return GENDER_BASE_LABELS[pluralMatch[1]] + " (pirjimar)"; } return GENDER_BASE_LABELS[code] || code; } /** * True if a sense has any content worth keeping besides its mane text — * etîket, hevmane/dijmane/koordîne/etc. word lists, nimûne, or jêder * (quote). Used so a sense with an empty mane but filled-in extra * fields still gets emitted (with {{mane?}} standing in for the gloss) * instead of being silently dropped. */ function senseHasExtraContent(s) { if (s.etiket && $.grep(s.etiket, function (e) { return $.trim(e) !== ""; }).length) return true; if (s.alternativ.length || s.hevmane.length || s.dijmane.length || s.koordine.length || s.jornav.length || s.jernav.length) return true; if (s.nimune && $.grep(s.nimune, function (n) { return (typeof n === "object" ? n.text : n) !== ""; }).length > 0) return true; if (s.jeder && $.grep(s.jeder, function (j) { return j && j.quote; }).length > 0) return true; return false; } /** * formatNimune: each nimûne item can be { text, tr, t }: * text — example text * tr — transliteration (only when the language needs it) * t — Kurdish translation (third positional param, no key) */ function formatNimune(nimunes, lang, hasJeder) { var hasNimune = nimunes && $.grep(nimunes, function (n) { return (typeof n === "object" ? n.text : n) !== ""; }).length > 0; if (!hasNimune) { return hasJeder ? "" : "\n#* {{bênimûne|" + lang + "}}"; } return $.map(nimunes, function (n) { var text = typeof n === "object" ? n.text : n; if (!text) return undefined; var bolded = text.replace( new RegExp("(" + pageNameRe + "([^( |,|;|\\?|\\.|\\!)]+)?)", "ig"), "'''$1'''"); var tpl = "\n#: {{nm|" + lang + "|" + bolded; if (typeof n === "object") { if (n.tr) tpl += "|tr=" + n.tr; // Translation as third positional param (no key needed). if (n.t) tpl += "|" + n.t; } // Short examples fit on one line together with their translation. // rêz=1 is not used for ku — definitions are shown on separate lines there. if (text.length < 200 && lang !== "ku") tpl += "|rêz=1"; tpl += "}}"; return tpl; }).join(""); } /** * Formats a list of jêder (quote/citation) objects into wikitext lines. * Each entry that has no quote text is skipped. Returns "" when the list * is empty or every entry is blank. * * #* {{jêder-…|lang|jêgirtin=…|tr=…|tercime=…|…fields…}} * * When no template is chosen, the generic {{jêder|…}} template is used * instead. Its 2nd positional param is the user's freeform "bi destê xwe * binivîsim" source text when supplied, or the çavkanî? placeholder otherwise. * If that text contains "=" it is passed as |2=… instead of a bare * positional param, since MediaWiki would otherwise misparse it as its * own key=value pair and break the template: * #* {{jêder|lang|jêgirtin=…|tr=…|tercime=…|<manual source or çavkanî?>}} */ function formatJeder(jederList, lang) { if (!jederList || !jederList.length) return ""; return $.map(jederList, function (jeder) { if (!jeder || !jeder.quote) return undefined; if (jeder.jederTpl) { var cite = "\n#* {{" + jeder.jederTpl + "|" + lang; cite += "|jêgirtin=" + jeder.quote; if (jeder.quoteTr) cite += "|tr=" + jeder.quoteTr; if (jeder.quoteT) cite += "|tercime=" + jeder.quoteT; $.each(jeder.jêderFields || {}, function (key, val) { if (val) cite += "|" + key + "=" + val; }); cite += "}}"; return cite; } var out = "\n#* {{jêder|" + lang + "|jêgirtin=" + jeder.quote; if (jeder.quoteTr) out += "|tr=" + jeder.quoteTr; if (jeder.quoteT) out += "|tercime=" + jeder.quoteT; var srcParam = jeder.jederManual ? jeder.jederManual : "çavkanî?"; // A positional param containing "=" gets parsed as its own key=value // pair by MediaWiki and breaks the template, so force it to be // explicitly named (|2=) whenever that's the case. out += (srcParam.indexOf("=") !== -1 ? "|2=" : "|") + srcParam; out += "}}"; return out; }).join(""); } function makeWordListStep(id, name, question_fmt, header, templateName) { return { id: id, name: name, question_fmt: question_fmt, multiple: true, narrow: true, visible: function (values) { return values.lang && values.pos; }, output: function (values) { var words = $.grep(values[id] || [], function (w) { return !!w; }); if (!words.length) return ""; var lang = values.lang; var section = "\n==== " + header + " ====\n"; if (words.length === 1) { // Single word — keep the simple inline template. return section + "* {{" + templateName + "|" + lang + "|" + words[0] + "}}\n"; } // Multiple words — use {{kol3}} with one positional param per word. var params = "cure=" + header + "\n" + $.map(words, function (w) { return "|" + w; }).join("\n"); return section + "{{kol3|" + lang + "|" + params + "\n}}\n"; } }; } var steps = { lang: { id: "lang", required: true, name: "ziman", question_fmt: '"' + pageName + '" bi çi zimanî ye?', question_br: true, // Populated from [[MediaWiki:Gadget-start.js/data.json]] (langChoices). choices: [], output: function (values) { return "== {{ziman|" + values.lang + "}} ==\n"; } }, pron: { id: "pron", name: "bilêvkirin", question_fmt: '"' + pageName + '" çawa tê telafûzkirin?', // pronTpls populated from data.json pronTpls: [], visible: function (values) { if (!values.lang) return false; // In addLangMode, only skip pron when this langcode's section // already exists in the page — if it's a new language, show it. if (addLangMode) { var existing = $("#wpTextbox1").val() || ""; var header = "== {{ziman|" + values.lang + "}} =="; return existing.indexOf(header) === -1; } return true; }, /** Fills (or refills) the insert-dropdown from the current pronTpls array, filtering by language. */ refreshTplSelect: function () { var sel = $("#wiktku-start-pron .wiktku-tpl-insert-select"); if (!sel.length) return; var lang = getValues().lang || ""; sel.find("option[value!='']").remove(); $.each(steps.pron.pronTpls, function (_, tpl) { // Filter: if tpl.langs exists, only show if lang is in that list; otherwise show always var allowed = !tpl.langs || tpl.langs.indexOf(lang) !== -1; if (allowed) { sel.append($("<option></option>") .val(tpl.snippet) .text(tpl.name + " — " + tpl.desc) .attr("data-nolang", tpl.noLang ? "1" : "")); } }); // Notify Chosen that the option list has changed (no-op on mobile). if (!isMobile) sel.trigger("chosen:updated"); }, build: function (stepDiv) { if (stepDiv.find(".wiktku-pron-wrap").length) return null; var wrap = $("<div class='wiktku-pron-wrap'></div>"); var ta = $("<textarea></textarea>") .attr("name", "wiktku-pron-" + $.now()) .attr("class", "wiktku-start-step-field wiktku-pron-text") .attr("rows", 4) .attr("placeholder", "Nimûne: {{IPA|ku|/pɛɪ̯n/}} yan {{kîte|ku|he|ce|ki|rin}}"); // Template insert dropdown — filtered by language. var sel = $("<select class='wiktku-tpl-insert-select'></select>"); sel.append($("<option value=''>— şablonek lê zêde bike —</option>")); var lang = getValues().lang || ""; $.each(steps.pron.pronTpls, function (_, tpl) { // Filter: if tpl.langs exists, only show if lang is in that list; otherwise show always var allowed = !tpl.langs || tpl.langs.indexOf(lang) !== -1; if (allowed) { sel.append($("<option></option>") .val(tpl.snippet) .text(tpl.name + " — " + tpl.desc) .attr("data-nolang", tpl.noLang ? "1" : "")); } }); sel.on("change", function () { var snippet = $(this).val(); if (!snippet) return; var lang = getValues().lang || ""; // Check if the selected option has noLang flag var selectedOption = sel.find("option:selected"); var hasNoLang = selectedOption.attr("data-nolang") === "1"; if (!hasNoLang) { snippet = snippet.replace(/CODE/g, lang).replace(/SOURCELANG/g, "?"); } insertAtCursor(ta[0], snippet); $(this).val(""); ta.focus(); }); wrap.append(sel).append($("<br>")).append(ta); stepDiv.append(wrap); return ta; }, output: function () { var text = $.trim($("#wiktku-start-pron .wiktku-pron-text").val()); if (!text) return ""; var lines = text.split("\n"); var out = $.map(lines, function (line) { line = $.trim(line); if (!line) return undefined; return line.charAt(0) === "*" ? line : "* " + line; }).join("\n"); return "\n=== Bilêvkirin ===\n" + out + "\n"; } }, pos: { id: "pos", required: true, name: "Cureyê rêzimanî", question_fmt: 'Cureyê rêzimanî yê "' + pageName + '" çi ye?', visible: function (values) { return values.lang; }, question_br: true, // Populated from [[MediaWiki:Gadget-start.js/data.json]] (posChoices). choices: [], output: function (values) { var pos = values.pos || ""; var cinsiyet = values.cinsiyet || ""; // from the cinsiyet step var lekTur = values.lektur || ""; // from the lêker transitivity step var capitalizedPos = capitalize(pos); var outputString = "\n=== " + capitalizedPos + " ===\n"; // Add ku-tewîn-nav for single-word navdêr/serenav with known gender. if (!pageName.includes(" ") && cinsiyet && GENDER_BASE_LABELS[cinsiyet] && (pos === "navdêr" || pos === "serenav") && values.lang === "ku") { outputString += "{{ku-tewîn-nav|" + pageName + "|" + GENDER_BASE_LABELS[cinsiyet]; if (pos === "serenav") outputString += "|y"; outputString += "}}\n"; } outputString += "{{" + pos + "|" + values.lang; if (pos === "navdêr" || pos === "serenav") { if (cinsiyet) { outputString += "|c=" + cinsiyet; } else if (values.lang === "ku") { // Unknown gender — prompt editor to fill it in. outputString += "|c=?"; } } else if (/^lêker/.test(pos) && lekTur) { outputString += "|c=" + lekTur; } if (values.tr) { outputString += "|tr=" + values.tr; } outputString += "}}\n"; return outputString; } }, /** * cinsiyet (grammatical gender) — only shown for navdêr/serenav, û * tenê ger metadata ji bo zimanê hilbijartî lîsteyeke "g" (cinsiyet) * were dayîn. Opsiyonên vê gavê ne sabît in — ji metadata[values.lang].g * têne çêkirin, ji ber ku di hemû zimanan de cinsiyet tine. */ cinsiyet: { id: "cinsiyet", name: "cinsiyet", question_fmt: 'Cinsiyeta "' + pageName + '" çi ye?', question_br: true, visible: function (values) { var meta = metadata[values.lang]; return !!(values.lang && (values.pos === "navdêr" || values.pos === "serenav") && meta && meta.g && meta.g.length); }, build: function (stepDiv, values) { var select = stepDiv.find("select.wiktku-start-step-field"); if (!select.length) { select = $(mw.html.element("select", { "class": "wiktku-start-step-field", id: "wiktku-start-cinsiyet-field" })); stepDiv.append(select); } if (!values) return select; var meta = metadata[values.lang]; var codes = (meta && meta.g) || []; var prevVal = select.val(); var choices = $.map(codes, function (code) { return [[code, genderLabel(code)]]; }); populateMenus(select, choices); if ($.grep(choices, function (c) { return c[0] === prevVal; }).length) { select.val(prevVal); } if (!isMobile) select.trigger("chosen:updated"); return select; }, output: function () { return ""; } // consumed by pos.output }, /** * Lêker transitivity — only shown for any lêker variant. */ lektur: { id: "lektur", name: "Cureyê lêkerê (fiîlê)", question_fmt: "Cureyê lêkerê (fiîlê) çi ye?", question_br: true, visible: function (values) { return values.lang && values.pos && /^lêker/.test(values.pos); }, // Dictionary: value → display label. Add new types here. choices: [ ["gh", "gerguhêz"], ['x-gh', 'xwerû-gerguhêz'], ['p-gh', 'pêkhatî-gerguhêz'], ['h-gh', 'hevedudanî-gerguhêz'], ['b-gh', 'biwêjî-gerguhêz'], ["ngh", "negerguhêz"], ['x-ngh', 'xwerû-negerguhêz'], ['p-ngh', 'pêkhatî-negerguhêz'], ['h-ngh', 'hevedudanî-negerguhêz'], ['b-ngh', 'biwêjî-negerguhêz'] ], output: function () { return ""; } // consumed by pos.output }, tr: { id: "tr", name: "transkrîpsiyon", question_fmt: "Transkrîpsiyona kelîmeyê", multiple: false, narrow: true, visible: function (values) { return values.lang && values.pos && needsTransliteration(values.lang); } }, dfn: { id: "dfn", // required: true, ger mane tinebe [[Şablon:mane?]] bi kar bîne name: "Mane", question_fmt: "Maneya kelîmeyê binivîse. Mane otomatîk tê lînkkirin! Ji bo tercimeyan beşa 'Werger' bi kar bîne!", multiple: true, ordered: true, rows: 3, visible: function (values) { return values.lang && values.pos; }, example: function (values) { // posExamples loaded from [[MediaWiki:Gadget-start.js/data.json]]. var examples = steps.dfn.posExamples || {}; var full = values.pos || ""; return examples[full] || ""; }, /** * Builds one sense block (<li>) inside the ordered list. * Each block contains: * - a textarea for the definition * - an expandable nimûne list * - single-row sub-lists for formên alternatîv, hevmane, dijmane */ buildSenseBlock: function (stepDiv) { var block = $("<li class='wiktku-dfn-sense'></li>"); // — Mane textarea (declared first so the template handler can reference it) — var dfnArea = $("<textarea></textarea>") .attr("name", "wiktku-dfn-mane-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("class", "wiktku-start-step-field wiktku-dfn-mane") .attr("rows", 6) .attr("placeholder", "Mane…"); dfnArea.on("input", function () { steps.dfn.onDfnInput(stepDiv, block, this); }); // — Template selector (optional — replaces mane when chosen) — // Template definitions loaded from [[MediaWiki:Gadget-start.js/data.json]]. var tplDefs = steps.dfn.tplDefs || []; // Cache of all non-placeholder option elements — used by updateTplOptions // to remove/re-add options (the only approach compatible with Chosen.js). var _allTplOptions = []; var tplSelect = $(mw.html.element("select", { "class": "wiktku-dfn-tpl-select" })); tplSelect.append($("<option value=''>— yan jî şablonek hilbijêre —</option>")); $.each(tplDefs, function (_, tpl) { var opt = $("<option></option>") .val(tpl.name) .text(tpl.name) .attr("data-langs", tpl.langs ? tpl.langs.join(",") : "") .attr("data-nolang", tpl.noLang ? "1" : ""); tplSelect.append(opt); _allTplOptions.push(opt[0]); }); function updateTplOptions() { var lang = getValues().lang || ""; var currentVal = tplSelect.val(); var currentStillValid = false; // Detach all non-placeholder options, then re-attach only the visible ones. // This is the only approach that works correctly with both native <select> // and Chosen.js on desktop. tplSelect.find("option[value!='']").detach(); $.each(_allTplOptions, function (_, opt) { var allowed = $(opt).attr("data-langs"); var visible = !allowed || allowed.split(",").indexOf(lang) !== -1; if (visible) { tplSelect.append(opt); if ($(opt).val() === currentVal) currentStillValid = true; } }); if (!isMobile) tplSelect.trigger("chosen:updated"); if (currentVal && !currentStillValid) { tplSelect.val(""); dfnArea.show(); tplTitleInput.hide().val(""); } } // Store updater on the element so refresh() can call it for all blocks. tplSelect.data("updateOptions", updateTplOptions); var tplTitleInput = $("<input type='text'>") .addClass("wiktku-dfn-tpl-title wiktku-start-narrow") .attr("placeholder", "Navê rûpelê…") .hide(); // Grow the sense list when the title field of the last block gets content, // mirroring what onDfnInput does for the plain mane textarea. tplTitleInput.on("input", function () { steps.dfn.onDfnInput(stepDiv, block, this); }); /** * When a şablon sense is chosen, formên alternatîv/hevmane/dijmane/ * termên koordîne/jornav/jêrnav don't apply (there's no plain gloss * to hang them off), so hide those subgroups. Etîket, Nimûne and * Jêgirtin stay visible and still usable for a şablon sense. */ function updateFieldVisibility() { var isTpl = !!tplSelect.val(); $.each(HIDDEN_ON_TPL_GROUPS, function (_, cls) { block.find("." + cls + "-group").toggle(!isTpl); }); } // Store on the block so restoreDfn() can re-sync visibility // after programmatically setting tplSelect's value. block.data("updateFieldVisibility", updateFieldVisibility); tplSelect.on("change", function () { var chosen = $(this).val(); if (chosen) { dfnArea.hide(); tplTitleInput.show().focus(); } else { dfnArea.show(); tplTitleInput.hide().val(""); } updateFieldVisibility(); // Re-run refresh so the Werger step visibility updates. refresh(); }); var tplRow = $("<div></div>").addClass("wiktku-dfn-tpl-row") .append(tplSelect).append(" ").append(tplTitleInput); block.append(tplRow); block.append(dfnArea); // Apply lang filter on initial build. updateTplOptions(); // — Sub-field groups — // All groups are always visible with a placeholder textarea. // Nimûne is last in the DOM and last in the output. var allGroups = [ { cls: "wiktku-dfn-etiket", label: "Etîket", rows: 1, narrow: true, izah: "xisûsen, Mêrdîn, anatomî, Badînî" }, { cls: "wiktku-dfn-alternativ", label: "Formên alternatîv", rows: 1, narrow: true, izah: "Varyantên vê kelîmeyê" }, { cls: "wiktku-dfn-hevmane", label: "Hevmane", rows: 1, narrow: true, izah: "Spehî hevmaneya Bedew e." }, { cls: "wiktku-dfn-dijmane", label: "Dijmane", rows: 1, narrow: true, izah: "Zengîn dijmaneya feqîr e." }, { cls: "wiktku-dfn-koordine", label: "Termên koordîne", rows: 1, narrow: true, izah: "Pisîk û kûçik termên koordîne ne çunkî Jornavên wan gelek in" }, { cls: "wiktku-dfn-jornav", label: "Jornav", rows: 1, narrow: true, izah: "Heywan jornavê guhandar e" }, { cls: "wiktku-dfn-jernav", label: "Jêrnav", rows: 1, narrow: true, izah: "Guhandar jêrnavê heywan e" }, { cls: "wiktku-dfn-nimune", label: "Nimûne", rows: 2, narrow: false } ]; $.each(allGroups, function (_, g) { var groupDiv = $("<div></div>").addClass("wiktku-dfn-subgroup " + g.cls + "-group"); function buildNimuneLi() { var lang = getValues().lang || ""; var li = $("<li></li>").addClass("wiktku-dfn-nimune-li"); var mainTa = $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-text-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", g.rows) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-text") .attr("placeholder", "Nimûneya emilandina kelîmeyê tu bi xwe binivîse…"); mainTa.on("input", function () { var val = $.trim($(this).val()); var isLast = li.is(list.children("li:last-child")); if (val && isLast) { list.append(buildNimuneLi()); } }); li.append(mainTa); var subWrap = $("<div></div>").addClass("wiktku-dfn-nimune-sub"); if (needsTransliteration(lang)) { subWrap.append( $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-tr-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 5) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-tr") .attr("placeholder", "Transkrîpsiyona bi alfabeya latînî") ); } if (lang && lang !== "ku") { subWrap.append( $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-t-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 5) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-t") .attr("placeholder", "Tercimeya kurmancî") ); } if (subWrap.children().length) li.append(subWrap); return li; } if (g.cls === "wiktku-dfn-nimune") { // Nimûne — compound widget with tr/t sub-fields. var lbl = $("<span></span>").addClass("wiktku-dfn-sublabel").text(g.label + ": "); var list = $("<ol></ol>").addClass("wiktku-dfn-sublist " + g.cls + "-list"); groupDiv.data("buildNimuneLi", buildNimuneLi); list.append(buildNimuneLi()); groupDiv.append(lbl).append(list); block.append(groupDiv); } else { // Regular always-visible group — label + growing textarea list. var lbl = $("<span></span>").addClass("wiktku-dfn-sublabel").text(g.label + ": " + g.izah); var list = $("<ol></ol>").addClass("wiktku-dfn-sublist " + g.cls + "-list"); var firstInput = $("<textarea></textarea>") .attr("name", g.cls + "-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", g.rows) .attr("class", "wiktku-dfn-subfield" + (g.narrow ? " wiktku-start-narrow" : "")) .attr("placeholder", g.label + "…"); firstInput.on("input", function () { steps.dfn.onSubInput(list, this, g.rows, g.narrow); }); list.append($("<li></li>").append(firstInput)); groupDiv.append(lbl).append(list); block.append(groupDiv); } }); // — Jêder (quote / citation) group — a growing list, sibling to Nimûne — // Structured the same way as Nimûne (ol.wiktku-dfn-sublist > li) so it // lines up at the same indentation, and so that typing into the last // citation's Jêgirtin box automatically opens a fresh empty one below it. (function () { var jederGroupDiv = $("<div></div>").addClass("wiktku-dfn-subgroup wiktku-dfn-jeder-group"); var jederLbl = $("<span></span>").addClass("wiktku-dfn-sublabel").text("Jêgirtin: "); var jederList = $("<ol></ol>").addClass("wiktku-dfn-sublist wiktku-dfn-jeder-list"); function buildJederLi() { var lang = getValues().lang || ""; var li = $("<li></li>").addClass("wiktku-dfn-jeder-li"); var dragHandle = $("<span></span>") .addClass("wiktku-jeder-drag-handle") .attr("title", "Bişkûne û bikişîne da ku rêzê biguhezîne") .html("⠿"); // Quote text textarea var quoteTa = $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-quote-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 2) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-quote") .attr("placeholder", "Nimûneya emilandinê ji kitêb an çavkaniyeke din binivîse"); quoteTa.on("input", function () { var val = $.trim($(this).val()); var isLast = li.is(jederList.children("li:last-child")); if (val && isLast) { jederList.append(buildJederLi()); } }); li.append(dragHandle).append(quoteTa); // tr/t sub-fields for the quote — shown as needed for the language. var quoteSubWrap = $("<div></div>").addClass("wiktku-dfn-quote-sub"); if (needsTransliteration(lang)) { quoteSubWrap.append( $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-quote-tr-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 2) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-quote-tr") .attr("placeholder", "Transkrîpsiyona jêgirtinê…") ); } if (lang && lang !== "ku") { quoteSubWrap.append( $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-quote-t-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 2) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-quote-t") .attr("placeholder", "Tercimeya jêgirtinê bi kurmancî") ); } if (quoteSubWrap.children().length) li.append(quoteSubWrap); // Citoid auto-fill: fetch citation data from a URL, DOI or ISBN and // prefill the source şablon + fields below (see Gadget-citoid-helper.js). var citoidWrap = $("<div></div>").addClass("wiktku-dfn-quote-citoid"); var citoidInput = $("<input type='text'>") .addClass("wiktku-dfn-quote-citoid-input wiktku-start-narrow") .attr("placeholder", "URL, DOI an ISBN binivîse ku otomatîk were tijekirin…"); var citoidBtn = new OO.ui.ButtonWidget({ label: "Bi Citoid bîne", classes: [ "wiktku-dfn-quote-citoid-btn" ] }); var citoidStatus = $("<span></span>").addClass("wiktku-dfn-quote-citoid-status"); /** * Fetches citation data from Citoid and applies it to this * citation's şablon selector + fields. Mirrors the logic in * Form.prototype._fillFromCitoid (Gadget-wikt.add-examples.js): * - only (re)selects the şablon when it actually differs from * what's already chosen, so a repeat fetch doesn't wipe out * a template the user already picked; * - only fills fields that are currently empty, so it never * overwrites something the user typed by hand; * - falls back to the freeform "bi destê xwe binivîsim" source * only when nothing was typed there yet. */ function runCitoidFetch() { var query = $.trim(citoidInput.val()); if (!query) { mw.notify("Ji kerema xwe re pêşî URL, DOI an ISBNyekê binivîse."); return; } citoidBtn.setDisabled(true); citoidStatus.text("Tê anîn…"); wikt.citoidHelper.ensure().then(function () { return wikt.citoid.fetchJederFields(query); }).then(function (result) { var jederKey = result.jederKey; var hasTpl = !!jederKey && srcSel.find("option[value='" + jederKey + "']").length > 0; var targetVal = hasTpl ? jederKey : "__manual__"; // Only (re)select — and thus rebuild — the field rows if // we're switching to a different şablon than what's // already chosen, so a second fetch doesn't clear fields // the user already filled in by hand. if (srcSel.val() !== targetVal) { srcSel.val(targetVal).trigger("change"); srcSel.trigger("chosen:updated"); } if (hasTpl) { // Tenê qadên vala tijî bike. $.each(result.fields, function (key, val) { var input = srcFields.find("input[data-field-key='" + key + "']"); if (input.length && !$.trim(input.val())) { input.val(val); } }); } else { // Şablonek nehat naskirin ji bo vê itemType — rêzikeke // çavkaniyê ya bi destan a ji qadên Citoid tê çêkirin, // lê tenê ger qada destan vala be. var manualField = srcFields.find(".wiktku-dfn-quote-src-manual"); if (!$.trim(manualField.val())) { var parts = []; $.each(["nivîskar", "sernav", "websîte", "kovar", "weşanxane", "sal", "url"], function (_, k) { if (result.fields[k]) parts.push(result.fields[k]); }); manualField.val(parts.join(", ")); } } citoidStatus.text(""); }, function (errorMsg) { citoidStatus.text(typeof errorMsg === "string" ? errorMsg : "Nehat dîtin. Kontrol bike ka URL/DOI/ISBN rast e."); }).always(function () { citoidBtn.setDisabled(false); }); } citoidBtn.on("click", runCitoidFetch); citoidInput.on("keydown", function (e) { if (e.which === 13) { // Enter e.preventDefault(); runCitoidFetch(); } }); citoidWrap.append(citoidInput).append(citoidBtn.$element).append(citoidStatus); // Source template selector, specific to this citation. var srcSel = $("<select></select>").addClass("wiktku-dfn-quote-src-sel"); srcSel.append($("<option value=''>— Çavkaniyê hilbijêre —</option>")); srcSel.append($("<option></option>").val("__manual__").text("Bi destê xwe binivîsim")); var jederDefs = steps.dfn.jederDefs || {}; $.each(jederDefs, function (tplName, def) { srcSel.append($("<option></option>").val(tplName).text(def.label)); }); // Dynamic source fields container. var srcFields = $("<div></div>").addClass("wiktku-dfn-quote-src-fields"); srcSel.on("change", function () { srcFields.empty(); var chosen = $(this).val(); if (!chosen) return; if (chosen === "__manual__") { // Freeform source, written by the user — becomes the 2nd // positional param of {{jêder|lang|…}} instead of çavkanî?. srcFields.append( $("<textarea></textarea>") .attr("rows", 4) .addClass("wiktku-dfn-subfield wiktku-dfn-quote-src-manual") .attr("placeholder", "Çavkaniyê bi destê xwe binivîse…") ); return; } var def = (steps.dfn.jederDefs || {})[chosen]; if (!def) return; $.each(def.fields, function (_, f) { var row = $("<div></div>").addClass("wiktku-dfn-quote-src-row"); var fieldLbl = $("<label></label>").text(f.label + ": "); var inp = $("<input type='text'>") .addClass("wiktku-dfn-quote-src-input wiktku-start-narrow") .attr("data-field-key", f.key) .attr("placeholder", f.label + "…"); row.append(fieldLbl).append(inp); srcFields.append(row); }); }); li.append(citoidWrap).append(srcSel).append(srcFields); return li; } jederGroupDiv.data("buildJederLi", buildJederLi); jederList.append(buildJederLi()); // Make citation rows sortable (drag to reorder). // The last row is always the empty trailing row — cancel its drag. mw.loader.using("jquery.ui.sortable", function () { jederList.sortable({ handle: ".wiktku-jeder-drag-handle", axis: "y", items: "li:not(:last-child)", tolerance: "pointer" }); }); jederGroupDiv.append(jederLbl).append(jederList); block.append(jederGroupDiv); }()); // Apply the initial hide/show state for the sub-groups (matches // tplSelect's starting value, which is normally empty). updateFieldVisibility(); return block; }, /** Grows the sense list when the last mane textarea gets content. */ onDfnInput: function (stepDiv, block, textarea) { var val = $.trim($(textarea).val()); var list = stepDiv.find("ol.wiktku-dfn-list"); var isLast = block.is(list.children("li:last-child")); if (val && isLast) { var newBlock = steps.dfn.buildSenseBlock(stepDiv); list.append(newBlock); // Apply Chosen to the new block's template selector on desktop. if (!isMobile) newBlock.find("select.wiktku-dfn-tpl-select").chosen(chosenOptions); } refresh(); }, /** Grows a sub-list (nimûne/formên alternatîv/hevmane/dijmane/termên koordîne) on input. */ onSubInput: function (list, input, rows, narrow) { var val = $.trim($(input).val()); var item = $(input).parent(); var isLast = item.is(list.children("li:last-child")); if (val && isLast) { var next = $("<textarea></textarea>") .attr("name", "wiktku-dfn-sub-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", rows) .attr("class", "wiktku-dfn-subfield" + (narrow ? " wiktku-start-narrow" : "")); next.on("input", function () { steps.dfn.onSubInput(list, this, rows, narrow); }); list.append($("<li></li>").append(next)); } }, // Populated from [[MediaWiki:Gadget-start.js/data.json]] (tplDefs, posExamples, jederDefs). tplDefs: [], posExamples: {}, jederDefs: {}, build: function (stepDiv) { if (stepDiv.find("ol.wiktku-dfn-list").length) return null; var list = $("<ol class='wiktku-dfn-list'></ol>"); list.append(steps.dfn.buildSenseBlock(stepDiv)); stepDiv.append(list); return null; }, /** Reads all sense blocks from the DOM and returns an array of sense objects. */ getSenses: function (stepDiv) { var senses = []; stepDiv.find("li.wiktku-dfn-sense").each(function () { var block = $(this); var tplSel = block.find("select.wiktku-dfn-tpl-select"); var tpl = tplSel.val() || ""; // noLang: template already encodes the language — don't add |lang| param. var tplNoLang = tpl ? tplSel.find("option[value='" + tpl + "']").attr("data-nolang") === "1" : false; var tplTitle = $.trim(block.find("input.wiktku-dfn-tpl-title").val()); var mane = $.trim(block.find("textarea.wiktku-dfn-mane").val()); var etiket = (function () { var vals = []; block.find(".wiktku-dfn-etiket-list textarea").each(function () { var v = $.trim($(this).val()); if (v) vals.push(v); }); return vals; }()); function readList(cls) { var vals = []; block.find("." + cls + "-list textarea").each(function () { var v = $.trim($(this).val()); if (v) vals.push(v); }); return vals; } // Nimûne items are compound: { text, tr?, t? } function readNimuneList() { var items = []; block.find(".wiktku-dfn-nimune-list li.wiktku-dfn-nimune-li").each(function () { var text = $.trim($(this).find(".wiktku-dfn-nimune-text").val()); if (!text) return; var obj = { text: text }; var tr = $.trim($(this).find(".wiktku-dfn-nimune-tr").val()); var t = $.trim($(this).find(".wiktku-dfn-nimune-t").val()); if (tr) obj.tr = tr; if (t) obj.t = t; items.push(obj); }); return items; } // Jêder is a growing list of citations, one per li — mirrors readNimuneList(). function readJederList() { var items = []; block.find(".wiktku-dfn-jeder-list li.wiktku-dfn-jeder-li").each(function () { var li = $(this); var quote = $.trim(li.find(".wiktku-dfn-nimune-quote").val()); if (!quote) return; var obj = { quote: quote }; var qtr = $.trim(li.find(".wiktku-dfn-nimune-quote-tr").val()); var qt = $.trim(li.find(".wiktku-dfn-nimune-quote-t").val()); if (qtr) obj.quoteTr = qtr; if (qt) obj.quoteT = qt; var tplName = li.find(".wiktku-dfn-quote-src-sel").val(); if (tplName === "__manual__") { var manual = $.trim(li.find(".wiktku-dfn-quote-src-manual").val()); if (manual) obj.jederManual = manual; } else if (tplName) { obj.jederTpl = tplName; var fields = {}; li.find(".wiktku-dfn-quote-src-input").each(function () { var k = $(this).attr("data-field-key"); var v = $.trim($(this).val()); if (k && v) fields[k] = v; }); obj.jêderFields = fields; } items.push(obj); }); return items; } senses.push({ tpl: tpl, tplNoLang: tplNoLang, tplTitle: tplTitle, mane: mane, etiket: etiket, nimune: readNimuneList(), jeder: readJederList(), alternativ: readList("wiktku-dfn-alternativ"), hevmane: readList("wiktku-dfn-hevmane"), dijmane: readList("wiktku-dfn-dijmane"), koordine: readList("wiktku-dfn-koordine"), jornav: readList("wiktku-dfn-jornav"), jernav: readList("wiktku-dfn-jernav") }); }); return senses; }, getOutput: function (values, callback) { var stepDiv = $("#wiktku-start-dfn"); var senses = steps.dfn.getSenses(stepDiv); var lang = values.lang; // A sense counts as "filled" if it has a mane, a chosen template + title, // or any other content (etîket/hevmane/nimûne/jêder…) worth keeping. var hasMane = senses.some(function (s) { return s.mane !== "" || (s.tpl && s.tplTitle) || senseHasExtraContent(s); }); // True only when at least one sense has a regular mane (needs linkify). var hasRegularMane = senses.some(function (s) { return !s.tpl && s.mane !== ""; }); // Each sense is built as two parts: // .def — the definition line + word-list lines (safe to linkify) // .cite — nimûne + jêder lines (must NOT be linkified) // They are rejoined after linkify runs on the def parts only. var CITE_PLACEHOLDER = "\x00CITE\x00"; var citeBlocks = []; var text = $.map(senses, function (sense) { // — Template sense (e.g. {{guharto|ku|somepage}} or {{ku-Latn|somepage}}) — if (sense.tpl) { if (!sense.tplTitle) return undefined; // Etîket still applies to a şablon sense — build the same // {{e|lang|label1|label2}} prefix as a regular sense would get. var tplLabelTpl = ""; if (sense.etiket && sense.etiket.length) { var tplLabelParts = sense.etiket.map(function (part) { return $.trim(part); }).filter(function (part) { return part !== ""; }); if (tplLabelParts.length) { tplLabelTpl = " {{e|" + lang + "|" + tplLabelParts.join("|") + "}} "; } } // noLang templates encode the language in their name — omit the |lang| param. var tplCall = sense.tplNoLang ? "{{" + sense.tpl + "|" + sense.tplTitle + "}}" : "{{" + sense.tpl + "|" + lang + "|" + sense.tplTitle + "}}"; var tplLine = "#" + (tplLabelTpl ? tplLabelTpl : " ") + tplCall; // Nimûne / Jêder still apply to a şablon sense too. var tplHasJeder = sense.jeder && $.grep(sense.jeder, function (j) { return j && j.quote; }).length > 0; tplLine += formatNimune(sense.nimune, lang, tplHasJeder); tplLine += formatJeder(sense.jeder, lang); return tplLine; } // — Normal mane sense — var dfn = sense.mane; // A sense with no mane text AND nothing else filled in is // truly empty — drop it. If it has other content (etîket, // hevmane, nimûne, jêder…), keep it and use {{mane?}} as // a stand-in for the missing gloss instead of discarding // everything the user entered. if (!dfn && !senseHasExtraContent(sense)) return undefined; if (dfn) { // Strip any wikilinks the user may have typed before // linkify processes the text — avoids double-linking. dfn = stripWikilinks(dfn); // Capitalize and punctuate. if (dfn[0] !== dfn[0].toUpperCase()) dfn = capitalize(dfn); if (!dfn.match(/[.…?!)\]]$/)) dfn += "."; } else { dfn = "{{mane?|" + lang + "}}"; } // {{e|lang|label1|label2}} var labelTpl = ""; if (sense.etiket && sense.etiket.length) { var labelParts = sense.etiket.map(function (part) { return $.trim(part); }).filter(function (part) { return part !== ""; }); if (labelParts.length) { labelTpl = " {{e|" + lang + "|" + labelParts.join("|") + "}} "; } } var out = "#" + (labelTpl ? labelTpl : " ") + dfn; // Per-sense word lists as #: template lines. function wordLine(tpl, words) { if (!words.length) return ""; return "\n#: {{" + tpl + "|" + lang + "|" + words.join("|") + "}}"; } out += wordLine("alt-r", sense.alternativ); out += wordLine("hevmane", sense.hevmane); out += wordLine("dijmane", sense.dijmane); out += wordLine("koordîne", sense.koordine); out += wordLine("jornav", sense.jornav); out += wordLine("jêrnav", sense.jernav); // Nimûne + jêder lines must not pass through linkify — stash them // behind a placeholder and restore them after linkify runs. var hasJeder = sense.jeder && $.grep(sense.jeder, function (j) { return j && j.quote; }).length > 0; var citeText = formatNimune(sense.nimune, lang, hasJeder) + formatJeder(sense.jeder, lang); if (citeText) { citeBlocks.push(citeText); out += CITE_PLACEHOLDER; } return out; }).join("\n") + "\n"; if (!hasMane) { // No definitions entered — emit {{mane?}} with bênimûne. text = "# {{mane?|" + lang + "}}\n#* {{bênimûne|" + lang + "}}\n"; callback(text); return; } // Restore cite blocks (nimûne/jêder) into the final text after // linkify has already processed the definition portions. function restoreCiteBlocks(t) { var i = 0; return t.replace(new RegExp(escapeRegExp(CITE_PLACEHOLDER), "g"), function () { return citeBlocks[i++] || ""; }); } if (!hasRegularMane) { // All filled senses are template senses — no linkify needed. callback(restoreCiteBlocks(text)); return; } var didTryToLoad = function () { // If the module failed to load, $.wiktviLinkify won't exist — // fall back to the unlinkified text instead of throwing. if (typeof $.wiktviLinkify === "function") { $.wiktviLinkify(text, function (linked) { callback(restoreCiteBlocks(linked)); }); } else { callback(restoreCiteBlocks(text)); } }; mw.loader.using("ext.gadget.linkify", didTryToLoad, didTryToLoad); } }, je: makeWordListStep("je", "jê", "Kelîmeyên jê çêbûyî binivîse", "Jê", "g"), tekildar: makeWordListStep("tekildar", "têkildar", "Kelîmeyên ji aliyê etîmolojiyê ve têkildarî vê kelîmeyê binivîse", "Têkildar", "g"), binereherwiha: makeWordListStep("binereherwiha", "binêre herwiha", "Kelîmeyên din ên eleqedar binivîse", "Binêre herwiha", "g"), etym: { id: "etym", name: "etîmolojî", question_fmt: "Etîmolojiya kelîmeyê binivîse", // etymTpls populated from data.json etymTpls: [], visible: function (values) { return values.lang && values.pos; }, /** Fills (or refills) the insert-dropdown from the current etymTpls array. */ refreshTplSelect: function () { var sel = $("#wiktku-start-etym .wiktku-tpl-insert-select"); if (!sel.length) return; sel.find("option[value!='']").remove(); $.each(steps.etym.etymTpls, function (_, tpl) { sel.append($("<option></option>").val(tpl.snippet).text(tpl.name + " — " + tpl.desc)); }); // Notify Chosen that the option list has changed (no-op on mobile). if (!isMobile) sel.trigger("chosen:updated"); }, build: function (stepDiv) { if (stepDiv.find(".wiktku-etym-wrap").length) return null; var wrap = $("<div class='wiktku-etym-wrap'></div>"); var ta = $("<textarea></textarea>") .attr("name", "wiktku-etym-" + $.now()) .attr("class", "wiktku-start-step-field wiktku-etym-text") .attr("rows", 4) .attr("placeholder", "Nimûne: Ji {{ji|en|ku|apple}}. yan rasterast binivîse…"); // Template insert dropdown — options also refreshed after data.json loads. var sel = $("<select class='wiktku-tpl-insert-select'></select>"); sel.append($("<option value=''>— şablonek lê zêde bike —</option>")); $.each(steps.etym.etymTpls, function (_, tpl) { sel.append($("<option></option>").val(tpl.snippet).text(tpl.name + " — " + tpl.desc)); }); sel.on("change", function () { var snippet = $(this).val(); if (!snippet) return; var lang = getValues().lang || ""; snippet = snippet.replace(/CODE/g, lang).replace(/SOURCELANG/g, "?"); insertAtCursor(ta[0], snippet); $(this).val(""); ta.focus(); }); wrap.append(sel).append($("<br>")).append(ta); stepDiv.append(wrap); return ta; }, output: function (values) { var text = $.trim($("#wiktku-start-etym .wiktku-etym-text").val()); if (text) { return "\n==== Etîmolojî ====\n" + text + "\n"; } // No etymology entered — emit {{ji?|lang}} as a placeholder, // but only when the entry has at least one regular (non-şablon) // sense with content — either real mane text, or an empty mane // with other fields filled in (which dfn.getOutput() renders as // {{mane?|lang}} with those fields attached). A şablon sense // like {{guharto|…}} never counts, filled in or not. var dfnSenses = steps.dfn.getSenses($("#wiktku-start-dfn")); var hasRegularMane = dfnSenses.some(function (s) { return !s.tpl && (s.mane !== "" || senseHasExtraContent(s)); }); if (!hasRegularMane) return ""; return "\n==== Etîmolojî ====\n{{ji?|" + values.lang + "}}\n"; } }, dunde: { id: "dunde", name: "dûnde", question_fmt: "Eger ev kelîme ji vî zimanî ketibe zimanekî din, vî zimanî û kelîmeya wî binivîse", visible: function (values) { return !!values.pos; }, disabledKeys: { "navz": true}, /** * Builds one row: a language dropdown + a growing list of word * inputs. When the dropdown gets a value the next empty row is * appended automatically. Mirrors steps.trans's row widget, but * flat (one shared list — dûnde isn't tied to individual senses). */ buildRow: function (stepDiv) { var row = $("<li class='wiktku-dunde-row wiktku-lang-row'></li>"); // Language selector — chosen is applied after insertion into DOM. var langSel = $(mw.html.element("select", { "class": "wiktku-start-step-keyfield wiktku-start-narrow" })); langSel.attr("data-placeholder", "Zimanekî lê bigere"); populateMenus(langSel, steps.dunde.keys || [], steps.dunde.disabledKeys); // When a language is chosen, ensure a next empty row exists. langSel.on("change", function () { steps.dunde.onLangChange(stepDiv, row); }); // Word list for this language. var wordList = $("<ul class='wiktku-dunde-words wiktku-lang-row-words'></ul>"); var firstWord = steps.dunde.makeWordInput(); wordList.append($("<li></li>").append(firstWord)); if (isMobile) { row.append(wrapNativeSelect(langSel)).append(wordList); } else { row.append(langSel).append(wordList); } return row; }, makeWordInput: function () { var input = $("<textarea></textarea>") .attr("name", "wiktku-dunde-word-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 1) .attr("class", "wiktku-dfn-subfield wiktku-start-narrow") .attr("placeholder", "Kelîme…"); input.on("input", function () { var list = $(this).closest("ul.wiktku-dunde-words"); var item = $(this).parent(); var val = $.trim($(this).val()); if (val && item.is(list.children("li:last-child"))) { var next = steps.dunde.makeWordInput(); list.append($("<li></li>").append(next)); } }); return input; }, onLangChange: function (stepDiv, row) { var list = stepDiv.find("ul.wiktku-dunde-list"); var isLast = row.is(list.children("li.wiktku-dunde-row:last-child")); if (isLast) { var newRow = steps.dunde.buildRow(stepDiv); list.append(newRow); // Init chosen after the new row is in the DOM (desktop only). if (!isMobile) newRow.find("select").chosen(chosenOptions); } // Keep disabled keys in sync across all lang selectors. steps.dunde.syncDisabledKeys(stepDiv); }, /** Disables already-selected languages in all other dropdowns. */ syncDisabledKeys: function (stepDiv) { var taken = $.extend({}, steps.dunde.disabledKeys); stepDiv.find("li.wiktku-dunde-row select").each(function () { var v = $(this).val(); if (v) taken[v] = true; }); stepDiv.find("li.wiktku-dunde-row select").each(function () { var self = $(this); var own = self.val(); self.find("option").each(function () { var code = $(this).val(); if (!code) return; $(this).prop("disabled", taken[code] && code !== own); }); self.trigger("chosen:updated"); }); }, build: function (stepDiv) { if (stepDiv.find("ul.wiktku-dunde-list").length) return null; var list = $("<ul class='wiktku-dunde-list wiktku-lang-row-list'></ul>"); list.append(steps.dunde.buildRow(stepDiv)); stepDiv.append(list); // Init chosen after the select is in the DOM (desktop only). if (!isMobile) list.find("select").chosen(chosenOptions); return null; }, /** Reads all [langcode, words[]] rows from the DOM. */ getRows: function (stepDiv) { var result = []; stepDiv.find("li.wiktku-dunde-row").each(function () { var lang = $(this).find("select").val(); if (!lang) return; var words = []; $(this).find("ul.wiktku-dunde-words textarea").each(function () { var v = $.trim($(this).val()); if (v) words.push(v); }); if (words.length) result.push([lang, words]); }); return result; }, output: function () { var stepDiv = $("#wiktku-start-dunde"); var rows = steps.dunde.getRows(stepDiv); if (!rows.length) return ""; var lines = $.map(rows, function (row) { var lang = row[0], words = row[1]; return "* {{dû|" + lang + "|" + words.join("|") + "}}"; }); return "\n==== Dûnde ====\n" + lines.join("\n") + "\n"; } }, zarava: { id: "zarava", name: "bi zaravayên din", visible: function (values) { return steps.trans.visible(values); }, disabledKeys: { "navz": true }, buildRow: function (group) { var row = $("<li class='wiktku-zarava-row wiktku-lang-row'></li>"); var langSel = $(mw.html.element("select", { "class": "wiktku-start-step-keyfield wiktku-start-narrow" })); populateMenus(langSel, steps.zarava.keys || [], steps.zarava.disabledKeys); langSel.on("change", function () { steps.zarava.onLangChange(group, row); }); var wordList = $("<ul class='wiktku-zarava-words wiktku-lang-row-words'></ul>"); var firstWord = steps.zarava.makeWordInput(); wordList.append($("<li></li>").append(firstWord)); row.append(langSel).append(wordList); return row; }, makeWordInput: function () { var input = $("<textarea></textarea>") .attr("name", "wiktku-zarava-word-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 1) .attr("class", "wiktku-dfn-subfield wiktku-start-narrow") .attr("placeholder", "Tercime…"); input.on("input", function () { var list = $(this).closest("ul.wiktku-zarava-words"); var item = $(this).parent(); var val = $.trim($(this).val()); if (val && item.is(list.children("li:last-child"))) { var next = steps.zarava.makeWordInput(); list.append($("<li></li>").append(next)); } }); return input; }, onLangChange: function (group, row) { var list = group.find("ul.wiktku-zarava-list"); var isLast = row.is(list.children("li.wiktku-zarava-row:last-child")); if (isLast) { var newRow = steps.zarava.buildRow(group); list.append(newRow); } steps.zarava.syncDisabledKeys(group); }, /** Disables already-selected dialects in all other dropdowns within one group. */ syncDisabledKeys: function (group) { var taken = $.extend({}, steps.zarava.disabledKeys); group.find("li.wiktku-zarava-row select").each(function () { var v = $(this).val(); if (v) taken[v] = true; }); group.find("li.wiktku-zarava-row select").each(function () { var self = $(this); var own = self.val(); self.find("option").each(function () { var code = $(this).val(); if (!code) return; $(this).prop("disabled", taken[code] && code !== own); }); }); }, /** Builds (or fetches) the .wiktku-zarava-group for one gloss. */ buildGroup: function (stepDiv, gi) { var group = $("<div class='wiktku-zarava-group'></div>").attr("data-gloss-pos", gi); var list = $("<ul class='wiktku-zarava-list wiktku-lang-row-list'></ul>"); list.append(steps.zarava.buildRow(group)); group.append(list); stepDiv.append(group); return group; }, /** Syncs one .wiktku-zarava-group per current gloss (same logic as steps.trans.build). */ build: function (stepDiv) { var glosses = steps.trans.glossList(); if (!glosses.length) { stepDiv.find(".wiktku-zarava-group").remove(); return null; } var existingGroups = stepDiv.find(".wiktku-zarava-group"); if (existingGroups.length > glosses.length) { existingGroups.slice(glosses.length).remove(); } $.each(glosses, function (gi, gloss) { var group = stepDiv.find(".wiktku-zarava-group[data-gloss-pos='" + gi + "']"); if (!group.length) group = steps.zarava.buildGroup(stepDiv, gi); var label = group.find(".wiktku-zarava-group-label"); if (glosses.length > 1) { if (!label.length) { label = $("<div class='wiktku-zarava-group-label'></div>"); group.prepend(label); } label.text(gloss.index + " " + gloss.text); } else if (label.length) { label.remove(); } }); return null; }, /** Reads the dialect rows for a single gloss group. */ getGroupTranslations: function (group) { var result = []; group.find("li.wiktku-zarava-row").each(function () { var lang = $(this).find("select").val(); if (!lang) return; var words = []; $(this).find("ul.wiktku-zarava-words textarea").each(function () { var v = $.trim($(this).val()); if (v) words.push(v); }); if (words.length) result.push([lang, words]); }); return result; }, /** Reads all rows from the DOM, grouped by gloss position. */ getTranslations: function (stepDiv) { var result = []; stepDiv.find(".wiktku-zarava-group").each(function () { result.push(steps.zarava.getGroupTranslations($(this))); }); return result; }, output: function (values) { if (values.lang !== "ku") return ""; var stepDiv = $("#wiktku-start-zarava"); var glosses = steps.trans.glossList(); if (!glosses.length) return ""; var blocks = $.map(glosses, function (gloss, gi) { var group = stepDiv.find(".wiktku-zarava-group[data-gloss-pos='" + gi + "']"); var rows = group.length ? steps.zarava.getGroupTranslations(group) : []; if (!gloss.text && !rows.length) return undefined; if (rows.length) { rows.sort(function (a, b) { var aLang = langsByCode[a[0]] || []; var bLang = langsByCode[b[0]] || []; return (aLang[2] || "").localeCompare(bLang[2] || "", "ku"); }); } var wordLines = $.map(rows, function (row) { var lang = row[0]; var words = row[1]; var wikiWords = words.map(function (w) { return "{{W|" + lang + "|" + w + "}}"; }).join(", "); return "* {{Z|" + lang + "}}: " + wikiWords; }).join("\n"); if (!wordLines) return undefined; var block = "{{werger-ser|" + (gloss.text || "?") + "|" + gloss.index + "}}"; block += "\n" + wordLines; block += "\n{{werger-bin}}"; return block; }); if (!blocks.length) return ""; return "\n==== Bi zaravayên din ====\n" + blocks.join("\n") + "\n"; } }, trans: { id: "trans", name: "werger", visible: function (values) { if (!(values.lang === "ku" && values.pos)) return false; // Hide Werger only when EVERY sense is a template sense (Guharto etc.) // with a title filled in — i.e. there is real content but no plain // gloss to attach a translation table to. A mix of real + template // senses still shows Werger; the template senses are simply skipped // in output(). // // "Real" here means a non-şablon sense with either mane text or // other filled-in fields (etîket/hevmane/nimûne/jêder…), since // dfn.getOutput() renders the latter too, as {{mane?|lang}} plus // whatever else was filled in. // // When nothing has been filled in at all, output() will emit // {{mane?|lang}} instead of a gloss — but Werger should still show, // since the user may want to add translations before they've // settled on a gloss. var dfnSenses = steps.dfn.getSenses($("#wiktku-start-dfn")); var hasRealSense = dfnSenses.some(function (s) { return !s.tpl && (s.mane !== "" || senseHasExtraContent(s)); }); var hasFilledTplSense = dfnSenses.some(function (s) { return s.tpl && s.tplTitle; }); return hasRealSense || !hasFilledTplSense; }, disabledKeys: { "navz": true, "ku": true, "ckb": true, "sdh": true, "lki": true, "hac": true, "zza": true }, /** * Builds one translation row: a language dropdown + a growing list * of word inputs. When the dropdown gets a value the next empty row * is appended automatically. * * @param group the specific .wiktku-trans-group this row belongs to * (each gloss has its own group and its own list of rows, so the * lookups below must stay scoped to that group rather than the * whole step — the step now holds one list per gloss). */ buildRow: function (group) { var row = $("<li class='wiktku-trans-row wiktku-lang-row'></li>"); // Language selector — chosen is applied after insertion into DOM. var langSel = $(mw.html.element("select", { "class": "wiktku-start-step-keyfield wiktku-start-narrow" })); langSel.attr("data-placeholder", "Zimanekî lê bigere"); populateMenus(langSel, steps.trans.keys || [], steps.trans.disabledKeys); // When a language is chosen, ensure a next empty row exists. langSel.on("change", function () { steps.trans.onLangChange(group, row); }); // Word list for this language. var wordList = $("<ul class='wiktku-trans-words wiktku-lang-row-words'></ul>"); var firstWord = steps.trans.makeWordInput(); wordList.append($("<li></li>").append(firstWord)); if (isMobile) { row.append(wrapNativeSelect(langSel)).append(wordList); } else { row.append(langSel).append(wordList); } return row; }, makeWordInput: function () { var input = $("<textarea></textarea>") .attr("name", "wiktku-trans-word-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 1) .attr("class", "wiktku-dfn-subfield wiktku-start-narrow") .attr("placeholder", "Tercime…"); input.on("input", function () { var list = $(this).closest("ul.wiktku-trans-words"); var item = $(this).parent(); var val = $.trim($(this).val()); if (val && item.is(list.children("li:last-child"))) { var next = steps.trans.makeWordInput(); list.append($("<li></li>").append(next)); } }); return input; }, onLangChange: function (group, row) { var list = group.find("ul.wiktku-trans-list"); var isLast = row.is(list.children("li.wiktku-trans-row:last-child")); if (isLast) { var newRow = steps.trans.buildRow(group); list.append(newRow); // Init chosen after the new row is in the DOM (desktop only). if (!isMobile) newRow.find("select").chosen(chosenOptions); } // Keep disabled keys in sync across this gloss's lang selectors // only — the same language can be used for different senses. steps.trans.syncDisabledKeys(group); }, /** Disables already-selected languages in all other dropdowns within one group. */ syncDisabledKeys: function (group) { var taken = $.extend({}, steps.trans.disabledKeys); group.find("li.wiktku-trans-row select").each(function () { var v = $(this).val(); if (v) taken[v] = true; }); group.find("li.wiktku-trans-row select").each(function () { var self = $(this); var own = self.val(); self.find("option").each(function () { var code = $(this).val(); if (!code) return; $(this).prop("disabled", taken[code] && code !== own); }); self.trigger("chosen:updated"); }); }, /** * Builds (or fetches) the .wiktku-trans-group for one gloss, with * its own label and its own list of translation rows. */ buildGroup: function (stepDiv, gi) { var group = $("<div class='wiktku-trans-group'></div>").attr("data-gloss-pos", gi); var list = $("<ul class='wiktku-trans-list wiktku-lang-row-list'></ul>"); list.append(steps.trans.buildRow(group)); group.append(list); stepDiv.append(group); // Init chosen after the select is in the DOM (desktop only). if (!isMobile) list.find("select").chosen(chosenOptions); return group; }, /** * Syncs one .wiktku-trans-group per current gloss, adding new * groups and removing stale ones as senses are added or removed, * while leaving existing groups (and whatever translations the * user has already typed into them) untouched. Groups are keyed * to their gloss's position in glossList() via data-gloss-pos, so * a group always matches the same sense across rebuilds as long * as senses aren't reordered relative to each other. */ build: function (stepDiv) { var glosses = steps.trans.glossList(); if (!glosses.length) { stepDiv.find(".wiktku-trans-group").remove(); return null; } // Drop groups for glosses that no longer exist (always from the // tail — groups are only ever appended in gloss order below). var existingGroups = stepDiv.find(".wiktku-trans-group"); if (existingGroups.length > glosses.length) { existingGroups.slice(glosses.length).remove(); } $.each(glosses, function (gi, gloss) { var group = stepDiv.find(".wiktku-trans-group[data-gloss-pos='" + gi + "']"); if (!group.length) group = steps.trans.buildGroup(stepDiv, gi); // Only label groups when there's more than one gloss to // distinguish between — a single gloss needs no caption. var label = group.find(".wiktku-trans-group-label"); if (glosses.length > 1) { if (!label.length) { label = $("<div class='wiktku-trans-group-label'></div>"); group.prepend(label); } label.text(gloss.index + " " + gloss.text); } else if (label.length) { label.remove(); } }); return null; }, /** Reads the translation rows for a single gloss group. */ getGroupTranslations: function (group) { var result = []; group.find("li.wiktku-trans-row").each(function () { var lang = $(this).find("select").val(); if (!lang) return; var words = []; $(this).find("ul.wiktku-trans-words textarea").each(function () { var v = $.trim($(this).val()); if (v) words.push(v); }); if (words.length) result.push([lang, words]); }); return result; }, /** * Reads all translation rows from the DOM, grouped by gloss * position — one array of [lang, words] rows per gloss group, in * the same order as the .wiktku-trans-group elements. */ getTranslations: function (stepDiv) { var result = []; stepDiv.find(".wiktku-trans-group").each(function () { result.push(steps.trans.getGroupTranslations($(this))); }); return result; }, /** * Builds the numbered "{ index, gloss }" list — one entry per dfn * sense that has a real mane (skips template senses like Guharto, * which have nothing to caption a translation table with). The * index matches the sense's actual position in the numbered "#" * definition list (1-based), including template senses in the count, * so the number printed next to {{werger-ser}} lines up with the * gloss the reader sees in the entry. * * When nothing has been filled in at all (dfn.getOutput() will emit * {{mane?|lang}} as sense 1), this returns a single placeholder * entry with empty text instead of an empty array, so Werger still * has one group to attach translations to before a gloss exists. * When every filled sense is a template sense instead, this stays * empty — that mirrors trans.visible()'s hidden case, where there's * no group in the DOM for a placeholder to attach to anyway. */ glossList: function () { var dfnSenses = steps.dfn.getSenses($("#wiktku-start-dfn")); var glosses = []; var hasFilledTplSense = false; $.each(dfnSenses, function (i, s) { if (s.tpl) { if (s.tplTitle) hasFilledTplSense = true; return; // template sense — no gloss to caption with } var dfn = s.mane; if (!dfn) { // No mane text, but other fields (etîket/hevmane/nimûne/ // jêder…) are filled — dfn.getOutput() still emits this // sense as a numbered line using {{mane?|lang}}, so it // needs its own gloss group too, just with no caption text. if (senseHasExtraContent(s)) glosses.push({ index: i + 1, text: "" }); return; } if (dfn[0] !== dfn[0].toLowerCase()) dfn = decapitalize(dfn); dfn = stripWikilinks(dfn).replace(/[.…?!)\]،؟]+$/, ""); glosses.push({ index: i + 1, text: dfn }); }); if (!glosses.length && !hasFilledTplSense) { glosses.push({ index: 1, text: "" }); } return glosses; }, output: function (values) { if (values.lang !== "ku") return ""; var stepDiv = $("#wiktku-start-trans"); var glosses = steps.trans.glossList(); // Every sense is a template sense — there's no real gloss // anywhere and no group in the DOM either (glossList() only // returns empty in that case), so skip the section entirely. if (!glosses.length) return ""; // Each gloss now has its own group of translation rows — // attach every gloss's own words under its own werger-ser/-bin // pair instead of dumping everything under the first one. var blocks = $.map(glosses, function (gloss, gi) { var group = stepDiv.find(".wiktku-trans-group[data-gloss-pos='" + gi + "']"); var rows = group.length ? steps.trans.getGroupTranslations(group) : []; // Placeholder gloss (no real mane entered yet) with nothing // translated into it — nothing to output, and gloss.text is // empty so there's no caption to give {{werger-ser}} anyway. if (!gloss.text && !rows.length) return undefined; if (rows.length) { // Sort by Kurdish sort key. rows.sort(function (a, b) { var aLang = langsByCode[a[0]] || []; var bLang = langsByCode[b[0]] || []; return (aLang[2] || "").localeCompare(bLang[2] || "", "ku"); }); } var wordLines = $.map(rows, function (row) { var lang = row[0]; var words = row[1]; var wikiWords = words.map(function (w) { return "{{W|" + lang + "|" + w + "}}"; }).join(", "); return "* {{Z|" + lang + "}}: " + wikiWords; }).join("\n"); var block = "{{werger-ser|" + (gloss.text || "?") + "|" + gloss.index + "}}"; if (wordLines) block += "\n" + wordLines; block += "\n{{werger-bin}}"; return block; }); if (!blocks.length) return ""; return "\n==== Werger ====\n" + blocks.join("\n") + "\n"; } }, }; steps.trans.keys = steps.lang.choices; steps.dunde.keys = steps.lang.choices; steps.zarava.keys = getZaravaKeys(steps.lang.choices); var ordered_steps = [ steps.lang, steps.pron, steps.pos, steps.cinsiyet, steps.lektur, steps.tr, steps.dfn, steps.je, steps.tekildar, steps.etym, steps.dunde, steps.binereherwiha, steps.zarava, steps.trans]; // Step ids that belong to each section (not shared across sections). var PER_SECTION_STEP_IDS = [ "pos", "cinsiyet", "lektur", "tr", "dfn", "je", "tekildar", "etym", "dunde", "binereherwiha", "zarava", "trans" ]; // ── Multi-section state ────────────────────────────────────────────────── // Each entry is a plain snapshot: { pos, cinsiyet, lektur, tr, dfn (senses[]), // je, tekildar, binereherwiha, trans (rows[]) }. var sections = [{}]; // section 0 starts empty (DOM is the truth) var activeSection = 0; function snapshotDfn() { return steps.dfn.getSenses($("#wiktku-start-dfn")); } /** * Rebuild the dfn DOM from a previously snapshotted senses array. */ function restoreDfn(senses) { var stepDiv = $("#wiktku-start-dfn"); // Tear down the existing list so build() recreates it cleanly. stepDiv.find("ol.wiktku-dfn-list").remove(); steps.dfn.build(stepDiv); var list = stepDiv.find("ol.wiktku-dfn-list"); $.each(senses, function (i, sense) { // Ensure enough blocks exist (build() seeds one). var blocks = list.find("li.wiktku-dfn-sense"); var block = blocks.eq(i); if (!block.length) { var nb = steps.dfn.buildSenseBlock(stepDiv); list.append(nb); block = list.find("li.wiktku-dfn-sense").last(); } // Template selector. block.find("select.wiktku-dfn-tpl-select").val(sense.tpl || ""); if (sense.tpl) { block.find("textarea.wiktku-dfn-mane").hide(); block.find("input.wiktku-dfn-tpl-title").val(sense.tplTitle || "").show(); } else { block.find("textarea.wiktku-dfn-mane").val(sense.mane || "").show(); block.find("input.wiktku-dfn-tpl-title").hide().val(""); } // Re-sync the formên alternatîv/hevmane/… hide state now that // tplSelect's value was set programmatically (its own "change" // handler doesn't fire from .val(), so this doesn't happen otherwise). var updateVis = block.data("updateFieldVisibility"); if (updateVis) updateVis(); // Restore a sub-list (etiket, formên alternatîv, hevmane …) from a values array. function restoreSubList(cls, values) { if (!values || !values.length) return; var groupDiv = block.find("." + cls + "-group"); var subList = groupDiv.find("ol, ul").first(); if (!subList.length) return; // group not found // Fill existing items, append new ones as needed. $.each(values, function (j, val) { var items = subList.find("li"); if (j < items.length) { items.eq(j).find("textarea").val(val); } else { var ta = $("<textarea></textarea>") .attr("name", "wiktku-dfn-restore-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 1) .attr("class", "wiktku-dfn-subfield wiktku-start-narrow") .val(val); ta.on("input", function () { steps.dfn.onSubInput(subList, this, 1, true); }); subList.append($("<li></li>").append(ta)); } }); } // Reveal and populate lazy groups that have data. var lazyMap = { "wiktku-dfn-etiket": sense.etiket, "wiktku-dfn-alternativ": sense.alternativ, "wiktku-dfn-hevmane": sense.hevmane, "wiktku-dfn-dijmane": sense.dijmane, "wiktku-dfn-koordine": sense.koordine, "wiktku-dfn-jornav": sense.jornav, "wiktku-dfn-jernav": sense.jernav }; $.each(lazyMap, function (cls, vals) { if (vals && vals.length) restoreSubList(cls, vals); }); // Nimûne items are objects { text, tr?, t? } — restore using the builder. if (sense.nimune && sense.nimune.length) { var nimuneGroupDiv = block.find(".wiktku-dfn-nimune-group"); var nimuneList = nimuneGroupDiv.find("ol.wiktku-dfn-nimune-list"); var buildFn = nimuneGroupDiv.data("buildNimuneLi"); nimuneList.empty(); $.each(sense.nimune, function (_, n) { var text = typeof n === "object" ? (n.text || "") : n; if (!text) return; var li = buildFn ? buildFn() : $("<li class='wiktku-dfn-nimune-li'></li>"); li.find(".wiktku-dfn-nimune-text").val(text); if (n.tr) li.find(".wiktku-dfn-nimune-tr").val(n.tr); if (n.t) li.find(".wiktku-dfn-nimune-t").val(n.t); nimuneList.append(li); }); // Always leave a blank trailing item. if (buildFn) nimuneList.append(buildFn()); } // Restore jêder (quote/citation) entries — a growing list, restored using the // builder just like Nimûne. Accepts either the current array shape or a // single legacy object (from older saved sections) for backwards compatibility. var jederArr = $.isArray(sense.jeder) ? sense.jeder : (sense.jeder ? [sense.jeder] : []); if (jederArr.length) { var jederGroupDiv = block.find(".wiktku-dfn-jeder-group"); var jederList = jederGroupDiv.find("ol.wiktku-dfn-jeder-list"); var buildJederFn = jederGroupDiv.data("buildJederLi"); jederList.empty(); $.each(jederArr, function (_, j) { if (!j || !j.quote) return; var li = buildJederFn ? buildJederFn() : $("<li class='wiktku-dfn-jeder-li'></li>"); li.find(".wiktku-dfn-nimune-quote").val(j.quote); if (j.quoteTr) li.find(".wiktku-dfn-nimune-quote-tr").val(j.quoteTr); if (j.quoteT) li.find(".wiktku-dfn-nimune-quote-t").val(j.quoteT); if (j.jederManual) { var manualSel = li.find(".wiktku-dfn-quote-src-sel"); manualSel.val("__manual__").trigger("change"); li.find(".wiktku-dfn-quote-src-manual").val(j.jederManual); } else if (j.jederTpl) { var srcSel = li.find(".wiktku-dfn-quote-src-sel"); srcSel.val(j.jederTpl).trigger("change"); if (j.jêderFields) { $.each(j.jêderFields, function (key, val) { li.find(".wiktku-dfn-quote-src-input[data-field-key='" + key + "']").val(val); }); } } jederList.append(li); }); // Always leave a blank trailing item, same as Nimûne. if (buildJederFn) jederList.append(buildJederFn()); } }); } /** * Snapshot simple (non-dfn) per-section steps from current DOM into obj. */ function saveCurrentSection() { var snap = {}; $.each(PER_SECTION_STEP_IDS, function (_, id) { if (id === "dfn") { snap.dfn = snapshotDfn(); return; } if (id === "etym") { snap.etym = $.trim($("#wiktku-start-etym .wiktku-etym-text").val()); return; } var step = steps[id]; if (!step) return; var stepDiv = $("#wiktku-start-" + id); if (id === "trans") { snap.trans = steps.trans.getTranslations(stepDiv); return; } if (id === "zarava") { snap.zarava = steps.zarava.getTranslations(stepDiv); return; } if (id === "dunde") { snap.dunde = steps.dunde.getRows(stepDiv); return; } // Generic: read all step fields. var fields = stepDiv.find(".wiktku-start-step-field"); if (step.multiple) { snap[id] = fields.map(function () { return $(this).val(); }).get(); } else { snap[id] = fields.val(); } }); sections[activeSection] = snap; } /** * Restore a previously saved snapshot into the form DOM. */ function restoreSection(snap) { $.each(PER_SECTION_STEP_IDS, function (_, id) { if (id === "dfn") { restoreDfn(snap.dfn || []); return; } if (id === "etym") { $("#wiktku-start-etym .wiktku-etym-wrap").remove(); steps.etym.build($("#wiktku-start-etym")); $("#wiktku-start-etym .wiktku-etym-text").val(snap.etym || ""); return; } if (id === "trans") { // Rebuild trans groups (dfn must already be restored by this // point in the $.each loop, so glossList() reflects it). var transDiv = $("#wiktku-start-trans"); transDiv.find(".wiktku-trans-group").remove(); steps.trans.build(transDiv); var groupsSnap = snap.trans || []; $.each(groupsSnap, function (gi, rows) { var group = transDiv.find(".wiktku-trans-group[data-gloss-pos='" + gi + "']"); if (!group.length) return; // gloss no longer exists — drop its rows var list = group.find("ul.wiktku-trans-list"); $.each(rows, function (j, row) { var lang = row[0], words = row[1]; var lastRow = list.find("li.wiktku-trans-row").last(); lastRow.find("select").val(lang).trigger("change"); var wordList = lastRow.find("ul.wiktku-trans-words"); $.each(words, function (k, word) { var wordItems = wordList.find("li"); if (k < wordItems.length) { wordItems.eq(k).find("textarea").val(word); } else { // .val() below doesn't fire "input", so the normal // auto-grow never runs — append a matching item // ourselves instead of silently dropping the word. var extraInput = steps.trans.makeWordInput(); wordList.append($("<li></li>").append(extraInput)); extraInput.val(word); } }); // Leave one trailing empty field so the row can still grow // when the user types, matching a freshly-built row. if ($.trim(wordList.children("li").last().find("textarea").val())) { wordList.append($("<li></li>").append(steps.trans.makeWordInput())); } }); }); return; } if (id === "zarava") { // Rebuild zarava groups (dfn must already be restored by this // point in the $.each loop, so glossList() reflects it). var zaravaDiv = $("#wiktku-start-zarava"); zaravaDiv.find(".wiktku-zarava-group").remove(); steps.zarava.build(zaravaDiv); var zaravaGroupsSnap = snap.zarava || []; $.each(zaravaGroupsSnap, function (gi, rows) { var group = zaravaDiv.find(".wiktku-zarava-group[data-gloss-pos='" + gi + "']"); if (!group.length) return; // gloss no longer exists — drop its rows var list = group.find("ul.wiktku-zarava-list"); $.each(rows, function (j, row) { var lang = row[0], words = row[1]; var lastRow = list.find("li.wiktku-zarava-row").last(); lastRow.find("select").val(lang).trigger("change"); var wordList = lastRow.find("ul.wiktku-zarava-words"); $.each(words, function (k, word) { var wordItems = wordList.find("li"); if (k < wordItems.length) { wordItems.eq(k).find("textarea").val(word); } else { var extraInput = steps.zarava.makeWordInput(); wordList.append($("<li></li>").append(extraInput)); extraInput.val(word); } }); if ($.trim(wordList.children("li").last().find("textarea").val())) { wordList.append($("<li></li>").append(steps.zarava.makeWordInput())); } }); }); return; } if (id === "dunde") { // Rebuild dunde rows. var dundeDiv = $("#wiktku-start-dunde"); dundeDiv.find("ul.wiktku-dunde-list").remove(); steps.dunde.build(dundeDiv); var dundeRows = snap.dunde || []; $.each(dundeRows, function (i, row) { var lang = row[0], words = row[1]; var list = dundeDiv.find("ul.wiktku-dunde-list"); var lastRow = list.find("li.wiktku-dunde-row").last(); lastRow.find("select").val(lang).trigger("change"); var wordList = lastRow.find("ul.wiktku-dunde-words"); $.each(words, function (j, word) { var wordItems = wordList.find("li"); if (j < wordItems.length) { wordItems.eq(j).find("textarea").val(word); } else { // .val() below doesn't fire "input", so the normal // auto-grow never runs — append a matching item // ourselves instead of silently dropping the word. var extraInput = steps.dunde.makeWordInput(); wordList.append($("<li></li>").append(extraInput)); extraInput.val(word); } }); // Leave one trailing empty field so the row can still grow // when the user types, matching a freshly-built row. if ($.trim(wordList.children("li").last().find("textarea").val())) { wordList.append($("<li></li>").append(steps.dunde.makeWordInput())); } }); return; } var step = steps[id]; if (!step) return; var stepDiv = $("#wiktku-start-" + id); var fields = stepDiv.find(".wiktku-start-step-field"); var val = snap[id]; if (val === undefined || val === null) return; if (step.multiple) { var arr = val; fields.each(function (i) { if (i < arr.length) $(this).val(arr[i]); }); } else { fields.val(val); } // Notify chosen widgets of the programmatic value change. if (!isMobile) fields.filter("select").trigger("chosen:updated"); }); } function getWikitextForCurrentSection(callback) { var values = getValues(); var entry = steps.pos.output(values); steps.dfn.getOutput(values, function (output) { entry += output; entry += steps.je.output(values); entry += steps.tekildar.output(values); entry += steps.etym.output(values); entry += steps.dunde.output(values); entry += steps.binereherwiha.output(values); entry += steps.zarava.output(values); entry += steps.trans.output(values); callback(entry, values); }); } function getWikitextAllSections(callback) { saveCurrentSection(); var results = new Array(sections.length); var sharedValues = getValues(); // lang/pron are shared function processSection(i) { if (i >= sections.length) { // All done — restore original active section. restoreSection(sections[activeSection]); refresh(); callback(results, sharedValues); return; } restoreSection(sections[i]); refresh(); getWikitextForCurrentSection(function (sectionText) { results[i] = sectionText; processSection(i + 1); }); } processSection(0); } /** * Assembles wikitext for all sections plus the shared lang/pron header. */ function getWikitext(callback) { getWikitextAllSections(function (sectionTexts, sharedValues) { var entry = steps.lang.output(sharedValues); entry += steps.pron.output(sharedValues); entry += sectionTexts.join("\n"); // Edit summary uses section 0's values. Read from the saved snapshot // (not the live DOM) so it doesn't mix section 0's pos with whichever // section happens to be active/restored at this point. var dfnSenses = (sections[0] && sections[0].dfn) || []; var dfnSummary = dfnSenses.map(function (s) { return s.mane; }).filter(Boolean).join("; "); var summaryLabel = addLangMode ? "WF:Ziman lê zêde" : "WF:Nû"; var summary = "([[Mediawiki:Gadget-start.js|" + summaryLabel + "]] v.2.0) +" + sharedValues.lang + ":" + sections[0].pos + ":" + dfnSummary; var summaryField = document.getElementById("wpSummary"); if (addLangMode && summaryField.value) { summary = summaryField.value + " " + summary; } summaryField.value = summary; callback(entry); }); } var continueBtn; function getValuesForStep(stepId) { var fields = $("#wiktku-start-" + stepId + " .wiktku-start-step-field"); var step = steps[stepId]; if (step.keys) { var values = {}; fields.each(function (i, field) { var key = $(field).prevAll(".wiktku-start-step-keyfield").val(); if (key) values[key] = $(field).val(); }); return values; } else if (step.multiple) { return fields.map(function () { return $(this).val(); }).get(); } return fields.val(); } function getValues() { var values = {}; $.each(steps, function (stepId) { values[stepId] = getValuesForStep(stepId); }); return values; } function populateMenus(inputs, choices, disabledValues) { if (!disabledValues) disabledValues = {}; var vals = inputs.map(function (i, input) { return $(input).val(); }); inputs.empty(); inputs.append($("<option></option>")); $.each(choices, function (j, choice) { // Append the language code in parentheses so that typing a code // (e.g. "ku") in the search box still finds the language name. var displayText = capitalize(choice[1]); if (choice[2] !== undefined) { // This is a language choice [code, name, sortKey] — show code. displayText = capitalize(choice[1]) + " (" + choice[0] + ")"; } var option = $(mw.html.element("option", { value: choice[0] }, displayText)); if (disabledValues[choice[0]]) option.prop("disabled", true); inputs.append(option); }); inputs.val(function (i) { return vals[i]; }); } /** * Returns a bitmap containing the keys that should be disabled for a key * menu in the given step because they are disabled or already taken by * another key menu. */ function getDisabledKeys(step) { var occupiedKeys = {}; $("#wiktku-start-" + step.id + " .wiktku-start-step-keyfield").each(function () { occupiedKeys[$(this).val()] = true; }); if (step.disabledKeys) $.extend(occupiedKeys, step.disabledKeys); return occupiedKeys; } function buildKeyInput(step) { if (!step.keys) return undefined; var input = $(mw.html.element("select", { "class": "wiktku-start-step-keyfield wiktku-start-narrow" })); input.attr("data-placeholder", "Hilbijêre " + step.keyName); if (isMobile) { populateMenus(input, step.keys, getDisabledKeys(step)); // On mobile return the wrapper; the select is inside it. // Change events still fire on the inner select. return wrapNativeSelect(input); } input.on("chosen:showing_dropdown", function () { $(this).data("wiktku-defaultValue", $(this).val()); }); input.change(function (_, context) { var inputs = $("#wiktku-start-" + step.id + " .wiktku-start-step-keyfield").not(this); var oldValue = $(this).data("wiktku-defaultValue"); var newValue = context.selected; inputs.find("option[value='" + oldValue + "']").prop('disabled', false); inputs.find("option[value='" + newValue + "']").prop('disabled', true); inputs.trigger("chosen:updated"); }); populateMenus(input, step.keys, getDisabledKeys(step)); return input; } /** * If the current text field has text and there are no more text fields after * the current text field in the list, add another text field to the list. */ function refreshForTextField(currentInput, step) { currentInput = $(currentInput); var value = currentInput.val(); var item = currentInput.parent(); if (value && !item.next("li").length) { var nextInput = $("<textarea></textarea>") .attr("name", "wiktku-field-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("class", currentInput.attr("class")) .attr("rows", currentInput.attr("rows") || 1); nextInput.on("input", function (evt) { refreshForTextField(evt.target, step); }); var nextKeyInput = buildKeyInput(step); var nextItem = $("<li></li>").append(nextKeyInput).append(nextInput); item.parent().append(nextItem); if (nextKeyInput) nextKeyInput.chosen(chosenOptions); } var canContinue = !continueBtn.isDisabled(); if ((value && !canContinue) || (!value && canContinue)) { refresh(step); } } function prepareInput(input, step) { if (!input) return; if (step.required) input.prop('required', true); input.change(step, refresh); } /** * Shows and hides all the steps based on whether their prerequisites are met, * and updates placeholders where applicable. */ function refresh(evt) { var values = getValues(); var changedStep = evt && evt.data; var didFocus = false; var canContinue = true; // Re-filter template options in every sense block whenever lang changes. $("#wiktku-start-dfn .wiktku-dfn-tpl-select").each(function () { var fn = $(this).data("updateOptions"); if (typeof fn === "function") fn(); }); // Re-filter pronunciation and etymology template dropdowns when language changes. steps.pron.refreshTplSelect(); steps.etym.refreshTplSelect(); // Sync tr/t sub-fields in every nimûne item to the current language. // tr shown when language needs transliteration; t shown when lang !== "ku". (function () { var lang = values.lang || ""; var showTr = needsTransliteration(lang); var showT = lang && lang !== "ku"; $("#wiktku-start-dfn .wiktku-dfn-nimune-list li.wiktku-dfn-nimune-li").each(function () { var li = $(this); // Ensure the sub-wrapper exists when we need it. var subWrap = li.find(".wiktku-dfn-nimune-sub"); // tr field var trTa = li.find(".wiktku-dfn-nimune-tr"); if (showTr && !trTa.length) { if (!subWrap.length) { subWrap = $("<div></div>").addClass("wiktku-dfn-nimune-sub"); li.append(subWrap); } trTa = $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-tr-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 5) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-tr") .attr("placeholder", "Transkrîpsiyon…"); subWrap.prepend(trTa); } else if (!showTr && trTa.length) { trTa.remove(); } // t field var tTa = li.find(".wiktku-dfn-nimune-t"); if (showT && !tTa.length) { if (!subWrap.length) { subWrap = $("<div></div>").addClass("wiktku-dfn-nimune-sub"); li.append(subWrap); } tTa = $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-t-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 5) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-t") .attr("placeholder", "Tercimeya nimûneyê kurmancî…"); subWrap.append(tTa); } else if (!showT && tTa.length) { tTa.remove(); } // Remove the wrapper if it ended up empty. subWrap = li.find(".wiktku-dfn-nimune-sub"); if (subWrap.length && !subWrap.children().length) subWrap.remove(); }); }()); // Sync tr/t sub-fields in every jêder citation to the current language. // tr shown when language needs transliteration; t shown when lang !== "ku". (function () { var lang = values.lang || ""; var showTr = needsTransliteration(lang); var showT = lang && lang !== "ku"; $("#wiktku-start-dfn .wiktku-dfn-jeder-list li.wiktku-dfn-jeder-li").each(function () { var li = $(this); // Ensure the sub-wrapper exists when we need it. It must sit right // after the quote textarea and before the source selector. var subWrap = li.find(".wiktku-dfn-quote-sub"); // tr field var trTa = li.find(".wiktku-dfn-nimune-quote-tr"); if (showTr && !trTa.length) { if (!subWrap.length) { subWrap = $("<div></div>").addClass("wiktku-dfn-quote-sub"); li.find(".wiktku-dfn-nimune-quote").after(subWrap); } trTa = $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-quote-tr-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 2) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-quote-tr") .attr("placeholder", "Transkrîpsiyona jêgirtinê…"); subWrap.prepend(trTa); } else if (!showTr && trTa.length) { trTa.remove(); } // t field var tTa = li.find(".wiktku-dfn-nimune-quote-t"); if (showT && !tTa.length) { if (!subWrap.length) { subWrap = $("<div></div>").addClass("wiktku-dfn-quote-sub"); li.find(".wiktku-dfn-nimune-quote").after(subWrap); } tTa = $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-quote-t-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 2) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-quote-t") .attr("placeholder", "Tercimeya jêgirtinê ya kurmancî…"); subWrap.append(tTa); } else if (!showT && tTa.length) { tTa.remove(); } // Remove the wrapper if it ended up empty. subWrap = li.find(".wiktku-dfn-quote-sub"); if (subWrap.length && !subWrap.children().length) subWrap.remove(); }); }()); $.each(steps, function (stepId, step) { if (typeof(step.visible) === "function" && !step.visible(values)) { $("#wiktku-start-" + stepId).slideUp(); } else { var stepDiv = $("#wiktku-start-" + stepId); if (changedStep !== step && typeof(step.build) === "function") { prepareInput(step.build(stepDiv, values), step); } var input = stepDiv.find(".wiktku-start-step-field"); if (typeof(step.example) === "function") { // .find() above already reaches nested fields (e.g. the dfn // step's mane textareas inside each sense block), so one // assignment covers every step; dfn keeps its own fallback. var exampleText = step.example(values) || (step.id === "dfn" ? "Mane…" : ""); input.attr("placeholder", exampleText); } var didSlideDown; if (!didFocus && stepDiv.css("display") === "none" && step.required) { didSlideDown = function (evt) { input.focus(); }; didFocus = true; } stepDiv.slideDown(didSlideDown); } if (step.required && (values[stepId] === "" || (step.multiple && values[stepId].join("") === ""))) { canContinue = false; } }); continueBtn.setDisabled(!canContinue); } function destroy() { $("#wiktku-start-form, .noafterwizard").slideUp(function () { $(this).remove(); }); $(".noarticletext .nowizard, #editform").slideDown(); $("#ca-edit").removeClass("selected"); $("#ca-wiktku-nowizard").addClass("selected"); } // Priority order for Kurdish dialects and the navz pseudo-code. // Codes listed here come before all other languages; unlisted codes // are sorted alphabetically by their display name via localeCompare. var LANG_PRIORITY = ["navz", "ku", "hac", "sdh", "lki", "ckb", "zza"]; /** * Inserts a new == {{ziman|code}} == section into existing page wikitext * at the correct sorted position: * 1. Any content before the first language section is preserved at the top. * 2. navz is always first, then ku/hac/sdh/lki/ckb/zza in that order, * then all other languages sorted by display name (localeCompare). */ function insertNewLangSection(existing, wikitext) { var newCodeMatch = wikitext.match(/^== \{\{ziman\|([^}]+)\}\} ==/); var newCode = newCodeMatch ? newCodeMatch[1] : ""; var sections = []; var preamble = ""; var firstMatch = existing.match(/(?:^|\n)== \{\{ziman\|/); if (!firstMatch) { // No existing lang sections at all — just append. var sep = existing && !/\n\s*$/.test(existing) ? "\n\n" : ""; return existing + sep + wikitext; } // Everything before the first == {{ziman|...}} == is the preamble. var firstSectionStart = existing.indexOf("== {{ziman|"); // Walk back to the start of that line. var lineStart = existing.lastIndexOf("\n", firstSectionStart - 1); var preambleEnd = lineStart !== -1 ? lineStart + 1 : 0; preamble = existing.slice(0, preambleEnd); // Parse each language section: header line + everything until the next header. var body = existing.slice(preambleEnd); // NOTE: with the /m flag, a bare "$" matches end-of-*line*, not just // end-of-string — that previously made the non-greedy content group // stop at the section's first line break instead of running to the // next language header (or the real end of the text), silently // dropping the rest of that section's wikitext. (?![\s\S]) matches // only the true end of the string, /m flag or not. var langSectionRe = /^(== \{\{ziman\|([^}]+)\}\} ==\n?)([\s\S]*?)(?=\n== \{\{ziman\||(?![\s\S]))/gm; var m; while ((m = langSectionRe.exec(body)) !== null) { sections.push({ code: m[2], content: m[0] // full text of this section including header }); } // Determine sort rank: priority list first (by index), then alphabetical. function getLangName(code) { var entry = langsByCode[code]; return entry ? entry[1] : code; } function sortRank(code) { var idx = LANG_PRIORITY.indexOf(code); return idx !== -1 ? idx : LANG_PRIORITY.length; } function compareLangs(a, b) { var ra = sortRank(a), rb = sortRank(b); if (ra !== rb) return ra - rb; // Both are outside priority list — sort by display name. return getLangName(a).localeCompare(getLangName(b), userLang); } // Insert the new section into the sorted list. var newSection = { code: newCode, content: wikitext }; var inserted = false; for (var i = 0; i < sections.length; i++) { if (compareLangs(newCode, sections[i].code) < 0) { sections.splice(i, 0, newSection); inserted = true; break; } } if (!inserted) sections.push(newSection); // Re-join: preamble + sections separated by newlines. var joined = sections.map(function (s) { // Ensure each section ends with exactly one newline before the next. return s.content.replace(/\n+$/, ""); }).join("\n"); return preamble + joined + "\n"; } function build() { $(".nowizard, .nowizard .noafterwizard").hide(); var callToAction = $("#wiktku-calltoaction"); var origCallToActionText = callToAction.text(); $(mw.util.addPortletLink("p-views", "#", "Edîtora çavkaniyê veke", "ca-wiktku-nowizard", "Vê rûpelê bi edîtora çavkaniyê çêke", undefined, "#ca-watch")).click(function (evt) { evt.preventDefault(); callToAction.text(origCallToActionText); destroy(); }); if (callToAction.length) { callToAction.text(origCallToActionText + " Forma li jêr ji bo çêkirina madeyeke nû bi kar bîne."); } var startForm = $("<form id='wiktku-start-form'></form>"); if (addLangMode) { startForm.append($("<p class='wiktku-addlang-notice'></p>").text( "Agahiyên zimanê nû yê hûnê li vê rûpelê zêde bikin dagirin. " + "Piştî temambûnê, beşa nû dê li dawiya nivîsa heyî were zêdekirin.")); } var spinner; // Tab bar for switching between POS sections. var sectionTabsDiv = $("<div id='wiktku-section-tabs'></div>"); startForm.submit(function (evt) { evt.preventDefault(); continueBtn.setDisabled(true); spinner.show(); getWikitext(function (wikitext) { if (addLangMode) { var textbox = $("#wpTextbox1"); var existing = textbox.val() || ""; // Check whether the generated lang header already exists in the page. // wikitext always starts with "== {{ziman|CODE}} ==\n" (from steps.lang.output). // If that exact section heading is already present in the existing content, // strip it from the new output and insert the remaining content at the end // of that lang section (just before the next == level-2 heading, or at the // very end of the page if there is no following section). var langHeaderMatch = wikitext.match(/^(== \{\{ziman\|[^}]+\}\} ==\n)/); if (langHeaderMatch) { var langHeader = langHeaderMatch[1]; // e.g. "== {{ziman|ku}} ==\n" // Escape for use in RegExp. var escapedHeader = langHeader.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); if (new RegExp(escapedHeader).test(existing)) { // Strip the header from the new output. var newContent = wikitext.slice(langHeader.length); // Find the insertion point: end of the existing lang section. // A new L2 heading marks the start of the next language block. var afterHeader = existing.indexOf(langHeader); var searchFrom = afterHeader + langHeader.length; // Find the next == … == heading after this section's start. var nextL2 = existing.indexOf("\n== ", searchFrom); var insertAt = nextL2 !== -1 ? nextL2 : existing.length; // Ensure there's a blank line before the inserted block. var before = existing.slice(0, insertAt); var after = existing.slice(insertAt); var sep = /\n\s*$/.test(before) ? "" : "\n"; textbox.val(before + sep + newContent + after); } else { // New language — insert at the correct sorted position. textbox.val(insertNewLangSection(existing, wikitext)); } } else { // Unexpected format — insert at sorted position anyway. textbox.val(insertNewLangSection(existing, wikitext)); } } else { $("#wpTextbox1").val(wikitext); } $("html, body").animate({scrollTop: 0}); callToAction.text("Hindik ma!"); $("#wiktku-preview-container").remove(); destroy(); }); }); $.each(ordered_steps, function (i, step) { var stepDiv = $(mw.html.element("div", { "class": "wiktku-start-step", id: "wiktku-start-" + step.id })); var name = capitalize(step.name); stepDiv.append($(mw.html.element("h3", { "class": "wiktku-start-step-name" }, new mw.html.Raw(mw.html.element("label", { "for": "wiktku-start-" + step.id + "-field" }, name))))); if (step.question_fmt) { stepDiv.append($(mw.html.element("label", { "class": "wiktku-start-step-question", "for": "wiktku-start-" + step.id + "-field" }, step.question_fmt))); if (step.question_br) stepDiv.append($("<br>")); } var input; if (step.choices) { input = $(mw.html.element("select", { "class": "wiktku-start-step-field", id: "wiktku-start-" + step.id + "-field" })); input.attr("data-placeholder", capitalize(step.name) + " hilbijêre "); populateMenus(input, step.choices); if (step.multiple) input.attr("multiple", true); if (isMobile) { stepDiv.append(wrapNativeSelect(input)); } else { stepDiv.append(input); } } else if (typeof(step.build) === "function") { input = step.build(stepDiv); } else { input = $("<textarea></textarea>") .attr("class", "wiktku-start-step-field") .attr("id", "wiktku-start-" + step.id + "-field") .attr("rows", step.rows || 2); if (step.narrow) input.addClass("wiktku-start-narrow"); if (step.multiple) { input.on("input", function (evt) { refreshForTextField(evt.target, step); }); var keyInput = buildKeyInput(step); var list = $(step.ordered ? "<ol></ol>" : "<ul></ul>") .append($("<li></li>").append(keyInput).append(input)); stepDiv.append(list); } else stepDiv.append(input); } prepareInput(input, step); stepDiv.hide(); // Insert tab bar just before the first per-section step. if (step.id === "pos") startForm.append(sectionTabsDiv); startForm.append(stepDiv); }); // ── Section tab helpers ────────────────────────────────────────────── // ── Add-section button — lives in the tab bar, disabled until pos chosen ── var addSectionBtn = new OO.ui.ButtonWidget({ label: "+ Beş zêde bike", disabled: true }); addSectionBtn.on("click", function () { saveCurrentSection(); sections.push({}); activeSection = sections.length - 1; $.each(PER_SECTION_STEP_IDS, function (_, id) { if (id === "dfn") { var stepDiv = $("#wiktku-start-dfn"); stepDiv.find("ol.wiktku-dfn-list").remove(); steps.dfn.build(stepDiv); return; } if (id === "etym") { $("#wiktku-start-etym .wiktku-etym-wrap").remove(); steps.etym.build($("#wiktku-start-etym")); return; } if (id === "trans") { var transDiv = $("#wiktku-start-trans"); transDiv.find(".wiktku-trans-group").remove(); return; } if (id === "zarava") { var zaravaDiv = $("#wiktku-start-zarava"); zaravaDiv.find(".wiktku-zarava-group").remove(); return; } if (id === "dunde") { var dundeDiv = $("#wiktku-start-dunde"); dundeDiv.find("ul.wiktku-dunde-list").remove(); return; } var stepDiv = $("#wiktku-start-" + id); stepDiv.find(".wiktku-start-step-field").val(""); if (!isMobile) stepDiv.find("select.wiktku-start-step-field").trigger("chosen:updated"); }); renderSectionTabs(); refresh(); $("html, body").animate({ scrollTop: sectionTabsDiv.offset().top - 20 }, 300); }); /** Re-render the tab bar to reflect current sections[] and activeSection. */ function renderSectionTabs() { // Detach (not remove) the button first: .empty() strips bound // event data from any children left inside it, which would // silently kill addSectionBtn's click handler on every re-render. addSectionBtn.$element.detach(); sectionTabsDiv.empty(); var lang = getValues().lang || ""; if (!lang) { sectionTabsDiv.hide(); return; } sectionTabsDiv.show(); $.each(sections, function (i) { var posVal = sections[i].pos || ""; var tabLabel = posVal ? capitalize(posVal) : ("Beş " + (i + 1)); var tab = $("<span></span>") .addClass("wiktku-section-tab") .text(tabLabel) .toggleClass("wiktku-tab-active", i === activeSection); (function (idx) { tab.on("click", function () { if (idx === activeSection) return; saveCurrentSection(); activeSection = idx; restoreSection(sections[activeSection]); refresh(); renderSectionTabs(); }); }(i)); sectionTabsDiv.append(tab); }); // Enable "Beş zêde bike" only when the active section has a pos chosen. var activePos = sections[activeSection] && sections[activeSection].pos ? sections[activeSection].pos : getValues().pos; addSectionBtn.setDisabled(!activePos); sectionTabsDiv.append(addSectionBtn.$element); } renderSectionTabs(); // Update the active tab's label whenever pos changes. startForm.on("change", "#wiktku-start-pos-field", function () { renderSectionTabs(); }); // Show the tab bar as soon as a language is selected. startForm.on("change", "#wiktku-start-lang-field", function () { renderSectionTabs(); }); var footer = $("<div id='wiktku-start-footer'></div>"); spinner = $(mw.html.element("img", { id: "wiktku-start-spinner", src: "//upload.wikimedia.org/wikipedia/commons/d/de/Ajax-loader.gif", alt: "Tê barkirin…", title: "Tê barkirin…" })); footer.append(spinner.hide()); continueBtn = new OO.ui.ButtonWidget({ id: "wiktku-unhide-editform", label: "Bişîne", flags: [ "primary", "progressive" ] }); continueBtn.on("click", function () { mw.notify("Tê şandin…", { type: "info", tag: "wiktku-submit" }); startForm.trigger("submit"); }); footer.append(continueBtn.$element); // ── Preview checkboxes ─────────────────────────────────────────────── // Wikitext preview (raw text panel) var previewCheck = $("<input type='checkbox' id='wiktku-preview-toggle'>"); var previewLabel = $("<label for='wiktku-preview-toggle'></label>") .text(" Pêşdîtina wîkîtekstê"); var previewPanel = $("<pre id='wiktku-preview-panel'></pre>").hide(); // Live rendered preview (parsed HTML panel, same logic as AjaxEdit). // Not available on mobile — API polling causes too many problems on small screens. var livePreviewCheck = null; var livePreviewPanel = null; if (!isMobile) { livePreviewCheck = $("<input type='checkbox' id='wiktku-live-preview-toggle'>"); livePreviewPanel = $("<div id='wiktku-live-preview-panel'></div>").hide(); } // Container that holds both panels and switches between stacked / side-by-side. var previewContainer = $("<div id='wiktku-preview-container'></div>"); previewContainer.append(previewPanel); if (!isMobile) previewContainer.append(livePreviewPanel); var previewTimer = null; var livePreviewIntervalId = -1; /** Rebuilds wikitext preview if its checkbox is checked. */ function schedulePreview() { if (!previewCheck.prop("checked")) return; clearTimeout(previewTimer); // Debounce: wait 400 ms after the last keystroke before rebuilding. previewTimer = setTimeout(function () { getWikitext(function (wikitext) { previewPanel.text(wikitext).show(); updatePanelLayout(); }); }, 400); } /** Fetches parsed HTML and populates the live preview panel. */ function loadLivePreview() { getWikitext(function (wikitext) { new mw.Api().parse(wikitext, { title: mw.config.get("wgPageName") }).done(function (html) { livePreviewPanel.html(html).show(); updatePanelLayout(); }); }); } /** Adjusts panel widths depending on which previews are visible. */ function updatePanelLayout() { var wikitextVisible = previewCheck.prop("checked"); var liveVisible = livePreviewCheck && livePreviewCheck.prop("checked"); if (wikitextVisible && liveVisible) { // Side by side — each panel takes roughly half the available width. previewPanel.css({ "flex": "1 1 45%", "min-width": "280px" }); livePreviewPanel.css({ "flex": "1 1 45%", "min-width": "280px" }); } else { // Full width for whichever is visible. previewPanel.css({ "flex": "1 1 100%", "min-width": "" }); if (livePreviewPanel) livePreviewPanel.css({ "flex": "1 1 100%", "min-width": "" }); } } previewCheck.on("change", function () { if ($(this).prop("checked")) { schedulePreview(); } else { clearTimeout(previewTimer); previewPanel.hide(); updatePanelLayout(); } }); if (!isMobile) { livePreviewCheck.on("change", function () { if ($(this).prop("checked")) { livePreviewPanel.show(); loadLivePreview(); livePreviewIntervalId = setInterval(loadLivePreview, 500); } else { clearInterval(livePreviewIntervalId); livePreviewIntervalId = -1; livePreviewPanel.hide().empty(); updatePanelLayout(); } }); } // Listen on all input/change events on the form and update both previews. startForm.on("input change", function () { schedulePreview(); }); footer.append($("<span style='margin-left:1em'></span>") .append(previewCheck).append(previewLabel)); if (!isMobile) { var livePreviewLabel = $("<label for='wiktku-live-preview-toggle'></label>") .text(" Pêşdîtina zindî"); footer.append($("<span style='margin-left:1em'></span>") .append(livePreviewCheck).append(livePreviewLabel)); } startForm.append(footer); $("#editform").hide().before(startForm); // Insert preview container (holds both panels) after the form. startForm.after(previewContainer); if (!isMobile) startForm.find("select").chosen(chosenOptions); refresh(); // Zimanan ji MediaWiki:Gadget-translation_editor.js/ziman.json bar bike. // Kodên ku bi "-pro" diqedin û navên ku "zimanê destan" tê de heye // tên derxistin. Zimanên xardkirî li serî dimînin, yên din // bi alfabeyê li dû wan tên. // Pinned choices come from MediaWiki:Gadget-start.js/data.json (langChoices), // already loaded into steps.lang.choices before build() runs. var pinnedChoices = steps.lang.choices.slice(); var pinnedCodes = $.map(pinnedChoices, function (choice) { return choice[0]; }); new mw.Api().get({ action: "query", prop: "revisions", titles: "MediaWiki:Gadget-translation_editor.js/ziman.json", rvprop: "content", rvslots: "main", formatversion: 2 }).then(function (data) { var page = data.query.pages[0]; var content = page && page.revisions && page.revisions[0].slots.main.content; var zimanData; try { zimanData = JSON.parse(content); } catch (e) { zimanData = {}; } var extraChoices = []; $.each(zimanData, function (code, name) { // Filter: skip proto-language codes and legendary/reconstructed langs. if (/-pro$/i.test(code)) return; if (/ziman[eê]\s+destan/i.test(name)) return; // Skip codes already in the pinned list (they are handled above). if (pinnedCodes.indexOf(code) !== -1) return; // sortKey: bare name without leading "zimanê " for sorting. var sortKey = name.replace(/^ziman[eê]\s+/i, ""); var choice = [code, name, sortKey]; extraChoices.push(choice); langsByCode[code] = choice; }); // Populate langsByCode for pinned choices too. $.each(pinnedChoices, function (i, choice) { // Ensure pinned choices have a sortKey (index 2). if (choice.length < 3) choice[2] = choice[1]; langsByCode[choice[0]] = choice; }); // Sort the extra choices alphabetically by sort key. extraChoices.sort(function (a, b) { return a[2].localeCompare(b[2], userLang); }); // Final list: pinned first, then the rest. var allChoices = pinnedChoices.concat(extraChoices); steps.lang.choices = allChoices; steps.trans.keys = allChoices; steps.dunde.keys = allChoices; steps.zarava.keys = getZaravaKeys(allChoices); var langMenu = $("#wiktku-start-lang-field"); populateMenus(langMenu, steps.lang.choices); langMenu.trigger("chosen:updated"); var transMenus = $("#wiktku-start-trans .wiktku-start-step-keyfield"); populateMenus(transMenus, steps.trans.keys, getDisabledKeys(steps.trans)); transMenus.trigger("chosen:updated"); var dundeMenus = $("#wiktku-start-dunde .wiktku-start-step-keyfield"); populateMenus(dundeMenus, steps.dunde.keys, getDisabledKeys(steps.dunde)); dundeMenus.trigger("chosen:updated"); var zaravaMenus = $("#wiktku-start-zarava .wiktku-start-step-keyfield"); populateMenus(zaravaMenus, steps.zarava.keys, getDisabledKeys(steps.zarava)); }); } mw.loader.using(["jquery.chosen", "mediawiki.api", "oojs-ui-core"], function () { // Load metadata, langChoices, posChoices and tplDefs from the companion // data page so they can be updated without touching this script. new mw.Api().get({ action: "query", prop: "revisions", titles: "MediaWiki:Gadget-start.js/data.json", rvprop: "content", rvslots: "main", formatversion: 2 }).then(function (data) { var page = data.query.pages[0]; var content = page && page.revisions && page.revisions[0].slots.main.content; var d; try { d = JSON.parse(content); } catch (e) { d = {}; } // Populate metadata. if (d.metadata) $.extend(metadata, d.metadata); // Populate lang choices (pinned list used by build() → ziman.json loader). if (d.langChoices) steps.lang.choices = d.langChoices; // Populate POS choices. if (d.posChoices) steps.pos.choices = d.posChoices; // Populate template definitions for the dfn sense-block builder. if (d.tplDefs) steps.dfn.tplDefs = d.tplDefs; // Populate pos placeholder examples. if (d.posExamples) steps.dfn.posExamples = d.posExamples; // Populate citation template definitions for the quote widget. if (d.jederDefs) steps.dfn.jederDefs = d.jederDefs; // Populate pronunciation and etymology template insert lists. if (d.pronTpls) { steps.pron.pronTpls = d.pronTpls; steps.pron.refreshTplSelect(); } if (d.etymTpls) { steps.etym.etymTpls = d.etymTpls; steps.etym.refreshTplSelect(); } // Sync trans/dunde/zarava keys with the (now populated) lang choices. steps.trans.keys = steps.lang.choices; steps.dunde.keys = steps.lang.choices; steps.zarava.keys = getZaravaKeys(steps.lang.choices); }).always(build); }); }); //</nowiki> 3d03lkrwr4vei9s94mfbatows9rh5rr 6265555 6265553 2026-07-19T12:22:03Z Wikihez 7344 6265555 javascript text/javascript // Li ser [[vi:MediaWiki:Gadget-start.js]] hatiye refaktorkirin. //<nowiki> $(function () { var ns = mw.config.get("wgNamespaceNumber"); if (ns && !(ns === 2 && mw.config.get("wgPageName").match(/\/ceribandin$|\/test$/))) { return; } var action = mw.config.get("wgAction"); var pageExists = !!mw.config.get("wgArticleId"); // "Zimanek lê zêde bike" mode: triggered from the portlet link below. // Runs the same wizard on an EXISTING page's edit form, but appends the // generated section instead of replacing the textarea's content. var addLangMode = pageExists && mw.util.getParamValue("wiktkuaddlang") === "1"; // On a normal page view of an existing page, just add the portlet link // that takes the user into addLangMode; don't build anything else here. if (action === "view" && pageExists) { mw.util.addPortletLink("p-views", mw.util.getUrl(mw.config.get("wgPageName"), { action: "submit", wiktkuaddlang: "1" }), "+Ziman/beşeke din", "ca-wiktku-addlang", "Ji vê rûpelê re zimanekî nû zêde bike"); return; } if (!(action === "edit" || action === "submit")) { return; } if (!addLangMode && !$(".mw-newarticletext, .mw-newarticletextanon").length) { return; } if (window.location.href.includes("editintro=User:Wikihez/creation/intro")) { return; // Do not run the script wextê WF:Bilez dişuxile } function capitalize(str) { if (!str) return str; return str[0].toUpperCase() + str.substr(1); } function decapitalize(str) { if (!str) return str; return str[0].toLowerCase() + str.substr(1); } function escapeRegExp(str) { return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); } function stripWikilinks(str) { return str.replace(/\[\[([^\]|]+)(?:\|([^\]]+))?\]\]/g, function (m, target, display) { return display || target; }); } function insertAtCursor(el, text) { var start = el.selectionStart; var end = el.selectionEnd; var val = el.value; el.value = val.slice(0, start) + text + val.slice(end); var pos = start + text.length; el.selectionStart = el.selectionEnd = pos; } var pageName = mw.config.get("wgPageName").replaceAll(/_/g, " "); if (ns) pageName = pageName.replace(/.*\//, ""); var pageNameRe = escapeRegExp(pageName); var userLang = mw.config.get("wgUserLanguage"); // Mobile detection: MobileFrontend sets wgMFMode, or fall back to touch check. var isMobile = !!mw.config.get("wgMFMode") || window.matchMedia("(pointer: coarse)").matches; var chosenOptions = { width: "20em", disable_search_threshold: 0, placeholder_text_single: "Yekî hilbijêre", placeholder_text_multiple: "Hilbijêre", no_results_text: "Nehat dîtin", enable_split_word_search: true, search_contains: true }; function wrapNativeSelect(select) { var placeholder = select.attr("data-placeholder") || "Lê bigere…"; // Hide the native select — we drive it programmatically. select.hide(); var wrapper = $("<span class='wiktku-native-select-wrap'></span>"); var textInput = $("<input type='search' autocomplete='off'>") .attr("placeholder", placeholder) .addClass("wiktku-start-narrow wiktku-ac-input"); var resultsList = $("<ul class='wiktku-ac-results'></ul>").hide(); // Full option cache — rebuilt when chosen:updated fires. var allOptions = []; function cacheOptions() { allOptions = []; select.find("option").each(function () { var v = $(this).val(); if (!v) return; // skip the empty placeholder option allOptions.push({ value: v, text: $(this).text(), disabled: $(this).prop("disabled") }); }); } cacheOptions(); function showResults(query) { var q = query.trim().toLowerCase(); resultsList.empty(); var matched; if (q) { matched = []; $.each(allOptions, function (_, o) { if (o.disabled) return; var codeMatch = o.value.toLowerCase().indexOf(q) !== -1; var nameMatch = o.text.toLowerCase().indexOf(q) !== -1; if (codeMatch || nameMatch) { matched.push({ opt: o, codeMatch: codeMatch }); } }); // Code matches (especially prefix matches) come first. matched.sort(function (a, b) { var aCode = a.opt.value.toLowerCase(); var bCode = b.opt.value.toLowerCase(); var aPrefix = aCode.indexOf(q) === 0; var bPrefix = bCode.indexOf(q) === 0; if (aPrefix !== bPrefix) return aPrefix ? -1 : 1; if (a.codeMatch !== b.codeMatch) return a.codeMatch ? -1 : 1; return 0; }); matched = matched.map(function (item) { return item.opt; }); } else { matched = allOptions.filter(function (o) { return !o.disabled; }); } if (!matched.length) { resultsList.hide(); return; } $.each(matched.slice(0, 50), function (_, opt) { var li = $("<li></li>").text(opt.text).attr("data-value", opt.value); // Use touchend instead of touchstart so that a scroll gesture does // not accidentally select an item. We track whether the finger moved // between touchstart and touchend — if it did, it was a scroll. var touchMoved = false; li.on("touchstart", function () { touchMoved = false; }); li.on("touchmove", function () { touchMoved = true; }); li.on("touchend", function (e) { if (touchMoved) return; // was a scroll, not a tap e.preventDefault(); selectOption(opt.value, opt.text); }); // Keep mousedown for desktop fallback. li.on("mousedown", function (e) { e.preventDefault(); selectOption(opt.value, opt.text); }); resultsList.append(li); }); // Position the list above or below depending on available viewport space. var inputRect = textInput[0].getBoundingClientRect(); var viewportH = window.innerHeight; var spaceBelow = viewportH - inputRect.bottom - 8; var spaceAbove = inputRect.top - 8; var maxH = Math.min(224, Math.max(spaceBelow, spaceAbove)); // 224px ≈ 14em resultsList.css({ "max-height": maxH + "px", "top": spaceBelow >= spaceAbove ? "100%" : "auto", "bottom": spaceBelow >= spaceAbove ? "auto" : "100%" }); resultsList.show(); } function selectOption(value, text) { textInput.val(text); select.val(value); resultsList.hide(); select.trigger("change"); } textInput.on("input focus", function () { showResults($(this).val()); }); textInput.on("blur", function () { // Short delay so a touchstart on a result item fires first. setTimeout(function () { resultsList.hide(); }, 200); }); // chosen:updated → re-cache (called after ziman.json loads). select.on("chosen:updated", function () { cacheOptions(); // If a value is already selected, keep the display text in sync. var cur = select.val(); if (cur) { var match = $.grep(allOptions, function (o) { return o.value === cur; })[0]; if (match) textInput.val(match.text); } }); // No-op .chosen() so desktop call-sites don't need guarding. select.chosen = function () { return select; }; wrapper.append(textInput).append(resultsList).append(select); return wrapper; } var langsByCode = {}; // Populated from [[MediaWiki:Gadget-start.js/data.json]] at runtime. var metadata = {}; // Zaravayên kurdî yên ku di beşa "Bi zaravayên din" de tên pêşkêşkirin — // ev kod ji beşa Werger têne derxistin daku heman zimên du caran neyê xwendin. var ZARAVA_LANG_CODES = ["ckb", "sdh", "lki", "hac", "zza"]; function getZaravaKeys(choices) { var byCode = {}; $.each(choices || [], function (_, c) { byCode[c[0]] = c; }); var result = []; $.each(ZARAVA_LANG_CODES, function (_, code) { if (byCode[code]) result.push(byCode[code]); }); return result; } function needsTransliteration(langCode) { var meta = metadata[langCode]; if (!meta || !meta.sc) return false; var scripts = Array.isArray(meta.sc) ? meta.sc : [meta.sc]; return scripts.length > 0 && scripts[0] !== "Latn"; } // Kodên cinsiyetê yên di metadata.g de var GENDER_BASE_LABELS = { m: "mê", n: "nêr", nt: "nêtar", mn: "mê û nêr", mnmane: "mê yan nêr li gorî maneyê", g: "giştî", y: "yekjimar", p: "pirjimar" }; // Sub-lists that only make sense for a plain (non-şablon) sense — hidden // when a şablon (e.g. {{guharto|…}}) is chosen for that sense, since a // template-based sense has no "own" gloss for alternate forms, synonyms, // antonyms, coordinate terms, hypernyms or hyponyms to attach to. Etîket, // Nimûne and Jêgirtin stay visible either way. var HIDDEN_ON_TPL_GROUPS = [ "wiktku-dfn-alternativ", "wiktku-dfn-hevmane", "wiktku-dfn-dijmane", "wiktku-dfn-koordine", "wiktku-dfn-jornav", "wiktku-dfn-jernav" ]; function genderLabel(code) { if (code === "p") return "Pirjimar"; var pluralMatch = code.match(/^(.+)-p$/); if (pluralMatch && GENDER_BASE_LABELS[pluralMatch[1]]) { return GENDER_BASE_LABELS[pluralMatch[1]] + " (pirjimar)"; } return GENDER_BASE_LABELS[code] || code; } /** * True if a sense has any content worth keeping besides its mane text — * etîket, hevmane/dijmane/koordîne/etc. word lists, nimûne, or jêder * (quote). Used so a sense with an empty mane but filled-in extra * fields still gets emitted (with {{mane?}} standing in for the gloss) * instead of being silently dropped. */ function senseHasExtraContent(s) { if (s.etiket && $.grep(s.etiket, function (e) { return $.trim(e) !== ""; }).length) return true; if (s.alternativ.length || s.hevmane.length || s.dijmane.length || s.koordine.length || s.jornav.length || s.jernav.length) return true; if (s.nimune && $.grep(s.nimune, function (n) { return (typeof n === "object" ? n.text : n) !== ""; }).length > 0) return true; if (s.jeder && $.grep(s.jeder, function (j) { return j && j.quote; }).length > 0) return true; return false; } /** * formatNimune: each nimûne item can be { text, tr, t }: * text — example text * tr — transliteration (only when the language needs it) * t — Kurdish translation (third positional param, no key) */ function formatNimune(nimunes, lang, hasJeder) { var hasNimune = nimunes && $.grep(nimunes, function (n) { return (typeof n === "object" ? n.text : n) !== ""; }).length > 0; if (!hasNimune) { return hasJeder ? "" : "\n#* {{bênimûne|" + lang + "}}"; } return $.map(nimunes, function (n) { var text = typeof n === "object" ? n.text : n; if (!text) return undefined; var bolded = text.replace( new RegExp("(" + pageNameRe + "([^( |,|;|\\?|\\.|\\!)]+)?)", "ig"), "'''$1'''"); var tpl = "\n#: {{nm|" + lang + "|" + bolded; if (typeof n === "object") { if (n.tr) tpl += "|tr=" + n.tr; // Translation as third positional param (no key needed). if (n.t) tpl += "|" + n.t; } // Short examples fit on one line together with their translation. // rêz=1 is not used for ku — definitions are shown on separate lines there. if (text.length < 200 && lang !== "ku") tpl += "|rêz=1"; tpl += "}}"; return tpl; }).join(""); } /** * Formats a list of jêder (quote/citation) objects into wikitext lines. * Each entry that has no quote text is skipped. Returns "" when the list * is empty or every entry is blank. * * #* {{jêder-…|lang|jêgirtin=…|tr=…|tercime=…|…fields…}} * * When no template is chosen, the generic {{jêder|…}} template is used * instead. Its 2nd positional param is the user's freeform "bi destê xwe * binivîsim" source text when supplied, or the çavkanî? placeholder otherwise. * If that text contains "=" it is passed as |2=… instead of a bare * positional param, since MediaWiki would otherwise misparse it as its * own key=value pair and break the template: * #* {{jêder|lang|jêgirtin=…|tr=…|tercime=…|<manual source or çavkanî?>}} */ function formatJeder(jederList, lang) { if (!jederList || !jederList.length) return ""; return $.map(jederList, function (jeder) { if (!jeder || !jeder.quote) return undefined; if (jeder.jederTpl) { var cite = "\n#* {{" + jeder.jederTpl + "|" + lang; cite += "|jêgirtin=" + jeder.quote; if (jeder.quoteTr) cite += "|tr=" + jeder.quoteTr; if (jeder.quoteT) cite += "|tercime=" + jeder.quoteT; $.each(jeder.jêderFields || {}, function (key, val) { if (val) cite += "|" + key + "=" + val; }); cite += "}}"; return cite; } var out = "\n#* {{jêder|" + lang + "|jêgirtin=" + jeder.quote; if (jeder.quoteTr) out += "|tr=" + jeder.quoteTr; if (jeder.quoteT) out += "|tercime=" + jeder.quoteT; var srcParam = jeder.jederManual ? jeder.jederManual : "çavkanî?"; // A positional param containing "=" gets parsed as its own key=value // pair by MediaWiki and breaks the template, so force it to be // explicitly named (|2=) whenever that's the case. out += (srcParam.indexOf("=") !== -1 ? "|2=" : "|") + srcParam; out += "}}"; return out; }).join(""); } function makeWordListStep(id, name, question_fmt, header, templateName) { return { id: id, name: name, question_fmt: question_fmt, multiple: true, narrow: true, visible: function (values) { return values.lang && values.pos; }, output: function (values) { var words = $.grep(values[id] || [], function (w) { return !!w; }); if (!words.length) return ""; var lang = values.lang; var section = "\n==== " + header + " ====\n"; if (words.length === 1) { // Single word — keep the simple inline template. return section + "* {{" + templateName + "|" + lang + "|" + words[0] + "}}\n"; } // Multiple words — use {{kol3}} with one positional param per word. var params = "cure=" + header + "\n" + $.map(words, function (w) { return "|" + w; }).join("\n"); return section + "{{kol3|" + lang + "|" + params + "\n}}\n"; } }; } var steps = { lang: { id: "lang", required: true, name: "ziman", question_fmt: '"' + pageName + '" bi çi zimanî ye?', question_br: true, // Populated from [[MediaWiki:Gadget-start.js/data.json]] (langChoices). choices: [], output: function (values) { return "== {{ziman|" + values.lang + "}} ==\n"; } }, pron: { id: "pron", name: "bilêvkirin", question_fmt: '"' + pageName + '" çawa tê telafûzkirin?', // pronTpls populated from data.json pronTpls: [], visible: function (values) { if (!values.lang) return false; // In addLangMode, only skip pron when this langcode's section // already exists in the page — if it's a new language, show it. if (addLangMode) { var existing = $("#wpTextbox1").val() || ""; var header = "== {{ziman|" + values.lang + "}} =="; return existing.indexOf(header) === -1; } return true; }, /** Fills (or refills) the insert-dropdown from the current pronTpls array, filtering by language. */ refreshTplSelect: function () { var sel = $("#wiktku-start-pron .wiktku-tpl-insert-select"); if (!sel.length) return; var lang = getValues().lang || ""; sel.find("option[value!='']").remove(); $.each(steps.pron.pronTpls, function (_, tpl) { // Filter: if tpl.langs exists, only show if lang is in that list; otherwise show always var allowed = !tpl.langs || tpl.langs.indexOf(lang) !== -1; if (allowed) { sel.append($("<option></option>") .val(tpl.snippet) .text(tpl.name + " — " + tpl.desc) .attr("data-nolang", tpl.noLang ? "1" : "")); } }); // Notify Chosen that the option list has changed (no-op on mobile). if (!isMobile) sel.trigger("chosen:updated"); }, build: function (stepDiv) { if (stepDiv.find(".wiktku-pron-wrap").length) return null; var wrap = $("<div class='wiktku-pron-wrap'></div>"); var ta = $("<textarea></textarea>") .attr("name", "wiktku-pron-" + $.now()) .attr("class", "wiktku-start-step-field wiktku-pron-text") .attr("rows", 4) .attr("placeholder", "Nimûne: {{IPA|ku|/pɛɪ̯n/}} yan {{kîte|ku|he|ce|ki|rin}}"); // Template insert dropdown — filtered by language. var sel = $("<select class='wiktku-tpl-insert-select'></select>"); sel.append($("<option value=''>— şablonek lê zêde bike —</option>")); var lang = getValues().lang || ""; $.each(steps.pron.pronTpls, function (_, tpl) { // Filter: if tpl.langs exists, only show if lang is in that list; otherwise show always var allowed = !tpl.langs || tpl.langs.indexOf(lang) !== -1; if (allowed) { sel.append($("<option></option>") .val(tpl.snippet) .text(tpl.name + " — " + tpl.desc) .attr("data-nolang", tpl.noLang ? "1" : "")); } }); sel.on("change", function () { var snippet = $(this).val(); if (!snippet) return; var lang = getValues().lang || ""; // Check if the selected option has noLang flag var selectedOption = sel.find("option:selected"); var hasNoLang = selectedOption.attr("data-nolang") === "1"; if (!hasNoLang) { snippet = snippet.replace(/CODE/g, lang).replace(/SOURCELANG/g, "?"); } insertAtCursor(ta[0], snippet); $(this).val(""); ta.focus(); }); wrap.append(sel).append($("<br>")).append(ta); stepDiv.append(wrap); return ta; }, output: function () { var text = $.trim($("#wiktku-start-pron .wiktku-pron-text").val()); if (!text) return ""; var lines = text.split("\n"); var out = $.map(lines, function (line) { line = $.trim(line); if (!line) return undefined; return line.charAt(0) === "*" ? line : "* " + line; }).join("\n"); return "\n=== Bilêvkirin ===\n" + out + "\n"; } }, pos: { id: "pos", required: true, name: "Cureyê rêzimanî", question_fmt: 'Cureyê rêzimanî yê "' + pageName + '" çi ye?', visible: function (values) { return values.lang; }, question_br: true, // Populated from [[MediaWiki:Gadget-start.js/data.json]] (posChoices). choices: [], output: function (values) { var pos = values.pos || ""; var cinsiyet = values.cinsiyet || ""; // from the cinsiyet step var lekTur = values.lektur || ""; // from the lêker transitivity step var capitalizedPos = capitalize(pos); var outputString = "\n=== " + capitalizedPos + " ===\n"; // Add ku-tewîn-nav for single-word navdêr/serenav with known gender. if (!pageName.includes(" ") && cinsiyet && GENDER_BASE_LABELS[cinsiyet] && (pos === "navdêr" || pos === "serenav") && values.lang === "ku") { outputString += "{{ku-tewîn-nav|" + pageName + "|" + GENDER_BASE_LABELS[cinsiyet]; if (pos === "serenav") outputString += "|y"; outputString += "}}\n"; } outputString += "{{" + pos + "|" + values.lang; if (pos === "navdêr" || pos === "serenav") { if (cinsiyet) { outputString += "|c=" + cinsiyet; } else if (values.lang === "ku") { // Unknown gender — prompt editor to fill it in. outputString += "|c=?"; } } else if (/^lêker/.test(pos) && lekTur) { outputString += "|c=" + lekTur; } if (values.tr) { outputString += "|tr=" + values.tr; } outputString += "}}\n"; return outputString; } }, /** * cinsiyet (grammatical gender) — only shown for navdêr/serenav, û * tenê ger metadata ji bo zimanê hilbijartî lîsteyeke "g" (cinsiyet) * were dayîn. Opsiyonên vê gavê ne sabît in — ji metadata[values.lang].g * têne çêkirin, ji ber ku di hemû zimanan de cinsiyet tine. */ cinsiyet: { id: "cinsiyet", name: "cinsiyet", question_fmt: 'Cinsiyeta "' + pageName + '" çi ye?', question_br: true, visible: function (values) { var meta = metadata[values.lang]; return !!(values.lang && (values.pos === "navdêr" || values.pos === "serenav") && meta && meta.g && meta.g.length); }, build: function (stepDiv, values) { var select = stepDiv.find("select.wiktku-start-step-field"); if (!select.length) { select = $(mw.html.element("select", { "class": "wiktku-start-step-field", id: "wiktku-start-cinsiyet-field" })); stepDiv.append(select); } if (!values) return select; var meta = metadata[values.lang]; var codes = (meta && meta.g) || []; var prevVal = select.val(); var choices = $.map(codes, function (code) { return [[code, genderLabel(code)]]; }); populateMenus(select, choices); if ($.grep(choices, function (c) { return c[0] === prevVal; }).length) { select.val(prevVal); } if (!isMobile) select.trigger("chosen:updated"); return select; }, output: function () { return ""; } // consumed by pos.output }, /** * Lêker transitivity — only shown for any lêker variant. */ lektur: { id: "lektur", name: "Cureyê lêkerê (fiîlê)", question_fmt: "Cureyê lêkerê (fiîlê) çi ye?", question_br: true, visible: function (values) { return values.lang && values.pos && /^lêker/.test(values.pos); }, // Dictionary: value → display label. Add new types here. choices: [ ["gh", "gerguhêz"], ['x-gh', 'xwerû-gerguhêz'], ['p-gh', 'pêkhatî-gerguhêz'], ['h-gh', 'hevedudanî-gerguhêz'], ['b-gh', 'biwêjî-gerguhêz'], ["ngh", "negerguhêz"], ['x-ngh', 'xwerû-negerguhêz'], ['p-ngh', 'pêkhatî-negerguhêz'], ['h-ngh', 'hevedudanî-negerguhêz'], ['b-ngh', 'biwêjî-negerguhêz'] ], output: function () { return ""; } // consumed by pos.output }, tr: { id: "tr", name: "transkrîpsiyon", question_fmt: "Transkrîpsiyona kelîmeyê", multiple: false, narrow: true, visible: function (values) { return values.lang && values.pos && needsTransliteration(values.lang); } }, dfn: { id: "dfn", // required: true, ger mane tinebe [[Şablon:mane?]] bi kar bîne name: "Mane", question_fmt: "Maneya kelîmeyê binivîse. Mane otomatîk tê lînkkirin! Ji bo tercimeyan beşa 'Werger' bi kar bîne!", multiple: true, ordered: true, rows: 3, visible: function (values) { return values.lang && values.pos; }, example: function (values) { // posExamples loaded from [[MediaWiki:Gadget-start.js/data.json]]. var examples = steps.dfn.posExamples || {}; var full = values.pos || ""; return examples[full] || ""; }, /** * Builds one sense block (<li>) inside the ordered list. * Each block contains: * - a textarea for the definition * - an expandable nimûne list * - single-row sub-lists for formên alternatîv, hevmane, dijmane */ buildSenseBlock: function (stepDiv) { var block = $("<li class='wiktku-dfn-sense'></li>"); // — Mane textarea (declared first so the template handler can reference it) — var dfnArea = $("<textarea></textarea>") .attr("name", "wiktku-dfn-mane-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("class", "wiktku-start-step-field wiktku-dfn-mane") .attr("rows", 6) .attr("placeholder", "Mane…"); dfnArea.on("input", function () { steps.dfn.onDfnInput(stepDiv, block, this); }); // — Template selector (optional — replaces mane when chosen) — // Template definitions loaded from [[MediaWiki:Gadget-start.js/data.json]]. var tplDefs = steps.dfn.tplDefs || []; // Cache of all non-placeholder option elements — used by updateTplOptions // to remove/re-add options (the only approach compatible with Chosen.js). var _allTplOptions = []; var tplSelect = $(mw.html.element("select", { "class": "wiktku-dfn-tpl-select" })); tplSelect.append($("<option value=''>— yan jî şablonek hilbijêre —</option>")); $.each(tplDefs, function (_, tpl) { var opt = $("<option></option>") .val(tpl.name) .text(tpl.name) .attr("data-langs", tpl.langs ? tpl.langs.join(",") : "") .attr("data-nolang", tpl.noLang ? "1" : ""); tplSelect.append(opt); _allTplOptions.push(opt[0]); }); function updateTplOptions() { var lang = getValues().lang || ""; var currentVal = tplSelect.val(); var currentStillValid = false; // Detach all non-placeholder options, then re-attach only the visible ones. // This is the only approach that works correctly with both native <select> // and Chosen.js on desktop. tplSelect.find("option[value!='']").detach(); $.each(_allTplOptions, function (_, opt) { var allowed = $(opt).attr("data-langs"); var visible = !allowed || allowed.split(",").indexOf(lang) !== -1; if (visible) { tplSelect.append(opt); if ($(opt).val() === currentVal) currentStillValid = true; } }); if (!isMobile) tplSelect.trigger("chosen:updated"); if (currentVal && !currentStillValid) { tplSelect.val(""); dfnArea.show(); tplTitleInput.hide().val(""); } } // Store updater on the element so refresh() can call it for all blocks. tplSelect.data("updateOptions", updateTplOptions); var tplTitleInput = $("<input type='text'>") .addClass("wiktku-dfn-tpl-title wiktku-start-narrow") .attr("placeholder", "Navê rûpelê…") .hide(); // Grow the sense list when the title field of the last block gets content, // mirroring what onDfnInput does for the plain mane textarea. tplTitleInput.on("input", function () { steps.dfn.onDfnInput(stepDiv, block, this); }); /** * When a şablon sense is chosen, formên alternatîv/hevmane/dijmane/ * termên koordîne/jornav/jêrnav don't apply (there's no plain gloss * to hang them off), so hide those subgroups. Etîket, Nimûne and * Jêgirtin stay visible and still usable for a şablon sense. */ function updateFieldVisibility() { var isTpl = !!tplSelect.val(); $.each(HIDDEN_ON_TPL_GROUPS, function (_, cls) { block.find("." + cls + "-group").toggle(!isTpl); }); } // Store on the block so restoreDfn() can re-sync visibility // after programmatically setting tplSelect's value. block.data("updateFieldVisibility", updateFieldVisibility); tplSelect.on("change", function () { var chosen = $(this).val(); if (chosen) { dfnArea.hide(); tplTitleInput.show().focus(); } else { dfnArea.show(); tplTitleInput.hide().val(""); } updateFieldVisibility(); // Re-run refresh so the Werger step visibility updates. refresh(); }); var tplRow = $("<div></div>").addClass("wiktku-dfn-tpl-row") .append(tplSelect).append(" ").append(tplTitleInput); block.append(tplRow); block.append(dfnArea); // Apply lang filter on initial build. updateTplOptions(); // — Sub-field groups — // All groups are always visible with a placeholder textarea. // Nimûne is last in the DOM and last in the output. var allGroups = [ { cls: "wiktku-dfn-etiket", label: "Etîket", rows: 1, narrow: true, izah: "xisûsen, Mêrdîn, anatomî, Badînî" }, { cls: "wiktku-dfn-alternativ", label: "Formên alternatîv", rows: 1, narrow: true, izah: "Varyantên vê kelîmeyê" }, { cls: "wiktku-dfn-hevmane", label: "Hevmane", rows: 1, narrow: true, izah: "Spehî hevmaneya Bedew e." }, { cls: "wiktku-dfn-dijmane", label: "Dijmane", rows: 1, narrow: true, izah: "Zengîn dijmaneya feqîr e." }, { cls: "wiktku-dfn-koordine", label: "Termên koordîne", rows: 1, narrow: true, izah: "Pisîk û kûçik termên koordîne ne çunkî Jornavên wan gelek in" }, { cls: "wiktku-dfn-jornav", label: "Jornav", rows: 1, narrow: true, izah: "Heywan jornavê guhandar e" }, { cls: "wiktku-dfn-jernav", label: "Jêrnav", rows: 1, narrow: true, izah: "Guhandar jêrnavê heywan e" }, { cls: "wiktku-dfn-nimune", label: "Nimûne", rows: 2, narrow: false } ]; $.each(allGroups, function (_, g) { var groupDiv = $("<div></div>").addClass("wiktku-dfn-subgroup " + g.cls + "-group"); function buildNimuneLi() { var lang = getValues().lang || ""; var li = $("<li></li>").addClass("wiktku-dfn-nimune-li"); var mainTa = $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-text-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", g.rows) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-text") .attr("placeholder", "Nimûneya emilandina kelîmeyê tu bi xwe binivîse…"); mainTa.on("input", function () { var val = $.trim($(this).val()); var isLast = li.is(list.children("li:last-child")); if (val && isLast) { list.append(buildNimuneLi()); } }); li.append(mainTa); var subWrap = $("<div></div>").addClass("wiktku-dfn-nimune-sub"); if (needsTransliteration(lang)) { subWrap.append( $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-tr-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 5) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-tr") .attr("placeholder", "Transkrîpsiyona bi alfabeya latînî") ); } if (lang && lang !== "ku") { subWrap.append( $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-t-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 5) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-t") .attr("placeholder", "Tercimeya kurmancî") ); } if (subWrap.children().length) li.append(subWrap); return li; } if (g.cls === "wiktku-dfn-nimune") { // Nimûne — compound widget with tr/t sub-fields. var lbl = $("<span></span>").addClass("wiktku-dfn-sublabel").text(g.label + ": "); var list = $("<ol></ol>").addClass("wiktku-dfn-sublist " + g.cls + "-list"); groupDiv.data("buildNimuneLi", buildNimuneLi); list.append(buildNimuneLi()); groupDiv.append(lbl).append(list); block.append(groupDiv); } else { // Regular always-visible group — label + growing textarea list. var lbl = $("<span></span>").addClass("wiktku-dfn-sublabel").text(g.label + ": " + g.izah); var list = $("<ol></ol>").addClass("wiktku-dfn-sublist " + g.cls + "-list"); var firstInput = $("<textarea></textarea>") .attr("name", g.cls + "-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", g.rows) .attr("class", "wiktku-dfn-subfield" + (g.narrow ? " wiktku-start-narrow" : "")) .attr("placeholder", g.label + "…"); firstInput.on("input", function () { steps.dfn.onSubInput(list, this, g.rows, g.narrow); }); list.append($("<li></li>").append(firstInput)); groupDiv.append(lbl).append(list); block.append(groupDiv); } }); // — Jêder (quote / citation) group — a growing list, sibling to Nimûne — // Structured the same way as Nimûne (ol.wiktku-dfn-sublist > li) so it // lines up at the same indentation, and so that typing into the last // citation's Jêgirtin box automatically opens a fresh empty one below it. (function () { var jederGroupDiv = $("<div></div>").addClass("wiktku-dfn-subgroup wiktku-dfn-jeder-group"); var jederLbl = $("<span></span>").addClass("wiktku-dfn-sublabel").text("Jêgirtin: "); var jederList = $("<ol></ol>").addClass("wiktku-dfn-sublist wiktku-dfn-jeder-list"); function buildJederLi() { var lang = getValues().lang || ""; var li = $("<li></li>").addClass("wiktku-dfn-jeder-li"); var dragHandle = $("<span></span>") .addClass("wiktku-jeder-drag-handle") .attr("title", "Bişkûne û bikişîne da ku rêzê biguhezîne") .html("⠿"); // Quote text textarea var quoteTa = $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-quote-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 2) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-quote") .attr("placeholder", "Nimûneya emilandinê ji kitêb an çavkaniyeke din binivîse"); quoteTa.on("input", function () { var val = $.trim($(this).val()); var isLast = li.is(jederList.children("li:last-child")); if (val && isLast) { jederList.append(buildJederLi()); } }); li.append(dragHandle).append(quoteTa); // tr/t sub-fields for the quote — shown as needed for the language. var quoteSubWrap = $("<div></div>").addClass("wiktku-dfn-quote-sub"); if (needsTransliteration(lang)) { quoteSubWrap.append( $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-quote-tr-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 2) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-quote-tr") .attr("placeholder", "Transkrîpsiyona jêgirtinê…") ); } if (lang && lang !== "ku") { quoteSubWrap.append( $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-quote-t-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 2) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-quote-t") .attr("placeholder", "Tercimeya jêgirtinê bi kurmancî") ); } if (quoteSubWrap.children().length) li.append(quoteSubWrap); // Citoid auto-fill: fetch citation data from a URL, DOI or ISBN and // prefill the source şablon + fields below (see Gadget-citoid-helper.js). var citoidWrap = $("<div></div>").addClass("wiktku-dfn-quote-citoid"); var citoidInput = $("<input type='text'>") .addClass("wiktku-dfn-quote-citoid-input wiktku-start-narrow") .attr("placeholder", "URL, DOI an ISBN binivîse ku otomatîk were tijekirin…"); var citoidBtn = new OO.ui.ButtonWidget({ label: "Bi Citoid bîne", classes: [ "wiktku-dfn-quote-citoid-btn" ] }); var citoidStatus = $("<span></span>").addClass("wiktku-dfn-quote-citoid-status"); /** * Fetches citation data from Citoid and applies it to this * citation's şablon selector + fields. Mirrors the logic in * Form.prototype._fillFromCitoid (Gadget-wikt.add-examples.js): * - only (re)selects the şablon when it actually differs from * what's already chosen, so a repeat fetch doesn't wipe out * a template the user already picked; * - only fills fields that are currently empty, so it never * overwrites something the user typed by hand; * - falls back to the freeform "bi destê xwe binivîsim" source * only when nothing was typed there yet. */ function runCitoidFetch() { var query = $.trim(citoidInput.val()); if (!query) { mw.notify("Ji kerema xwe re pêşî URL, DOI an ISBNyekê binivîse."); return; } citoidBtn.setDisabled(true); citoidStatus.text("Tê anîn…"); wikt.citoidHelper.ensure().then(function () { return wikt.citoid.fetchJederFields(query); }).then(function (result) { var jederKey = result.jederKey; var hasTpl = !!jederKey && srcSel.find("option[value='" + jederKey + "']").length > 0; var targetVal = hasTpl ? jederKey : "__manual__"; // Only (re)select — and thus rebuild — the field rows if // we're switching to a different şablon than what's // already chosen, so a second fetch doesn't clear fields // the user already filled in by hand. if (srcSel.val() !== targetVal) { srcSel.val(targetVal).trigger("change"); srcSel.trigger("chosen:updated"); } if (hasTpl) { // Tenê qadên vala tijî bike. $.each(result.fields, function (key, val) { var input = srcFields.find("input[data-field-key='" + key + "']"); if (input.length && !$.trim(input.val())) { input.val(val); } }); } else { // Şablonek nehat naskirin ji bo vê itemType — rêzikeke // çavkaniyê ya bi destan a ji qadên Citoid tê çêkirin, // lê tenê ger qada destan vala be. var manualField = srcFields.find(".wiktku-dfn-quote-src-manual"); if (!$.trim(manualField.val())) { var parts = []; $.each(["nivîskar", "sernav", "websîte", "kovar", "weşanxane", "sal", "url"], function (_, k) { if (result.fields[k]) parts.push(result.fields[k]); }); manualField.val(parts.join(", ")); } } citoidStatus.text(""); }, function (errorMsg) { citoidStatus.text(typeof errorMsg === "string" ? errorMsg : "Nehat dîtin. Kontrol bike ka URL/DOI/ISBN rast e."); }).always(function () { citoidBtn.setDisabled(false); }); } citoidBtn.on("click", runCitoidFetch); citoidInput.on("keydown", function (e) { if (e.which === 13) { // Enter e.preventDefault(); runCitoidFetch(); } }); citoidWrap.append(citoidInput).append(citoidBtn.$element).append(citoidStatus); // Source template selector, specific to this citation. var srcSel = $("<select></select>").addClass("wiktku-dfn-quote-src-sel"); srcSel.append($("<option value=''>— Çavkaniyê hilbijêre —</option>")); srcSel.append($("<option></option>").val("__manual__").text("Bi destê xwe binivîsim")); var jederDefs = steps.dfn.jederDefs || {}; $.each(jederDefs, function (tplName, def) { srcSel.append($("<option></option>").val(tplName).text(def.label)); }); // Dynamic source fields container. var srcFields = $("<div></div>").addClass("wiktku-dfn-quote-src-fields"); srcSel.on("change", function () { srcFields.empty(); var chosen = $(this).val(); if (!chosen) return; if (chosen === "__manual__") { // Freeform source, written by the user — becomes the 2nd // positional param of {{jêder|lang|…}} instead of çavkanî?. srcFields.append( $("<textarea></textarea>") .attr("rows", 4) .addClass("wiktku-dfn-subfield wiktku-dfn-quote-src-manual") .attr("placeholder", "Çavkaniyê bi destê xwe binivîse…") ); return; } var def = (steps.dfn.jederDefs || {})[chosen]; if (!def) return; $.each(def.fields, function (_, f) { var row = $("<div></div>").addClass("wiktku-dfn-quote-src-row"); var fieldLbl = $("<label></label>").text(f.label + ": "); var inp = $("<input type='text'>") .addClass("wiktku-dfn-quote-src-input wiktku-start-narrow") .attr("data-field-key", f.key) .attr("placeholder", f.label + "…"); row.append(fieldLbl).append(inp); srcFields.append(row); }); }); li.append(citoidWrap).append(srcSel).append(srcFields); return li; } jederGroupDiv.data("buildJederLi", buildJederLi); jederList.append(buildJederLi()); // Make citation rows sortable (drag to reorder). // The last row is always the empty trailing row — cancel its drag. mw.loader.using("jquery.ui.sortable", function () { jederList.sortable({ handle: ".wiktku-jeder-drag-handle", axis: "y", items: "li:not(:last-child)", tolerance: "pointer" }); }); jederGroupDiv.append(jederLbl).append(jederList); block.append(jederGroupDiv); }()); // Apply the initial hide/show state for the sub-groups (matches // tplSelect's starting value, which is normally empty). updateFieldVisibility(); return block; }, /** Grows the sense list when the last mane textarea gets content. */ onDfnInput: function (stepDiv, block, textarea) { var val = $.trim($(textarea).val()); var list = stepDiv.find("ol.wiktku-dfn-list"); var isLast = block.is(list.children("li:last-child")); if (val && isLast) { var newBlock = steps.dfn.buildSenseBlock(stepDiv); list.append(newBlock); // Apply Chosen to the new block's template selector on desktop. if (!isMobile) newBlock.find("select.wiktku-dfn-tpl-select").chosen(chosenOptions); } refresh(); }, /** Grows a sub-list (nimûne/formên alternatîv/hevmane/dijmane/termên koordîne) on input. */ onSubInput: function (list, input, rows, narrow) { var val = $.trim($(input).val()); var item = $(input).parent(); var isLast = item.is(list.children("li:last-child")); if (val && isLast) { var next = $("<textarea></textarea>") .attr("name", "wiktku-dfn-sub-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", rows) .attr("class", "wiktku-dfn-subfield" + (narrow ? " wiktku-start-narrow" : "")); next.on("input", function () { steps.dfn.onSubInput(list, this, rows, narrow); }); list.append($("<li></li>").append(next)); } }, // Populated from [[MediaWiki:Gadget-start.js/data.json]] (tplDefs, posExamples, jederDefs). tplDefs: [], posExamples: {}, jederDefs: {}, build: function (stepDiv) { if (stepDiv.find("ol.wiktku-dfn-list").length) return null; var list = $("<ol class='wiktku-dfn-list'></ol>"); list.append(steps.dfn.buildSenseBlock(stepDiv)); stepDiv.append(list); return null; }, /** Reads all sense blocks from the DOM and returns an array of sense objects. */ getSenses: function (stepDiv) { var senses = []; stepDiv.find("li.wiktku-dfn-sense").each(function () { var block = $(this); var tplSel = block.find("select.wiktku-dfn-tpl-select"); var tpl = tplSel.val() || ""; // noLang: template already encodes the language — don't add |lang| param. var tplNoLang = tpl ? tplSel.find("option[value='" + tpl + "']").attr("data-nolang") === "1" : false; var tplTitle = $.trim(block.find("input.wiktku-dfn-tpl-title").val()); var mane = $.trim(block.find("textarea.wiktku-dfn-mane").val()); var etiket = (function () { var vals = []; block.find(".wiktku-dfn-etiket-list textarea").each(function () { var v = $.trim($(this).val()); if (v) vals.push(v); }); return vals; }()); function readList(cls) { var vals = []; block.find("." + cls + "-list textarea").each(function () { var v = $.trim($(this).val()); if (v) vals.push(v); }); return vals; } // Nimûne items are compound: { text, tr?, t? } function readNimuneList() { var items = []; block.find(".wiktku-dfn-nimune-list li.wiktku-dfn-nimune-li").each(function () { var text = $.trim($(this).find(".wiktku-dfn-nimune-text").val()); if (!text) return; var obj = { text: text }; var tr = $.trim($(this).find(".wiktku-dfn-nimune-tr").val()); var t = $.trim($(this).find(".wiktku-dfn-nimune-t").val()); if (tr) obj.tr = tr; if (t) obj.t = t; items.push(obj); }); return items; } // Jêder is a growing list of citations, one per li — mirrors readNimuneList(). function readJederList() { var items = []; block.find(".wiktku-dfn-jeder-list li.wiktku-dfn-jeder-li").each(function () { var li = $(this); var quote = $.trim(li.find(".wiktku-dfn-nimune-quote").val()); if (!quote) return; var obj = { quote: quote }; var qtr = $.trim(li.find(".wiktku-dfn-nimune-quote-tr").val()); var qt = $.trim(li.find(".wiktku-dfn-nimune-quote-t").val()); if (qtr) obj.quoteTr = qtr; if (qt) obj.quoteT = qt; var tplName = li.find(".wiktku-dfn-quote-src-sel").val(); if (tplName === "__manual__") { var manual = $.trim(li.find(".wiktku-dfn-quote-src-manual").val()); if (manual) obj.jederManual = manual; } else if (tplName) { obj.jederTpl = tplName; var fields = {}; li.find(".wiktku-dfn-quote-src-input").each(function () { var k = $(this).attr("data-field-key"); var v = $.trim($(this).val()); if (k && v) fields[k] = v; }); obj.jêderFields = fields; } items.push(obj); }); return items; } senses.push({ tpl: tpl, tplNoLang: tplNoLang, tplTitle: tplTitle, mane: mane, etiket: etiket, nimune: readNimuneList(), jeder: readJederList(), alternativ: readList("wiktku-dfn-alternativ"), hevmane: readList("wiktku-dfn-hevmane"), dijmane: readList("wiktku-dfn-dijmane"), koordine: readList("wiktku-dfn-koordine"), jornav: readList("wiktku-dfn-jornav"), jernav: readList("wiktku-dfn-jernav") }); }); return senses; }, getOutput: function (values, callback) { var stepDiv = $("#wiktku-start-dfn"); var senses = steps.dfn.getSenses(stepDiv); var lang = values.lang; // A sense counts as "filled" if it has a mane, a chosen template + title, // or any other content (etîket/hevmane/nimûne/jêder…) worth keeping. var hasMane = senses.some(function (s) { return s.mane !== "" || (s.tpl && s.tplTitle) || senseHasExtraContent(s); }); // True only when at least one sense has a regular mane (needs linkify). var hasRegularMane = senses.some(function (s) { return !s.tpl && s.mane !== ""; }); // Each sense is built as two parts: // .def — the definition line + word-list lines (safe to linkify) // .cite — nimûne + jêder lines (must NOT be linkified) // They are rejoined after linkify runs on the def parts only. var CITE_PLACEHOLDER = "\x00CITE\x00"; var citeBlocks = []; var text = $.map(senses, function (sense) { // — Template sense (e.g. {{guharto|ku|somepage}} or {{ku-Latn|somepage}}) — if (sense.tpl) { if (!sense.tplTitle) return undefined; // Etîket still applies to a şablon sense — build the same // {{e|lang|label1|label2}} prefix as a regular sense would get. var tplLabelTpl = ""; if (sense.etiket && sense.etiket.length) { var tplLabelParts = sense.etiket.map(function (part) { return $.trim(part); }).filter(function (part) { return part !== ""; }); if (tplLabelParts.length) { tplLabelTpl = " {{e|" + lang + "|" + tplLabelParts.join("|") + "}} "; } } // noLang templates encode the language in their name — omit the |lang| param. var tplCall = sense.tplNoLang ? "{{" + sense.tpl + "|" + sense.tplTitle + "}}" : "{{" + sense.tpl + "|" + lang + "|" + sense.tplTitle + "}}"; var tplLine = "#" + (tplLabelTpl ? tplLabelTpl : " ") + tplCall; // Nimûne / Jêder still apply to a şablon sense too. var tplHasJeder = sense.jeder && $.grep(sense.jeder, function (j) { return j && j.quote; }).length > 0; tplLine += formatNimune(sense.nimune, lang, tplHasJeder); tplLine += formatJeder(sense.jeder, lang); return tplLine; } // — Normal mane sense — var dfn = sense.mane; // A sense with no mane text AND nothing else filled in is // truly empty — drop it. If it has other content (etîket, // hevmane, nimûne, jêder…), keep it and use {{mane?}} as // a stand-in for the missing gloss instead of discarding // everything the user entered. if (!dfn && !senseHasExtraContent(sense)) return undefined; if (dfn) { // Strip any wikilinks the user may have typed before // linkify processes the text — avoids double-linking. dfn = stripWikilinks(dfn); // Capitalize and punctuate. if (dfn[0] !== dfn[0].toUpperCase()) dfn = capitalize(dfn); if (!dfn.match(/[.…?!)\]]$/)) dfn += "."; } else { dfn = "{{mane?|" + lang + "}}"; } // {{e|lang|label1|label2}} var labelTpl = ""; if (sense.etiket && sense.etiket.length) { var labelParts = sense.etiket.map(function (part) { return $.trim(part); }).filter(function (part) { return part !== ""; }); if (labelParts.length) { labelTpl = " {{e|" + lang + "|" + labelParts.join("|") + "}} "; } } var out = "#" + (labelTpl ? labelTpl : " ") + dfn; // Per-sense word lists as #: template lines. function wordLine(tpl, words) { if (!words.length) return ""; return "\n#: {{" + tpl + "|" + lang + "|" + words.join("|") + "}}"; } out += wordLine("alt-r", sense.alternativ); out += wordLine("hevmane", sense.hevmane); out += wordLine("dijmane", sense.dijmane); out += wordLine("koordîne", sense.koordine); out += wordLine("jornav", sense.jornav); out += wordLine("jêrnav", sense.jernav); // Nimûne + jêder lines must not pass through linkify — stash them // behind a placeholder and restore them after linkify runs. var hasJeder = sense.jeder && $.grep(sense.jeder, function (j) { return j && j.quote; }).length > 0; var citeText = formatNimune(sense.nimune, lang, hasJeder) + formatJeder(sense.jeder, lang); if (citeText) { citeBlocks.push(citeText); out += CITE_PLACEHOLDER; } return out; }).join("\n") + "\n"; if (!hasMane) { // No definitions entered — emit {{mane?}} with bênimûne. text = "# {{mane?|" + lang + "}}\n#* {{bênimûne|" + lang + "}}\n"; callback(text); return; } // Restore cite blocks (nimûne/jêder) into the final text after // linkify has already processed the definition portions. function restoreCiteBlocks(t) { var i = 0; return t.replace(new RegExp(escapeRegExp(CITE_PLACEHOLDER), "g"), function () { return citeBlocks[i++] || ""; }); } if (!hasRegularMane) { // All filled senses are template senses — no linkify needed. callback(restoreCiteBlocks(text)); return; } var didTryToLoad = function () { // If the module failed to load, $.wiktviLinkify won't exist — // fall back to the unlinkified text instead of throwing. if (typeof $.wiktviLinkify === "function") { $.wiktviLinkify(text, function (linked) { callback(restoreCiteBlocks(linked)); }); } else { callback(restoreCiteBlocks(text)); } }; mw.loader.using("ext.gadget.linkify", didTryToLoad, didTryToLoad); } }, je: makeWordListStep("je", "jê", "Kelîmeyên jê çêbûyî binivîse", "Jê", "g"), tekildar: makeWordListStep("tekildar", "têkildar", "Kelîmeyên ji aliyê etîmolojiyê ve têkildarî vê kelîmeyê binivîse", "Têkildar", "g"), binereherwiha: makeWordListStep("binereherwiha", "binêre herwiha", "Kelîmeyên din ên eleqedar binivîse", "Binêre herwiha", "g"), etym: { id: "etym", name: "etîmolojî", question_fmt: "Etîmolojiya kelîmeyê binivîse", // etymTpls populated from data.json etymTpls: [], visible: function (values) { return values.lang && values.pos; }, /** Fills (or refills) the insert-dropdown from the current etymTpls array. */ refreshTplSelect: function () { var sel = $("#wiktku-start-etym .wiktku-tpl-insert-select"); if (!sel.length) return; sel.find("option[value!='']").remove(); $.each(steps.etym.etymTpls, function (_, tpl) { sel.append($("<option></option>").val(tpl.snippet).text(tpl.name + " — " + tpl.desc)); }); // Notify Chosen that the option list has changed (no-op on mobile). if (!isMobile) sel.trigger("chosen:updated"); }, build: function (stepDiv) { if (stepDiv.find(".wiktku-etym-wrap").length) return null; var wrap = $("<div class='wiktku-etym-wrap'></div>"); var ta = $("<textarea></textarea>") .attr("name", "wiktku-etym-" + $.now()) .attr("class", "wiktku-start-step-field wiktku-etym-text") .attr("rows", 4) .attr("placeholder", "Nimûne: Ji {{ji|en|ku|apple}}. yan rasterast binivîse…"); // Template insert dropdown — options also refreshed after data.json loads. var sel = $("<select class='wiktku-tpl-insert-select'></select>"); sel.append($("<option value=''>— şablonek lê zêde bike —</option>")); $.each(steps.etym.etymTpls, function (_, tpl) { sel.append($("<option></option>").val(tpl.snippet).text(tpl.name + " — " + tpl.desc)); }); sel.on("change", function () { var snippet = $(this).val(); if (!snippet) return; var lang = getValues().lang || ""; snippet = snippet.replace(/CODE/g, lang).replace(/SOURCELANG/g, "?"); insertAtCursor(ta[0], snippet); $(this).val(""); ta.focus(); }); wrap.append(sel).append($("<br>")).append(ta); stepDiv.append(wrap); return ta; }, output: function (values) { var text = $.trim($("#wiktku-start-etym .wiktku-etym-text").val()); if (text) { return "\n==== Etîmolojî ====\n" + text + "\n"; } // No etymology entered — emit {{ji?|lang}} as a placeholder, // but only when the entry has at least one regular (non-şablon) // sense with content — either real mane text, or an empty mane // with other fields filled in (which dfn.getOutput() renders as // {{mane?|lang}} with those fields attached). A şablon sense // like {{guharto|…}} never counts, filled in or not. var dfnSenses = steps.dfn.getSenses($("#wiktku-start-dfn")); var hasRegularMane = dfnSenses.some(function (s) { return !s.tpl && (s.mane !== "" || senseHasExtraContent(s)); }); if (!hasRegularMane) return ""; return "\n==== Etîmolojî ====\n{{ji?|" + values.lang + "}}\n"; } }, dunde: { id: "dunde", name: "dûnde", question_fmt: "Eger ev kelîme ji vî zimanî ketibe zimanekî din, vî zimanî û kelîmeya wî binivîse", visible: function (values) { return !!values.pos; }, disabledKeys: { "navz": true}, /** * Builds one row: a language dropdown + a growing list of word * inputs. When the dropdown gets a value the next empty row is * appended automatically. Mirrors steps.trans's row widget, but * flat (one shared list — dûnde isn't tied to individual senses). */ buildRow: function (stepDiv) { var row = $("<li class='wiktku-dunde-row wiktku-lang-row'></li>"); // Language selector — chosen is applied after insertion into DOM. var langSel = $(mw.html.element("select", { "class": "wiktku-start-step-keyfield wiktku-start-narrow" })); langSel.attr("data-placeholder", "Zimanekî lê bigere"); populateMenus(langSel, steps.dunde.keys || [], steps.dunde.disabledKeys); // When a language is chosen, ensure a next empty row exists. langSel.on("change", function () { steps.dunde.onLangChange(stepDiv, row); }); // Word list for this language. var wordList = $("<ul class='wiktku-dunde-words wiktku-lang-row-words'></ul>"); var firstWord = steps.dunde.makeWordInput(); wordList.append($("<li></li>").append(firstWord)); if (isMobile) { row.append(wrapNativeSelect(langSel)).append(wordList); } else { row.append(langSel).append(wordList); } return row; }, makeWordInput: function () { var input = $("<textarea></textarea>") .attr("name", "wiktku-dunde-word-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 1) .attr("class", "wiktku-dfn-subfield wiktku-start-narrow") .attr("placeholder", "Kelîme…"); input.on("input", function () { var list = $(this).closest("ul.wiktku-dunde-words"); var item = $(this).parent(); var val = $.trim($(this).val()); if (val && item.is(list.children("li:last-child"))) { var next = steps.dunde.makeWordInput(); list.append($("<li></li>").append(next)); } }); return input; }, onLangChange: function (stepDiv, row) { var list = stepDiv.find("ul.wiktku-dunde-list"); var isLast = row.is(list.children("li.wiktku-dunde-row:last-child")); if (isLast) { var newRow = steps.dunde.buildRow(stepDiv); list.append(newRow); // Init chosen after the new row is in the DOM (desktop only). if (!isMobile) newRow.find("select").chosen(chosenOptions); } // Keep disabled keys in sync across all lang selectors. steps.dunde.syncDisabledKeys(stepDiv); }, /** Disables already-selected languages in all other dropdowns. */ syncDisabledKeys: function (stepDiv) { var taken = $.extend({}, steps.dunde.disabledKeys); stepDiv.find("li.wiktku-dunde-row select").each(function () { var v = $(this).val(); if (v) taken[v] = true; }); stepDiv.find("li.wiktku-dunde-row select").each(function () { var self = $(this); var own = self.val(); self.find("option").each(function () { var code = $(this).val(); if (!code) return; $(this).prop("disabled", taken[code] && code !== own); }); self.trigger("chosen:updated"); }); }, build: function (stepDiv) { if (stepDiv.find("ul.wiktku-dunde-list").length) return null; var list = $("<ul class='wiktku-dunde-list wiktku-lang-row-list'></ul>"); list.append(steps.dunde.buildRow(stepDiv)); stepDiv.append(list); // Init chosen after the select is in the DOM (desktop only). if (!isMobile) list.find("select").chosen(chosenOptions); return null; }, /** Reads all [langcode, words[]] rows from the DOM. */ getRows: function (stepDiv) { var result = []; stepDiv.find("li.wiktku-dunde-row").each(function () { var lang = $(this).find("select").val(); if (!lang) return; var words = []; $(this).find("ul.wiktku-dunde-words textarea").each(function () { var v = $.trim($(this).val()); if (v) words.push(v); }); if (words.length) result.push([lang, words]); }); return result; }, output: function () { var stepDiv = $("#wiktku-start-dunde"); var rows = steps.dunde.getRows(stepDiv); if (!rows.length) return ""; var lines = $.map(rows, function (row) { var lang = row[0], words = row[1]; return "* {{dû|" + lang + "|" + words.join("|") + "}}"; }); return "\n==== Dûnde ====\n" + lines.join("\n") + "\n"; } }, zarava: { id: "zarava", name: "bi zaravayên din", visible: function (values) { return steps.trans.visible(values); }, disabledKeys: { "navz": true }, buildRow: function (group) { var row = $("<li class='wiktku-zarava-row wiktku-lang-row'></li>"); var langSel = $(mw.html.element("select", { "class": "wiktku-start-step-keyfield wiktku-start-narrow" })); populateMenus(langSel, steps.zarava.keys || [], steps.zarava.disabledKeys); langSel.on("change", function () { steps.zarava.onLangChange(group, row); }); var wordList = $("<ul class='wiktku-zarava-words wiktku-lang-row-words'></ul>"); var firstWord = steps.zarava.makeWordInput(); wordList.append($("<li></li>").append(firstWord)); row.append(langSel).append(wordList); return row; }, makeWordInput: function () { var input = $("<textarea></textarea>") .attr("name", "wiktku-zarava-word-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 1) .attr("class", "wiktku-dfn-subfield wiktku-start-narrow") .attr("placeholder", "Tercime…"); input.on("input", function () { var list = $(this).closest("ul.wiktku-zarava-words"); var item = $(this).parent(); var val = $.trim($(this).val()); if (val && item.is(list.children("li:last-child"))) { var next = steps.zarava.makeWordInput(); list.append($("<li></li>").append(next)); } }); return input; }, onLangChange: function (group, row) { var list = group.find("ul.wiktku-zarava-list"); var isLast = row.is(list.children("li.wiktku-zarava-row:last-child")); if (isLast) { var newRow = steps.zarava.buildRow(group); list.append(newRow); } steps.zarava.syncDisabledKeys(group); }, /** Disables already-selected dialects in all other dropdowns within one group. */ syncDisabledKeys: function (group) { var taken = $.extend({}, steps.zarava.disabledKeys); group.find("li.wiktku-zarava-row select").each(function () { var v = $(this).val(); if (v) taken[v] = true; }); group.find("li.wiktku-zarava-row select").each(function () { var self = $(this); var own = self.val(); self.find("option").each(function () { var code = $(this).val(); if (!code) return; $(this).prop("disabled", taken[code] && code !== own); }); }); }, /** Builds (or fetches) the .wiktku-zarava-group for one gloss. */ buildGroup: function (stepDiv, gi) { var group = $("<div class='wiktku-zarava-group'></div>").attr("data-gloss-pos", gi); var list = $("<ul class='wiktku-zarava-list wiktku-lang-row-list'></ul>"); list.append(steps.zarava.buildRow(group)); group.append(list); stepDiv.append(group); return group; }, /** Syncs one .wiktku-zarava-group per current gloss (same logic as steps.trans.build). */ build: function (stepDiv) { var glosses = steps.trans.glossList(); if (!glosses.length) { stepDiv.find(".wiktku-zarava-group").remove(); return null; } var existingGroups = stepDiv.find(".wiktku-zarava-group"); if (existingGroups.length > glosses.length) { existingGroups.slice(glosses.length).remove(); } $.each(glosses, function (gi, gloss) { var group = stepDiv.find(".wiktku-zarava-group[data-gloss-pos='" + gi + "']"); if (!group.length) group = steps.zarava.buildGroup(stepDiv, gi); var label = group.find(".wiktku-zarava-group-label"); if (glosses.length > 1) { if (!label.length) { label = $("<div class='wiktku-zarava-group-label'></div>"); group.prepend(label); } label.text(gloss.index + " " + gloss.text); } else if (label.length) { label.remove(); } }); return null; }, /** Reads the dialect rows for a single gloss group. */ getGroupTranslations: function (group) { var result = []; group.find("li.wiktku-zarava-row").each(function () { var lang = $(this).find("select").val(); if (!lang) return; var words = []; $(this).find("ul.wiktku-zarava-words textarea").each(function () { var v = $.trim($(this).val()); if (v) words.push(v); }); if (words.length) result.push([lang, words]); }); return result; }, /** Reads all rows from the DOM, grouped by gloss position. */ getTranslations: function (stepDiv) { var result = []; stepDiv.find(".wiktku-zarava-group").each(function () { result.push(steps.zarava.getGroupTranslations($(this))); }); return result; }, output: function (values) { if (values.lang !== "ku") return ""; var stepDiv = $("#wiktku-start-zarava"); var glosses = steps.trans.glossList(); if (!glosses.length) return ""; var blocks = $.map(glosses, function (gloss, gi) { var group = stepDiv.find(".wiktku-zarava-group[data-gloss-pos='" + gi + "']"); var rows = group.length ? steps.zarava.getGroupTranslations(group) : []; if (!gloss.text && !rows.length) return undefined; if (rows.length) { rows.sort(function (a, b) { var aLang = langsByCode[a[0]] || []; var bLang = langsByCode[b[0]] || []; return (aLang[2] || "").localeCompare(bLang[2] || "", "ku"); }); } var wordLines = $.map(rows, function (row) { var lang = row[0]; var words = row[1]; var wikiWords = words.map(function (w) { return "{{W|" + lang + "|" + w + "}}"; }).join(", "); return "* {{Z|" + lang + "}}: " + wikiWords; }).join("\n"); if (!wordLines) return undefined; var block = "{{werger-ser|" + (gloss.text || "?") + "|" + gloss.index + "}}"; block += "\n" + wordLines; block += "\n{{werger-bin}}"; return block; }); if (!blocks.length) return ""; return "\n==== Bi zaravayên din ====\n" + blocks.join("\n") + "\n"; } }, trans: { id: "trans", name: "werger", visible: function (values) { if (!(values.lang === "ku" && values.pos)) return false; // Hide Werger only when EVERY sense is a template sense (Guharto etc.) // with a title filled in — i.e. there is real content but no plain // gloss to attach a translation table to. A mix of real + template // senses still shows Werger; the template senses are simply skipped // in output(). // // "Real" here means a non-şablon sense with either mane text or // other filled-in fields (etîket/hevmane/nimûne/jêder…), since // dfn.getOutput() renders the latter too, as {{mane?|lang}} plus // whatever else was filled in. // // When nothing has been filled in at all, output() will emit // {{mane?|lang}} instead of a gloss — but Werger should still show, // since the user may want to add translations before they've // settled on a gloss. var dfnSenses = steps.dfn.getSenses($("#wiktku-start-dfn")); var hasRealSense = dfnSenses.some(function (s) { return !s.tpl && (s.mane !== "" || senseHasExtraContent(s)); }); var hasFilledTplSense = dfnSenses.some(function (s) { return s.tpl && s.tplTitle; }); return hasRealSense || !hasFilledTplSense; }, disabledKeys: { "navz": true, "ku": true, "ckb": true, "sdh": true, "lki": true, "hac": true, "zza": true }, /** * Builds one translation row: a language dropdown + a growing list * of word inputs. When the dropdown gets a value the next empty row * is appended automatically. * * @param group the specific .wiktku-trans-group this row belongs to * (each gloss has its own group and its own list of rows, so the * lookups below must stay scoped to that group rather than the * whole step — the step now holds one list per gloss). */ buildRow: function (group) { var row = $("<li class='wiktku-trans-row wiktku-lang-row'></li>"); // Language selector — chosen is applied after insertion into DOM. var langSel = $(mw.html.element("select", { "class": "wiktku-start-step-keyfield wiktku-start-narrow" })); langSel.attr("data-placeholder", "Zimanekî lê bigere"); populateMenus(langSel, steps.trans.keys || [], steps.trans.disabledKeys); // When a language is chosen, ensure a next empty row exists. langSel.on("change", function () { steps.trans.onLangChange(group, row); }); // Word list for this language. var wordList = $("<ul class='wiktku-trans-words wiktku-lang-row-words'></ul>"); var firstWord = steps.trans.makeWordInput(); wordList.append($("<li></li>").append(firstWord)); if (isMobile) { row.append(wrapNativeSelect(langSel)).append(wordList); } else { row.append(langSel).append(wordList); } return row; }, makeWordInput: function () { var input = $("<textarea></textarea>") .attr("name", "wiktku-trans-word-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 1) .attr("class", "wiktku-dfn-subfield wiktku-start-narrow") .attr("placeholder", "Tercime…"); input.on("input", function () { var list = $(this).closest("ul.wiktku-trans-words"); var item = $(this).parent(); var val = $.trim($(this).val()); if (val && item.is(list.children("li:last-child"))) { var next = steps.trans.makeWordInput(); list.append($("<li></li>").append(next)); } }); return input; }, onLangChange: function (group, row) { var list = group.find("ul.wiktku-trans-list"); var isLast = row.is(list.children("li.wiktku-trans-row:last-child")); if (isLast) { var newRow = steps.trans.buildRow(group); list.append(newRow); // Init chosen after the new row is in the DOM (desktop only). if (!isMobile) newRow.find("select").chosen(chosenOptions); } // Keep disabled keys in sync across this gloss's lang selectors // only — the same language can be used for different senses. steps.trans.syncDisabledKeys(group); }, /** Disables already-selected languages in all other dropdowns within one group. */ syncDisabledKeys: function (group) { var taken = $.extend({}, steps.trans.disabledKeys); group.find("li.wiktku-trans-row select").each(function () { var v = $(this).val(); if (v) taken[v] = true; }); group.find("li.wiktku-trans-row select").each(function () { var self = $(this); var own = self.val(); self.find("option").each(function () { var code = $(this).val(); if (!code) return; $(this).prop("disabled", taken[code] && code !== own); }); self.trigger("chosen:updated"); }); }, /** * Builds (or fetches) the .wiktku-trans-group for one gloss, with * its own label and its own list of translation rows. */ buildGroup: function (stepDiv, gi) { var group = $("<div class='wiktku-trans-group'></div>").attr("data-gloss-pos", gi); var list = $("<ul class='wiktku-trans-list wiktku-lang-row-list'></ul>"); list.append(steps.trans.buildRow(group)); group.append(list); stepDiv.append(group); // Init chosen after the select is in the DOM (desktop only). if (!isMobile) list.find("select").chosen(chosenOptions); return group; }, /** * Syncs one .wiktku-trans-group per current gloss, adding new * groups and removing stale ones as senses are added or removed, * while leaving existing groups (and whatever translations the * user has already typed into them) untouched. Groups are keyed * to their gloss's position in glossList() via data-gloss-pos, so * a group always matches the same sense across rebuilds as long * as senses aren't reordered relative to each other. */ build: function (stepDiv) { var glosses = steps.trans.glossList(); if (!glosses.length) { stepDiv.find(".wiktku-trans-group").remove(); return null; } // Drop groups for glosses that no longer exist (always from the // tail — groups are only ever appended in gloss order below). var existingGroups = stepDiv.find(".wiktku-trans-group"); if (existingGroups.length > glosses.length) { existingGroups.slice(glosses.length).remove(); } $.each(glosses, function (gi, gloss) { var group = stepDiv.find(".wiktku-trans-group[data-gloss-pos='" + gi + "']"); if (!group.length) group = steps.trans.buildGroup(stepDiv, gi); // Only label groups when there's more than one gloss to // distinguish between — a single gloss needs no caption. var label = group.find(".wiktku-trans-group-label"); if (glosses.length > 1) { if (!label.length) { label = $("<div class='wiktku-trans-group-label'></div>"); group.prepend(label); } label.text(gloss.index + " " + gloss.text); } else if (label.length) { label.remove(); } }); return null; }, /** Reads the translation rows for a single gloss group. */ getGroupTranslations: function (group) { var result = []; group.find("li.wiktku-trans-row").each(function () { var lang = $(this).find("select").val(); if (!lang) return; var words = []; $(this).find("ul.wiktku-trans-words textarea").each(function () { var v = $.trim($(this).val()); if (v) words.push(v); }); if (words.length) result.push([lang, words]); }); return result; }, /** * Reads all translation rows from the DOM, grouped by gloss * position — one array of [lang, words] rows per gloss group, in * the same order as the .wiktku-trans-group elements. */ getTranslations: function (stepDiv) { var result = []; stepDiv.find(".wiktku-trans-group").each(function () { result.push(steps.trans.getGroupTranslations($(this))); }); return result; }, /** * Builds the numbered "{ index, gloss }" list — one entry per dfn * sense that has a real mane (skips template senses like Guharto, * which have nothing to caption a translation table with). The * index matches the sense's actual position in the numbered "#" * definition list (1-based), including template senses in the count, * so the number printed next to {{werger-ser}} lines up with the * gloss the reader sees in the entry. * * When nothing has been filled in at all (dfn.getOutput() will emit * {{mane?|lang}} as sense 1), this returns a single placeholder * entry with empty text instead of an empty array, so Werger still * has one group to attach translations to before a gloss exists. * When every filled sense is a template sense instead, this stays * empty — that mirrors trans.visible()'s hidden case, where there's * no group in the DOM for a placeholder to attach to anyway. */ glossList: function () { var dfnSenses = steps.dfn.getSenses($("#wiktku-start-dfn")); var glosses = []; var hasFilledTplSense = false; $.each(dfnSenses, function (i, s) { if (s.tpl) { if (s.tplTitle) hasFilledTplSense = true; return; // template sense — no gloss to caption with } var dfn = s.mane; if (!dfn) { // No mane text, but other fields (etîket/hevmane/nimûne/ // jêder…) are filled — dfn.getOutput() still emits this // sense as a numbered line using {{mane?|lang}}, so it // needs its own gloss group too, just with no caption text. if (senseHasExtraContent(s)) glosses.push({ index: i + 1, text: "" }); return; } if (dfn[0] !== dfn[0].toLowerCase()) dfn = decapitalize(dfn); dfn = stripWikilinks(dfn).replace(/[.…?!)\]،؟]+$/, ""); glosses.push({ index: i + 1, text: dfn }); }); if (!glosses.length && !hasFilledTplSense) { glosses.push({ index: 1, text: "" }); } return glosses; }, output: function (values) { if (values.lang !== "ku") return ""; var stepDiv = $("#wiktku-start-trans"); var glosses = steps.trans.glossList(); // Every sense is a template sense — there's no real gloss // anywhere and no group in the DOM either (glossList() only // returns empty in that case), so skip the section entirely. if (!glosses.length) return ""; // Each gloss now has its own group of translation rows — // attach every gloss's own words under its own werger-ser/-bin // pair instead of dumping everything under the first one. var blocks = $.map(glosses, function (gloss, gi) { var group = stepDiv.find(".wiktku-trans-group[data-gloss-pos='" + gi + "']"); var rows = group.length ? steps.trans.getGroupTranslations(group) : []; // Placeholder gloss (no real mane entered yet) with nothing // translated into it — nothing to output, and gloss.text is // empty so there's no caption to give {{werger-ser}} anyway. if (!gloss.text && !rows.length) return undefined; if (rows.length) { // Sort by Kurdish sort key. rows.sort(function (a, b) { var aLang = langsByCode[a[0]] || []; var bLang = langsByCode[b[0]] || []; return (aLang[2] || "").localeCompare(bLang[2] || "", "ku"); }); } var wordLines = $.map(rows, function (row) { var lang = row[0]; var words = row[1]; var wikiWords = words.map(function (w) { return "{{W|" + lang + "|" + w + "}}"; }).join(", "); return "* {{Z|" + lang + "}}: " + wikiWords; }).join("\n"); var block = "{{werger-ser|" + (gloss.text || "?") + "|" + gloss.index + "}}"; if (wordLines) block += "\n" + wordLines; block += "\n{{werger-bin}}"; return block; }); if (!blocks.length) return ""; return "\n==== Werger ====\n" + blocks.join("\n") + "\n"; } }, }; steps.trans.keys = steps.lang.choices; steps.dunde.keys = steps.lang.choices; steps.zarava.keys = getZaravaKeys(steps.lang.choices); var ordered_steps = [ steps.lang, steps.pron, steps.pos, steps.cinsiyet, steps.lektur, steps.tr, steps.dfn, steps.je, steps.tekildar, steps.etym, steps.dunde, steps.binereherwiha, steps.zarava, steps.trans]; // Step ids that belong to each section (not shared across sections). var PER_SECTION_STEP_IDS = [ "pos", "cinsiyet", "lektur", "tr", "dfn", "je", "tekildar", "etym", "dunde", "binereherwiha", "zarava", "trans" ]; // ── Multi-section state ────────────────────────────────────────────────── // Each entry is a plain snapshot: { pos, cinsiyet, lektur, tr, dfn (senses[]), // je, tekildar, binereherwiha, trans (rows[]) }. var sections = [{}]; // section 0 starts empty (DOM is the truth) var activeSection = 0; function snapshotDfn() { return steps.dfn.getSenses($("#wiktku-start-dfn")); } /** * Rebuild the dfn DOM from a previously snapshotted senses array. */ function restoreDfn(senses) { var stepDiv = $("#wiktku-start-dfn"); // Tear down the existing list so build() recreates it cleanly. stepDiv.find("ol.wiktku-dfn-list").remove(); steps.dfn.build(stepDiv); var list = stepDiv.find("ol.wiktku-dfn-list"); $.each(senses, function (i, sense) { // Ensure enough blocks exist (build() seeds one). var blocks = list.find("li.wiktku-dfn-sense"); var block = blocks.eq(i); if (!block.length) { var nb = steps.dfn.buildSenseBlock(stepDiv); list.append(nb); block = list.find("li.wiktku-dfn-sense").last(); } // Template selector. block.find("select.wiktku-dfn-tpl-select").val(sense.tpl || ""); if (sense.tpl) { block.find("textarea.wiktku-dfn-mane").hide(); block.find("input.wiktku-dfn-tpl-title").val(sense.tplTitle || "").show(); } else { block.find("textarea.wiktku-dfn-mane").val(sense.mane || "").show(); block.find("input.wiktku-dfn-tpl-title").hide().val(""); } // Re-sync the formên alternatîv/hevmane/… hide state now that // tplSelect's value was set programmatically (its own "change" // handler doesn't fire from .val(), so this doesn't happen otherwise). var updateVis = block.data("updateFieldVisibility"); if (updateVis) updateVis(); // Restore a sub-list (etiket, formên alternatîv, hevmane …) from a values array. function restoreSubList(cls, values) { if (!values || !values.length) return; var groupDiv = block.find("." + cls + "-group"); var subList = groupDiv.find("ol, ul").first(); if (!subList.length) return; // group not found // Fill existing items, append new ones as needed. $.each(values, function (j, val) { var items = subList.find("li"); if (j < items.length) { items.eq(j).find("textarea").val(val); } else { var ta = $("<textarea></textarea>") .attr("name", "wiktku-dfn-restore-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 1) .attr("class", "wiktku-dfn-subfield wiktku-start-narrow") .val(val); ta.on("input", function () { steps.dfn.onSubInput(subList, this, 1, true); }); subList.append($("<li></li>").append(ta)); } }); } // Reveal and populate lazy groups that have data. var lazyMap = { "wiktku-dfn-etiket": sense.etiket, "wiktku-dfn-alternativ": sense.alternativ, "wiktku-dfn-hevmane": sense.hevmane, "wiktku-dfn-dijmane": sense.dijmane, "wiktku-dfn-koordine": sense.koordine, "wiktku-dfn-jornav": sense.jornav, "wiktku-dfn-jernav": sense.jernav }; $.each(lazyMap, function (cls, vals) { if (vals && vals.length) restoreSubList(cls, vals); }); // Nimûne items are objects { text, tr?, t? } — restore using the builder. if (sense.nimune && sense.nimune.length) { var nimuneGroupDiv = block.find(".wiktku-dfn-nimune-group"); var nimuneList = nimuneGroupDiv.find("ol.wiktku-dfn-nimune-list"); var buildFn = nimuneGroupDiv.data("buildNimuneLi"); nimuneList.empty(); $.each(sense.nimune, function (_, n) { var text = typeof n === "object" ? (n.text || "") : n; if (!text) return; var li = buildFn ? buildFn() : $("<li class='wiktku-dfn-nimune-li'></li>"); li.find(".wiktku-dfn-nimune-text").val(text); if (n.tr) li.find(".wiktku-dfn-nimune-tr").val(n.tr); if (n.t) li.find(".wiktku-dfn-nimune-t").val(n.t); nimuneList.append(li); }); // Always leave a blank trailing item. if (buildFn) nimuneList.append(buildFn()); } // Restore jêder (quote/citation) entries — a growing list, restored using the // builder just like Nimûne. Accepts either the current array shape or a // single legacy object (from older saved sections) for backwards compatibility. var jederArr = $.isArray(sense.jeder) ? sense.jeder : (sense.jeder ? [sense.jeder] : []); if (jederArr.length) { var jederGroupDiv = block.find(".wiktku-dfn-jeder-group"); var jederList = jederGroupDiv.find("ol.wiktku-dfn-jeder-list"); var buildJederFn = jederGroupDiv.data("buildJederLi"); jederList.empty(); $.each(jederArr, function (_, j) { if (!j || !j.quote) return; var li = buildJederFn ? buildJederFn() : $("<li class='wiktku-dfn-jeder-li'></li>"); li.find(".wiktku-dfn-nimune-quote").val(j.quote); if (j.quoteTr) li.find(".wiktku-dfn-nimune-quote-tr").val(j.quoteTr); if (j.quoteT) li.find(".wiktku-dfn-nimune-quote-t").val(j.quoteT); if (j.jederManual) { var manualSel = li.find(".wiktku-dfn-quote-src-sel"); manualSel.val("__manual__").trigger("change"); li.find(".wiktku-dfn-quote-src-manual").val(j.jederManual); } else if (j.jederTpl) { var srcSel = li.find(".wiktku-dfn-quote-src-sel"); srcSel.val(j.jederTpl).trigger("change"); if (j.jêderFields) { $.each(j.jêderFields, function (key, val) { li.find(".wiktku-dfn-quote-src-input[data-field-key='" + key + "']").val(val); }); } } jederList.append(li); }); // Always leave a blank trailing item, same as Nimûne. if (buildJederFn) jederList.append(buildJederFn()); } }); } /** * Snapshot simple (non-dfn) per-section steps from current DOM into obj. */ function saveCurrentSection() { var snap = {}; $.each(PER_SECTION_STEP_IDS, function (_, id) { if (id === "dfn") { snap.dfn = snapshotDfn(); return; } if (id === "etym") { snap.etym = $.trim($("#wiktku-start-etym .wiktku-etym-text").val()); return; } var step = steps[id]; if (!step) return; var stepDiv = $("#wiktku-start-" + id); if (id === "trans") { snap.trans = steps.trans.getTranslations(stepDiv); return; } if (id === "zarava") { snap.zarava = steps.zarava.getTranslations(stepDiv); return; } if (id === "dunde") { snap.dunde = steps.dunde.getRows(stepDiv); return; } // Generic: read all step fields. var fields = stepDiv.find(".wiktku-start-step-field"); if (step.multiple) { snap[id] = fields.map(function () { return $(this).val(); }).get(); } else { snap[id] = fields.val(); } }); sections[activeSection] = snap; } /** * Restore a previously saved snapshot into the form DOM. */ function restoreSection(snap) { $.each(PER_SECTION_STEP_IDS, function (_, id) { if (id === "dfn") { restoreDfn(snap.dfn || []); return; } if (id === "etym") { $("#wiktku-start-etym .wiktku-etym-wrap").remove(); steps.etym.build($("#wiktku-start-etym")); $("#wiktku-start-etym .wiktku-etym-text").val(snap.etym || ""); return; } if (id === "trans") { // Rebuild trans groups (dfn must already be restored by this // point in the $.each loop, so glossList() reflects it). var transDiv = $("#wiktku-start-trans"); transDiv.find(".wiktku-trans-group").remove(); steps.trans.build(transDiv); var groupsSnap = snap.trans || []; $.each(groupsSnap, function (gi, rows) { var group = transDiv.find(".wiktku-trans-group[data-gloss-pos='" + gi + "']"); if (!group.length) return; // gloss no longer exists — drop its rows var list = group.find("ul.wiktku-trans-list"); $.each(rows, function (j, row) { var lang = row[0], words = row[1]; var lastRow = list.find("li.wiktku-trans-row").last(); lastRow.find("select").val(lang).trigger("change"); var wordList = lastRow.find("ul.wiktku-trans-words"); $.each(words, function (k, word) { var wordItems = wordList.find("li"); if (k < wordItems.length) { wordItems.eq(k).find("textarea").val(word); } else { // .val() below doesn't fire "input", so the normal // auto-grow never runs — append a matching item // ourselves instead of silently dropping the word. var extraInput = steps.trans.makeWordInput(); wordList.append($("<li></li>").append(extraInput)); extraInput.val(word); } }); // Leave one trailing empty field so the row can still grow // when the user types, matching a freshly-built row. if ($.trim(wordList.children("li").last().find("textarea").val())) { wordList.append($("<li></li>").append(steps.trans.makeWordInput())); } }); }); return; } if (id === "zarava") { // Rebuild zarava groups (dfn must already be restored by this // point in the $.each loop, so glossList() reflects it). var zaravaDiv = $("#wiktku-start-zarava"); zaravaDiv.find(".wiktku-zarava-group").remove(); steps.zarava.build(zaravaDiv); var zaravaGroupsSnap = snap.zarava || []; $.each(zaravaGroupsSnap, function (gi, rows) { var group = zaravaDiv.find(".wiktku-zarava-group[data-gloss-pos='" + gi + "']"); if (!group.length) return; // gloss no longer exists — drop its rows var list = group.find("ul.wiktku-zarava-list"); $.each(rows, function (j, row) { var lang = row[0], words = row[1]; var lastRow = list.find("li.wiktku-zarava-row").last(); lastRow.find("select").val(lang).trigger("change"); var wordList = lastRow.find("ul.wiktku-zarava-words"); $.each(words, function (k, word) { var wordItems = wordList.find("li"); if (k < wordItems.length) { wordItems.eq(k).find("textarea").val(word); } else { var extraInput = steps.zarava.makeWordInput(); wordList.append($("<li></li>").append(extraInput)); extraInput.val(word); } }); if ($.trim(wordList.children("li").last().find("textarea").val())) { wordList.append($("<li></li>").append(steps.zarava.makeWordInput())); } }); }); return; } if (id === "dunde") { // Rebuild dunde rows. var dundeDiv = $("#wiktku-start-dunde"); dundeDiv.find("ul.wiktku-dunde-list").remove(); steps.dunde.build(dundeDiv); var dundeRows = snap.dunde || []; $.each(dundeRows, function (i, row) { var lang = row[0], words = row[1]; var list = dundeDiv.find("ul.wiktku-dunde-list"); var lastRow = list.find("li.wiktku-dunde-row").last(); lastRow.find("select").val(lang).trigger("change"); var wordList = lastRow.find("ul.wiktku-dunde-words"); $.each(words, function (j, word) { var wordItems = wordList.find("li"); if (j < wordItems.length) { wordItems.eq(j).find("textarea").val(word); } else { // .val() below doesn't fire "input", so the normal // auto-grow never runs — append a matching item // ourselves instead of silently dropping the word. var extraInput = steps.dunde.makeWordInput(); wordList.append($("<li></li>").append(extraInput)); extraInput.val(word); } }); // Leave one trailing empty field so the row can still grow // when the user types, matching a freshly-built row. if ($.trim(wordList.children("li").last().find("textarea").val())) { wordList.append($("<li></li>").append(steps.dunde.makeWordInput())); } }); return; } var step = steps[id]; if (!step) return; var stepDiv = $("#wiktku-start-" + id); var fields = stepDiv.find(".wiktku-start-step-field"); var val = snap[id]; if (val === undefined || val === null) return; if (step.multiple) { var arr = val; fields.each(function (i) { if (i < arr.length) $(this).val(arr[i]); }); } else { fields.val(val); } // Notify chosen widgets of the programmatic value change. if (!isMobile) fields.filter("select").trigger("chosen:updated"); }); } function getWikitextForCurrentSection(callback) { var values = getValues(); var entry = steps.pos.output(values); steps.dfn.getOutput(values, function (output) { entry += output; entry += steps.je.output(values); entry += steps.tekildar.output(values); entry += steps.etym.output(values); entry += steps.dunde.output(values); entry += steps.binereherwiha.output(values); entry += steps.zarava.output(values); entry += steps.trans.output(values); callback(entry, values); }); } function getWikitextAllSections(callback) { saveCurrentSection(); var results = new Array(sections.length); var sharedValues = getValues(); // lang/pron are shared function processSection(i) { if (i >= sections.length) { // All done — restore original active section. restoreSection(sections[activeSection]); refresh(); callback(results, sharedValues); return; } restoreSection(sections[i]); refresh(); getWikitextForCurrentSection(function (sectionText) { results[i] = sectionText; processSection(i + 1); }); } processSection(0); } /** * Assembles wikitext for all sections plus the shared lang/pron header. */ function getWikitext(callback) { getWikitextAllSections(function (sectionTexts, sharedValues) { var entry = steps.lang.output(sharedValues); entry += steps.pron.output(sharedValues); entry += sectionTexts.join("\n"); // Edit summary uses section 0's values. Read from the saved snapshot // (not the live DOM) so it doesn't mix section 0's pos with whichever // section happens to be active/restored at this point. var dfnSenses = (sections[0] && sections[0].dfn) || []; var dfnSummary = dfnSenses.map(function (s) { return s.mane; }).filter(Boolean).join("; "); var summaryLabel = addLangMode ? "WF:Ziman lê zêde" : "WF:Nû"; var summary = "([[Mediawiki:Gadget-start.js|" + summaryLabel + "]] v.2.0) +" + sharedValues.lang + ":" + sections[0].pos + ":" + dfnSummary; var summaryField = document.getElementById("wpSummary"); if (addLangMode && summaryField.value) { summary = summaryField.value + " " + summary; } summaryField.value = summary; callback(entry); }); } var continueBtn; function getValuesForStep(stepId) { var fields = $("#wiktku-start-" + stepId + " .wiktku-start-step-field"); var step = steps[stepId]; if (step.keys) { var values = {}; fields.each(function (i, field) { var key = $(field).prevAll(".wiktku-start-step-keyfield").val(); if (key) values[key] = $(field).val(); }); return values; } else if (step.multiple) { return fields.map(function () { return $(this).val(); }).get(); } return fields.val(); } function getValues() { var values = {}; $.each(steps, function (stepId) { values[stepId] = getValuesForStep(stepId); }); return values; } function populateMenus(inputs, choices, disabledValues) { if (!disabledValues) disabledValues = {}; var vals = inputs.map(function (i, input) { return $(input).val(); }); inputs.empty(); inputs.append($("<option></option>")); $.each(choices, function (j, choice) { // Append the language code in parentheses so that typing a code // (e.g. "ku") in the search box still finds the language name. var displayText = capitalize(choice[1]); if (choice[2] !== undefined) { // This is a language choice [code, name, sortKey] — show code. displayText = capitalize(choice[1]) + " (" + choice[0] + ")"; } var option = $(mw.html.element("option", { value: choice[0] }, displayText)); if (disabledValues[choice[0]]) option.prop("disabled", true); inputs.append(option); }); inputs.val(function (i) { return vals[i]; }); } /** * Returns a bitmap containing the keys that should be disabled for a key * menu in the given step because they are disabled or already taken by * another key menu. */ function getDisabledKeys(step) { var occupiedKeys = {}; $("#wiktku-start-" + step.id + " .wiktku-start-step-keyfield").each(function () { occupiedKeys[$(this).val()] = true; }); if (step.disabledKeys) $.extend(occupiedKeys, step.disabledKeys); return occupiedKeys; } function buildKeyInput(step) { if (!step.keys) return undefined; var input = $(mw.html.element("select", { "class": "wiktku-start-step-keyfield wiktku-start-narrow" })); input.attr("data-placeholder", "Hilbijêre " + step.keyName); if (isMobile) { populateMenus(input, step.keys, getDisabledKeys(step)); // On mobile return the wrapper; the select is inside it. // Change events still fire on the inner select. return wrapNativeSelect(input); } input.on("chosen:showing_dropdown", function () { $(this).data("wiktku-defaultValue", $(this).val()); }); input.change(function (_, context) { var inputs = $("#wiktku-start-" + step.id + " .wiktku-start-step-keyfield").not(this); var oldValue = $(this).data("wiktku-defaultValue"); var newValue = context.selected; inputs.find("option[value='" + oldValue + "']").prop('disabled', false); inputs.find("option[value='" + newValue + "']").prop('disabled', true); inputs.trigger("chosen:updated"); }); populateMenus(input, step.keys, getDisabledKeys(step)); return input; } /** * If the current text field has text and there are no more text fields after * the current text field in the list, add another text field to the list. */ function refreshForTextField(currentInput, step) { currentInput = $(currentInput); var value = currentInput.val(); var item = currentInput.parent(); if (value && !item.next("li").length) { var nextInput = $("<textarea></textarea>") .attr("name", "wiktku-field-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("class", currentInput.attr("class")) .attr("rows", currentInput.attr("rows") || 1); nextInput.on("input", function (evt) { refreshForTextField(evt.target, step); }); var nextKeyInput = buildKeyInput(step); var nextItem = $("<li></li>").append(nextKeyInput).append(nextInput); item.parent().append(nextItem); if (nextKeyInput) nextKeyInput.chosen(chosenOptions); } var canContinue = !continueBtn.isDisabled(); if ((value && !canContinue) || (!value && canContinue)) { refresh(step); } } function prepareInput(input, step) { if (!input) return; if (step.required) input.prop('required', true); input.change(step, refresh); } /** * Shows and hides all the steps based on whether their prerequisites are met, * and updates placeholders where applicable. */ function refresh(evt) { var values = getValues(); var changedStep = evt && evt.data; var didFocus = false; var canContinue = true; // Re-filter template options in every sense block whenever lang changes. $("#wiktku-start-dfn .wiktku-dfn-tpl-select").each(function () { var fn = $(this).data("updateOptions"); if (typeof fn === "function") fn(); }); // Re-filter pronunciation and etymology template dropdowns when language changes. steps.pron.refreshTplSelect(); steps.etym.refreshTplSelect(); // Sync tr/t sub-fields in every nimûne item to the current language. // tr shown when language needs transliteration; t shown when lang !== "ku". (function () { var lang = values.lang || ""; var showTr = needsTransliteration(lang); var showT = lang && lang !== "ku"; $("#wiktku-start-dfn .wiktku-dfn-nimune-list li.wiktku-dfn-nimune-li").each(function () { var li = $(this); // Ensure the sub-wrapper exists when we need it. var subWrap = li.find(".wiktku-dfn-nimune-sub"); // tr field var trTa = li.find(".wiktku-dfn-nimune-tr"); if (showTr && !trTa.length) { if (!subWrap.length) { subWrap = $("<div></div>").addClass("wiktku-dfn-nimune-sub"); li.append(subWrap); } trTa = $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-tr-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 5) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-tr") .attr("placeholder", "Transkrîpsiyon…"); subWrap.prepend(trTa); } else if (!showTr && trTa.length) { trTa.remove(); } // t field var tTa = li.find(".wiktku-dfn-nimune-t"); if (showT && !tTa.length) { if (!subWrap.length) { subWrap = $("<div></div>").addClass("wiktku-dfn-nimune-sub"); li.append(subWrap); } tTa = $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-t-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 5) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-t") .attr("placeholder", "Tercimeya nimûneyê kurmancî…"); subWrap.append(tTa); } else if (!showT && tTa.length) { tTa.remove(); } // Remove the wrapper if it ended up empty. subWrap = li.find(".wiktku-dfn-nimune-sub"); if (subWrap.length && !subWrap.children().length) subWrap.remove(); }); }()); // Sync tr/t sub-fields in every jêder citation to the current language. // tr shown when language needs transliteration; t shown when lang !== "ku". (function () { var lang = values.lang || ""; var showTr = needsTransliteration(lang); var showT = lang && lang !== "ku"; $("#wiktku-start-dfn .wiktku-dfn-jeder-list li.wiktku-dfn-jeder-li").each(function () { var li = $(this); // Ensure the sub-wrapper exists when we need it. It must sit right // after the quote textarea and before the source selector. var subWrap = li.find(".wiktku-dfn-quote-sub"); // tr field var trTa = li.find(".wiktku-dfn-nimune-quote-tr"); if (showTr && !trTa.length) { if (!subWrap.length) { subWrap = $("<div></div>").addClass("wiktku-dfn-quote-sub"); li.find(".wiktku-dfn-nimune-quote").after(subWrap); } trTa = $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-quote-tr-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 2) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-quote-tr") .attr("placeholder", "Transkrîpsiyona jêgirtinê…"); subWrap.prepend(trTa); } else if (!showTr && trTa.length) { trTa.remove(); } // t field var tTa = li.find(".wiktku-dfn-nimune-quote-t"); if (showT && !tTa.length) { if (!subWrap.length) { subWrap = $("<div></div>").addClass("wiktku-dfn-quote-sub"); li.find(".wiktku-dfn-nimune-quote").after(subWrap); } tTa = $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-quote-t-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 2) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-quote-t") .attr("placeholder", "Tercimeya jêgirtinê ya kurmancî…"); subWrap.append(tTa); } else if (!showT && tTa.length) { tTa.remove(); } // Remove the wrapper if it ended up empty. subWrap = li.find(".wiktku-dfn-quote-sub"); if (subWrap.length && !subWrap.children().length) subWrap.remove(); }); }()); $.each(steps, function (stepId, step) { if (typeof(step.visible) === "function" && !step.visible(values)) { $("#wiktku-start-" + stepId).slideUp(); } else { var stepDiv = $("#wiktku-start-" + stepId); if (changedStep !== step && typeof(step.build) === "function") { prepareInput(step.build(stepDiv, values), step); } var input = stepDiv.find(".wiktku-start-step-field"); if (typeof(step.example) === "function") { // .find() above already reaches nested fields (e.g. the dfn // step's mane textareas inside each sense block), so one // assignment covers every step; dfn keeps its own fallback. var exampleText = step.example(values) || (step.id === "dfn" ? "Mane…" : ""); input.attr("placeholder", exampleText); } var didSlideDown; if (!didFocus && stepDiv.css("display") === "none" && step.required) { didSlideDown = function (evt) { input.focus(); }; didFocus = true; } stepDiv.slideDown(didSlideDown); } if (step.required && (values[stepId] === "" || (step.multiple && values[stepId].join("") === ""))) { canContinue = false; } }); continueBtn.setDisabled(!canContinue); } function destroy() { $("#wiktku-start-form, .noafterwizard").slideUp(function () { $(this).remove(); }); $(".noarticletext .nowizard, #editform").slideDown(); $("#ca-edit").removeClass("selected"); $("#ca-wiktku-nowizard").addClass("selected"); } // Priority order for Kurdish dialects and the navz pseudo-code. // Codes listed here come before all other languages; unlisted codes // are sorted alphabetically by their display name via localeCompare. var LANG_PRIORITY = ["navz", "ku", "hac", "sdh", "lki", "ckb", "zza"]; /** * Inserts a new == {{ziman|code}} == section into existing page wikitext * at the correct sorted position: * 1. Any content before the first language section is preserved at the top. * 2. navz is always first, then ku/hac/sdh/lki/ckb/zza in that order, * then all other languages sorted by display name (localeCompare). */ function insertNewLangSection(existing, wikitext) { var newCodeMatch = wikitext.match(/^== \{\{ziman\|([^}]+)\}\} ==/); var newCode = newCodeMatch ? newCodeMatch[1] : ""; var sections = []; var preamble = ""; var firstMatch = existing.match(/(?:^|\n)== \{\{ziman\|/); if (!firstMatch) { // No existing lang sections at all — just append. var sep = existing && !/\n\s*$/.test(existing) ? "\n\n" : ""; return existing + sep + wikitext; } // Everything before the first == {{ziman|...}} == is the preamble. var firstSectionStart = existing.indexOf("== {{ziman|"); // Walk back to the start of that line. var lineStart = existing.lastIndexOf("\n", firstSectionStart - 1); var preambleEnd = lineStart !== -1 ? lineStart + 1 : 0; preamble = existing.slice(0, preambleEnd); // Parse each language section: header line + everything until the next header. var body = existing.slice(preambleEnd); // NOTE: with the /m flag, a bare "$" matches end-of-*line*, not just // end-of-string — that previously made the non-greedy content group // stop at the section's first line break instead of running to the // next language header (or the real end of the text), silently // dropping the rest of that section's wikitext. (?![\s\S]) matches // only the true end of the string, /m flag or not. var langSectionRe = /^(== \{\{ziman\|([^}]+)\}\} ==\n?)([\s\S]*?)(?=\n== \{\{ziman\||(?![\s\S]))/gm; var m; while ((m = langSectionRe.exec(body)) !== null) { sections.push({ code: m[2], content: m[0] // full text of this section including header }); } // Determine sort rank: priority list first (by index), then alphabetical. function getLangName(code) { var entry = langsByCode[code]; return entry ? entry[1] : code; } function sortRank(code) { var idx = LANG_PRIORITY.indexOf(code); return idx !== -1 ? idx : LANG_PRIORITY.length; } function compareLangs(a, b) { var ra = sortRank(a), rb = sortRank(b); if (ra !== rb) return ra - rb; // Both are outside priority list — sort by display name. return getLangName(a).localeCompare(getLangName(b), userLang); } // Insert the new section into the sorted list. var newSection = { code: newCode, content: wikitext }; var inserted = false; for (var i = 0; i < sections.length; i++) { if (compareLangs(newCode, sections[i].code) < 0) { sections.splice(i, 0, newSection); inserted = true; break; } } if (!inserted) sections.push(newSection); // Re-join: preamble + sections separated by newlines. var joined = sections.map(function (s) { // Ensure each section ends with exactly one newline before the next. return s.content.replace(/\n+$/, ""); }).join("\n"); return preamble + joined + "\n"; } function build() { $(".nowizard, .nowizard .noafterwizard").hide(); var callToAction = $("#wiktku-calltoaction"); var origCallToActionText = callToAction.text(); $(mw.util.addPortletLink("p-views", "#", "Edîtora çavkaniyê veke", "ca-wiktku-nowizard", "Vê rûpelê bi edîtora çavkaniyê çêke", undefined, "#ca-watch")).click(function (evt) { evt.preventDefault(); callToAction.text(origCallToActionText); destroy(); }); if (callToAction.length) { callToAction.text(origCallToActionText + " Forma li jêr ji bo çêkirina madeyeke nû bi kar bîne."); } var startForm = $("<form id='wiktku-start-form'></form>"); if (addLangMode) { startForm.append($("<p class='wiktku-addlang-notice'></p>").text( "Agahiyên zimanê nû yê hûnê li vê rûpelê zêde bikin dagirin. " + "Piştî temambûnê, beşa nû dê li dawiya nivîsa heyî were zêdekirin.")); } var spinner; // Tab bar for switching between POS sections. var sectionTabsDiv = $("<div id='wiktku-section-tabs'></div>"); startForm.submit(function (evt) { evt.preventDefault(); continueBtn.setDisabled(true); spinner.show(); getWikitext(function (wikitext) { if (addLangMode) { var textbox = $("#wpTextbox1"); var existing = textbox.val() || ""; // Check whether the generated lang header already exists in the page. // wikitext always starts with "== {{ziman|CODE}} ==\n" (from steps.lang.output). // If that exact section heading is already present in the existing content, // strip it from the new output and insert the remaining content at the end // of that lang section (just before the next == level-2 heading, or at the // very end of the page if there is no following section). var langHeaderMatch = wikitext.match(/^(== \{\{ziman\|[^}]+\}\} ==\n)/); if (langHeaderMatch) { var langHeader = langHeaderMatch[1]; // e.g. "== {{ziman|ku}} ==\n" // Escape for use in RegExp. var escapedHeader = langHeader.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); if (new RegExp(escapedHeader).test(existing)) { // Strip the header from the new output. var newContent = wikitext.slice(langHeader.length); // Find the insertion point: end of the existing lang section. // A new L2 heading marks the start of the next language block. var afterHeader = existing.indexOf(langHeader); var searchFrom = afterHeader + langHeader.length; // Find the next == … == heading after this section's start. var nextL2 = existing.indexOf("\n== ", searchFrom); var insertAt = nextL2 !== -1 ? nextL2 : existing.length; // Ensure there's a blank line before the inserted block. var before = existing.slice(0, insertAt); var after = existing.slice(insertAt); var sep = /\n\s*$/.test(before) ? "" : "\n"; textbox.val(before + sep + newContent + after); } else { // New language — insert at the correct sorted position. textbox.val(insertNewLangSection(existing, wikitext)); } } else { // Unexpected format — insert at sorted position anyway. textbox.val(insertNewLangSection(existing, wikitext)); } } else { $("#wpTextbox1").val(wikitext); } $("html, body").animate({scrollTop: 0}); callToAction.text("Hindik ma!"); $("#wiktku-preview-container").remove(); destroy(); }); }); $.each(ordered_steps, function (i, step) { var stepDiv = $(mw.html.element("div", { "class": "wiktku-start-step", id: "wiktku-start-" + step.id })); var name = capitalize(step.name); stepDiv.append($(mw.html.element("h3", { "class": "wiktku-start-step-name" }, new mw.html.Raw(mw.html.element("label", { "for": "wiktku-start-" + step.id + "-field" }, name))))); if (step.question_fmt) { stepDiv.append($(mw.html.element("label", { "class": "wiktku-start-step-question", "for": "wiktku-start-" + step.id + "-field" }, step.question_fmt))); if (step.question_br) stepDiv.append($("<br>")); } var input; if (step.choices) { input = $(mw.html.element("select", { "class": "wiktku-start-step-field", id: "wiktku-start-" + step.id + "-field" })); input.attr("data-placeholder", capitalize(step.name) + " hilbijêre "); populateMenus(input, step.choices); if (step.multiple) input.attr("multiple", true); if (isMobile) { stepDiv.append(wrapNativeSelect(input)); } else { stepDiv.append(input); } } else if (typeof(step.build) === "function") { input = step.build(stepDiv); } else { input = $("<textarea></textarea>") .attr("class", "wiktku-start-step-field") .attr("id", "wiktku-start-" + step.id + "-field") .attr("rows", step.rows || 2); if (step.narrow) input.addClass("wiktku-start-narrow"); if (step.multiple) { input.on("input", function (evt) { refreshForTextField(evt.target, step); }); var keyInput = buildKeyInput(step); var list = $(step.ordered ? "<ol></ol>" : "<ul></ul>") .append($("<li></li>").append(keyInput).append(input)); stepDiv.append(list); } else stepDiv.append(input); } prepareInput(input, step); stepDiv.hide(); // Insert tab bar just before the first per-section step. if (step.id === "pos") startForm.append(sectionTabsDiv); startForm.append(stepDiv); }); // ── Section tab helpers ────────────────────────────────────────────── // ── Add-section button — lives in the tab bar, disabled until pos chosen ── var addSectionBtn = new OO.ui.ButtonWidget({ label: "+ Beş zêde bike", disabled: true }); addSectionBtn.on("click", function () { saveCurrentSection(); sections.push({}); activeSection = sections.length - 1; $.each(PER_SECTION_STEP_IDS, function (_, id) { if (id === "dfn") { var stepDiv = $("#wiktku-start-dfn"); stepDiv.find("ol.wiktku-dfn-list").remove(); steps.dfn.build(stepDiv); return; } if (id === "etym") { $("#wiktku-start-etym .wiktku-etym-wrap").remove(); steps.etym.build($("#wiktku-start-etym")); return; } if (id === "trans") { var transDiv = $("#wiktku-start-trans"); transDiv.find(".wiktku-trans-group").remove(); return; } if (id === "zarava") { var zaravaDiv = $("#wiktku-start-zarava"); zaravaDiv.find(".wiktku-zarava-group").remove(); return; } if (id === "dunde") { var dundeDiv = $("#wiktku-start-dunde"); dundeDiv.find("ul.wiktku-dunde-list").remove(); return; } var stepDiv = $("#wiktku-start-" + id); stepDiv.find(".wiktku-start-step-field").val(""); if (!isMobile) stepDiv.find("select.wiktku-start-step-field").trigger("chosen:updated"); }); renderSectionTabs(); refresh(); $("html, body").animate({ scrollTop: sectionTabsDiv.offset().top - 20 }, 300); }); /** Re-render the tab bar to reflect current sections[] and activeSection. */ function renderSectionTabs() { // Detach (not remove) the button first: .empty() strips bound // event data from any children left inside it, which would // silently kill addSectionBtn's click handler on every re-render. addSectionBtn.$element.detach(); sectionTabsDiv.empty(); var lang = getValues().lang || ""; if (!lang) { sectionTabsDiv.hide(); return; } sectionTabsDiv.show(); $.each(sections, function (i) { var posVal = sections[i].pos || ""; var tabLabel = posVal ? capitalize(posVal) : ("Beş " + (i + 1)); var tab = $("<span></span>") .addClass("wiktku-section-tab") .text(tabLabel) .toggleClass("wiktku-tab-active", i === activeSection); (function (idx) { tab.on("click", function () { if (idx === activeSection) return; saveCurrentSection(); activeSection = idx; restoreSection(sections[activeSection]); refresh(); renderSectionTabs(); }); }(i)); sectionTabsDiv.append(tab); }); // Enable "Beş zêde bike" only when the active section has a pos chosen. var activePos = sections[activeSection] && sections[activeSection].pos ? sections[activeSection].pos : getValues().pos; addSectionBtn.setDisabled(!activePos); sectionTabsDiv.append(addSectionBtn.$element); } renderSectionTabs(); // Update the active tab's label whenever pos changes. startForm.on("change", "#wiktku-start-pos-field", function () { renderSectionTabs(); }); // Show the tab bar as soon as a language is selected. startForm.on("change", "#wiktku-start-lang-field", function () { renderSectionTabs(); }); var footer = $("<div id='wiktku-start-footer'></div>"); spinner = $(mw.html.element("img", { id: "wiktku-start-spinner", src: "//upload.wikimedia.org/wikipedia/commons/d/de/Ajax-loader.gif", alt: "Tê barkirin…", title: "Tê barkirin…" })); footer.append(spinner.hide()); continueBtn = new OO.ui.ButtonWidget({ id: "wiktku-unhide-editform", label: "Bişîne", flags: [ "primary", "progressive" ] }); continueBtn.on("click", function () { mw.notify("Tê şandin…", { type: "info", tag: "wiktku-submit" }); startForm.trigger("submit"); }); footer.append(continueBtn.$element); // ── Preview checkboxes ─────────────────────────────────────────────── // Wikitext preview (raw text panel) var previewCheck = $("<input type='checkbox' id='wiktku-preview-toggle'>"); var previewLabel = $("<label for='wiktku-preview-toggle'></label>") .text(" Pêşdîtina wîkîtekstê"); var previewPanel = $("<pre id='wiktku-preview-panel'></pre>").hide(); // Live rendered preview (parsed HTML panel, same logic as AjaxEdit). // Not available on mobile — API polling causes too many problems on small screens. var livePreviewCheck = null; var livePreviewPanel = null; if (!isMobile) { livePreviewCheck = $("<input type='checkbox' id='wiktku-live-preview-toggle'>"); livePreviewPanel = $("<div id='wiktku-live-preview-panel'></div>").hide(); } // Container that holds both panels and switches between stacked / side-by-side. var previewContainer = $("<div id='wiktku-preview-container'></div>"); previewContainer.append(previewPanel); if (!isMobile) previewContainer.append(livePreviewPanel); var previewTimer = null; var livePreviewIntervalId = -1; /** Rebuilds wikitext preview if its checkbox is checked. */ function schedulePreview() { if (!previewCheck.prop("checked")) return; clearTimeout(previewTimer); // Debounce: wait 400 ms after the last keystroke before rebuilding. previewTimer = setTimeout(function () { getWikitext(function (wikitext) { previewPanel.text(wikitext).show(); updatePanelLayout(); }); }, 400); } /** Fetches parsed HTML and populates the live preview panel. */ function loadLivePreview() { getWikitext(function (wikitext) { new mw.Api().parse(wikitext, { title: mw.config.get("wgPageName") }).done(function (html) { livePreviewPanel.html(html).show(); updatePanelLayout(); }); }); } /** Adjusts panel widths depending on which previews are visible. */ function updatePanelLayout() { var wikitextVisible = previewCheck.prop("checked"); var liveVisible = livePreviewCheck && livePreviewCheck.prop("checked"); if (wikitextVisible && liveVisible) { // Side by side — each panel takes roughly half the available width. previewPanel.css({ "flex": "1 1 45%", "min-width": "280px" }); livePreviewPanel.css({ "flex": "1 1 45%", "min-width": "280px" }); } else { // Full width for whichever is visible. previewPanel.css({ "flex": "1 1 100%", "min-width": "" }); if (livePreviewPanel) livePreviewPanel.css({ "flex": "1 1 100%", "min-width": "" }); } } previewCheck.on("change", function () { if ($(this).prop("checked")) { schedulePreview(); } else { clearTimeout(previewTimer); previewPanel.hide(); updatePanelLayout(); } }); if (!isMobile) { livePreviewCheck.on("change", function () { if ($(this).prop("checked")) { livePreviewPanel.show(); loadLivePreview(); livePreviewIntervalId = setInterval(loadLivePreview, 500); } else { clearInterval(livePreviewIntervalId); livePreviewIntervalId = -1; livePreviewPanel.hide().empty(); updatePanelLayout(); } }); } // Listen on all input/change events on the form and update both previews. startForm.on("input change", function () { schedulePreview(); }); footer.append($("<span style='margin-left:1em'></span>") .append(previewCheck).append(previewLabel)); if (!isMobile) { var livePreviewLabel = $("<label for='wiktku-live-preview-toggle'></label>") .text(" Pêşdîtina zindî"); footer.append($("<span style='margin-left:1em'></span>") .append(livePreviewCheck).append(livePreviewLabel)); } startForm.append(footer); $("#editform").hide().before(startForm); // Insert preview container (holds both panels) after the form. startForm.after(previewContainer); if (!isMobile) startForm.find("select").chosen(chosenOptions); refresh(); // Zimanan ji MediaWiki:Gadget-translation_editor.js/ziman.json bar bike. // Kodên ku bi "-pro" diqedin û navên ku "zimanê destan" tê de heye // tên derxistin. Zimanên xardkirî li serî dimînin, yên din // bi alfabeyê li dû wan tên. // Pinned choices come from MediaWiki:Gadget-start.js/data.json (langChoices), // already loaded into steps.lang.choices before build() runs. var pinnedChoices = steps.lang.choices.slice(); var pinnedCodes = $.map(pinnedChoices, function (choice) { return choice[0]; }); new mw.Api().get({ action: "query", prop: "revisions", titles: "MediaWiki:Gadget-translation_editor.js/ziman.json", rvprop: "content", rvslots: "main", formatversion: 2 }).then(function (data) { var page = data.query.pages[0]; var content = page && page.revisions && page.revisions[0].slots.main.content; var zimanData; try { zimanData = JSON.parse(content); } catch (e) { zimanData = {}; } var extraChoices = []; $.each(zimanData, function (code, name) { // Filter: skip proto-language codes and legendary/reconstructed langs. if (/-pro$/i.test(code)) return; if (/ziman[eê]\s+destan/i.test(name)) return; // Skip codes already in the pinned list (they are handled above). if (pinnedCodes.indexOf(code) !== -1) return; // sortKey: bare name without leading "zimanê " for sorting. var sortKey = name.replace(/^ziman[eê]\s+/i, ""); var choice = [code, name, sortKey]; extraChoices.push(choice); langsByCode[code] = choice; }); // Populate langsByCode for pinned choices too. $.each(pinnedChoices, function (i, choice) { // Ensure pinned choices have a sortKey (index 2). if (choice.length < 3) choice[2] = choice[1]; langsByCode[choice[0]] = choice; }); // Sort the extra choices alphabetically by sort key. extraChoices.sort(function (a, b) { return a[2].localeCompare(b[2], userLang); }); // Final list: pinned first, then the rest. var allChoices = pinnedChoices.concat(extraChoices); steps.lang.choices = allChoices; steps.trans.keys = allChoices; steps.dunde.keys = allChoices; steps.zarava.keys = getZaravaKeys(allChoices); var langMenu = $("#wiktku-start-lang-field"); populateMenus(langMenu, steps.lang.choices); langMenu.trigger("chosen:updated"); var transMenus = $("#wiktku-start-trans .wiktku-start-step-keyfield"); populateMenus(transMenus, steps.trans.keys, getDisabledKeys(steps.trans)); transMenus.trigger("chosen:updated"); var dundeMenus = $("#wiktku-start-dunde .wiktku-start-step-keyfield"); populateMenus(dundeMenus, steps.dunde.keys, getDisabledKeys(steps.dunde)); dundeMenus.trigger("chosen:updated"); var zaravaMenus = $("#wiktku-start-zarava .wiktku-start-step-keyfield"); populateMenus(zaravaMenus, steps.zarava.keys, getDisabledKeys(steps.zarava)); }); } mw.loader.using(["jquery.chosen", "mediawiki.api", "oojs-ui-core"], function () { // Build the form immediately so the user can start interacting with it // (lang dropdown, etc.) while data.json loads in the background. build(); // Load metadata, langChoices, posChoices and tplDefs from the companion // data page so they can be updated without touching this script. new mw.Api().get({ action: "query", prop: "revisions", titles: "MediaWiki:Gadget-start.js/data.json", rvprop: "content", rvslots: "main", formatversion: 2 }).then(function (data) { var page = data.query.pages[0]; var content = page && page.revisions && page.revisions[0].slots.main.content; var d; try { d = JSON.parse(content); } catch (e) { d = {}; } // Populate metadata. if (d.metadata) $.extend(metadata, d.metadata); // Repopulate lang choices and their dependent menus. if (d.langChoices) { steps.lang.choices = d.langChoices; steps.trans.keys = d.langChoices; steps.dunde.keys = d.langChoices; steps.zarava.keys = getZaravaKeys(d.langChoices); var langMenu = $("#wiktku-start-lang-field"); // Preserve whatever the user may have already selected. var prevLang = langMenu.val(); populateMenus(langMenu, steps.lang.choices); if (prevLang) langMenu.val(prevLang); if (!isMobile) langMenu.trigger("chosen:updated"); } // Repopulate POS choices, preserving any existing selection. if (d.posChoices) { steps.pos.choices = d.posChoices; var posMenu = $("#wiktku-start-pos-field"); var prevPos = posMenu.val(); populateMenus(posMenu, steps.pos.choices); if (prevPos) posMenu.val(prevPos); if (!isMobile) posMenu.trigger("chosen:updated"); } // Populate template definitions for the dfn sense-block builder. if (d.tplDefs) { steps.dfn.tplDefs = d.tplDefs; // Refresh any sense-block template selectors already in the DOM. $("#wiktku-start-dfn .wiktku-dfn-tpl-select").each(function () { var fn = $(this).data("updateOptions"); if (typeof fn === "function") fn(); }); } // Populate pos placeholder examples. if (d.posExamples) steps.dfn.posExamples = d.posExamples; // Populate citation template definitions for the quote widget. if (d.jederDefs) steps.dfn.jederDefs = d.jederDefs; // Populate pronunciation and etymology template insert lists. if (d.pronTpls) { steps.pron.pronTpls = d.pronTpls; steps.pron.refreshTplSelect(); } if (d.etymTpls) { steps.etym.etymTpls = d.etymTpls; steps.etym.refreshTplSelect(); } // Sync trans/dunde/zarava keys with the (now populated) lang choices. steps.trans.keys = steps.lang.choices; steps.dunde.keys = steps.lang.choices; steps.zarava.keys = getZaravaKeys(steps.lang.choices); }); }); }); //</nowiki> 5fed0qy0ej7ymfuntlm1wjilwg93pxq 6265558 6265555 2026-07-19T12:51:24Z Wikihez 7344 Restored revision 6265457 by [[Special:Contributions/Wikihez|Wikihez]] ([[User talk:Wikihez|talk]]) ([[:m:User:Xiplus/TwinkleGlobal|TwinkleGlobal]]) 6265558 javascript text/javascript // Li ser [[vi:MediaWiki:Gadget-start.js]] hatiye refaktorkirin. //<nowiki> $(function () { var ns = mw.config.get("wgNamespaceNumber"); if (ns && !(ns === 2 && mw.config.get("wgPageName").match(/\/ceribandin$|\/test$/))) { return; } var action = mw.config.get("wgAction"); var pageExists = !!mw.config.get("wgArticleId"); // "Zimanek lê zêde bike" mode: triggered from the portlet link below. // Runs the same wizard on an EXISTING page's edit form, but appends the // generated section instead of replacing the textarea's content. var addLangMode = pageExists && mw.util.getParamValue("wiktkuaddlang") === "1"; // On a normal page view of an existing page, just add the portlet link // that takes the user into addLangMode; don't build anything else here. if (action === "view" && pageExists) { mw.util.addPortletLink("p-views", mw.util.getUrl(mw.config.get("wgPageName"), { action: "submit", wiktkuaddlang: "1" }), "+Ziman/beşeke din", "ca-wiktku-addlang", "Ji vê rûpelê re zimanekî nû zêde bike"); return; } if (!(action === "edit" || action === "submit")) { return; } if (!addLangMode && !$(".mw-newarticletext, .mw-newarticletextanon").length) { return; } if (window.location.href.includes("editintro=User:Wikihez/creation/intro")) { return; // Do not run the script wextê WF:Bilez dişuxile } function capitalize(str) { if (!str) return str; return str[0].toUpperCase() + str.substr(1); } function decapitalize(str) { if (!str) return str; return str[0].toLowerCase() + str.substr(1); } function escapeRegExp(str) { return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); } function stripWikilinks(str) { return str.replace(/\[\[([^\]|]+)(?:\|([^\]]+))?\]\]/g, function (m, target, display) { return display || target; }); } function insertAtCursor(el, text) { var start = el.selectionStart; var end = el.selectionEnd; var val = el.value; el.value = val.slice(0, start) + text + val.slice(end); var pos = start + text.length; el.selectionStart = el.selectionEnd = pos; } var pageName = mw.config.get("wgPageName").replaceAll(/_/g, " "); if (ns) pageName = pageName.replace(/.*\//, ""); var pageNameRe = escapeRegExp(pageName); var userLang = mw.config.get("wgUserLanguage"); // Mobile detection: MobileFrontend sets wgMFMode, or fall back to touch check. var isMobile = !!mw.config.get("wgMFMode") || window.matchMedia("(pointer: coarse)").matches; var chosenOptions = { width: "20em", disable_search_threshold: 0, placeholder_text_single: "Yekî hilbijêre", placeholder_text_multiple: "Hilbijêre", no_results_text: "Nehat dîtin", enable_split_word_search: true, search_contains: true }; function wrapNativeSelect(select) { var placeholder = select.attr("data-placeholder") || "Lê bigere…"; // Hide the native select — we drive it programmatically. select.hide(); var wrapper = $("<span class='wiktku-native-select-wrap'></span>"); var textInput = $("<input type='search' autocomplete='off'>") .attr("placeholder", placeholder) .addClass("wiktku-start-narrow wiktku-ac-input"); var resultsList = $("<ul class='wiktku-ac-results'></ul>").hide(); // Full option cache — rebuilt when chosen:updated fires. var allOptions = []; function cacheOptions() { allOptions = []; select.find("option").each(function () { var v = $(this).val(); if (!v) return; // skip the empty placeholder option allOptions.push({ value: v, text: $(this).text(), disabled: $(this).prop("disabled") }); }); } cacheOptions(); function showResults(query) { var q = query.trim().toLowerCase(); resultsList.empty(); var matched; if (q) { matched = []; $.each(allOptions, function (_, o) { if (o.disabled) return; var codeMatch = o.value.toLowerCase().indexOf(q) !== -1; var nameMatch = o.text.toLowerCase().indexOf(q) !== -1; if (codeMatch || nameMatch) { matched.push({ opt: o, codeMatch: codeMatch }); } }); // Code matches (especially prefix matches) come first. matched.sort(function (a, b) { var aCode = a.opt.value.toLowerCase(); var bCode = b.opt.value.toLowerCase(); var aPrefix = aCode.indexOf(q) === 0; var bPrefix = bCode.indexOf(q) === 0; if (aPrefix !== bPrefix) return aPrefix ? -1 : 1; if (a.codeMatch !== b.codeMatch) return a.codeMatch ? -1 : 1; return 0; }); matched = matched.map(function (item) { return item.opt; }); } else { matched = allOptions.filter(function (o) { return !o.disabled; }); } if (!matched.length) { resultsList.hide(); return; } $.each(matched.slice(0, 50), function (_, opt) { var li = $("<li></li>").text(opt.text).attr("data-value", opt.value); // Use touchend instead of touchstart so that a scroll gesture does // not accidentally select an item. We track whether the finger moved // between touchstart and touchend — if it did, it was a scroll. var touchMoved = false; li.on("touchstart", function () { touchMoved = false; }); li.on("touchmove", function () { touchMoved = true; }); li.on("touchend", function (e) { if (touchMoved) return; // was a scroll, not a tap e.preventDefault(); selectOption(opt.value, opt.text); }); // Keep mousedown for desktop fallback. li.on("mousedown", function (e) { e.preventDefault(); selectOption(opt.value, opt.text); }); resultsList.append(li); }); // Position the list above or below depending on available viewport space. var inputRect = textInput[0].getBoundingClientRect(); var viewportH = window.innerHeight; var spaceBelow = viewportH - inputRect.bottom - 8; var spaceAbove = inputRect.top - 8; var maxH = Math.min(224, Math.max(spaceBelow, spaceAbove)); // 224px ≈ 14em resultsList.css({ "max-height": maxH + "px", "top": spaceBelow >= spaceAbove ? "100%" : "auto", "bottom": spaceBelow >= spaceAbove ? "auto" : "100%" }); resultsList.show(); } function selectOption(value, text) { textInput.val(text); select.val(value); resultsList.hide(); select.trigger("change"); } textInput.on("input focus", function () { showResults($(this).val()); }); textInput.on("blur", function () { // Short delay so a touchstart on a result item fires first. setTimeout(function () { resultsList.hide(); }, 200); }); // chosen:updated → re-cache (called after ziman.json loads). select.on("chosen:updated", function () { cacheOptions(); // If a value is already selected, keep the display text in sync. var cur = select.val(); if (cur) { var match = $.grep(allOptions, function (o) { return o.value === cur; })[0]; if (match) textInput.val(match.text); } }); // No-op .chosen() so desktop call-sites don't need guarding. select.chosen = function () { return select; }; wrapper.append(textInput).append(resultsList).append(select); return wrapper; } var langsByCode = {}; // Populated from [[MediaWiki:Gadget-start.js/data.json]] at runtime. var metadata = {}; // Zaravayên kurdî yên ku di beşa "Bi zaravayên din" de tên pêşkêşkirin — // ev kod ji beşa Werger têne derxistin daku heman zimên du caran neyê xwendin. var ZARAVA_LANG_CODES = ["ckb", "sdh", "lki", "hac", "zza"]; function getZaravaKeys(choices) { var byCode = {}; $.each(choices || [], function (_, c) { byCode[c[0]] = c; }); var result = []; $.each(ZARAVA_LANG_CODES, function (_, code) { if (byCode[code]) result.push(byCode[code]); }); return result; } function needsTransliteration(langCode) { var meta = metadata[langCode]; if (!meta || !meta.sc) return false; var scripts = Array.isArray(meta.sc) ? meta.sc : [meta.sc]; return scripts.length > 0 && scripts[0] !== "Latn"; } // Kodên cinsiyetê yên di metadata.g de var GENDER_BASE_LABELS = { m: "mê", n: "nêr", nt: "nêtar", mn: "mê û nêr", mnmane: "mê yan nêr li gorî maneyê", g: "giştî", y: "yekjimar", p: "pirjimar" }; // Sub-lists that only make sense for a plain (non-şablon) sense — hidden // when a şablon (e.g. {{guharto|…}}) is chosen for that sense, since a // template-based sense has no "own" gloss for alternate forms, synonyms, // antonyms, coordinate terms, hypernyms or hyponyms to attach to. Etîket, // Nimûne and Jêgirtin stay visible either way. var HIDDEN_ON_TPL_GROUPS = [ "wiktku-dfn-alternativ", "wiktku-dfn-hevmane", "wiktku-dfn-dijmane", "wiktku-dfn-koordine", "wiktku-dfn-jornav", "wiktku-dfn-jernav" ]; function genderLabel(code) { if (code === "p") return "Pirjimar"; var pluralMatch = code.match(/^(.+)-p$/); if (pluralMatch && GENDER_BASE_LABELS[pluralMatch[1]]) { return GENDER_BASE_LABELS[pluralMatch[1]] + " (pirjimar)"; } return GENDER_BASE_LABELS[code] || code; } /** * True if a sense has any content worth keeping besides its mane text — * etîket, hevmane/dijmane/koordîne/etc. word lists, nimûne, or jêder * (quote). Used so a sense with an empty mane but filled-in extra * fields still gets emitted (with {{mane?}} standing in for the gloss) * instead of being silently dropped. */ function senseHasExtraContent(s) { if (s.etiket && $.grep(s.etiket, function (e) { return $.trim(e) !== ""; }).length) return true; if (s.alternativ.length || s.hevmane.length || s.dijmane.length || s.koordine.length || s.jornav.length || s.jernav.length) return true; if (s.nimune && $.grep(s.nimune, function (n) { return (typeof n === "object" ? n.text : n) !== ""; }).length > 0) return true; if (s.jeder && $.grep(s.jeder, function (j) { return j && j.quote; }).length > 0) return true; return false; } /** * formatNimune: each nimûne item can be { text, tr, t }: * text — example text * tr — transliteration (only when the language needs it) * t — Kurdish translation (third positional param, no key) */ function formatNimune(nimunes, lang, hasJeder) { var hasNimune = nimunes && $.grep(nimunes, function (n) { return (typeof n === "object" ? n.text : n) !== ""; }).length > 0; if (!hasNimune) { return hasJeder ? "" : "\n#* {{bênimûne|" + lang + "}}"; } return $.map(nimunes, function (n) { var text = typeof n === "object" ? n.text : n; if (!text) return undefined; var bolded = text.replace( new RegExp("(" + pageNameRe + "([^( |,|;|\\?|\\.|\\!)]+)?)", "ig"), "'''$1'''"); var tpl = "\n#: {{nm|" + lang + "|" + bolded; if (typeof n === "object") { if (n.tr) tpl += "|tr=" + n.tr; // Translation as third positional param (no key needed). if (n.t) tpl += "|" + n.t; } // Short examples fit on one line together with their translation. // rêz=1 is not used for ku — definitions are shown on separate lines there. if (text.length < 200 && lang !== "ku") tpl += "|rêz=1"; tpl += "}}"; return tpl; }).join(""); } /** * Formats a list of jêder (quote/citation) objects into wikitext lines. * Each entry that has no quote text is skipped. Returns "" when the list * is empty or every entry is blank. * * #* {{jêder-…|lang|jêgirtin=…|tr=…|tercime=…|…fields…}} * * When no template is chosen, the generic {{jêder|…}} template is used * instead. Its 2nd positional param is the user's freeform "bi destê xwe * binivîsim" source text when supplied, or the çavkanî? placeholder otherwise. * If that text contains "=" it is passed as |2=… instead of a bare * positional param, since MediaWiki would otherwise misparse it as its * own key=value pair and break the template: * #* {{jêder|lang|jêgirtin=…|tr=…|tercime=…|<manual source or çavkanî?>}} */ function formatJeder(jederList, lang) { if (!jederList || !jederList.length) return ""; return $.map(jederList, function (jeder) { if (!jeder || !jeder.quote) return undefined; if (jeder.jederTpl) { var cite = "\n#* {{" + jeder.jederTpl + "|" + lang; cite += "|jêgirtin=" + jeder.quote; if (jeder.quoteTr) cite += "|tr=" + jeder.quoteTr; if (jeder.quoteT) cite += "|tercime=" + jeder.quoteT; $.each(jeder.jêderFields || {}, function (key, val) { if (val) cite += "|" + key + "=" + val; }); cite += "}}"; return cite; } var out = "\n#* {{jêder|" + lang + "|jêgirtin=" + jeder.quote; if (jeder.quoteTr) out += "|tr=" + jeder.quoteTr; if (jeder.quoteT) out += "|tercime=" + jeder.quoteT; var srcParam = jeder.jederManual ? jeder.jederManual : "çavkanî?"; // A positional param containing "=" gets parsed as its own key=value // pair by MediaWiki and breaks the template, so force it to be // explicitly named (|2=) whenever that's the case. out += (srcParam.indexOf("=") !== -1 ? "|2=" : "|") + srcParam; out += "}}"; return out; }).join(""); } function makeWordListStep(id, name, question_fmt, header, templateName) { return { id: id, name: name, question_fmt: question_fmt, multiple: true, narrow: true, visible: function (values) { return values.lang && values.pos; }, output: function (values) { var words = $.grep(values[id] || [], function (w) { return !!w; }); if (!words.length) return ""; var lang = values.lang; var section = "\n==== " + header + " ====\n"; if (words.length === 1) { // Single word — keep the simple inline template. return section + "* {{" + templateName + "|" + lang + "|" + words[0] + "}}\n"; } // Multiple words — use {{kol3}} with one positional param per word. var params = "cure=" + header + "\n" + $.map(words, function (w) { return "|" + w; }).join("\n"); return section + "{{kol3|" + lang + "|" + params + "\n}}\n"; } }; } var steps = { lang: { id: "lang", required: true, name: "ziman", question_fmt: '"' + pageName + '" bi çi zimanî ye?', question_br: true, // Populated from [[MediaWiki:Gadget-start.js/data.json]] (langChoices). choices: [], output: function (values) { return "== {{ziman|" + values.lang + "}} ==\n"; } }, pron: { id: "pron", name: "bilêvkirin", question_fmt: '"' + pageName + '" çawa tê telafûzkirin?', // pronTpls populated from data.json pronTpls: [], visible: function (values) { if (!values.lang) return false; // In addLangMode, only skip pron when this langcode's section // already exists in the page — if it's a new language, show it. if (addLangMode) { var existing = $("#wpTextbox1").val() || ""; var header = "== {{ziman|" + values.lang + "}} =="; return existing.indexOf(header) === -1; } return true; }, /** Fills (or refills) the insert-dropdown from the current pronTpls array, filtering by language. */ refreshTplSelect: function () { var sel = $("#wiktku-start-pron .wiktku-tpl-insert-select"); if (!sel.length) return; var lang = getValues().lang || ""; sel.find("option[value!='']").remove(); $.each(steps.pron.pronTpls, function (_, tpl) { // Filter: if tpl.langs exists, only show if lang is in that list; otherwise show always var allowed = !tpl.langs || tpl.langs.indexOf(lang) !== -1; if (allowed) { sel.append($("<option></option>") .val(tpl.snippet) .text(tpl.name + " — " + tpl.desc) .attr("data-nolang", tpl.noLang ? "1" : "")); } }); // Notify Chosen that the option list has changed (no-op on mobile). if (!isMobile) sel.trigger("chosen:updated"); }, build: function (stepDiv) { if (stepDiv.find(".wiktku-pron-wrap").length) return null; var wrap = $("<div class='wiktku-pron-wrap'></div>"); var ta = $("<textarea></textarea>") .attr("name", "wiktku-pron-" + $.now()) .attr("class", "wiktku-start-step-field wiktku-pron-text") .attr("rows", 4) .attr("placeholder", "Nimûne: {{IPA|ku|/pɛɪ̯n/}} yan {{kîte|ku|he|ce|ki|rin}}"); // Template insert dropdown — filtered by language. var sel = $("<select class='wiktku-tpl-insert-select'></select>"); sel.append($("<option value=''>— şablonek lê zêde bike —</option>")); var lang = getValues().lang || ""; $.each(steps.pron.pronTpls, function (_, tpl) { // Filter: if tpl.langs exists, only show if lang is in that list; otherwise show always var allowed = !tpl.langs || tpl.langs.indexOf(lang) !== -1; if (allowed) { sel.append($("<option></option>") .val(tpl.snippet) .text(tpl.name + " — " + tpl.desc) .attr("data-nolang", tpl.noLang ? "1" : "")); } }); sel.on("change", function () { var snippet = $(this).val(); if (!snippet) return; var lang = getValues().lang || ""; // Check if the selected option has noLang flag var selectedOption = sel.find("option:selected"); var hasNoLang = selectedOption.attr("data-nolang") === "1"; if (!hasNoLang) { snippet = snippet.replace(/CODE/g, lang).replace(/SOURCELANG/g, "?"); } insertAtCursor(ta[0], snippet); $(this).val(""); ta.focus(); }); wrap.append(sel).append($("<br>")).append(ta); stepDiv.append(wrap); return ta; }, output: function () { var text = $.trim($("#wiktku-start-pron .wiktku-pron-text").val()); if (!text) return ""; var lines = text.split("\n"); var out = $.map(lines, function (line) { line = $.trim(line); if (!line) return undefined; return line.charAt(0) === "*" ? line : "* " + line; }).join("\n"); return "\n=== Bilêvkirin ===\n" + out + "\n"; } }, pos: { id: "pos", required: true, name: "Cureyê rêzimanî", question_fmt: 'Cureyê rêzimanî yê "' + pageName + '" çi ye?', visible: function (values) { return values.lang; }, question_br: true, // Populated from [[MediaWiki:Gadget-start.js/data.json]] (posChoices). choices: [], output: function (values) { var pos = values.pos || ""; var cinsiyet = values.cinsiyet || ""; // from the cinsiyet step var lekTur = values.lektur || ""; // from the lêker transitivity step var capitalizedPos = capitalize(pos); var outputString = "\n=== " + capitalizedPos + " ===\n"; // Add ku-tewîn-nav for single-word navdêr/serenav with known gender. if (!pageName.includes(" ") && cinsiyet && GENDER_BASE_LABELS[cinsiyet] && (pos === "navdêr" || pos === "serenav") && values.lang === "ku") { outputString += "{{ku-tewîn-nav|" + pageName + "|" + GENDER_BASE_LABELS[cinsiyet]; if (pos === "serenav") outputString += "|y"; outputString += "}}\n"; } outputString += "{{" + pos + "|" + values.lang; if (pos === "navdêr" || pos === "serenav") { if (cinsiyet) { outputString += "|c=" + cinsiyet; } else if (values.lang === "ku") { // Unknown gender — prompt editor to fill it in. outputString += "|c=?"; } } else if (/^lêker/.test(pos) && lekTur) { outputString += "|c=" + lekTur; } if (values.tr) { outputString += "|tr=" + values.tr; } outputString += "}}\n"; return outputString; } }, /** * cinsiyet (grammatical gender) — only shown for navdêr/serenav, û * tenê ger metadata ji bo zimanê hilbijartî lîsteyeke "g" (cinsiyet) * were dayîn. Opsiyonên vê gavê ne sabît in — ji metadata[values.lang].g * têne çêkirin, ji ber ku di hemû zimanan de cinsiyet tine. */ cinsiyet: { id: "cinsiyet", name: "cinsiyet", question_fmt: 'Cinsiyeta "' + pageName + '" çi ye?', question_br: true, visible: function (values) { var meta = metadata[values.lang]; return !!(values.lang && (values.pos === "navdêr" || values.pos === "serenav") && meta && meta.g && meta.g.length); }, build: function (stepDiv, values) { var select = stepDiv.find("select.wiktku-start-step-field"); if (!select.length) { select = $(mw.html.element("select", { "class": "wiktku-start-step-field", id: "wiktku-start-cinsiyet-field" })); stepDiv.append(select); } if (!values) return select; var meta = metadata[values.lang]; var codes = (meta && meta.g) || []; var prevVal = select.val(); var choices = $.map(codes, function (code) { return [[code, genderLabel(code)]]; }); populateMenus(select, choices); if ($.grep(choices, function (c) { return c[0] === prevVal; }).length) { select.val(prevVal); } if (!isMobile) select.trigger("chosen:updated"); return select; }, output: function () { return ""; } // consumed by pos.output }, /** * Lêker transitivity — only shown for any lêker variant. */ lektur: { id: "lektur", name: "Cureyê lêkerê (fiîlê)", question_fmt: "Cureyê lêkerê (fiîlê) çi ye?", question_br: true, visible: function (values) { return values.lang && values.pos && /^lêker/.test(values.pos); }, // Dictionary: value → display label. Add new types here. choices: [ ["gh", "gerguhêz"], ['x-gh', 'xwerû-gerguhêz'], ['p-gh', 'pêkhatî-gerguhêz'], ['h-gh', 'hevedudanî-gerguhêz'], ['b-gh', 'biwêjî-gerguhêz'], ["ngh", "negerguhêz"], ['x-ngh', 'xwerû-negerguhêz'], ['p-ngh', 'pêkhatî-negerguhêz'], ['h-ngh', 'hevedudanî-negerguhêz'], ['b-ngh', 'biwêjî-negerguhêz'] ], output: function () { return ""; } // consumed by pos.output }, tr: { id: "tr", name: "transkrîpsiyon", question_fmt: "Transkrîpsiyona kelîmeyê", multiple: false, narrow: true, visible: function (values) { return values.lang && values.pos && needsTransliteration(values.lang); } }, dfn: { id: "dfn", // required: true, ger mane tinebe [[Şablon:mane?]] bi kar bîne name: "Mane", question_fmt: "Maneya kelîmeyê binivîse. Mane otomatîk tê lînkkirin! Ji bo tercimeyan beşa 'Werger' bi kar bîne!", multiple: true, ordered: true, rows: 3, visible: function (values) { return values.lang && values.pos; }, example: function (values) { // posExamples loaded from [[MediaWiki:Gadget-start.js/data.json]]. var examples = steps.dfn.posExamples || {}; var full = values.pos || ""; return examples[full] || ""; }, /** * Builds one sense block (<li>) inside the ordered list. * Each block contains: * - a textarea for the definition * - an expandable nimûne list * - single-row sub-lists for formên alternatîv, hevmane, dijmane */ buildSenseBlock: function (stepDiv) { var block = $("<li class='wiktku-dfn-sense'></li>"); // — Mane textarea (declared first so the template handler can reference it) — var dfnArea = $("<textarea></textarea>") .attr("name", "wiktku-dfn-mane-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("class", "wiktku-start-step-field wiktku-dfn-mane") .attr("rows", 6) .attr("placeholder", "Mane…"); dfnArea.on("input", function () { steps.dfn.onDfnInput(stepDiv, block, this); }); // — Template selector (optional — replaces mane when chosen) — // Template definitions loaded from [[MediaWiki:Gadget-start.js/data.json]]. var tplDefs = steps.dfn.tplDefs || []; // Cache of all non-placeholder option elements — used by updateTplOptions // to remove/re-add options (the only approach compatible with Chosen.js). var _allTplOptions = []; var tplSelect = $(mw.html.element("select", { "class": "wiktku-dfn-tpl-select" })); tplSelect.append($("<option value=''>— yan jî şablonek hilbijêre —</option>")); $.each(tplDefs, function (_, tpl) { var opt = $("<option></option>") .val(tpl.name) .text(tpl.name) .attr("data-langs", tpl.langs ? tpl.langs.join(",") : "") .attr("data-nolang", tpl.noLang ? "1" : ""); tplSelect.append(opt); _allTplOptions.push(opt[0]); }); function updateTplOptions() { var lang = getValues().lang || ""; var currentVal = tplSelect.val(); var currentStillValid = false; // Detach all non-placeholder options, then re-attach only the visible ones. // This is the only approach that works correctly with both native <select> // and Chosen.js on desktop. tplSelect.find("option[value!='']").detach(); $.each(_allTplOptions, function (_, opt) { var allowed = $(opt).attr("data-langs"); var visible = !allowed || allowed.split(",").indexOf(lang) !== -1; if (visible) { tplSelect.append(opt); if ($(opt).val() === currentVal) currentStillValid = true; } }); if (!isMobile) tplSelect.trigger("chosen:updated"); if (currentVal && !currentStillValid) { tplSelect.val(""); dfnArea.show(); tplTitleInput.hide().val(""); } } // Store updater on the element so refresh() can call it for all blocks. tplSelect.data("updateOptions", updateTplOptions); var tplTitleInput = $("<input type='text'>") .addClass("wiktku-dfn-tpl-title wiktku-start-narrow") .attr("placeholder", "Navê rûpelê…") .hide(); // Grow the sense list when the title field of the last block gets content, // mirroring what onDfnInput does for the plain mane textarea. tplTitleInput.on("input", function () { steps.dfn.onDfnInput(stepDiv, block, this); }); /** * When a şablon sense is chosen, formên alternatîv/hevmane/dijmane/ * termên koordîne/jornav/jêrnav don't apply (there's no plain gloss * to hang them off), so hide those subgroups. Etîket, Nimûne and * Jêgirtin stay visible and still usable for a şablon sense. */ function updateFieldVisibility() { var isTpl = !!tplSelect.val(); $.each(HIDDEN_ON_TPL_GROUPS, function (_, cls) { block.find("." + cls + "-group").toggle(!isTpl); }); } // Store on the block so restoreDfn() can re-sync visibility // after programmatically setting tplSelect's value. block.data("updateFieldVisibility", updateFieldVisibility); tplSelect.on("change", function () { var chosen = $(this).val(); if (chosen) { dfnArea.hide(); tplTitleInput.show().focus(); } else { dfnArea.show(); tplTitleInput.hide().val(""); } updateFieldVisibility(); // Re-run refresh so the Werger step visibility updates. refresh(); }); var tplRow = $("<div></div>").addClass("wiktku-dfn-tpl-row") .append(tplSelect).append(" ").append(tplTitleInput); block.append(tplRow); block.append(dfnArea); // Apply lang filter on initial build. updateTplOptions(); // — Sub-field groups — // All groups are always visible with a placeholder textarea. // Nimûne is last in the DOM and last in the output. var allGroups = [ { cls: "wiktku-dfn-etiket", label: "Etîket", rows: 1, narrow: true, izah: "xisûsen, Mêrdîn, anatomî, Badînî" }, { cls: "wiktku-dfn-alternativ", label: "Formên alternatîv", rows: 1, narrow: true, izah: "Varyantên vê kelîmeyê" }, { cls: "wiktku-dfn-hevmane", label: "Hevmane", rows: 1, narrow: true, izah: "Spehî hevmaneya Bedew e." }, { cls: "wiktku-dfn-dijmane", label: "Dijmane", rows: 1, narrow: true, izah: "Zengîn dijmaneya feqîr e." }, { cls: "wiktku-dfn-koordine", label: "Termên koordîne", rows: 1, narrow: true, izah: "Pisîk û kûçik termên koordîne ne çunkî Jornavên wan gelek in" }, { cls: "wiktku-dfn-jornav", label: "Jornav", rows: 1, narrow: true, izah: "Heywan jornavê guhandar e" }, { cls: "wiktku-dfn-jernav", label: "Jêrnav", rows: 1, narrow: true, izah: "Guhandar jêrnavê heywan e" }, { cls: "wiktku-dfn-nimune", label: "Nimûne", rows: 2, narrow: false } ]; $.each(allGroups, function (_, g) { var groupDiv = $("<div></div>").addClass("wiktku-dfn-subgroup " + g.cls + "-group"); function buildNimuneLi() { var lang = getValues().lang || ""; var li = $("<li></li>").addClass("wiktku-dfn-nimune-li"); var mainTa = $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-text-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", g.rows) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-text") .attr("placeholder", "Nimûneya emilandina kelîmeyê tu bi xwe binivîse…"); mainTa.on("input", function () { var val = $.trim($(this).val()); var isLast = li.is(list.children("li:last-child")); if (val && isLast) { list.append(buildNimuneLi()); } }); li.append(mainTa); var subWrap = $("<div></div>").addClass("wiktku-dfn-nimune-sub"); if (needsTransliteration(lang)) { subWrap.append( $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-tr-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 5) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-tr") .attr("placeholder", "Transkrîpsiyona bi alfabeya latînî") ); } if (lang && lang !== "ku") { subWrap.append( $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-t-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 5) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-t") .attr("placeholder", "Tercimeya kurmancî") ); } if (subWrap.children().length) li.append(subWrap); return li; } if (g.cls === "wiktku-dfn-nimune") { // Nimûne — compound widget with tr/t sub-fields. var lbl = $("<span></span>").addClass("wiktku-dfn-sublabel").text(g.label + ": "); var list = $("<ol></ol>").addClass("wiktku-dfn-sublist " + g.cls + "-list"); groupDiv.data("buildNimuneLi", buildNimuneLi); list.append(buildNimuneLi()); groupDiv.append(lbl).append(list); block.append(groupDiv); } else { // Regular always-visible group — label + growing textarea list. var lbl = $("<span></span>").addClass("wiktku-dfn-sublabel").text(g.label + ": " + g.izah); var list = $("<ol></ol>").addClass("wiktku-dfn-sublist " + g.cls + "-list"); var firstInput = $("<textarea></textarea>") .attr("name", g.cls + "-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", g.rows) .attr("class", "wiktku-dfn-subfield" + (g.narrow ? " wiktku-start-narrow" : "")) .attr("placeholder", g.label + "…"); firstInput.on("input", function () { steps.dfn.onSubInput(list, this, g.rows, g.narrow); }); list.append($("<li></li>").append(firstInput)); groupDiv.append(lbl).append(list); block.append(groupDiv); } }); // — Jêder (quote / citation) group — a growing list, sibling to Nimûne — // Structured the same way as Nimûne (ol.wiktku-dfn-sublist > li) so it // lines up at the same indentation, and so that typing into the last // citation's Jêgirtin box automatically opens a fresh empty one below it. (function () { var jederGroupDiv = $("<div></div>").addClass("wiktku-dfn-subgroup wiktku-dfn-jeder-group"); var jederLbl = $("<span></span>").addClass("wiktku-dfn-sublabel").text("Jêgirtin: "); var jederList = $("<ol></ol>").addClass("wiktku-dfn-sublist wiktku-dfn-jeder-list"); function buildJederLi() { var lang = getValues().lang || ""; var li = $("<li></li>").addClass("wiktku-dfn-jeder-li"); var dragHandle = $("<span></span>") .addClass("wiktku-jeder-drag-handle") .attr("title", "Bişkûne û bikişîne da ku rêzê biguhezîne") .html("⠿"); // Quote text textarea var quoteTa = $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-quote-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 2) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-quote") .attr("placeholder", "Nimûneya emilandinê ji kitêb an çavkaniyeke din binivîse"); quoteTa.on("input", function () { var val = $.trim($(this).val()); var isLast = li.is(jederList.children("li:last-child")); if (val && isLast) { jederList.append(buildJederLi()); } }); li.append(dragHandle).append(quoteTa); // tr/t sub-fields for the quote — shown as needed for the language. var quoteSubWrap = $("<div></div>").addClass("wiktku-dfn-quote-sub"); if (needsTransliteration(lang)) { quoteSubWrap.append( $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-quote-tr-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 2) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-quote-tr") .attr("placeholder", "Transkrîpsiyona jêgirtinê…") ); } if (lang && lang !== "ku") { quoteSubWrap.append( $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-quote-t-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 2) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-quote-t") .attr("placeholder", "Tercimeya jêgirtinê bi kurmancî") ); } if (quoteSubWrap.children().length) li.append(quoteSubWrap); // Citoid auto-fill: fetch citation data from a URL, DOI or ISBN and // prefill the source şablon + fields below (see Gadget-citoid-helper.js). var citoidWrap = $("<div></div>").addClass("wiktku-dfn-quote-citoid"); var citoidInput = $("<input type='text'>") .addClass("wiktku-dfn-quote-citoid-input wiktku-start-narrow") .attr("placeholder", "URL, DOI an ISBN binivîse ku otomatîk were tijekirin…"); var citoidBtn = new OO.ui.ButtonWidget({ label: "Bi Citoid bîne", classes: [ "wiktku-dfn-quote-citoid-btn" ] }); var citoidStatus = $("<span></span>").addClass("wiktku-dfn-quote-citoid-status"); /** * Fetches citation data from Citoid and applies it to this * citation's şablon selector + fields. Mirrors the logic in * Form.prototype._fillFromCitoid (Gadget-wikt.add-examples.js): * - only (re)selects the şablon when it actually differs from * what's already chosen, so a repeat fetch doesn't wipe out * a template the user already picked; * - only fills fields that are currently empty, so it never * overwrites something the user typed by hand; * - falls back to the freeform "bi destê xwe binivîsim" source * only when nothing was typed there yet. */ function runCitoidFetch() { var query = $.trim(citoidInput.val()); if (!query) { mw.notify("Ji kerema xwe re pêşî URL, DOI an ISBNyekê binivîse."); return; } citoidBtn.setDisabled(true); citoidStatus.text("Tê anîn…"); wikt.citoidHelper.ensure().then(function () { return wikt.citoid.fetchJederFields(query); }).then(function (result) { var jederKey = result.jederKey; var hasTpl = !!jederKey && srcSel.find("option[value='" + jederKey + "']").length > 0; var targetVal = hasTpl ? jederKey : "__manual__"; // Only (re)select — and thus rebuild — the field rows if // we're switching to a different şablon than what's // already chosen, so a second fetch doesn't clear fields // the user already filled in by hand. if (srcSel.val() !== targetVal) { srcSel.val(targetVal).trigger("change"); srcSel.trigger("chosen:updated"); } if (hasTpl) { // Tenê qadên vala tijî bike. $.each(result.fields, function (key, val) { var input = srcFields.find("input[data-field-key='" + key + "']"); if (input.length && !$.trim(input.val())) { input.val(val); } }); } else { // Şablonek nehat naskirin ji bo vê itemType — rêzikeke // çavkaniyê ya bi destan a ji qadên Citoid tê çêkirin, // lê tenê ger qada destan vala be. var manualField = srcFields.find(".wiktku-dfn-quote-src-manual"); if (!$.trim(manualField.val())) { var parts = []; $.each(["nivîskar", "sernav", "websîte", "kovar", "weşanxane", "sal", "url"], function (_, k) { if (result.fields[k]) parts.push(result.fields[k]); }); manualField.val(parts.join(", ")); } } citoidStatus.text(""); }, function (errorMsg) { citoidStatus.text(typeof errorMsg === "string" ? errorMsg : "Nehat dîtin. Kontrol bike ka URL/DOI/ISBN rast e."); }).always(function () { citoidBtn.setDisabled(false); }); } citoidBtn.on("click", runCitoidFetch); citoidInput.on("keydown", function (e) { if (e.which === 13) { // Enter e.preventDefault(); runCitoidFetch(); } }); citoidWrap.append(citoidInput).append(citoidBtn.$element).append(citoidStatus); // Source template selector, specific to this citation. var srcSel = $("<select></select>").addClass("wiktku-dfn-quote-src-sel"); srcSel.append($("<option value=''>— Çavkaniyê hilbijêre —</option>")); srcSel.append($("<option></option>").val("__manual__").text("Bi destê xwe binivîsim")); var jederDefs = steps.dfn.jederDefs || {}; $.each(jederDefs, function (tplName, def) { srcSel.append($("<option></option>").val(tplName).text(def.label)); }); // Dynamic source fields container. var srcFields = $("<div></div>").addClass("wiktku-dfn-quote-src-fields"); srcSel.on("change", function () { srcFields.empty(); var chosen = $(this).val(); if (!chosen) return; if (chosen === "__manual__") { // Freeform source, written by the user — becomes the 2nd // positional param of {{jêder|lang|…}} instead of çavkanî?. srcFields.append( $("<textarea></textarea>") .attr("rows", 4) .addClass("wiktku-dfn-subfield wiktku-dfn-quote-src-manual") .attr("placeholder", "Çavkaniyê bi destê xwe binivîse…") ); return; } var def = (steps.dfn.jederDefs || {})[chosen]; if (!def) return; $.each(def.fields, function (_, f) { var row = $("<div></div>").addClass("wiktku-dfn-quote-src-row"); var fieldLbl = $("<label></label>").text(f.label + ": "); var inp = $("<input type='text'>") .addClass("wiktku-dfn-quote-src-input wiktku-start-narrow") .attr("data-field-key", f.key) .attr("placeholder", f.label + "…"); row.append(fieldLbl).append(inp); srcFields.append(row); }); }); li.append(citoidWrap).append(srcSel).append(srcFields); return li; } jederGroupDiv.data("buildJederLi", buildJederLi); jederList.append(buildJederLi()); // Make citation rows sortable (drag to reorder). // The last row is always the empty trailing row — cancel its drag. mw.loader.using("jquery.ui.sortable", function () { jederList.sortable({ handle: ".wiktku-jeder-drag-handle", axis: "y", items: "li:not(:last-child)", tolerance: "pointer" }); }); jederGroupDiv.append(jederLbl).append(jederList); block.append(jederGroupDiv); }()); // Apply the initial hide/show state for the sub-groups (matches // tplSelect's starting value, which is normally empty). updateFieldVisibility(); return block; }, /** Grows the sense list when the last mane textarea gets content. */ onDfnInput: function (stepDiv, block, textarea) { var val = $.trim($(textarea).val()); var list = stepDiv.find("ol.wiktku-dfn-list"); var isLast = block.is(list.children("li:last-child")); if (val && isLast) { var newBlock = steps.dfn.buildSenseBlock(stepDiv); list.append(newBlock); // Apply Chosen to the new block's template selector on desktop. if (!isMobile) newBlock.find("select.wiktku-dfn-tpl-select").chosen(chosenOptions); } refresh(); }, /** Grows a sub-list (nimûne/formên alternatîv/hevmane/dijmane/termên koordîne) on input. */ onSubInput: function (list, input, rows, narrow) { var val = $.trim($(input).val()); var item = $(input).parent(); var isLast = item.is(list.children("li:last-child")); if (val && isLast) { var next = $("<textarea></textarea>") .attr("name", "wiktku-dfn-sub-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", rows) .attr("class", "wiktku-dfn-subfield" + (narrow ? " wiktku-start-narrow" : "")); next.on("input", function () { steps.dfn.onSubInput(list, this, rows, narrow); }); list.append($("<li></li>").append(next)); } }, // Populated from [[MediaWiki:Gadget-start.js/data.json]] (tplDefs, posExamples, jederDefs). tplDefs: [], posExamples: {}, jederDefs: {}, build: function (stepDiv) { if (stepDiv.find("ol.wiktku-dfn-list").length) return null; var list = $("<ol class='wiktku-dfn-list'></ol>"); list.append(steps.dfn.buildSenseBlock(stepDiv)); stepDiv.append(list); return null; }, /** Reads all sense blocks from the DOM and returns an array of sense objects. */ getSenses: function (stepDiv) { var senses = []; stepDiv.find("li.wiktku-dfn-sense").each(function () { var block = $(this); var tplSel = block.find("select.wiktku-dfn-tpl-select"); var tpl = tplSel.val() || ""; // noLang: template already encodes the language — don't add |lang| param. var tplNoLang = tpl ? tplSel.find("option[value='" + tpl + "']").attr("data-nolang") === "1" : false; var tplTitle = $.trim(block.find("input.wiktku-dfn-tpl-title").val()); var mane = $.trim(block.find("textarea.wiktku-dfn-mane").val()); var etiket = (function () { var vals = []; block.find(".wiktku-dfn-etiket-list textarea").each(function () { var v = $.trim($(this).val()); if (v) vals.push(v); }); return vals; }()); function readList(cls) { var vals = []; block.find("." + cls + "-list textarea").each(function () { var v = $.trim($(this).val()); if (v) vals.push(v); }); return vals; } // Nimûne items are compound: { text, tr?, t? } function readNimuneList() { var items = []; block.find(".wiktku-dfn-nimune-list li.wiktku-dfn-nimune-li").each(function () { var text = $.trim($(this).find(".wiktku-dfn-nimune-text").val()); if (!text) return; var obj = { text: text }; var tr = $.trim($(this).find(".wiktku-dfn-nimune-tr").val()); var t = $.trim($(this).find(".wiktku-dfn-nimune-t").val()); if (tr) obj.tr = tr; if (t) obj.t = t; items.push(obj); }); return items; } // Jêder is a growing list of citations, one per li — mirrors readNimuneList(). function readJederList() { var items = []; block.find(".wiktku-dfn-jeder-list li.wiktku-dfn-jeder-li").each(function () { var li = $(this); var quote = $.trim(li.find(".wiktku-dfn-nimune-quote").val()); if (!quote) return; var obj = { quote: quote }; var qtr = $.trim(li.find(".wiktku-dfn-nimune-quote-tr").val()); var qt = $.trim(li.find(".wiktku-dfn-nimune-quote-t").val()); if (qtr) obj.quoteTr = qtr; if (qt) obj.quoteT = qt; var tplName = li.find(".wiktku-dfn-quote-src-sel").val(); if (tplName === "__manual__") { var manual = $.trim(li.find(".wiktku-dfn-quote-src-manual").val()); if (manual) obj.jederManual = manual; } else if (tplName) { obj.jederTpl = tplName; var fields = {}; li.find(".wiktku-dfn-quote-src-input").each(function () { var k = $(this).attr("data-field-key"); var v = $.trim($(this).val()); if (k && v) fields[k] = v; }); obj.jêderFields = fields; } items.push(obj); }); return items; } senses.push({ tpl: tpl, tplNoLang: tplNoLang, tplTitle: tplTitle, mane: mane, etiket: etiket, nimune: readNimuneList(), jeder: readJederList(), alternativ: readList("wiktku-dfn-alternativ"), hevmane: readList("wiktku-dfn-hevmane"), dijmane: readList("wiktku-dfn-dijmane"), koordine: readList("wiktku-dfn-koordine"), jornav: readList("wiktku-dfn-jornav"), jernav: readList("wiktku-dfn-jernav") }); }); return senses; }, getOutput: function (values, callback) { var stepDiv = $("#wiktku-start-dfn"); var senses = steps.dfn.getSenses(stepDiv); var lang = values.lang; // A sense counts as "filled" if it has a mane, a chosen template + title, // or any other content (etîket/hevmane/nimûne/jêder…) worth keeping. var hasMane = senses.some(function (s) { return s.mane !== "" || (s.tpl && s.tplTitle) || senseHasExtraContent(s); }); // True only when at least one sense has a regular mane (needs linkify). var hasRegularMane = senses.some(function (s) { return !s.tpl && s.mane !== ""; }); var text = $.map(senses, function (sense) { // — Template sense (e.g. {{guharto|ku|somepage}} or {{ku-Latn|somepage}}) — if (sense.tpl) { if (!sense.tplTitle) return undefined; // Etîket still applies to a şablon sense — build the same // {{e|lang|label1|label2}} prefix as a regular sense would get. var tplLabelTpl = ""; if (sense.etiket && sense.etiket.length) { var tplLabelParts = sense.etiket.map(function (part) { return $.trim(part); }).filter(function (part) { return part !== ""; }); if (tplLabelParts.length) { tplLabelTpl = " {{e|" + lang + "|" + tplLabelParts.join("|") + "}} "; } } // noLang templates encode the language in their name — omit the |lang| param. var tplCall = sense.tplNoLang ? "{{" + sense.tpl + "|" + sense.tplTitle + "}}" : "{{" + sense.tpl + "|" + lang + "|" + sense.tplTitle + "}}"; var tplLine = "#" + (tplLabelTpl ? tplLabelTpl : " ") + tplCall; // Nimûne / Jêder still apply to a şablon sense too. var tplHasJeder = sense.jeder && $.grep(sense.jeder, function (j) { return j && j.quote; }).length > 0; tplLine += formatNimune(sense.nimune, lang, tplHasJeder); tplLine += formatJeder(sense.jeder, lang); return tplLine; } // — Normal mane sense — var dfn = sense.mane; // A sense with no mane text AND nothing else filled in is // truly empty — drop it. If it has other content (etîket, // hevmane, nimûne, jêder…), keep it and use {{mane?}} as // a stand-in for the missing gloss instead of discarding // everything the user entered. if (!dfn && !senseHasExtraContent(sense)) return undefined; if (dfn) { // Strip any wikilinks the user may have typed before // linkify processes the text — avoids double-linking. dfn = stripWikilinks(dfn); // Capitalize and punctuate. if (dfn[0] !== dfn[0].toUpperCase()) dfn = capitalize(dfn); if (!dfn.match(/[.…?!)\]]$/)) dfn += "."; } else { dfn = "{{mane?|" + lang + "}}"; } // {{e|lang|label1|label2}} var labelTpl = ""; if (sense.etiket && sense.etiket.length) { var labelParts = sense.etiket.map(function (part) { return $.trim(part); }).filter(function (part) { return part !== ""; }); if (labelParts.length) { labelTpl = " {{e|" + lang + "|" + labelParts.join("|") + "}} "; } } var out = "#" + (labelTpl ? labelTpl : " ") + dfn; // Per-sense word lists as #: template lines. function wordLine(tpl, words) { if (!words.length) return ""; return "\n#: {{" + tpl + "|" + lang + "|" + words.join("|") + "}}"; } out += wordLine("alt-r", sense.alternativ); out += wordLine("hevmane", sense.hevmane); out += wordLine("dijmane", sense.dijmane); out += wordLine("koordîne", sense.koordine); out += wordLine("jornav", sense.jornav); out += wordLine("jêrnav", sense.jernav); // Nimûne lines — always last, unless a jêder citation already covers it. var hasJeder = sense.jeder && $.grep(sense.jeder, function (j) { return j && j.quote; }).length > 0; out += formatNimune(sense.nimune, lang, hasJeder); // Jêder (quote/citation) — after nimune. out += formatJeder(sense.jeder, lang); return out; }).join("\n") + "\n"; if (!hasMane) { // No definitions entered — emit {{mane?}} with bênimûne. text = "# {{mane?|" + lang + "}}\n#* {{bênimûne|" + lang + "}}\n"; callback(text); return; } if (!hasRegularMane) { // All filled senses are template senses — no linkify needed. callback(text); return; } var didTryToLoad = function () { // If the module failed to load, $.wiktviLinkify won't exist — // fall back to the unlinkified text instead of throwing. if (typeof $.wiktviLinkify === "function") { $.wiktviLinkify(text, callback); } else { callback(text); } }; mw.loader.using("ext.gadget.linkify", didTryToLoad, didTryToLoad); } }, je: makeWordListStep("je", "jê", "Kelîmeyên jê çêbûyî binivîse", "Jê", "g"), tekildar: makeWordListStep("tekildar", "têkildar", "Kelîmeyên ji aliyê etîmolojiyê ve têkildarî vê kelîmeyê binivîse", "Têkildar", "g"), binereherwiha: makeWordListStep("binereherwiha", "binêre herwiha", "Kelîmeyên din ên eleqedar binivîse", "Binêre herwiha", "g"), etym: { id: "etym", name: "etîmolojî", question_fmt: "Etîmolojiya kelîmeyê binivîse", // etymTpls populated from data.json etymTpls: [], visible: function (values) { return values.lang && values.pos; }, /** Fills (or refills) the insert-dropdown from the current etymTpls array. */ refreshTplSelect: function () { var sel = $("#wiktku-start-etym .wiktku-tpl-insert-select"); if (!sel.length) return; sel.find("option[value!='']").remove(); $.each(steps.etym.etymTpls, function (_, tpl) { sel.append($("<option></option>").val(tpl.snippet).text(tpl.name + " — " + tpl.desc)); }); // Notify Chosen that the option list has changed (no-op on mobile). if (!isMobile) sel.trigger("chosen:updated"); }, build: function (stepDiv) { if (stepDiv.find(".wiktku-etym-wrap").length) return null; var wrap = $("<div class='wiktku-etym-wrap'></div>"); var ta = $("<textarea></textarea>") .attr("name", "wiktku-etym-" + $.now()) .attr("class", "wiktku-start-step-field wiktku-etym-text") .attr("rows", 4) .attr("placeholder", "Nimûne: Ji {{ji|en|ku|apple}}. yan rasterast binivîse…"); // Template insert dropdown — options also refreshed after data.json loads. var sel = $("<select class='wiktku-tpl-insert-select'></select>"); sel.append($("<option value=''>— şablonek lê zêde bike —</option>")); $.each(steps.etym.etymTpls, function (_, tpl) { sel.append($("<option></option>").val(tpl.snippet).text(tpl.name + " — " + tpl.desc)); }); sel.on("change", function () { var snippet = $(this).val(); if (!snippet) return; var lang = getValues().lang || ""; snippet = snippet.replace(/CODE/g, lang).replace(/SOURCELANG/g, "?"); insertAtCursor(ta[0], snippet); $(this).val(""); ta.focus(); }); wrap.append(sel).append($("<br>")).append(ta); stepDiv.append(wrap); return ta; }, output: function (values) { var text = $.trim($("#wiktku-start-etym .wiktku-etym-text").val()); if (text) { return "\n==== Etîmolojî ====\n" + text + "\n"; } // No etymology entered — emit {{ji?|lang}} as a placeholder, // but only when the entry has at least one regular (non-şablon) // sense with content — either real mane text, or an empty mane // with other fields filled in (which dfn.getOutput() renders as // {{mane?|lang}} with those fields attached). A şablon sense // like {{guharto|…}} never counts, filled in or not. var dfnSenses = steps.dfn.getSenses($("#wiktku-start-dfn")); var hasRegularMane = dfnSenses.some(function (s) { return !s.tpl && (s.mane !== "" || senseHasExtraContent(s)); }); if (!hasRegularMane) return ""; return "\n==== Etîmolojî ====\n{{ji?|" + values.lang + "}}\n"; } }, dunde: { id: "dunde", name: "dûnde", question_fmt: "Eger ev kelîme ji vî zimanî ketibe zimanekî din, vî zimanî û kelîmeya wî binivîse", visible: function (values) { return !!values.pos; }, disabledKeys: { "navz": true}, /** * Builds one row: a language dropdown + a growing list of word * inputs. When the dropdown gets a value the next empty row is * appended automatically. Mirrors steps.trans's row widget, but * flat (one shared list — dûnde isn't tied to individual senses). */ buildRow: function (stepDiv) { var row = $("<li class='wiktku-dunde-row wiktku-lang-row'></li>"); // Language selector — chosen is applied after insertion into DOM. var langSel = $(mw.html.element("select", { "class": "wiktku-start-step-keyfield wiktku-start-narrow" })); langSel.attr("data-placeholder", "Zimanekî lê bigere"); populateMenus(langSel, steps.dunde.keys || [], steps.dunde.disabledKeys); // When a language is chosen, ensure a next empty row exists. langSel.on("change", function () { steps.dunde.onLangChange(stepDiv, row); }); // Word list for this language. var wordList = $("<ul class='wiktku-dunde-words wiktku-lang-row-words'></ul>"); var firstWord = steps.dunde.makeWordInput(); wordList.append($("<li></li>").append(firstWord)); if (isMobile) { row.append(wrapNativeSelect(langSel)).append(wordList); } else { row.append(langSel).append(wordList); } return row; }, makeWordInput: function () { var input = $("<textarea></textarea>") .attr("name", "wiktku-dunde-word-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 1) .attr("class", "wiktku-dfn-subfield wiktku-start-narrow") .attr("placeholder", "Kelîme…"); input.on("input", function () { var list = $(this).closest("ul.wiktku-dunde-words"); var item = $(this).parent(); var val = $.trim($(this).val()); if (val && item.is(list.children("li:last-child"))) { var next = steps.dunde.makeWordInput(); list.append($("<li></li>").append(next)); } }); return input; }, onLangChange: function (stepDiv, row) { var list = stepDiv.find("ul.wiktku-dunde-list"); var isLast = row.is(list.children("li.wiktku-dunde-row:last-child")); if (isLast) { var newRow = steps.dunde.buildRow(stepDiv); list.append(newRow); // Init chosen after the new row is in the DOM (desktop only). if (!isMobile) newRow.find("select").chosen(chosenOptions); } // Keep disabled keys in sync across all lang selectors. steps.dunde.syncDisabledKeys(stepDiv); }, /** Disables already-selected languages in all other dropdowns. */ syncDisabledKeys: function (stepDiv) { var taken = $.extend({}, steps.dunde.disabledKeys); stepDiv.find("li.wiktku-dunde-row select").each(function () { var v = $(this).val(); if (v) taken[v] = true; }); stepDiv.find("li.wiktku-dunde-row select").each(function () { var self = $(this); var own = self.val(); self.find("option").each(function () { var code = $(this).val(); if (!code) return; $(this).prop("disabled", taken[code] && code !== own); }); self.trigger("chosen:updated"); }); }, build: function (stepDiv) { if (stepDiv.find("ul.wiktku-dunde-list").length) return null; var list = $("<ul class='wiktku-dunde-list wiktku-lang-row-list'></ul>"); list.append(steps.dunde.buildRow(stepDiv)); stepDiv.append(list); // Init chosen after the select is in the DOM (desktop only). if (!isMobile) list.find("select").chosen(chosenOptions); return null; }, /** Reads all [langcode, words[]] rows from the DOM. */ getRows: function (stepDiv) { var result = []; stepDiv.find("li.wiktku-dunde-row").each(function () { var lang = $(this).find("select").val(); if (!lang) return; var words = []; $(this).find("ul.wiktku-dunde-words textarea").each(function () { var v = $.trim($(this).val()); if (v) words.push(v); }); if (words.length) result.push([lang, words]); }); return result; }, output: function () { var stepDiv = $("#wiktku-start-dunde"); var rows = steps.dunde.getRows(stepDiv); if (!rows.length) return ""; var lines = $.map(rows, function (row) { var lang = row[0], words = row[1]; return "* {{dû|" + lang + "|" + words.join("|") + "}}"; }); return "\n==== Dûnde ====\n" + lines.join("\n") + "\n"; } }, zarava: { id: "zarava", name: "bi zaravayên din", visible: function (values) { return steps.trans.visible(values); }, disabledKeys: { "navz": true }, buildRow: function (group) { var row = $("<li class='wiktku-zarava-row wiktku-lang-row'></li>"); var langSel = $(mw.html.element("select", { "class": "wiktku-start-step-keyfield wiktku-start-narrow" })); populateMenus(langSel, steps.zarava.keys || [], steps.zarava.disabledKeys); langSel.on("change", function () { steps.zarava.onLangChange(group, row); }); var wordList = $("<ul class='wiktku-zarava-words wiktku-lang-row-words'></ul>"); var firstWord = steps.zarava.makeWordInput(); wordList.append($("<li></li>").append(firstWord)); row.append(langSel).append(wordList); return row; }, makeWordInput: function () { var input = $("<textarea></textarea>") .attr("name", "wiktku-zarava-word-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 1) .attr("class", "wiktku-dfn-subfield wiktku-start-narrow") .attr("placeholder", "Tercime…"); input.on("input", function () { var list = $(this).closest("ul.wiktku-zarava-words"); var item = $(this).parent(); var val = $.trim($(this).val()); if (val && item.is(list.children("li:last-child"))) { var next = steps.zarava.makeWordInput(); list.append($("<li></li>").append(next)); } }); return input; }, onLangChange: function (group, row) { var list = group.find("ul.wiktku-zarava-list"); var isLast = row.is(list.children("li.wiktku-zarava-row:last-child")); if (isLast) { var newRow = steps.zarava.buildRow(group); list.append(newRow); } steps.zarava.syncDisabledKeys(group); }, /** Disables already-selected dialects in all other dropdowns within one group. */ syncDisabledKeys: function (group) { var taken = $.extend({}, steps.zarava.disabledKeys); group.find("li.wiktku-zarava-row select").each(function () { var v = $(this).val(); if (v) taken[v] = true; }); group.find("li.wiktku-zarava-row select").each(function () { var self = $(this); var own = self.val(); self.find("option").each(function () { var code = $(this).val(); if (!code) return; $(this).prop("disabled", taken[code] && code !== own); }); }); }, /** Builds (or fetches) the .wiktku-zarava-group for one gloss. */ buildGroup: function (stepDiv, gi) { var group = $("<div class='wiktku-zarava-group'></div>").attr("data-gloss-pos", gi); var list = $("<ul class='wiktku-zarava-list wiktku-lang-row-list'></ul>"); list.append(steps.zarava.buildRow(group)); group.append(list); stepDiv.append(group); return group; }, /** Syncs one .wiktku-zarava-group per current gloss (same logic as steps.trans.build). */ build: function (stepDiv) { var glosses = steps.trans.glossList(); if (!glosses.length) { stepDiv.find(".wiktku-zarava-group").remove(); return null; } var existingGroups = stepDiv.find(".wiktku-zarava-group"); if (existingGroups.length > glosses.length) { existingGroups.slice(glosses.length).remove(); } $.each(glosses, function (gi, gloss) { var group = stepDiv.find(".wiktku-zarava-group[data-gloss-pos='" + gi + "']"); if (!group.length) group = steps.zarava.buildGroup(stepDiv, gi); var label = group.find(".wiktku-zarava-group-label"); if (glosses.length > 1) { if (!label.length) { label = $("<div class='wiktku-zarava-group-label'></div>"); group.prepend(label); } label.text(gloss.index + " " + gloss.text); } else if (label.length) { label.remove(); } }); return null; }, /** Reads the dialect rows for a single gloss group. */ getGroupTranslations: function (group) { var result = []; group.find("li.wiktku-zarava-row").each(function () { var lang = $(this).find("select").val(); if (!lang) return; var words = []; $(this).find("ul.wiktku-zarava-words textarea").each(function () { var v = $.trim($(this).val()); if (v) words.push(v); }); if (words.length) result.push([lang, words]); }); return result; }, /** Reads all rows from the DOM, grouped by gloss position. */ getTranslations: function (stepDiv) { var result = []; stepDiv.find(".wiktku-zarava-group").each(function () { result.push(steps.zarava.getGroupTranslations($(this))); }); return result; }, output: function (values) { if (values.lang !== "ku") return ""; var stepDiv = $("#wiktku-start-zarava"); var glosses = steps.trans.glossList(); if (!glosses.length) return ""; var blocks = $.map(glosses, function (gloss, gi) { var group = stepDiv.find(".wiktku-zarava-group[data-gloss-pos='" + gi + "']"); var rows = group.length ? steps.zarava.getGroupTranslations(group) : []; if (!gloss.text && !rows.length) return undefined; if (rows.length) { rows.sort(function (a, b) { var aLang = langsByCode[a[0]] || []; var bLang = langsByCode[b[0]] || []; return (aLang[2] || "").localeCompare(bLang[2] || "", "ku"); }); } var wordLines = $.map(rows, function (row) { var lang = row[0]; var words = row[1]; var wikiWords = words.map(function (w) { return "{{W|" + lang + "|" + w + "}}"; }).join(", "); return "* {{Z|" + lang + "}}: " + wikiWords; }).join("\n"); if (!wordLines) return undefined; var block = "{{werger-ser|" + (gloss.text || "?") + "|" + gloss.index + "}}"; block += "\n" + wordLines; block += "\n{{werger-bin}}"; return block; }); if (!blocks.length) return ""; return "\n==== Bi zaravayên din ====\n" + blocks.join("\n") + "\n"; } }, trans: { id: "trans", name: "werger", visible: function (values) { if (!(values.lang === "ku" && values.pos)) return false; // Hide Werger only when EVERY sense is a template sense (Guharto etc.) // with a title filled in — i.e. there is real content but no plain // gloss to attach a translation table to. A mix of real + template // senses still shows Werger; the template senses are simply skipped // in output(). // // "Real" here means a non-şablon sense with either mane text or // other filled-in fields (etîket/hevmane/nimûne/jêder…), since // dfn.getOutput() renders the latter too, as {{mane?|lang}} plus // whatever else was filled in. // // When nothing has been filled in at all, output() will emit // {{mane?|lang}} instead of a gloss — but Werger should still show, // since the user may want to add translations before they've // settled on a gloss. var dfnSenses = steps.dfn.getSenses($("#wiktku-start-dfn")); var hasRealSense = dfnSenses.some(function (s) { return !s.tpl && (s.mane !== "" || senseHasExtraContent(s)); }); var hasFilledTplSense = dfnSenses.some(function (s) { return s.tpl && s.tplTitle; }); return hasRealSense || !hasFilledTplSense; }, disabledKeys: { "navz": true, "ku": true, "ckb": true, "sdh": true, "lki": true, "hac": true, "zza": true }, /** * Builds one translation row: a language dropdown + a growing list * of word inputs. When the dropdown gets a value the next empty row * is appended automatically. * * @param group the specific .wiktku-trans-group this row belongs to * (each gloss has its own group and its own list of rows, so the * lookups below must stay scoped to that group rather than the * whole step — the step now holds one list per gloss). */ buildRow: function (group) { var row = $("<li class='wiktku-trans-row wiktku-lang-row'></li>"); // Language selector — chosen is applied after insertion into DOM. var langSel = $(mw.html.element("select", { "class": "wiktku-start-step-keyfield wiktku-start-narrow" })); langSel.attr("data-placeholder", "Zimanekî lê bigere"); populateMenus(langSel, steps.trans.keys || [], steps.trans.disabledKeys); // When a language is chosen, ensure a next empty row exists. langSel.on("change", function () { steps.trans.onLangChange(group, row); }); // Word list for this language. var wordList = $("<ul class='wiktku-trans-words wiktku-lang-row-words'></ul>"); var firstWord = steps.trans.makeWordInput(); wordList.append($("<li></li>").append(firstWord)); if (isMobile) { row.append(wrapNativeSelect(langSel)).append(wordList); } else { row.append(langSel).append(wordList); } return row; }, makeWordInput: function () { var input = $("<textarea></textarea>") .attr("name", "wiktku-trans-word-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 1) .attr("class", "wiktku-dfn-subfield wiktku-start-narrow") .attr("placeholder", "Tercime…"); input.on("input", function () { var list = $(this).closest("ul.wiktku-trans-words"); var item = $(this).parent(); var val = $.trim($(this).val()); if (val && item.is(list.children("li:last-child"))) { var next = steps.trans.makeWordInput(); list.append($("<li></li>").append(next)); } }); return input; }, onLangChange: function (group, row) { var list = group.find("ul.wiktku-trans-list"); var isLast = row.is(list.children("li.wiktku-trans-row:last-child")); if (isLast) { var newRow = steps.trans.buildRow(group); list.append(newRow); // Init chosen after the new row is in the DOM (desktop only). if (!isMobile) newRow.find("select").chosen(chosenOptions); } // Keep disabled keys in sync across this gloss's lang selectors // only — the same language can be used for different senses. steps.trans.syncDisabledKeys(group); }, /** Disables already-selected languages in all other dropdowns within one group. */ syncDisabledKeys: function (group) { var taken = $.extend({}, steps.trans.disabledKeys); group.find("li.wiktku-trans-row select").each(function () { var v = $(this).val(); if (v) taken[v] = true; }); group.find("li.wiktku-trans-row select").each(function () { var self = $(this); var own = self.val(); self.find("option").each(function () { var code = $(this).val(); if (!code) return; $(this).prop("disabled", taken[code] && code !== own); }); self.trigger("chosen:updated"); }); }, /** * Builds (or fetches) the .wiktku-trans-group for one gloss, with * its own label and its own list of translation rows. */ buildGroup: function (stepDiv, gi) { var group = $("<div class='wiktku-trans-group'></div>").attr("data-gloss-pos", gi); var list = $("<ul class='wiktku-trans-list wiktku-lang-row-list'></ul>"); list.append(steps.trans.buildRow(group)); group.append(list); stepDiv.append(group); // Init chosen after the select is in the DOM (desktop only). if (!isMobile) list.find("select").chosen(chosenOptions); return group; }, /** * Syncs one .wiktku-trans-group per current gloss, adding new * groups and removing stale ones as senses are added or removed, * while leaving existing groups (and whatever translations the * user has already typed into them) untouched. Groups are keyed * to their gloss's position in glossList() via data-gloss-pos, so * a group always matches the same sense across rebuilds as long * as senses aren't reordered relative to each other. */ build: function (stepDiv) { var glosses = steps.trans.glossList(); if (!glosses.length) { stepDiv.find(".wiktku-trans-group").remove(); return null; } // Drop groups for glosses that no longer exist (always from the // tail — groups are only ever appended in gloss order below). var existingGroups = stepDiv.find(".wiktku-trans-group"); if (existingGroups.length > glosses.length) { existingGroups.slice(glosses.length).remove(); } $.each(glosses, function (gi, gloss) { var group = stepDiv.find(".wiktku-trans-group[data-gloss-pos='" + gi + "']"); if (!group.length) group = steps.trans.buildGroup(stepDiv, gi); // Only label groups when there's more than one gloss to // distinguish between — a single gloss needs no caption. var label = group.find(".wiktku-trans-group-label"); if (glosses.length > 1) { if (!label.length) { label = $("<div class='wiktku-trans-group-label'></div>"); group.prepend(label); } label.text(gloss.index + " " + gloss.text); } else if (label.length) { label.remove(); } }); return null; }, /** Reads the translation rows for a single gloss group. */ getGroupTranslations: function (group) { var result = []; group.find("li.wiktku-trans-row").each(function () { var lang = $(this).find("select").val(); if (!lang) return; var words = []; $(this).find("ul.wiktku-trans-words textarea").each(function () { var v = $.trim($(this).val()); if (v) words.push(v); }); if (words.length) result.push([lang, words]); }); return result; }, /** * Reads all translation rows from the DOM, grouped by gloss * position — one array of [lang, words] rows per gloss group, in * the same order as the .wiktku-trans-group elements. */ getTranslations: function (stepDiv) { var result = []; stepDiv.find(".wiktku-trans-group").each(function () { result.push(steps.trans.getGroupTranslations($(this))); }); return result; }, /** * Builds the numbered "{ index, gloss }" list — one entry per dfn * sense that has a real mane (skips template senses like Guharto, * which have nothing to caption a translation table with). The * index matches the sense's actual position in the numbered "#" * definition list (1-based), including template senses in the count, * so the number printed next to {{werger-ser}} lines up with the * gloss the reader sees in the entry. * * When nothing has been filled in at all (dfn.getOutput() will emit * {{mane?|lang}} as sense 1), this returns a single placeholder * entry with empty text instead of an empty array, so Werger still * has one group to attach translations to before a gloss exists. * When every filled sense is a template sense instead, this stays * empty — that mirrors trans.visible()'s hidden case, where there's * no group in the DOM for a placeholder to attach to anyway. */ glossList: function () { var dfnSenses = steps.dfn.getSenses($("#wiktku-start-dfn")); var glosses = []; var hasFilledTplSense = false; $.each(dfnSenses, function (i, s) { if (s.tpl) { if (s.tplTitle) hasFilledTplSense = true; return; // template sense — no gloss to caption with } var dfn = s.mane; if (!dfn) { // No mane text, but other fields (etîket/hevmane/nimûne/ // jêder…) are filled — dfn.getOutput() still emits this // sense as a numbered line using {{mane?|lang}}, so it // needs its own gloss group too, just with no caption text. if (senseHasExtraContent(s)) glosses.push({ index: i + 1, text: "" }); return; } if (dfn[0] !== dfn[0].toLowerCase()) dfn = decapitalize(dfn); dfn = stripWikilinks(dfn).replace(/[.…?!)\]،؟]+$/, ""); glosses.push({ index: i + 1, text: dfn }); }); if (!glosses.length && !hasFilledTplSense) { glosses.push({ index: 1, text: "" }); } return glosses; }, output: function (values) { if (values.lang !== "ku") return ""; var stepDiv = $("#wiktku-start-trans"); var glosses = steps.trans.glossList(); // Every sense is a template sense — there's no real gloss // anywhere and no group in the DOM either (glossList() only // returns empty in that case), so skip the section entirely. if (!glosses.length) return ""; // Each gloss now has its own group of translation rows — // attach every gloss's own words under its own werger-ser/-bin // pair instead of dumping everything under the first one. var blocks = $.map(glosses, function (gloss, gi) { var group = stepDiv.find(".wiktku-trans-group[data-gloss-pos='" + gi + "']"); var rows = group.length ? steps.trans.getGroupTranslations(group) : []; // Placeholder gloss (no real mane entered yet) with nothing // translated into it — nothing to output, and gloss.text is // empty so there's no caption to give {{werger-ser}} anyway. if (!gloss.text && !rows.length) return undefined; if (rows.length) { // Sort by Kurdish sort key. rows.sort(function (a, b) { var aLang = langsByCode[a[0]] || []; var bLang = langsByCode[b[0]] || []; return (aLang[2] || "").localeCompare(bLang[2] || "", "ku"); }); } var wordLines = $.map(rows, function (row) { var lang = row[0]; var words = row[1]; var wikiWords = words.map(function (w) { return "{{W|" + lang + "|" + w + "}}"; }).join(", "); return "* {{Z|" + lang + "}}: " + wikiWords; }).join("\n"); var block = "{{werger-ser|" + (gloss.text || "?") + "|" + gloss.index + "}}"; if (wordLines) block += "\n" + wordLines; block += "\n{{werger-bin}}"; return block; }); if (!blocks.length) return ""; return "\n==== Werger ====\n" + blocks.join("\n") + "\n"; } }, }; steps.trans.keys = steps.lang.choices; steps.dunde.keys = steps.lang.choices; steps.zarava.keys = getZaravaKeys(steps.lang.choices); var ordered_steps = [ steps.lang, steps.pron, steps.pos, steps.cinsiyet, steps.lektur, steps.tr, steps.dfn, steps.je, steps.tekildar, steps.etym, steps.dunde, steps.binereherwiha, steps.zarava, steps.trans]; // Step ids that belong to each section (not shared across sections). var PER_SECTION_STEP_IDS = [ "pos", "cinsiyet", "lektur", "tr", "dfn", "je", "tekildar", "etym", "dunde", "binereherwiha", "zarava", "trans" ]; // ── Multi-section state ────────────────────────────────────────────────── // Each entry is a plain snapshot: { pos, cinsiyet, lektur, tr, dfn (senses[]), // je, tekildar, binereherwiha, trans (rows[]) }. var sections = [{}]; // section 0 starts empty (DOM is the truth) var activeSection = 0; function snapshotDfn() { return steps.dfn.getSenses($("#wiktku-start-dfn")); } /** * Rebuild the dfn DOM from a previously snapshotted senses array. */ function restoreDfn(senses) { var stepDiv = $("#wiktku-start-dfn"); // Tear down the existing list so build() recreates it cleanly. stepDiv.find("ol.wiktku-dfn-list").remove(); steps.dfn.build(stepDiv); var list = stepDiv.find("ol.wiktku-dfn-list"); $.each(senses, function (i, sense) { // Ensure enough blocks exist (build() seeds one). var blocks = list.find("li.wiktku-dfn-sense"); var block = blocks.eq(i); if (!block.length) { var nb = steps.dfn.buildSenseBlock(stepDiv); list.append(nb); block = list.find("li.wiktku-dfn-sense").last(); } // Template selector. block.find("select.wiktku-dfn-tpl-select").val(sense.tpl || ""); if (sense.tpl) { block.find("textarea.wiktku-dfn-mane").hide(); block.find("input.wiktku-dfn-tpl-title").val(sense.tplTitle || "").show(); } else { block.find("textarea.wiktku-dfn-mane").val(sense.mane || "").show(); block.find("input.wiktku-dfn-tpl-title").hide().val(""); } // Re-sync the formên alternatîv/hevmane/… hide state now that // tplSelect's value was set programmatically (its own "change" // handler doesn't fire from .val(), so this doesn't happen otherwise). var updateVis = block.data("updateFieldVisibility"); if (updateVis) updateVis(); // Restore a sub-list (etiket, formên alternatîv, hevmane …) from a values array. function restoreSubList(cls, values) { if (!values || !values.length) return; var groupDiv = block.find("." + cls + "-group"); var subList = groupDiv.find("ol, ul").first(); if (!subList.length) return; // group not found // Fill existing items, append new ones as needed. $.each(values, function (j, val) { var items = subList.find("li"); if (j < items.length) { items.eq(j).find("textarea").val(val); } else { var ta = $("<textarea></textarea>") .attr("name", "wiktku-dfn-restore-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 1) .attr("class", "wiktku-dfn-subfield wiktku-start-narrow") .val(val); ta.on("input", function () { steps.dfn.onSubInput(subList, this, 1, true); }); subList.append($("<li></li>").append(ta)); } }); } // Reveal and populate lazy groups that have data. var lazyMap = { "wiktku-dfn-etiket": sense.etiket, "wiktku-dfn-alternativ": sense.alternativ, "wiktku-dfn-hevmane": sense.hevmane, "wiktku-dfn-dijmane": sense.dijmane, "wiktku-dfn-koordine": sense.koordine, "wiktku-dfn-jornav": sense.jornav, "wiktku-dfn-jernav": sense.jernav }; $.each(lazyMap, function (cls, vals) { if (vals && vals.length) restoreSubList(cls, vals); }); // Nimûne items are objects { text, tr?, t? } — restore using the builder. if (sense.nimune && sense.nimune.length) { var nimuneGroupDiv = block.find(".wiktku-dfn-nimune-group"); var nimuneList = nimuneGroupDiv.find("ol.wiktku-dfn-nimune-list"); var buildFn = nimuneGroupDiv.data("buildNimuneLi"); nimuneList.empty(); $.each(sense.nimune, function (_, n) { var text = typeof n === "object" ? (n.text || "") : n; if (!text) return; var li = buildFn ? buildFn() : $("<li class='wiktku-dfn-nimune-li'></li>"); li.find(".wiktku-dfn-nimune-text").val(text); if (n.tr) li.find(".wiktku-dfn-nimune-tr").val(n.tr); if (n.t) li.find(".wiktku-dfn-nimune-t").val(n.t); nimuneList.append(li); }); // Always leave a blank trailing item. if (buildFn) nimuneList.append(buildFn()); } // Restore jêder (quote/citation) entries — a growing list, restored using the // builder just like Nimûne. Accepts either the current array shape or a // single legacy object (from older saved sections) for backwards compatibility. var jederArr = $.isArray(sense.jeder) ? sense.jeder : (sense.jeder ? [sense.jeder] : []); if (jederArr.length) { var jederGroupDiv = block.find(".wiktku-dfn-jeder-group"); var jederList = jederGroupDiv.find("ol.wiktku-dfn-jeder-list"); var buildJederFn = jederGroupDiv.data("buildJederLi"); jederList.empty(); $.each(jederArr, function (_, j) { if (!j || !j.quote) return; var li = buildJederFn ? buildJederFn() : $("<li class='wiktku-dfn-jeder-li'></li>"); li.find(".wiktku-dfn-nimune-quote").val(j.quote); if (j.quoteTr) li.find(".wiktku-dfn-nimune-quote-tr").val(j.quoteTr); if (j.quoteT) li.find(".wiktku-dfn-nimune-quote-t").val(j.quoteT); if (j.jederManual) { var manualSel = li.find(".wiktku-dfn-quote-src-sel"); manualSel.val("__manual__").trigger("change"); li.find(".wiktku-dfn-quote-src-manual").val(j.jederManual); } else if (j.jederTpl) { var srcSel = li.find(".wiktku-dfn-quote-src-sel"); srcSel.val(j.jederTpl).trigger("change"); if (j.jêderFields) { $.each(j.jêderFields, function (key, val) { li.find(".wiktku-dfn-quote-src-input[data-field-key='" + key + "']").val(val); }); } } jederList.append(li); }); // Always leave a blank trailing item, same as Nimûne. if (buildJederFn) jederList.append(buildJederFn()); } }); } /** * Snapshot simple (non-dfn) per-section steps from current DOM into obj. */ function saveCurrentSection() { var snap = {}; $.each(PER_SECTION_STEP_IDS, function (_, id) { if (id === "dfn") { snap.dfn = snapshotDfn(); return; } if (id === "etym") { snap.etym = $.trim($("#wiktku-start-etym .wiktku-etym-text").val()); return; } var step = steps[id]; if (!step) return; var stepDiv = $("#wiktku-start-" + id); if (id === "trans") { snap.trans = steps.trans.getTranslations(stepDiv); return; } if (id === "zarava") { snap.zarava = steps.zarava.getTranslations(stepDiv); return; } if (id === "dunde") { snap.dunde = steps.dunde.getRows(stepDiv); return; } // Generic: read all step fields. var fields = stepDiv.find(".wiktku-start-step-field"); if (step.multiple) { snap[id] = fields.map(function () { return $(this).val(); }).get(); } else { snap[id] = fields.val(); } }); sections[activeSection] = snap; } /** * Restore a previously saved snapshot into the form DOM. */ function restoreSection(snap) { $.each(PER_SECTION_STEP_IDS, function (_, id) { if (id === "dfn") { restoreDfn(snap.dfn || []); return; } if (id === "etym") { $("#wiktku-start-etym .wiktku-etym-wrap").remove(); steps.etym.build($("#wiktku-start-etym")); $("#wiktku-start-etym .wiktku-etym-text").val(snap.etym || ""); return; } if (id === "trans") { // Rebuild trans groups (dfn must already be restored by this // point in the $.each loop, so glossList() reflects it). var transDiv = $("#wiktku-start-trans"); transDiv.find(".wiktku-trans-group").remove(); steps.trans.build(transDiv); var groupsSnap = snap.trans || []; $.each(groupsSnap, function (gi, rows) { var group = transDiv.find(".wiktku-trans-group[data-gloss-pos='" + gi + "']"); if (!group.length) return; // gloss no longer exists — drop its rows var list = group.find("ul.wiktku-trans-list"); $.each(rows, function (j, row) { var lang = row[0], words = row[1]; var lastRow = list.find("li.wiktku-trans-row").last(); lastRow.find("select").val(lang).trigger("change"); var wordList = lastRow.find("ul.wiktku-trans-words"); $.each(words, function (k, word) { var wordItems = wordList.find("li"); if (k < wordItems.length) { wordItems.eq(k).find("textarea").val(word); } else { // .val() below doesn't fire "input", so the normal // auto-grow never runs — append a matching item // ourselves instead of silently dropping the word. var extraInput = steps.trans.makeWordInput(); wordList.append($("<li></li>").append(extraInput)); extraInput.val(word); } }); // Leave one trailing empty field so the row can still grow // when the user types, matching a freshly-built row. if ($.trim(wordList.children("li").last().find("textarea").val())) { wordList.append($("<li></li>").append(steps.trans.makeWordInput())); } }); }); return; } if (id === "zarava") { // Rebuild zarava groups (dfn must already be restored by this // point in the $.each loop, so glossList() reflects it). var zaravaDiv = $("#wiktku-start-zarava"); zaravaDiv.find(".wiktku-zarava-group").remove(); steps.zarava.build(zaravaDiv); var zaravaGroupsSnap = snap.zarava || []; $.each(zaravaGroupsSnap, function (gi, rows) { var group = zaravaDiv.find(".wiktku-zarava-group[data-gloss-pos='" + gi + "']"); if (!group.length) return; // gloss no longer exists — drop its rows var list = group.find("ul.wiktku-zarava-list"); $.each(rows, function (j, row) { var lang = row[0], words = row[1]; var lastRow = list.find("li.wiktku-zarava-row").last(); lastRow.find("select").val(lang).trigger("change"); var wordList = lastRow.find("ul.wiktku-zarava-words"); $.each(words, function (k, word) { var wordItems = wordList.find("li"); if (k < wordItems.length) { wordItems.eq(k).find("textarea").val(word); } else { var extraInput = steps.zarava.makeWordInput(); wordList.append($("<li></li>").append(extraInput)); extraInput.val(word); } }); if ($.trim(wordList.children("li").last().find("textarea").val())) { wordList.append($("<li></li>").append(steps.zarava.makeWordInput())); } }); }); return; } if (id === "dunde") { // Rebuild dunde rows. var dundeDiv = $("#wiktku-start-dunde"); dundeDiv.find("ul.wiktku-dunde-list").remove(); steps.dunde.build(dundeDiv); var dundeRows = snap.dunde || []; $.each(dundeRows, function (i, row) { var lang = row[0], words = row[1]; var list = dundeDiv.find("ul.wiktku-dunde-list"); var lastRow = list.find("li.wiktku-dunde-row").last(); lastRow.find("select").val(lang).trigger("change"); var wordList = lastRow.find("ul.wiktku-dunde-words"); $.each(words, function (j, word) { var wordItems = wordList.find("li"); if (j < wordItems.length) { wordItems.eq(j).find("textarea").val(word); } else { // .val() below doesn't fire "input", so the normal // auto-grow never runs — append a matching item // ourselves instead of silently dropping the word. var extraInput = steps.dunde.makeWordInput(); wordList.append($("<li></li>").append(extraInput)); extraInput.val(word); } }); // Leave one trailing empty field so the row can still grow // when the user types, matching a freshly-built row. if ($.trim(wordList.children("li").last().find("textarea").val())) { wordList.append($("<li></li>").append(steps.dunde.makeWordInput())); } }); return; } var step = steps[id]; if (!step) return; var stepDiv = $("#wiktku-start-" + id); var fields = stepDiv.find(".wiktku-start-step-field"); var val = snap[id]; if (val === undefined || val === null) return; if (step.multiple) { var arr = val; fields.each(function (i) { if (i < arr.length) $(this).val(arr[i]); }); } else { fields.val(val); } // Notify chosen widgets of the programmatic value change. if (!isMobile) fields.filter("select").trigger("chosen:updated"); }); } function getWikitextForCurrentSection(callback) { var values = getValues(); var entry = steps.pos.output(values); steps.dfn.getOutput(values, function (output) { entry += output; entry += steps.je.output(values); entry += steps.tekildar.output(values); entry += steps.etym.output(values); entry += steps.dunde.output(values); entry += steps.binereherwiha.output(values); entry += steps.zarava.output(values); entry += steps.trans.output(values); callback(entry, values); }); } function getWikitextAllSections(callback) { saveCurrentSection(); var results = new Array(sections.length); var sharedValues = getValues(); // lang/pron are shared function processSection(i) { if (i >= sections.length) { // All done — restore original active section. restoreSection(sections[activeSection]); refresh(); callback(results, sharedValues); return; } restoreSection(sections[i]); refresh(); getWikitextForCurrentSection(function (sectionText) { results[i] = sectionText; processSection(i + 1); }); } processSection(0); } /** * Assembles wikitext for all sections plus the shared lang/pron header. */ function getWikitext(callback) { getWikitextAllSections(function (sectionTexts, sharedValues) { var entry = steps.lang.output(sharedValues); entry += steps.pron.output(sharedValues); entry += sectionTexts.join("\n"); // Edit summary uses section 0's values. Read from the saved snapshot // (not the live DOM) so it doesn't mix section 0's pos with whichever // section happens to be active/restored at this point. var dfnSenses = (sections[0] && sections[0].dfn) || []; var dfnSummary = dfnSenses.map(function (s) { return s.mane; }).filter(Boolean).join("; "); var summaryLabel = addLangMode ? "WF:Ziman lê zêde" : "WF:Nû"; var summary = "([[Mediawiki:Gadget-start.js|" + summaryLabel + "]] v.2.0) +" + sharedValues.lang + ":" + sections[0].pos + ":" + dfnSummary; var summaryField = document.getElementById("wpSummary"); if (addLangMode && summaryField.value) { summary = summaryField.value + " " + summary; } summaryField.value = summary; callback(entry); }); } var continueBtn; function getValuesForStep(stepId) { var fields = $("#wiktku-start-" + stepId + " .wiktku-start-step-field"); var step = steps[stepId]; if (step.keys) { var values = {}; fields.each(function (i, field) { var key = $(field).prevAll(".wiktku-start-step-keyfield").val(); if (key) values[key] = $(field).val(); }); return values; } else if (step.multiple) { return fields.map(function () { return $(this).val(); }).get(); } return fields.val(); } function getValues() { var values = {}; $.each(steps, function (stepId) { values[stepId] = getValuesForStep(stepId); }); return values; } function populateMenus(inputs, choices, disabledValues) { if (!disabledValues) disabledValues = {}; var vals = inputs.map(function (i, input) { return $(input).val(); }); inputs.empty(); inputs.append($("<option></option>")); $.each(choices, function (j, choice) { // Append the language code in parentheses so that typing a code // (e.g. "ku") in the search box still finds the language name. var displayText = capitalize(choice[1]); if (choice[2] !== undefined) { // This is a language choice [code, name, sortKey] — show code. displayText = capitalize(choice[1]) + " (" + choice[0] + ")"; } var option = $(mw.html.element("option", { value: choice[0] }, displayText)); if (disabledValues[choice[0]]) option.prop("disabled", true); inputs.append(option); }); inputs.val(function (i) { return vals[i]; }); } /** * Returns a bitmap containing the keys that should be disabled for a key * menu in the given step because they are disabled or already taken by * another key menu. */ function getDisabledKeys(step) { var occupiedKeys = {}; $("#wiktku-start-" + step.id + " .wiktku-start-step-keyfield").each(function () { occupiedKeys[$(this).val()] = true; }); if (step.disabledKeys) $.extend(occupiedKeys, step.disabledKeys); return occupiedKeys; } function buildKeyInput(step) { if (!step.keys) return undefined; var input = $(mw.html.element("select", { "class": "wiktku-start-step-keyfield wiktku-start-narrow" })); input.attr("data-placeholder", "Hilbijêre " + step.keyName); if (isMobile) { populateMenus(input, step.keys, getDisabledKeys(step)); // On mobile return the wrapper; the select is inside it. // Change events still fire on the inner select. return wrapNativeSelect(input); } input.on("chosen:showing_dropdown", function () { $(this).data("wiktku-defaultValue", $(this).val()); }); input.change(function (_, context) { var inputs = $("#wiktku-start-" + step.id + " .wiktku-start-step-keyfield").not(this); var oldValue = $(this).data("wiktku-defaultValue"); var newValue = context.selected; inputs.find("option[value='" + oldValue + "']").prop('disabled', false); inputs.find("option[value='" + newValue + "']").prop('disabled', true); inputs.trigger("chosen:updated"); }); populateMenus(input, step.keys, getDisabledKeys(step)); return input; } /** * If the current text field has text and there are no more text fields after * the current text field in the list, add another text field to the list. */ function refreshForTextField(currentInput, step) { currentInput = $(currentInput); var value = currentInput.val(); var item = currentInput.parent(); if (value && !item.next("li").length) { var nextInput = $("<textarea></textarea>") .attr("name", "wiktku-field-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("class", currentInput.attr("class")) .attr("rows", currentInput.attr("rows") || 1); nextInput.on("input", function (evt) { refreshForTextField(evt.target, step); }); var nextKeyInput = buildKeyInput(step); var nextItem = $("<li></li>").append(nextKeyInput).append(nextInput); item.parent().append(nextItem); if (nextKeyInput) nextKeyInput.chosen(chosenOptions); } var canContinue = !continueBtn.isDisabled(); if ((value && !canContinue) || (!value && canContinue)) { refresh(step); } } function prepareInput(input, step) { if (!input) return; if (step.required) input.prop('required', true); input.change(step, refresh); } /** * Shows and hides all the steps based on whether their prerequisites are met, * and updates placeholders where applicable. */ function refresh(evt) { var values = getValues(); var changedStep = evt && evt.data; var didFocus = false; var canContinue = true; // Re-filter template options in every sense block whenever lang changes. $("#wiktku-start-dfn .wiktku-dfn-tpl-select").each(function () { var fn = $(this).data("updateOptions"); if (typeof fn === "function") fn(); }); // Re-filter pronunciation and etymology template dropdowns when language changes. steps.pron.refreshTplSelect(); steps.etym.refreshTplSelect(); // Sync tr/t sub-fields in every nimûne item to the current language. // tr shown when language needs transliteration; t shown when lang !== "ku". (function () { var lang = values.lang || ""; var showTr = needsTransliteration(lang); var showT = lang && lang !== "ku"; $("#wiktku-start-dfn .wiktku-dfn-nimune-list li.wiktku-dfn-nimune-li").each(function () { var li = $(this); // Ensure the sub-wrapper exists when we need it. var subWrap = li.find(".wiktku-dfn-nimune-sub"); // tr field var trTa = li.find(".wiktku-dfn-nimune-tr"); if (showTr && !trTa.length) { if (!subWrap.length) { subWrap = $("<div></div>").addClass("wiktku-dfn-nimune-sub"); li.append(subWrap); } trTa = $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-tr-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 5) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-tr") .attr("placeholder", "Transkrîpsiyon…"); subWrap.prepend(trTa); } else if (!showTr && trTa.length) { trTa.remove(); } // t field var tTa = li.find(".wiktku-dfn-nimune-t"); if (showT && !tTa.length) { if (!subWrap.length) { subWrap = $("<div></div>").addClass("wiktku-dfn-nimune-sub"); li.append(subWrap); } tTa = $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-t-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 5) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-t") .attr("placeholder", "Tercimeya nimûneyê kurmancî…"); subWrap.append(tTa); } else if (!showT && tTa.length) { tTa.remove(); } // Remove the wrapper if it ended up empty. subWrap = li.find(".wiktku-dfn-nimune-sub"); if (subWrap.length && !subWrap.children().length) subWrap.remove(); }); }()); // Sync tr/t sub-fields in every jêder citation to the current language. // tr shown when language needs transliteration; t shown when lang !== "ku". (function () { var lang = values.lang || ""; var showTr = needsTransliteration(lang); var showT = lang && lang !== "ku"; $("#wiktku-start-dfn .wiktku-dfn-jeder-list li.wiktku-dfn-jeder-li").each(function () { var li = $(this); // Ensure the sub-wrapper exists when we need it. It must sit right // after the quote textarea and before the source selector. var subWrap = li.find(".wiktku-dfn-quote-sub"); // tr field var trTa = li.find(".wiktku-dfn-nimune-quote-tr"); if (showTr && !trTa.length) { if (!subWrap.length) { subWrap = $("<div></div>").addClass("wiktku-dfn-quote-sub"); li.find(".wiktku-dfn-nimune-quote").after(subWrap); } trTa = $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-quote-tr-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 2) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-quote-tr") .attr("placeholder", "Transkrîpsiyona jêgirtinê…"); subWrap.prepend(trTa); } else if (!showTr && trTa.length) { trTa.remove(); } // t field var tTa = li.find(".wiktku-dfn-nimune-quote-t"); if (showT && !tTa.length) { if (!subWrap.length) { subWrap = $("<div></div>").addClass("wiktku-dfn-quote-sub"); li.find(".wiktku-dfn-nimune-quote").after(subWrap); } tTa = $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-quote-t-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 2) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-quote-t") .attr("placeholder", "Tercimeya jêgirtinê ya kurmancî…"); subWrap.append(tTa); } else if (!showT && tTa.length) { tTa.remove(); } // Remove the wrapper if it ended up empty. subWrap = li.find(".wiktku-dfn-quote-sub"); if (subWrap.length && !subWrap.children().length) subWrap.remove(); }); }()); $.each(steps, function (stepId, step) { if (typeof(step.visible) === "function" && !step.visible(values)) { $("#wiktku-start-" + stepId).slideUp(); } else { var stepDiv = $("#wiktku-start-" + stepId); if (changedStep !== step && typeof(step.build) === "function") { prepareInput(step.build(stepDiv, values), step); } var input = stepDiv.find(".wiktku-start-step-field"); if (typeof(step.example) === "function") { // .find() above already reaches nested fields (e.g. the dfn // step's mane textareas inside each sense block), so one // assignment covers every step; dfn keeps its own fallback. var exampleText = step.example(values) || (step.id === "dfn" ? "Mane…" : ""); input.attr("placeholder", exampleText); } var didSlideDown; if (!didFocus && stepDiv.css("display") === "none" && step.required) { didSlideDown = function (evt) { input.focus(); }; didFocus = true; } stepDiv.slideDown(didSlideDown); } if (step.required && (values[stepId] === "" || (step.multiple && values[stepId].join("") === ""))) { canContinue = false; } }); continueBtn.setDisabled(!canContinue); } function destroy() { $("#wiktku-start-form, .noafterwizard").slideUp(function () { $(this).remove(); }); $(".noarticletext .nowizard, #editform").slideDown(); $("#ca-edit").removeClass("selected"); $("#ca-wiktku-nowizard").addClass("selected"); } // Priority order for Kurdish dialects and the navz pseudo-code. // Codes listed here come before all other languages; unlisted codes // are sorted alphabetically by their display name via localeCompare. var LANG_PRIORITY = ["navz", "ku", "hac", "sdh", "lki", "ckb", "zza"]; /** * Inserts a new == {{ziman|code}} == section into existing page wikitext * at the correct sorted position: * 1. Any content before the first language section is preserved at the top. * 2. navz is always first, then ku/hac/sdh/lki/ckb/zza in that order, * then all other languages sorted by display name (localeCompare). */ function insertNewLangSection(existing, wikitext) { var newCodeMatch = wikitext.match(/^== \{\{ziman\|([^}]+)\}\} ==/); var newCode = newCodeMatch ? newCodeMatch[1] : ""; var sections = []; var preamble = ""; var firstMatch = existing.match(/(?:^|\n)== \{\{ziman\|/); if (!firstMatch) { // No existing lang sections at all — just append. var sep = existing && !/\n\s*$/.test(existing) ? "\n\n" : ""; return existing + sep + wikitext; } // Everything before the first == {{ziman|...}} == is the preamble. var firstSectionStart = existing.indexOf("== {{ziman|"); // Walk back to the start of that line. var lineStart = existing.lastIndexOf("\n", firstSectionStart - 1); var preambleEnd = lineStart !== -1 ? lineStart + 1 : 0; preamble = existing.slice(0, preambleEnd); // Parse each language section: header line + everything until the next header. var body = existing.slice(preambleEnd); // NOTE: with the /m flag, a bare "$" matches end-of-*line*, not just // end-of-string — that previously made the non-greedy content group // stop at the section's first line break instead of running to the // next language header (or the real end of the text), silently // dropping the rest of that section's wikitext. (?![\s\S]) matches // only the true end of the string, /m flag or not. var langSectionRe = /^(== \{\{ziman\|([^}]+)\}\} ==\n?)([\s\S]*?)(?=\n== \{\{ziman\||(?![\s\S]))/gm; var m; while ((m = langSectionRe.exec(body)) !== null) { sections.push({ code: m[2], content: m[0] // full text of this section including header }); } // Determine sort rank: priority list first (by index), then alphabetical. function getLangName(code) { var entry = langsByCode[code]; return entry ? entry[1] : code; } function sortRank(code) { var idx = LANG_PRIORITY.indexOf(code); return idx !== -1 ? idx : LANG_PRIORITY.length; } function compareLangs(a, b) { var ra = sortRank(a), rb = sortRank(b); if (ra !== rb) return ra - rb; // Both are outside priority list — sort by display name. return getLangName(a).localeCompare(getLangName(b), userLang); } // Insert the new section into the sorted list. var newSection = { code: newCode, content: wikitext }; var inserted = false; for (var i = 0; i < sections.length; i++) { if (compareLangs(newCode, sections[i].code) < 0) { sections.splice(i, 0, newSection); inserted = true; break; } } if (!inserted) sections.push(newSection); // Re-join: preamble + sections separated by newlines. var joined = sections.map(function (s) { // Ensure each section ends with exactly one newline before the next. return s.content.replace(/\n+$/, ""); }).join("\n"); return preamble + joined + "\n"; } function build() { $(".nowizard, .nowizard .noafterwizard").hide(); var callToAction = $("#wiktku-calltoaction"); var origCallToActionText = callToAction.text(); $(mw.util.addPortletLink("p-views", "#", "Edîtora çavkaniyê veke", "ca-wiktku-nowizard", "Vê rûpelê bi edîtora çavkaniyê çêke", undefined, "#ca-watch")).click(function (evt) { evt.preventDefault(); callToAction.text(origCallToActionText); destroy(); }); if (callToAction.length) { callToAction.text(origCallToActionText + " Forma li jêr ji bo çêkirina madeyeke nû bi kar bîne."); } var startForm = $("<form id='wiktku-start-form'></form>"); if (addLangMode) { startForm.append($("<p class='wiktku-addlang-notice'></p>").text( "Agahiyên zimanê nû yê hûnê li vê rûpelê zêde bikin dagirin. " + "Piştî temambûnê, beşa nû dê li dawiya nivîsa heyî were zêdekirin.")); } var spinner; // Tab bar for switching between POS sections. var sectionTabsDiv = $("<div id='wiktku-section-tabs'></div>"); startForm.submit(function (evt) { evt.preventDefault(); continueBtn.setDisabled(true); spinner.show(); getWikitext(function (wikitext) { if (addLangMode) { var textbox = $("#wpTextbox1"); var existing = textbox.val() || ""; // Check whether the generated lang header already exists in the page. // wikitext always starts with "== {{ziman|CODE}} ==\n" (from steps.lang.output). // If that exact section heading is already present in the existing content, // strip it from the new output and insert the remaining content at the end // of that lang section (just before the next == level-2 heading, or at the // very end of the page if there is no following section). var langHeaderMatch = wikitext.match(/^(== \{\{ziman\|[^}]+\}\} ==\n)/); if (langHeaderMatch) { var langHeader = langHeaderMatch[1]; // e.g. "== {{ziman|ku}} ==\n" // Escape for use in RegExp. var escapedHeader = langHeader.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); if (new RegExp(escapedHeader).test(existing)) { // Strip the header from the new output. var newContent = wikitext.slice(langHeader.length); // Find the insertion point: end of the existing lang section. // A new L2 heading marks the start of the next language block. var afterHeader = existing.indexOf(langHeader); var searchFrom = afterHeader + langHeader.length; // Find the next == … == heading after this section's start. var nextL2 = existing.indexOf("\n== ", searchFrom); var insertAt = nextL2 !== -1 ? nextL2 : existing.length; // Ensure there's a blank line before the inserted block. var before = existing.slice(0, insertAt); var after = existing.slice(insertAt); var sep = /\n\s*$/.test(before) ? "" : "\n"; textbox.val(before + sep + newContent + after); } else { // New language — insert at the correct sorted position. textbox.val(insertNewLangSection(existing, wikitext)); } } else { // Unexpected format — insert at sorted position anyway. textbox.val(insertNewLangSection(existing, wikitext)); } } else { $("#wpTextbox1").val(wikitext); } $("html, body").animate({scrollTop: 0}); callToAction.text("Hindik ma!"); $("#wiktku-preview-container").remove(); destroy(); }); }); $.each(ordered_steps, function (i, step) { var stepDiv = $(mw.html.element("div", { "class": "wiktku-start-step", id: "wiktku-start-" + step.id })); var name = capitalize(step.name); stepDiv.append($(mw.html.element("h3", { "class": "wiktku-start-step-name" }, new mw.html.Raw(mw.html.element("label", { "for": "wiktku-start-" + step.id + "-field" }, name))))); if (step.question_fmt) { stepDiv.append($(mw.html.element("label", { "class": "wiktku-start-step-question", "for": "wiktku-start-" + step.id + "-field" }, step.question_fmt))); if (step.question_br) stepDiv.append($("<br>")); } var input; if (step.choices) { input = $(mw.html.element("select", { "class": "wiktku-start-step-field", id: "wiktku-start-" + step.id + "-field" })); input.attr("data-placeholder", capitalize(step.name) + " hilbijêre "); populateMenus(input, step.choices); if (step.multiple) input.attr("multiple", true); if (isMobile) { stepDiv.append(wrapNativeSelect(input)); } else { stepDiv.append(input); } } else if (typeof(step.build) === "function") { input = step.build(stepDiv); } else { input = $("<textarea></textarea>") .attr("class", "wiktku-start-step-field") .attr("id", "wiktku-start-" + step.id + "-field") .attr("rows", step.rows || 2); if (step.narrow) input.addClass("wiktku-start-narrow"); if (step.multiple) { input.on("input", function (evt) { refreshForTextField(evt.target, step); }); var keyInput = buildKeyInput(step); var list = $(step.ordered ? "<ol></ol>" : "<ul></ul>") .append($("<li></li>").append(keyInput).append(input)); stepDiv.append(list); } else stepDiv.append(input); } prepareInput(input, step); stepDiv.hide(); // Insert tab bar just before the first per-section step. if (step.id === "pos") startForm.append(sectionTabsDiv); startForm.append(stepDiv); }); // ── Section tab helpers ────────────────────────────────────────────── // ── Add-section button — lives in the tab bar, disabled until pos chosen ── var addSectionBtn = new OO.ui.ButtonWidget({ label: "+ Beş zêde bike", disabled: true }); addSectionBtn.on("click", function () { saveCurrentSection(); sections.push({}); activeSection = sections.length - 1; $.each(PER_SECTION_STEP_IDS, function (_, id) { if (id === "dfn") { var stepDiv = $("#wiktku-start-dfn"); stepDiv.find("ol.wiktku-dfn-list").remove(); steps.dfn.build(stepDiv); return; } if (id === "etym") { $("#wiktku-start-etym .wiktku-etym-wrap").remove(); steps.etym.build($("#wiktku-start-etym")); return; } if (id === "trans") { var transDiv = $("#wiktku-start-trans"); transDiv.find(".wiktku-trans-group").remove(); return; } if (id === "zarava") { var zaravaDiv = $("#wiktku-start-zarava"); zaravaDiv.find(".wiktku-zarava-group").remove(); return; } if (id === "dunde") { var dundeDiv = $("#wiktku-start-dunde"); dundeDiv.find("ul.wiktku-dunde-list").remove(); return; } var stepDiv = $("#wiktku-start-" + id); stepDiv.find(".wiktku-start-step-field").val(""); if (!isMobile) stepDiv.find("select.wiktku-start-step-field").trigger("chosen:updated"); }); renderSectionTabs(); refresh(); $("html, body").animate({ scrollTop: sectionTabsDiv.offset().top - 20 }, 300); }); /** Re-render the tab bar to reflect current sections[] and activeSection. */ function renderSectionTabs() { // Detach (not remove) the button first: .empty() strips bound // event data from any children left inside it, which would // silently kill addSectionBtn's click handler on every re-render. addSectionBtn.$element.detach(); sectionTabsDiv.empty(); var lang = getValues().lang || ""; if (!lang) { sectionTabsDiv.hide(); return; } sectionTabsDiv.show(); $.each(sections, function (i) { var posVal = sections[i].pos || ""; var tabLabel = posVal ? capitalize(posVal) : ("Beş " + (i + 1)); var tab = $("<span></span>") .addClass("wiktku-section-tab") .text(tabLabel) .toggleClass("wiktku-tab-active", i === activeSection); (function (idx) { tab.on("click", function () { if (idx === activeSection) return; saveCurrentSection(); activeSection = idx; restoreSection(sections[activeSection]); refresh(); renderSectionTabs(); }); }(i)); sectionTabsDiv.append(tab); }); // Enable "Beş zêde bike" only when the active section has a pos chosen. var activePos = sections[activeSection] && sections[activeSection].pos ? sections[activeSection].pos : getValues().pos; addSectionBtn.setDisabled(!activePos); sectionTabsDiv.append(addSectionBtn.$element); } renderSectionTabs(); // Update the active tab's label whenever pos changes. startForm.on("change", "#wiktku-start-pos-field", function () { renderSectionTabs(); }); // Show the tab bar as soon as a language is selected. startForm.on("change", "#wiktku-start-lang-field", function () { renderSectionTabs(); }); var footer = $("<div id='wiktku-start-footer'></div>"); spinner = $(mw.html.element("img", { id: "wiktku-start-spinner", src: "//upload.wikimedia.org/wikipedia/commons/d/de/Ajax-loader.gif", alt: "Tê barkirin…", title: "Tê barkirin…" })); footer.append(spinner.hide()); continueBtn = new OO.ui.ButtonWidget({ id: "wiktku-unhide-editform", label: "Bişîne", flags: [ "primary", "progressive" ] }); continueBtn.on("click", function () { mw.notify("Tê şandin…", { type: "info", tag: "wiktku-submit" }); startForm.trigger("submit"); }); footer.append(continueBtn.$element); // ── Preview checkboxes ─────────────────────────────────────────────── // Wikitext preview (raw text panel) var previewCheck = $("<input type='checkbox' id='wiktku-preview-toggle'>"); var previewLabel = $("<label for='wiktku-preview-toggle'></label>") .text(" Pêşdîtina wîkîtekstê"); var previewPanel = $("<pre id='wiktku-preview-panel'></pre>").hide(); // Live rendered preview (parsed HTML panel, same logic as AjaxEdit). // Not available on mobile — API polling causes too many problems on small screens. var livePreviewCheck = null; var livePreviewPanel = null; if (!isMobile) { livePreviewCheck = $("<input type='checkbox' id='wiktku-live-preview-toggle'>"); livePreviewPanel = $("<div id='wiktku-live-preview-panel'></div>").hide(); } // Container that holds both panels and switches between stacked / side-by-side. var previewContainer = $("<div id='wiktku-preview-container'></div>"); previewContainer.append(previewPanel); if (!isMobile) previewContainer.append(livePreviewPanel); var previewTimer = null; var livePreviewIntervalId = -1; /** Rebuilds wikitext preview if its checkbox is checked. */ function schedulePreview() { if (!previewCheck.prop("checked")) return; clearTimeout(previewTimer); // Debounce: wait 400 ms after the last keystroke before rebuilding. previewTimer = setTimeout(function () { getWikitext(function (wikitext) { previewPanel.text(wikitext).show(); updatePanelLayout(); }); }, 400); } /** Fetches parsed HTML and populates the live preview panel. */ function loadLivePreview() { getWikitext(function (wikitext) { new mw.Api().parse(wikitext, { title: mw.config.get("wgPageName") }).done(function (html) { livePreviewPanel.html(html).show(); updatePanelLayout(); }); }); } /** Adjusts panel widths depending on which previews are visible. */ function updatePanelLayout() { var wikitextVisible = previewCheck.prop("checked"); var liveVisible = livePreviewCheck && livePreviewCheck.prop("checked"); if (wikitextVisible && liveVisible) { // Side by side — each panel takes roughly half the available width. previewPanel.css({ "flex": "1 1 45%", "min-width": "280px" }); livePreviewPanel.css({ "flex": "1 1 45%", "min-width": "280px" }); } else { // Full width for whichever is visible. previewPanel.css({ "flex": "1 1 100%", "min-width": "" }); if (livePreviewPanel) livePreviewPanel.css({ "flex": "1 1 100%", "min-width": "" }); } } previewCheck.on("change", function () { if ($(this).prop("checked")) { schedulePreview(); } else { clearTimeout(previewTimer); previewPanel.hide(); updatePanelLayout(); } }); if (!isMobile) { livePreviewCheck.on("change", function () { if ($(this).prop("checked")) { livePreviewPanel.show(); loadLivePreview(); livePreviewIntervalId = setInterval(loadLivePreview, 500); } else { clearInterval(livePreviewIntervalId); livePreviewIntervalId = -1; livePreviewPanel.hide().empty(); updatePanelLayout(); } }); } // Listen on all input/change events on the form and update both previews. startForm.on("input change", function () { schedulePreview(); }); footer.append($("<span style='margin-left:1em'></span>") .append(previewCheck).append(previewLabel)); if (!isMobile) { var livePreviewLabel = $("<label for='wiktku-live-preview-toggle'></label>") .text(" Pêşdîtina zindî"); footer.append($("<span style='margin-left:1em'></span>") .append(livePreviewCheck).append(livePreviewLabel)); } startForm.append(footer); $("#editform").hide().before(startForm); // Insert preview container (holds both panels) after the form. startForm.after(previewContainer); if (!isMobile) startForm.find("select").chosen(chosenOptions); refresh(); // Zimanan ji MediaWiki:Gadget-translation_editor.js/ziman.json bar bike. // Kodên ku bi "-pro" diqedin û navên ku "zimanê destan" tê de heye // tên derxistin. Zimanên xardkirî li serî dimînin, yên din // bi alfabeyê li dû wan tên. // Pinned choices come from MediaWiki:Gadget-start.js/data.json (langChoices), // already loaded into steps.lang.choices before build() runs. var pinnedChoices = steps.lang.choices.slice(); var pinnedCodes = $.map(pinnedChoices, function (choice) { return choice[0]; }); new mw.Api().get({ action: "query", prop: "revisions", titles: "MediaWiki:Gadget-translation_editor.js/ziman.json", rvprop: "content", rvslots: "main", formatversion: 2 }).then(function (data) { var page = data.query.pages[0]; var content = page && page.revisions && page.revisions[0].slots.main.content; var zimanData; try { zimanData = JSON.parse(content); } catch (e) { zimanData = {}; } var extraChoices = []; $.each(zimanData, function (code, name) { // Filter: skip proto-language codes and legendary/reconstructed langs. if (/-pro$/i.test(code)) return; if (/ziman[eê]\s+destan/i.test(name)) return; // Skip codes already in the pinned list (they are handled above). if (pinnedCodes.indexOf(code) !== -1) return; // sortKey: bare name without leading "zimanê " for sorting. var sortKey = name.replace(/^ziman[eê]\s+/i, ""); var choice = [code, name, sortKey]; extraChoices.push(choice); langsByCode[code] = choice; }); // Populate langsByCode for pinned choices too. $.each(pinnedChoices, function (i, choice) { // Ensure pinned choices have a sortKey (index 2). if (choice.length < 3) choice[2] = choice[1]; langsByCode[choice[0]] = choice; }); // Sort the extra choices alphabetically by sort key. extraChoices.sort(function (a, b) { return a[2].localeCompare(b[2], userLang); }); // Final list: pinned first, then the rest. var allChoices = pinnedChoices.concat(extraChoices); steps.lang.choices = allChoices; steps.trans.keys = allChoices; steps.dunde.keys = allChoices; steps.zarava.keys = getZaravaKeys(allChoices); var langMenu = $("#wiktku-start-lang-field"); populateMenus(langMenu, steps.lang.choices); langMenu.trigger("chosen:updated"); var transMenus = $("#wiktku-start-trans .wiktku-start-step-keyfield"); populateMenus(transMenus, steps.trans.keys, getDisabledKeys(steps.trans)); transMenus.trigger("chosen:updated"); var dundeMenus = $("#wiktku-start-dunde .wiktku-start-step-keyfield"); populateMenus(dundeMenus, steps.dunde.keys, getDisabledKeys(steps.dunde)); dundeMenus.trigger("chosen:updated"); var zaravaMenus = $("#wiktku-start-zarava .wiktku-start-step-keyfield"); populateMenus(zaravaMenus, steps.zarava.keys, getDisabledKeys(steps.zarava)); }); } mw.loader.using(["jquery.chosen", "mediawiki.api", "oojs-ui-core"], function () { // Load metadata, langChoices, posChoices and tplDefs from the companion // data page so they can be updated without touching this script. new mw.Api().get({ action: "query", prop: "revisions", titles: "MediaWiki:Gadget-start.js/data.json", rvprop: "content", rvslots: "main", formatversion: 2 }).then(function (data) { var page = data.query.pages[0]; var content = page && page.revisions && page.revisions[0].slots.main.content; var d; try { d = JSON.parse(content); } catch (e) { d = {}; } // Populate metadata. if (d.metadata) $.extend(metadata, d.metadata); // Populate lang choices (pinned list used by build() → ziman.json loader). if (d.langChoices) steps.lang.choices = d.langChoices; // Populate POS choices. if (d.posChoices) steps.pos.choices = d.posChoices; // Populate template definitions for the dfn sense-block builder. if (d.tplDefs) steps.dfn.tplDefs = d.tplDefs; // Populate pos placeholder examples. if (d.posExamples) steps.dfn.posExamples = d.posExamples; // Populate citation template definitions for the quote widget. if (d.jederDefs) steps.dfn.jederDefs = d.jederDefs; // Populate pronunciation and etymology template insert lists. if (d.pronTpls) { steps.pron.pronTpls = d.pronTpls; steps.pron.refreshTplSelect(); } if (d.etymTpls) { steps.etym.etymTpls = d.etymTpls; steps.etym.refreshTplSelect(); } // Sync trans/dunde/zarava keys with the (now populated) lang choices. steps.trans.keys = steps.lang.choices; steps.dunde.keys = steps.lang.choices; steps.zarava.keys = getZaravaKeys(steps.lang.choices); }).always(build); }); }); //</nowiki> 2d8vvizucjtpyhhxjn6hgp8tu3gmm1v 6265559 6265558 2026-07-19T12:55:53Z Wikihez 7344 6265559 javascript text/javascript // Li ser [[vi:MediaWiki:Gadget-start.js]] hatiye refaktorkirin. //<nowiki> $(function () { var ns = mw.config.get("wgNamespaceNumber"); if (ns && !(ns === 2 && mw.config.get("wgPageName").match(/\/ceribandin$|\/test$/))) { return; } var action = mw.config.get("wgAction"); var pageExists = !!mw.config.get("wgArticleId"); // "Zimanek lê zêde bike" mode: triggered from the portlet link below. // Runs the same wizard on an EXISTING page's edit form, but appends the // generated section instead of replacing the textarea's content. var addLangMode = pageExists && mw.util.getParamValue("wiktkuaddlang") === "1"; // On a normal page view of an existing page, just add the portlet link // that takes the user into addLangMode; don't build anything else here. if (action === "view" && pageExists) { mw.util.addPortletLink("p-views", mw.util.getUrl(mw.config.get("wgPageName"), { action: "submit", wiktkuaddlang: "1" }), "+Ziman/beşeke din", "ca-wiktku-addlang", "Ji vê rûpelê re zimanekî nû zêde bike"); return; } if (!(action === "edit" || action === "submit")) { return; } if (!addLangMode && !$(".mw-newarticletext, .mw-newarticletextanon").length) { return; } if (window.location.href.includes("editintro=User:Wikihez/creation/intro")) { return; // Do not run the script wextê WF:Bilez dişuxile } function capitalize(str) { if (!str) return str; return str[0].toUpperCase() + str.substr(1); } function decapitalize(str) { if (!str) return str; return str[0].toLowerCase() + str.substr(1); } function escapeRegExp(str) { return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); } function stripWikilinks(str) { return str.replace(/\[\[([^\]|]+)(?:\|([^\]]+))?\]\]/g, function (m, target, display) { return display || target; }); } function insertAtCursor(el, text) { var start = el.selectionStart; var end = el.selectionEnd; var val = el.value; el.value = val.slice(0, start) + text + val.slice(end); var pos = start + text.length; el.selectionStart = el.selectionEnd = pos; } var pageName = mw.config.get("wgPageName").replaceAll(/_/g, " "); if (ns) pageName = pageName.replace(/.*\//, ""); var pageNameRe = escapeRegExp(pageName); var userLang = mw.config.get("wgUserLanguage"); // Mobile detection: MobileFrontend sets wgMFMode, or fall back to touch check. var isMobile = !!mw.config.get("wgMFMode") || window.matchMedia("(pointer: coarse)").matches; var chosenOptions = { width: "20em", disable_search_threshold: 0, placeholder_text_single: "Yekî hilbijêre", placeholder_text_multiple: "Hilbijêre", no_results_text: "Nehat dîtin", enable_split_word_search: true, search_contains: true }; function wrapNativeSelect(select) { var placeholder = select.attr("data-placeholder") || "Lê bigere…"; // Hide the native select — we drive it programmatically. select.hide(); var wrapper = $("<span class='wiktku-native-select-wrap'></span>"); var textInput = $("<input type='search' autocomplete='off'>") .attr("placeholder", placeholder) .addClass("wiktku-start-narrow wiktku-ac-input"); var resultsList = $("<ul class='wiktku-ac-results'></ul>").hide(); // Full option cache — rebuilt when chosen:updated fires. var allOptions = []; function cacheOptions() { allOptions = []; select.find("option").each(function () { var v = $(this).val(); if (!v) return; // skip the empty placeholder option allOptions.push({ value: v, text: $(this).text(), disabled: $(this).prop("disabled") }); }); } cacheOptions(); function showResults(query) { var q = query.trim().toLowerCase(); resultsList.empty(); var matched; if (q) { matched = []; $.each(allOptions, function (_, o) { if (o.disabled) return; var codeMatch = o.value.toLowerCase().indexOf(q) !== -1; var nameMatch = o.text.toLowerCase().indexOf(q) !== -1; if (codeMatch || nameMatch) { matched.push({ opt: o, codeMatch: codeMatch }); } }); // Code matches (especially prefix matches) come first. matched.sort(function (a, b) { var aCode = a.opt.value.toLowerCase(); var bCode = b.opt.value.toLowerCase(); var aPrefix = aCode.indexOf(q) === 0; var bPrefix = bCode.indexOf(q) === 0; if (aPrefix !== bPrefix) return aPrefix ? -1 : 1; if (a.codeMatch !== b.codeMatch) return a.codeMatch ? -1 : 1; return 0; }); matched = matched.map(function (item) { return item.opt; }); } else { matched = allOptions.filter(function (o) { return !o.disabled; }); } if (!matched.length) { resultsList.hide(); return; } $.each(matched.slice(0, 50), function (_, opt) { var li = $("<li></li>").text(opt.text).attr("data-value", opt.value); // Use touchend instead of touchstart so that a scroll gesture does // not accidentally select an item. We track whether the finger moved // between touchstart and touchend — if it did, it was a scroll. var touchMoved = false; li.on("touchstart", function () { touchMoved = false; }); li.on("touchmove", function () { touchMoved = true; }); li.on("touchend", function (e) { if (touchMoved) return; // was a scroll, not a tap e.preventDefault(); selectOption(opt.value, opt.text); }); // Keep mousedown for desktop fallback. li.on("mousedown", function (e) { e.preventDefault(); selectOption(opt.value, opt.text); }); resultsList.append(li); }); // Position the list above or below depending on available viewport space. var inputRect = textInput[0].getBoundingClientRect(); var viewportH = window.innerHeight; var spaceBelow = viewportH - inputRect.bottom - 8; var spaceAbove = inputRect.top - 8; var maxH = Math.min(224, Math.max(spaceBelow, spaceAbove)); // 224px ≈ 14em resultsList.css({ "max-height": maxH + "px", "top": spaceBelow >= spaceAbove ? "100%" : "auto", "bottom": spaceBelow >= spaceAbove ? "auto" : "100%" }); resultsList.show(); } function selectOption(value, text) { textInput.val(text); select.val(value); resultsList.hide(); select.trigger("change"); } textInput.on("input focus", function () { showResults($(this).val()); }); textInput.on("blur", function () { // Short delay so a touchstart on a result item fires first. setTimeout(function () { resultsList.hide(); }, 200); }); // chosen:updated → re-cache (called after ziman.json loads). select.on("chosen:updated", function () { cacheOptions(); // If a value is already selected, keep the display text in sync. var cur = select.val(); if (cur) { var match = $.grep(allOptions, function (o) { return o.value === cur; })[0]; if (match) textInput.val(match.text); } }); // No-op .chosen() so desktop call-sites don't need guarding. select.chosen = function () { return select; }; wrapper.append(textInput).append(resultsList).append(select); return wrapper; } var langsByCode = {}; // Populated from [[MediaWiki:Gadget-start.js/data.json]] at runtime. var metadata = {}; // Zaravayên kurdî yên ku di beşa "Bi zaravayên din" de tên pêşkêşkirin — // ev kod ji beşa Werger têne derxistin daku heman zimên du caran neyê xwendin. var ZARAVA_LANG_CODES = ["ckb", "sdh", "lki", "hac", "zza"]; function getZaravaKeys(choices) { var byCode = {}; $.each(choices || [], function (_, c) { byCode[c[0]] = c; }); var result = []; $.each(ZARAVA_LANG_CODES, function (_, code) { if (byCode[code]) result.push(byCode[code]); }); return result; } function needsTransliteration(langCode) { var meta = metadata[langCode]; if (!meta || !meta.sc) return false; var scripts = Array.isArray(meta.sc) ? meta.sc : [meta.sc]; return scripts.length > 0 && scripts[0] !== "Latn"; } // Kodên cinsiyetê yên di metadata.g de var GENDER_BASE_LABELS = { m: "mê", n: "nêr", nt: "nêtar", mn: "mê û nêr", mnmane: "mê yan nêr li gorî maneyê", g: "giştî", y: "yekjimar", p: "pirjimar" }; // Sub-lists that only make sense for a plain (non-şablon) sense — hidden // when a şablon (e.g. {{guharto|…}}) is chosen for that sense, since a // template-based sense has no "own" gloss for alternate forms, synonyms, // antonyms, coordinate terms, hypernyms or hyponyms to attach to. Etîket, // Nimûne and Jêgirtin stay visible either way. var HIDDEN_ON_TPL_GROUPS = [ "wiktku-dfn-alternativ", "wiktku-dfn-hevmane", "wiktku-dfn-dijmane", "wiktku-dfn-koordine", "wiktku-dfn-jornav", "wiktku-dfn-jernav" ]; function genderLabel(code) { if (code === "p") return "Pirjimar"; var pluralMatch = code.match(/^(.+)-p$/); if (pluralMatch && GENDER_BASE_LABELS[pluralMatch[1]]) { return GENDER_BASE_LABELS[pluralMatch[1]] + " (pirjimar)"; } return GENDER_BASE_LABELS[code] || code; } /** * True if a sense has any content worth keeping besides its mane text — * etîket, hevmane/dijmane/koordîne/etc. word lists, nimûne, or jêder * (quote). Used so a sense with an empty mane but filled-in extra * fields still gets emitted (with {{mane?}} standing in for the gloss) * instead of being silently dropped. */ function senseHasExtraContent(s) { if (s.etiket && $.grep(s.etiket, function (e) { return $.trim(e) !== ""; }).length) return true; if (s.alternativ.length || s.hevmane.length || s.dijmane.length || s.koordine.length || s.jornav.length || s.jernav.length) return true; if (s.nimune && $.grep(s.nimune, function (n) { return (typeof n === "object" ? n.text : n) !== ""; }).length > 0) return true; if (s.jeder && $.grep(s.jeder, function (j) { return j && j.quote; }).length > 0) return true; return false; } /** * formatNimune: each nimûne item can be { text, tr, t }: * text — example text * tr — transliteration (only when the language needs it) * t — Kurdish translation (third positional param, no key) */ function formatNimune(nimunes, lang, hasJeder) { var hasNimune = nimunes && $.grep(nimunes, function (n) { return (typeof n === "object" ? n.text : n) !== ""; }).length > 0; if (!hasNimune) { return hasJeder ? "" : "\n#* {{bênimûne|" + lang + "}}"; } return $.map(nimunes, function (n) { var text = typeof n === "object" ? n.text : n; if (!text) return undefined; var bolded = text.replace( new RegExp("(" + pageNameRe + "([^( |,|;|\\?|\\.|\\!)]+)?)", "ig"), "'''$1'''"); var tpl = "\n#: {{nm|" + lang + "|" + bolded; if (typeof n === "object") { if (n.tr) tpl += "|tr=" + n.tr; // Translation as third positional param (no key needed). if (n.t) tpl += "|" + n.t; } // Short examples fit on one line together with their translation. // rêz=1 is not used for ku — definitions are shown on separate lines there. if (text.length < 200 && lang !== "ku") tpl += "|rêz=1"; tpl += "}}"; return tpl; }).join(""); } /** * Formats a list of jêder (quote/citation) objects into wikitext lines. * Each entry that has no quote text is skipped. Returns "" when the list * is empty or every entry is blank. * * #* {{jêder-…|lang|jêgirtin=…|tr=…|tercime=…|…fields…}} * * When no template is chosen, the generic {{jêder|…}} template is used * instead. Its 2nd positional param is the user's freeform "bi destê xwe * binivîsim" source text when supplied, or the çavkanî? placeholder otherwise. * If that text contains "=" it is passed as |2=… instead of a bare * positional param, since MediaWiki would otherwise misparse it as its * own key=value pair and break the template: * #* {{jêder|lang|jêgirtin=…|tr=…|tercime=…|<manual source or çavkanî?>}} */ function formatJeder(jederList, lang) { if (!jederList || !jederList.length) return ""; return $.map(jederList, function (jeder) { if (!jeder || !jeder.quote) return undefined; if (jeder.jederTpl) { var cite = "\n#* {{" + jeder.jederTpl + "|" + lang; cite += "|jêgirtin=" + jeder.quote; if (jeder.quoteTr) cite += "|tr=" + jeder.quoteTr; if (jeder.quoteT) cite += "|tercime=" + jeder.quoteT; $.each(jeder.jêderFields || {}, function (key, val) { if (val) cite += "|" + key + "=" + val; }); cite += "}}"; return cite; } var out = "\n#* {{jêder|" + lang + "|jêgirtin=" + jeder.quote; if (jeder.quoteTr) out += "|tr=" + jeder.quoteTr; if (jeder.quoteT) out += "|tercime=" + jeder.quoteT; var srcParam = jeder.jederManual ? jeder.jederManual : "çavkanî?"; // A positional param containing "=" gets parsed as its own key=value // pair by MediaWiki and breaks the template, so force it to be // explicitly named (|2=) whenever that's the case. out += (srcParam.indexOf("=") !== -1 ? "|2=" : "|") + srcParam; out += "}}"; return out; }).join(""); } function makeWordListStep(id, name, question_fmt, header, templateName) { return { id: id, name: name, question_fmt: question_fmt, multiple: true, narrow: true, visible: function (values) { return values.lang && values.pos; }, output: function (values) { var words = $.grep(values[id] || [], function (w) { return !!w; }); if (!words.length) return ""; var lang = values.lang; var section = "\n==== " + header + " ====\n"; if (words.length === 1) { // Single word — keep the simple inline template. return section + "* {{" + templateName + "|" + lang + "|" + words[0] + "}}\n"; } // Multiple words — use {{kol3}} with one positional param per word. var params = "cure=" + header + "\n" + $.map(words, function (w) { return "|" + w; }).join("\n"); return section + "{{kol3|" + lang + "|" + params + "\n}}\n"; } }; } var steps = { lang: { id: "lang", required: true, name: "ziman", question_fmt: '"' + pageName + '" bi çi zimanî ye?', question_br: true, // Populated from [[MediaWiki:Gadget-start.js/data.json]] (langChoices). choices: [], output: function (values) { return "== {{ziman|" + values.lang + "}} ==\n"; } }, pron: { id: "pron", name: "bilêvkirin", question_fmt: '"' + pageName + '" çawa tê telafûzkirin?', // pronTpls populated from data.json pronTpls: [], visible: function (values) { if (!values.lang) return false; // In addLangMode, only skip pron when this langcode's section // already exists in the page — if it's a new language, show it. if (addLangMode) { var existing = $("#wpTextbox1").val() || ""; var header = "== {{ziman|" + values.lang + "}} =="; return existing.indexOf(header) === -1; } return true; }, /** Fills (or refills) the insert-dropdown from the current pronTpls array, filtering by language. */ refreshTplSelect: function () { var sel = $("#wiktku-start-pron .wiktku-tpl-insert-select"); if (!sel.length) return; var lang = getValues().lang || ""; sel.find("option[value!='']").remove(); $.each(steps.pron.pronTpls, function (_, tpl) { // Filter: if tpl.langs exists, only show if lang is in that list; otherwise show always var allowed = !tpl.langs || tpl.langs.indexOf(lang) !== -1; if (allowed) { sel.append($("<option></option>") .val(tpl.snippet) .text(tpl.name + " — " + tpl.desc) .attr("data-nolang", tpl.noLang ? "1" : "")); } }); // Notify Chosen that the option list has changed (no-op on mobile). if (!isMobile) sel.trigger("chosen:updated"); }, build: function (stepDiv) { if (stepDiv.find(".wiktku-pron-wrap").length) return null; var wrap = $("<div class='wiktku-pron-wrap'></div>"); var ta = $("<textarea></textarea>") .attr("name", "wiktku-pron-" + $.now()) .attr("class", "wiktku-start-step-field wiktku-pron-text") .attr("rows", 4) .attr("placeholder", "Nimûne: {{IPA|ku|/pɛɪ̯n/}} yan {{kîte|ku|he|ce|ki|rin}}"); // Template insert dropdown — filtered by language. var sel = $("<select class='wiktku-tpl-insert-select'></select>"); sel.append($("<option value=''>— şablonek lê zêde bike —</option>")); var lang = getValues().lang || ""; $.each(steps.pron.pronTpls, function (_, tpl) { // Filter: if tpl.langs exists, only show if lang is in that list; otherwise show always var allowed = !tpl.langs || tpl.langs.indexOf(lang) !== -1; if (allowed) { sel.append($("<option></option>") .val(tpl.snippet) .text(tpl.name + " — " + tpl.desc) .attr("data-nolang", tpl.noLang ? "1" : "")); } }); sel.on("change", function () { var snippet = $(this).val(); if (!snippet) return; var lang = getValues().lang || ""; // Check if the selected option has noLang flag var selectedOption = sel.find("option:selected"); var hasNoLang = selectedOption.attr("data-nolang") === "1"; if (!hasNoLang) { snippet = snippet.replace(/CODE/g, lang).replace(/SOURCELANG/g, "?"); } insertAtCursor(ta[0], snippet); $(this).val(""); ta.focus(); }); wrap.append(sel).append($("<br>")).append(ta); stepDiv.append(wrap); return ta; }, output: function () { var text = $.trim($("#wiktku-start-pron .wiktku-pron-text").val()); if (!text) return ""; var lines = text.split("\n"); var out = $.map(lines, function (line) { line = $.trim(line); if (!line) return undefined; return line.charAt(0) === "*" ? line : "* " + line; }).join("\n"); return "\n=== Bilêvkirin ===\n" + out + "\n"; } }, pos: { id: "pos", required: true, name: "Cureyê rêzimanî", question_fmt: 'Cureyê rêzimanî yê "' + pageName + '" çi ye?', visible: function (values) { return values.lang; }, question_br: true, // Populated from [[MediaWiki:Gadget-start.js/data.json]] (posChoices). choices: [], output: function (values) { var pos = values.pos || ""; var cinsiyet = values.cinsiyet || ""; // from the cinsiyet step var lekTur = values.lektur || ""; // from the lêker transitivity step var capitalizedPos = capitalize(pos); var outputString = "\n=== " + capitalizedPos + " ===\n"; // Add ku-tewîn-nav for single-word navdêr/serenav with known gender. if (!pageName.includes(" ") && cinsiyet && GENDER_BASE_LABELS[cinsiyet] && (pos === "navdêr" || pos === "serenav") && values.lang === "ku") { outputString += "{{ku-tewîn-nav|" + pageName + "|" + GENDER_BASE_LABELS[cinsiyet]; if (pos === "serenav") outputString += "|y"; outputString += "}}\n"; } outputString += "{{" + pos + "|" + values.lang; if (pos === "navdêr" || pos === "serenav") { if (cinsiyet) { outputString += "|c=" + cinsiyet; } else if (values.lang === "ku") { // Unknown gender — prompt editor to fill it in. outputString += "|c=?"; } } else if (/^lêker/.test(pos) && lekTur) { outputString += "|c=" + lekTur; } if (values.tr) { outputString += "|tr=" + values.tr; } outputString += "}}\n"; return outputString; } }, /** * cinsiyet (grammatical gender) — only shown for navdêr/serenav, û * tenê ger metadata ji bo zimanê hilbijartî lîsteyeke "g" (cinsiyet) * were dayîn. Opsiyonên vê gavê ne sabît in — ji metadata[values.lang].g * têne çêkirin, ji ber ku di hemû zimanan de cinsiyet tine. */ cinsiyet: { id: "cinsiyet", name: "cinsiyet", question_fmt: 'Cinsiyeta "' + pageName + '" çi ye?', question_br: true, visible: function (values) { var meta = metadata[values.lang]; return !!(values.lang && (values.pos === "navdêr" || values.pos === "serenav") && meta && meta.g && meta.g.length); }, build: function (stepDiv, values) { var select = stepDiv.find("select.wiktku-start-step-field"); if (!select.length) { select = $(mw.html.element("select", { "class": "wiktku-start-step-field", id: "wiktku-start-cinsiyet-field" })); stepDiv.append(select); } if (!values) return select; var meta = metadata[values.lang]; var codes = (meta && meta.g) || []; var prevVal = select.val(); var choices = $.map(codes, function (code) { return [[code, genderLabel(code)]]; }); populateMenus(select, choices); if ($.grep(choices, function (c) { return c[0] === prevVal; }).length) { select.val(prevVal); } if (!isMobile) select.trigger("chosen:updated"); return select; }, output: function () { return ""; } // consumed by pos.output }, /** * Lêker transitivity — only shown for any lêker variant. */ lektur: { id: "lektur", name: "Cureyê lêkerê (fiîlê)", question_fmt: "Cureyê lêkerê (fiîlê) çi ye?", question_br: true, visible: function (values) { return values.lang && values.pos && /^lêker/.test(values.pos); }, // Dictionary: value → display label. Add new types here. choices: [ ["gh", "gerguhêz"], ['x-gh', 'xwerû-gerguhêz'], ['p-gh', 'pêkhatî-gerguhêz'], ['h-gh', 'hevedudanî-gerguhêz'], ['b-gh', 'biwêjî-gerguhêz'], ["ngh", "negerguhêz"], ['x-ngh', 'xwerû-negerguhêz'], ['p-ngh', 'pêkhatî-negerguhêz'], ['h-ngh', 'hevedudanî-negerguhêz'], ['b-ngh', 'biwêjî-negerguhêz'] ], output: function () { return ""; } // consumed by pos.output }, tr: { id: "tr", name: "transkrîpsiyon", question_fmt: "Transkrîpsiyona kelîmeyê", multiple: false, narrow: true, visible: function (values) { return values.lang && values.pos && needsTransliteration(values.lang); } }, dfn: { id: "dfn", // required: true, ger mane tinebe [[Şablon:mane?]] bi kar bîne name: "Mane", question_fmt: "Maneya kelîmeyê binivîse. Mane otomatîk tê lînkkirin! Ji bo tercimeyan beşa 'Werger' bi kar bîne!", multiple: true, ordered: true, rows: 3, visible: function (values) { return values.lang && values.pos; }, example: function (values) { // posExamples loaded from [[MediaWiki:Gadget-start.js/data.json]]. var examples = steps.dfn.posExamples || {}; var full = values.pos || ""; return examples[full] || ""; }, /** * Builds one sense block (<li>) inside the ordered list. * Each block contains: * - a textarea for the definition * - an expandable nimûne list * - single-row sub-lists for formên alternatîv, hevmane, dijmane */ buildSenseBlock: function (stepDiv) { var block = $("<li class='wiktku-dfn-sense'></li>"); // — Mane textarea (declared first so the template handler can reference it) — var dfnArea = $("<textarea></textarea>") .attr("name", "wiktku-dfn-mane-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("class", "wiktku-start-step-field wiktku-dfn-mane") .attr("rows", 6) .attr("placeholder", "Mane…"); dfnArea.on("input", function () { steps.dfn.onDfnInput(stepDiv, block, this); }); // — Template selector (optional — replaces mane when chosen) — // Template definitions loaded from [[MediaWiki:Gadget-start.js/data.json]]. var tplDefs = steps.dfn.tplDefs || []; // Cache of all non-placeholder option elements — used by updateTplOptions // to remove/re-add options (the only approach compatible with Chosen.js). var _allTplOptions = []; var tplSelect = $(mw.html.element("select", { "class": "wiktku-dfn-tpl-select" })); tplSelect.append($("<option value=''>— yan jî şablonek hilbijêre —</option>")); $.each(tplDefs, function (_, tpl) { var opt = $("<option></option>") .val(tpl.name) .text(tpl.name) .attr("data-langs", tpl.langs ? tpl.langs.join(",") : "") .attr("data-nolang", tpl.noLang ? "1" : ""); tplSelect.append(opt); _allTplOptions.push(opt[0]); }); function updateTplOptions() { var lang = getValues().lang || ""; var currentVal = tplSelect.val(); var currentStillValid = false; // Detach all non-placeholder options, then re-attach only the visible ones. // This is the only approach that works correctly with both native <select> // and Chosen.js on desktop. tplSelect.find("option[value!='']").detach(); $.each(_allTplOptions, function (_, opt) { var allowed = $(opt).attr("data-langs"); var visible = !allowed || allowed.split(",").indexOf(lang) !== -1; if (visible) { tplSelect.append(opt); if ($(opt).val() === currentVal) currentStillValid = true; } }); if (!isMobile) tplSelect.trigger("chosen:updated"); if (currentVal && !currentStillValid) { tplSelect.val(""); dfnArea.show(); tplTitleInput.hide().val(""); } } // Store updater on the element so refresh() can call it for all blocks. tplSelect.data("updateOptions", updateTplOptions); var tplTitleInput = $("<input type='text'>") .addClass("wiktku-dfn-tpl-title wiktku-start-narrow") .attr("placeholder", "Navê rûpelê…") .hide(); // Grow the sense list when the title field of the last block gets content, // mirroring what onDfnInput does for the plain mane textarea. tplTitleInput.on("input", function () { steps.dfn.onDfnInput(stepDiv, block, this); }); /** * When a şablon sense is chosen, formên alternatîv/hevmane/dijmane/ * termên koordîne/jornav/jêrnav don't apply (there's no plain gloss * to hang them off), so hide those subgroups. Etîket, Nimûne and * Jêgirtin stay visible and still usable for a şablon sense. */ function updateFieldVisibility() { var isTpl = !!tplSelect.val(); $.each(HIDDEN_ON_TPL_GROUPS, function (_, cls) { block.find("." + cls + "-group").toggle(!isTpl); }); } // Store on the block so restoreDfn() can re-sync visibility // after programmatically setting tplSelect's value. block.data("updateFieldVisibility", updateFieldVisibility); tplSelect.on("change", function () { var chosen = $(this).val(); if (chosen) { dfnArea.hide(); tplTitleInput.show().focus(); } else { dfnArea.show(); tplTitleInput.hide().val(""); } updateFieldVisibility(); // Re-run refresh so the Werger step visibility updates. refresh(); }); var tplRow = $("<div></div>").addClass("wiktku-dfn-tpl-row") .append(tplSelect).append(" ").append(tplTitleInput); block.append(tplRow); block.append(dfnArea); // Apply lang filter on initial build. updateTplOptions(); // — Sub-field groups — // All groups are always visible with a placeholder textarea. // Nimûne is last in the DOM and last in the output. var allGroups = [ { cls: "wiktku-dfn-etiket", label: "Etîket", rows: 1, narrow: true, izah: "xisûsen, Mêrdîn, anatomî, Badînî" }, { cls: "wiktku-dfn-alternativ", label: "Formên alternatîv", rows: 1, narrow: true, izah: "Varyantên vê kelîmeyê" }, { cls: "wiktku-dfn-hevmane", label: "Hevmane", rows: 1, narrow: true, izah: "Spehî hevmaneya Bedew e." }, { cls: "wiktku-dfn-dijmane", label: "Dijmane", rows: 1, narrow: true, izah: "Zengîn dijmaneya feqîr e." }, { cls: "wiktku-dfn-koordine", label: "Termên koordîne", rows: 1, narrow: true, izah: "Pisîk û kûçik termên koordîne ne çunkî Jornavên wan gelek in" }, { cls: "wiktku-dfn-jornav", label: "Jornav", rows: 1, narrow: true, izah: "Heywan jornavê guhandar e" }, { cls: "wiktku-dfn-jernav", label: "Jêrnav", rows: 1, narrow: true, izah: "Guhandar jêrnavê heywan e" }, { cls: "wiktku-dfn-nimune", label: "Nimûne", rows: 2, narrow: false } ]; $.each(allGroups, function (_, g) { var groupDiv = $("<div></div>").addClass("wiktku-dfn-subgroup " + g.cls + "-group"); function buildNimuneLi() { var lang = getValues().lang || ""; var li = $("<li></li>").addClass("wiktku-dfn-nimune-li"); var mainTa = $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-text-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", g.rows) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-text") .attr("placeholder", "Nimûneya emilandina kelîmeyê tu bi xwe binivîse…"); mainTa.on("input", function () { var val = $.trim($(this).val()); var isLast = li.is(list.children("li:last-child")); if (val && isLast) { list.append(buildNimuneLi()); } }); li.append(mainTa); var subWrap = $("<div></div>").addClass("wiktku-dfn-nimune-sub"); if (needsTransliteration(lang)) { subWrap.append( $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-tr-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 5) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-tr") .attr("placeholder", "Transkrîpsiyona bi alfabeya latînî") ); } if (lang && lang !== "ku") { subWrap.append( $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-t-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 5) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-t") .attr("placeholder", "Tercimeya kurmancî") ); } if (subWrap.children().length) li.append(subWrap); return li; } if (g.cls === "wiktku-dfn-nimune") { // Nimûne — compound widget with tr/t sub-fields. var lbl = $("<span></span>").addClass("wiktku-dfn-sublabel").text(g.label + ": "); var list = $("<ol></ol>").addClass("wiktku-dfn-sublist " + g.cls + "-list"); groupDiv.data("buildNimuneLi", buildNimuneLi); list.append(buildNimuneLi()); groupDiv.append(lbl).append(list); block.append(groupDiv); } else { // Regular always-visible group — label + growing textarea list. var lbl = $("<span></span>").addClass("wiktku-dfn-sublabel").text(g.label + ": " + g.izah); var list = $("<ol></ol>").addClass("wiktku-dfn-sublist " + g.cls + "-list"); var firstInput = $("<textarea></textarea>") .attr("name", g.cls + "-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", g.rows) .attr("class", "wiktku-dfn-subfield" + (g.narrow ? " wiktku-start-narrow" : "")) .attr("placeholder", g.label + "…"); firstInput.on("input", function () { steps.dfn.onSubInput(list, this, g.rows, g.narrow); }); list.append($("<li></li>").append(firstInput)); groupDiv.append(lbl).append(list); block.append(groupDiv); } }); // — Jêder (quote / citation) group — a growing list, sibling to Nimûne — // Structured the same way as Nimûne (ol.wiktku-dfn-sublist > li) so it // lines up at the same indentation, and so that typing into the last // citation's Jêgirtin box automatically opens a fresh empty one below it. (function () { var jederGroupDiv = $("<div></div>").addClass("wiktku-dfn-subgroup wiktku-dfn-jeder-group"); var jederLbl = $("<span></span>").addClass("wiktku-dfn-sublabel").text("Jêgirtin: "); var jederList = $("<ol></ol>").addClass("wiktku-dfn-sublist wiktku-dfn-jeder-list"); function buildJederLi() { var lang = getValues().lang || ""; var li = $("<li></li>").addClass("wiktku-dfn-jeder-li"); var dragHandle = $("<span></span>") .addClass("wiktku-jeder-drag-handle") .attr("title", "Bişkûne û bikişîne da ku rêzê biguhezîne") .html("⠿"); // Quote text textarea var quoteTa = $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-quote-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 2) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-quote") .attr("placeholder", "Nimûneya emilandinê ji kitêb an çavkaniyeke din binivîse"); quoteTa.on("input", function () { var val = $.trim($(this).val()); var isLast = li.is(jederList.children("li:last-child")); if (val && isLast) { jederList.append(buildJederLi()); } }); li.append(dragHandle).append(quoteTa); // tr/t sub-fields for the quote — shown as needed for the language. var quoteSubWrap = $("<div></div>").addClass("wiktku-dfn-quote-sub"); if (needsTransliteration(lang)) { quoteSubWrap.append( $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-quote-tr-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 2) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-quote-tr") .attr("placeholder", "Transkrîpsiyona jêgirtinê…") ); } if (lang && lang !== "ku") { quoteSubWrap.append( $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-quote-t-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 2) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-quote-t") .attr("placeholder", "Tercimeya jêgirtinê bi kurmancî") ); } if (quoteSubWrap.children().length) li.append(quoteSubWrap); // Citoid auto-fill: fetch citation data from a URL, DOI or ISBN and // prefill the source şablon + fields below (see Gadget-citoid-helper.js). var citoidWrap = $("<div></div>").addClass("wiktku-dfn-quote-citoid"); var citoidInput = $("<input type='text'>") .addClass("wiktku-dfn-quote-citoid-input wiktku-start-narrow") .attr("placeholder", "URL, DOI an ISBN binivîse ku otomatîk were tijekirin…"); var citoidBtn = new OO.ui.ButtonWidget({ label: "Bi Citoid bîne", classes: [ "wiktku-dfn-quote-citoid-btn" ] }); var citoidStatus = $("<span></span>").addClass("wiktku-dfn-quote-citoid-status"); /** * Fetches citation data from Citoid and applies it to this * citation's şablon selector + fields. Mirrors the logic in * Form.prototype._fillFromCitoid (Gadget-wikt.add-examples.js): * - only (re)selects the şablon when it actually differs from * what's already chosen, so a repeat fetch doesn't wipe out * a template the user already picked; * - only fills fields that are currently empty, so it never * overwrites something the user typed by hand; * - falls back to the freeform "bi destê xwe binivîsim" source * only when nothing was typed there yet. */ function runCitoidFetch() { var query = $.trim(citoidInput.val()); if (!query) { mw.notify("Ji kerema xwe re pêşî URL, DOI an ISBNyekê binivîse."); return; } citoidBtn.setDisabled(true); citoidStatus.text("Tê anîn…"); wikt.citoidHelper.ensure().then(function () { return wikt.citoid.fetchJederFields(query); }).then(function (result) { var jederKey = result.jederKey; var hasTpl = !!jederKey && srcSel.find("option[value='" + jederKey + "']").length > 0; var targetVal = hasTpl ? jederKey : "__manual__"; // Only (re)select — and thus rebuild — the field rows if // we're switching to a different şablon than what's // already chosen, so a second fetch doesn't clear fields // the user already filled in by hand. if (srcSel.val() !== targetVal) { srcSel.val(targetVal).trigger("change"); srcSel.trigger("chosen:updated"); } if (hasTpl) { // Tenê qadên vala tijî bike. $.each(result.fields, function (key, val) { var input = srcFields.find("input[data-field-key='" + key + "']"); if (input.length && !$.trim(input.val())) { input.val(val); } }); } else { // Şablonek nehat naskirin ji bo vê itemType — rêzikeke // çavkaniyê ya bi destan a ji qadên Citoid tê çêkirin, // lê tenê ger qada destan vala be. var manualField = srcFields.find(".wiktku-dfn-quote-src-manual"); if (!$.trim(manualField.val())) { var parts = []; $.each(["nivîskar", "sernav", "websîte", "kovar", "weşanxane", "sal", "url"], function (_, k) { if (result.fields[k]) parts.push(result.fields[k]); }); manualField.val(parts.join(", ")); } } citoidStatus.text(""); }, function (errorMsg) { citoidStatus.text(typeof errorMsg === "string" ? errorMsg : "Nehat dîtin. Kontrol bike ka URL/DOI/ISBN rast e."); }).always(function () { citoidBtn.setDisabled(false); }); } citoidBtn.on("click", runCitoidFetch); citoidInput.on("keydown", function (e) { if (e.which === 13) { // Enter e.preventDefault(); runCitoidFetch(); } }); citoidWrap.append(citoidInput).append(citoidBtn.$element).append(citoidStatus); // Source template selector, specific to this citation. var srcSel = $("<select></select>").addClass("wiktku-dfn-quote-src-sel"); srcSel.append($("<option value=''>— Çavkaniyê hilbijêre —</option>")); srcSel.append($("<option></option>").val("__manual__").text("Bi destê xwe binivîsim")); var jederDefs = steps.dfn.jederDefs || {}; $.each(jederDefs, function (tplName, def) { srcSel.append($("<option></option>").val(tplName).text(def.label)); }); // Dynamic source fields container. var srcFields = $("<div></div>").addClass("wiktku-dfn-quote-src-fields"); srcSel.on("change", function () { srcFields.empty(); var chosen = $(this).val(); if (!chosen) return; if (chosen === "__manual__") { // Freeform source, written by the user — becomes the 2nd // positional param of {{jêder|lang|…}} instead of çavkanî?. srcFields.append( $("<textarea></textarea>") .attr("rows", 4) .addClass("wiktku-dfn-subfield wiktku-dfn-quote-src-manual") .attr("placeholder", "Çavkaniyê bi destê xwe binivîse…") ); return; } var def = (steps.dfn.jederDefs || {})[chosen]; if (!def) return; $.each(def.fields, function (_, f) { var row = $("<div></div>").addClass("wiktku-dfn-quote-src-row"); var fieldLbl = $("<label></label>").text(f.label + ": "); var inp = $("<input type='text'>") .addClass("wiktku-dfn-quote-src-input wiktku-start-narrow") .attr("data-field-key", f.key) .attr("placeholder", f.label + "…"); row.append(fieldLbl).append(inp); srcFields.append(row); }); }); li.append(citoidWrap).append(srcSel).append(srcFields); return li; } jederGroupDiv.data("buildJederLi", buildJederLi); jederList.append(buildJederLi()); // Make citation rows sortable (drag to reorder). // The last row is always the empty trailing row — cancel its drag. mw.loader.using("jquery.ui.sortable", function () { jederList.sortable({ handle: ".wiktku-jeder-drag-handle", axis: "y", items: "li:not(:last-child)", tolerance: "pointer" }); }); jederGroupDiv.append(jederLbl).append(jederList); block.append(jederGroupDiv); }()); // Apply the initial hide/show state for the sub-groups (matches // tplSelect's starting value, which is normally empty). updateFieldVisibility(); return block; }, /** Grows the sense list when the last mane textarea gets content. */ onDfnInput: function (stepDiv, block, textarea) { var val = $.trim($(textarea).val()); var list = stepDiv.find("ol.wiktku-dfn-list"); var isLast = block.is(list.children("li:last-child")); if (val && isLast) { var newBlock = steps.dfn.buildSenseBlock(stepDiv); list.append(newBlock); // Apply Chosen to the new block's template selector on desktop. if (!isMobile) newBlock.find("select.wiktku-dfn-tpl-select").chosen(chosenOptions); } refresh(); }, /** Grows a sub-list (nimûne/formên alternatîv/hevmane/dijmane/termên koordîne) on input. */ onSubInput: function (list, input, rows, narrow) { var val = $.trim($(input).val()); var item = $(input).parent(); var isLast = item.is(list.children("li:last-child")); if (val && isLast) { var next = $("<textarea></textarea>") .attr("name", "wiktku-dfn-sub-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", rows) .attr("class", "wiktku-dfn-subfield" + (narrow ? " wiktku-start-narrow" : "")); next.on("input", function () { steps.dfn.onSubInput(list, this, rows, narrow); }); list.append($("<li></li>").append(next)); } }, // Populated from [[MediaWiki:Gadget-start.js/data.json]] (tplDefs, posExamples, jederDefs). tplDefs: [], posExamples: {}, jederDefs: {}, build: function (stepDiv) { if (stepDiv.find("ol.wiktku-dfn-list").length) return null; var list = $("<ol class='wiktku-dfn-list'></ol>"); list.append(steps.dfn.buildSenseBlock(stepDiv)); stepDiv.append(list); return null; }, /** Reads all sense blocks from the DOM and returns an array of sense objects. */ getSenses: function (stepDiv) { var senses = []; stepDiv.find("li.wiktku-dfn-sense").each(function () { var block = $(this); var tplSel = block.find("select.wiktku-dfn-tpl-select"); var tpl = tplSel.val() || ""; // noLang: template already encodes the language — don't add |lang| param. var tplNoLang = tpl ? tplSel.find("option[value='" + tpl + "']").attr("data-nolang") === "1" : false; var tplTitle = $.trim(block.find("input.wiktku-dfn-tpl-title").val()); var mane = $.trim(block.find("textarea.wiktku-dfn-mane").val()); var etiket = (function () { var vals = []; block.find(".wiktku-dfn-etiket-list textarea").each(function () { var v = $.trim($(this).val()); if (v) vals.push(v); }); return vals; }()); function readList(cls) { var vals = []; block.find("." + cls + "-list textarea").each(function () { var v = $.trim($(this).val()); if (v) vals.push(v); }); return vals; } // Nimûne items are compound: { text, tr?, t? } function readNimuneList() { var items = []; block.find(".wiktku-dfn-nimune-list li.wiktku-dfn-nimune-li").each(function () { var text = $.trim($(this).find(".wiktku-dfn-nimune-text").val()); if (!text) return; var obj = { text: text }; var tr = $.trim($(this).find(".wiktku-dfn-nimune-tr").val()); var t = $.trim($(this).find(".wiktku-dfn-nimune-t").val()); if (tr) obj.tr = tr; if (t) obj.t = t; items.push(obj); }); return items; } // Jêder is a growing list of citations, one per li — mirrors readNimuneList(). function readJederList() { var items = []; block.find(".wiktku-dfn-jeder-list li.wiktku-dfn-jeder-li").each(function () { var li = $(this); var quote = $.trim(li.find(".wiktku-dfn-nimune-quote").val()); if (!quote) return; var obj = { quote: quote }; var qtr = $.trim(li.find(".wiktku-dfn-nimune-quote-tr").val()); var qt = $.trim(li.find(".wiktku-dfn-nimune-quote-t").val()); if (qtr) obj.quoteTr = qtr; if (qt) obj.quoteT = qt; var tplName = li.find(".wiktku-dfn-quote-src-sel").val(); if (tplName === "__manual__") { var manual = $.trim(li.find(".wiktku-dfn-quote-src-manual").val()); if (manual) obj.jederManual = manual; } else if (tplName) { obj.jederTpl = tplName; var fields = {}; li.find(".wiktku-dfn-quote-src-input").each(function () { var k = $(this).attr("data-field-key"); var v = $.trim($(this).val()); if (k && v) fields[k] = v; }); obj.jêderFields = fields; } items.push(obj); }); return items; } senses.push({ tpl: tpl, tplNoLang: tplNoLang, tplTitle: tplTitle, mane: mane, etiket: etiket, nimune: readNimuneList(), jeder: readJederList(), alternativ: readList("wiktku-dfn-alternativ"), hevmane: readList("wiktku-dfn-hevmane"), dijmane: readList("wiktku-dfn-dijmane"), koordine: readList("wiktku-dfn-koordine"), jornav: readList("wiktku-dfn-jornav"), jernav: readList("wiktku-dfn-jernav") }); }); return senses; }, getOutput: function (values, callback) { var stepDiv = $("#wiktku-start-dfn"); var senses = steps.dfn.getSenses(stepDiv); var lang = values.lang; // A sense counts as "filled" if it has a mane, a chosen template + title, // or any other content (etîket/hevmane/nimûne/jêder…) worth keeping. var hasMane = senses.some(function (s) { return s.mane !== "" || (s.tpl && s.tplTitle) || senseHasExtraContent(s); }); // True only when at least one sense has a regular mane (needs linkify). var hasRegularMane = senses.some(function (s) { return !s.tpl && s.mane !== ""; }); // nimûne and jêder lines must never pass through linkify — only // the plain mane text should be linkified. We build two parallel // arrays: defLines (sent to linkify) and citeLines (kept aside). // Each entry in citeLines corresponds 1-to-1 with a defLines entry; // a template token {{wiktku-cite-N}} is embedded in defLines so // that after linkify runs we know exactly where to splice them back. // Template-call syntax is guaranteed safe: linkifiers leave {{ }} // tokens completely untouched. var defLines = []; // one entry per kept sense (goes to linkify) var citeLines = []; // parallel — nimûne+jêder for that same sense $.each(senses, function (_, sense) { // — Template sense (e.g. {{guharto|ku|somepage}}) — if (sense.tpl) { if (!sense.tplTitle) return; // skip empty template senses var tplLabelTpl = ""; if (sense.etiket && sense.etiket.length) { var tplLabelParts = sense.etiket.map(function (part) { return $.trim(part); }).filter(function (part) { return part !== ""; }); if (tplLabelParts.length) { tplLabelTpl = " {{e|" + lang + "|" + tplLabelParts.join("|") + "}} "; } } var tplCall = sense.tplNoLang ? "{{" + sense.tpl + "|" + sense.tplTitle + "}}" : "{{" + sense.tpl + "|" + lang + "|" + sense.tplTitle + "}}"; var tplHasJeder = sense.jeder && $.grep(sense.jeder, function (j) { return j && j.quote; }).length > 0; var idx = defLines.length; var cite = formatNimune(sense.nimune, lang, tplHasJeder) + formatJeder(sense.jeder, lang); defLines.push("#" + (tplLabelTpl ? tplLabelTpl : " ") + tplCall + (cite ? "{{wiktku-cite-" + idx + "}}" : "")); citeLines.push(cite); return; } // — Normal mane sense — var dfn = sense.mane; if (!dfn && !senseHasExtraContent(sense)) return; // truly empty if (dfn) { dfn = stripWikilinks(dfn); if (dfn[0] !== dfn[0].toUpperCase()) dfn = capitalize(dfn); if (!dfn.match(/[.…?!)\]]$/)) dfn += "."; } else { dfn = "{{mane?|" + lang + "}}"; } var labelTpl = ""; if (sense.etiket && sense.etiket.length) { var labelParts = sense.etiket.map(function (part) { return $.trim(part); }).filter(function (part) { return part !== ""; }); if (labelParts.length) { labelTpl = " {{e|" + lang + "|" + labelParts.join("|") + "}} "; } } var out = "#" + (labelTpl ? labelTpl : " ") + dfn; function wordLine(tpl, words) { if (!words.length) return ""; return "\n#: {{" + tpl + "|" + lang + "|" + words.join("|") + "}}"; } out += wordLine("alt-r", sense.alternativ); out += wordLine("hevmane", sense.hevmane); out += wordLine("dijmane", sense.dijmane); out += wordLine("koordîne", sense.koordine); out += wordLine("jornav", sense.jornav); out += wordLine("jêrnav", sense.jernav); var hasJeder = sense.jeder && $.grep(sense.jeder, function (j) { return j && j.quote; }).length > 0; var cite = formatNimune(sense.nimune, lang, hasJeder) + formatJeder(sense.jeder, lang); var idx = defLines.length; defLines.push(out + (cite ? "{{wiktku-cite-" + idx + "}}" : "")); citeLines.push(cite); }); // Splice citeLines back into a linkified string, replacing each // {{wiktku-cite-N}} token with its stored nimûne/jêder block. function restoreCites(t) { return t.replace(/\{\{wiktku-cite-(\d+)\}\}/g, function (_, n) { return citeLines[parseInt(n, 10)] || ""; }); } var text = defLines.join("\n") + "\n"; if (!hasMane) { // No definitions entered — emit {{mane?}} with bênimûne. text = "# {{mane?|" + lang + "}}\n#* {{bênimûne|" + lang + "}}\n"; callback(text); return; } if (!hasRegularMane) { // All filled senses are template senses — no linkify needed. callback(restoreCites(text)); return; } var didTryToLoad = function () { if (typeof $.wiktviLinkify === "function") { $.wiktviLinkify(text, function (linked) { callback(restoreCites(linked)); }); } else { callback(restoreCites(text)); } }; mw.loader.using("ext.gadget.linkify", didTryToLoad, didTryToLoad); } }, je: makeWordListStep("je", "jê", "Kelîmeyên jê çêbûyî binivîse", "Jê", "g"), tekildar: makeWordListStep("tekildar", "têkildar", "Kelîmeyên ji aliyê etîmolojiyê ve têkildarî vê kelîmeyê binivîse", "Têkildar", "g"), binereherwiha: makeWordListStep("binereherwiha", "binêre herwiha", "Kelîmeyên din ên eleqedar binivîse", "Binêre herwiha", "g"), etym: { id: "etym", name: "etîmolojî", question_fmt: "Etîmolojiya kelîmeyê binivîse", // etymTpls populated from data.json etymTpls: [], visible: function (values) { return values.lang && values.pos; }, /** Fills (or refills) the insert-dropdown from the current etymTpls array. */ refreshTplSelect: function () { var sel = $("#wiktku-start-etym .wiktku-tpl-insert-select"); if (!sel.length) return; sel.find("option[value!='']").remove(); $.each(steps.etym.etymTpls, function (_, tpl) { sel.append($("<option></option>").val(tpl.snippet).text(tpl.name + " — " + tpl.desc)); }); // Notify Chosen that the option list has changed (no-op on mobile). if (!isMobile) sel.trigger("chosen:updated"); }, build: function (stepDiv) { if (stepDiv.find(".wiktku-etym-wrap").length) return null; var wrap = $("<div class='wiktku-etym-wrap'></div>"); var ta = $("<textarea></textarea>") .attr("name", "wiktku-etym-" + $.now()) .attr("class", "wiktku-start-step-field wiktku-etym-text") .attr("rows", 4) .attr("placeholder", "Nimûne: Ji {{ji|en|ku|apple}}. yan rasterast binivîse…"); // Template insert dropdown — options also refreshed after data.json loads. var sel = $("<select class='wiktku-tpl-insert-select'></select>"); sel.append($("<option value=''>— şablonek lê zêde bike —</option>")); $.each(steps.etym.etymTpls, function (_, tpl) { sel.append($("<option></option>").val(tpl.snippet).text(tpl.name + " — " + tpl.desc)); }); sel.on("change", function () { var snippet = $(this).val(); if (!snippet) return; var lang = getValues().lang || ""; snippet = snippet.replace(/CODE/g, lang).replace(/SOURCELANG/g, "?"); insertAtCursor(ta[0], snippet); $(this).val(""); ta.focus(); }); wrap.append(sel).append($("<br>")).append(ta); stepDiv.append(wrap); return ta; }, output: function (values) { var text = $.trim($("#wiktku-start-etym .wiktku-etym-text").val()); if (text) { return "\n==== Etîmolojî ====\n" + text + "\n"; } // No etymology entered — emit {{ji?|lang}} as a placeholder, // but only when the entry has at least one regular (non-şablon) // sense with content — either real mane text, or an empty mane // with other fields filled in (which dfn.getOutput() renders as // {{mane?|lang}} with those fields attached). A şablon sense // like {{guharto|…}} never counts, filled in or not. var dfnSenses = steps.dfn.getSenses($("#wiktku-start-dfn")); var hasRegularMane = dfnSenses.some(function (s) { return !s.tpl && (s.mane !== "" || senseHasExtraContent(s)); }); if (!hasRegularMane) return ""; return "\n==== Etîmolojî ====\n{{ji?|" + values.lang + "}}\n"; } }, dunde: { id: "dunde", name: "dûnde", question_fmt: "Eger ev kelîme ji vî zimanî ketibe zimanekî din, vî zimanî û kelîmeya wî binivîse", visible: function (values) { return !!values.pos; }, disabledKeys: { "navz": true}, /** * Builds one row: a language dropdown + a growing list of word * inputs. When the dropdown gets a value the next empty row is * appended automatically. Mirrors steps.trans's row widget, but * flat (one shared list — dûnde isn't tied to individual senses). */ buildRow: function (stepDiv) { var row = $("<li class='wiktku-dunde-row wiktku-lang-row'></li>"); // Language selector — chosen is applied after insertion into DOM. var langSel = $(mw.html.element("select", { "class": "wiktku-start-step-keyfield wiktku-start-narrow" })); langSel.attr("data-placeholder", "Zimanekî lê bigere"); populateMenus(langSel, steps.dunde.keys || [], steps.dunde.disabledKeys); // When a language is chosen, ensure a next empty row exists. langSel.on("change", function () { steps.dunde.onLangChange(stepDiv, row); }); // Word list for this language. var wordList = $("<ul class='wiktku-dunde-words wiktku-lang-row-words'></ul>"); var firstWord = steps.dunde.makeWordInput(); wordList.append($("<li></li>").append(firstWord)); if (isMobile) { row.append(wrapNativeSelect(langSel)).append(wordList); } else { row.append(langSel).append(wordList); } return row; }, makeWordInput: function () { var input = $("<textarea></textarea>") .attr("name", "wiktku-dunde-word-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 1) .attr("class", "wiktku-dfn-subfield wiktku-start-narrow") .attr("placeholder", "Kelîme…"); input.on("input", function () { var list = $(this).closest("ul.wiktku-dunde-words"); var item = $(this).parent(); var val = $.trim($(this).val()); if (val && item.is(list.children("li:last-child"))) { var next = steps.dunde.makeWordInput(); list.append($("<li></li>").append(next)); } }); return input; }, onLangChange: function (stepDiv, row) { var list = stepDiv.find("ul.wiktku-dunde-list"); var isLast = row.is(list.children("li.wiktku-dunde-row:last-child")); if (isLast) { var newRow = steps.dunde.buildRow(stepDiv); list.append(newRow); // Init chosen after the new row is in the DOM (desktop only). if (!isMobile) newRow.find("select").chosen(chosenOptions); } // Keep disabled keys in sync across all lang selectors. steps.dunde.syncDisabledKeys(stepDiv); }, /** Disables already-selected languages in all other dropdowns. */ syncDisabledKeys: function (stepDiv) { var taken = $.extend({}, steps.dunde.disabledKeys); stepDiv.find("li.wiktku-dunde-row select").each(function () { var v = $(this).val(); if (v) taken[v] = true; }); stepDiv.find("li.wiktku-dunde-row select").each(function () { var self = $(this); var own = self.val(); self.find("option").each(function () { var code = $(this).val(); if (!code) return; $(this).prop("disabled", taken[code] && code !== own); }); self.trigger("chosen:updated"); }); }, build: function (stepDiv) { if (stepDiv.find("ul.wiktku-dunde-list").length) return null; var list = $("<ul class='wiktku-dunde-list wiktku-lang-row-list'></ul>"); list.append(steps.dunde.buildRow(stepDiv)); stepDiv.append(list); // Init chosen after the select is in the DOM (desktop only). if (!isMobile) list.find("select").chosen(chosenOptions); return null; }, /** Reads all [langcode, words[]] rows from the DOM. */ getRows: function (stepDiv) { var result = []; stepDiv.find("li.wiktku-dunde-row").each(function () { var lang = $(this).find("select").val(); if (!lang) return; var words = []; $(this).find("ul.wiktku-dunde-words textarea").each(function () { var v = $.trim($(this).val()); if (v) words.push(v); }); if (words.length) result.push([lang, words]); }); return result; }, output: function () { var stepDiv = $("#wiktku-start-dunde"); var rows = steps.dunde.getRows(stepDiv); if (!rows.length) return ""; var lines = $.map(rows, function (row) { var lang = row[0], words = row[1]; return "* {{dû|" + lang + "|" + words.join("|") + "}}"; }); return "\n==== Dûnde ====\n" + lines.join("\n") + "\n"; } }, zarava: { id: "zarava", name: "bi zaravayên din", visible: function (values) { return steps.trans.visible(values); }, disabledKeys: { "navz": true }, buildRow: function (group) { var row = $("<li class='wiktku-zarava-row wiktku-lang-row'></li>"); var langSel = $(mw.html.element("select", { "class": "wiktku-start-step-keyfield wiktku-start-narrow" })); populateMenus(langSel, steps.zarava.keys || [], steps.zarava.disabledKeys); langSel.on("change", function () { steps.zarava.onLangChange(group, row); }); var wordList = $("<ul class='wiktku-zarava-words wiktku-lang-row-words'></ul>"); var firstWord = steps.zarava.makeWordInput(); wordList.append($("<li></li>").append(firstWord)); row.append(langSel).append(wordList); return row; }, makeWordInput: function () { var input = $("<textarea></textarea>") .attr("name", "wiktku-zarava-word-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 1) .attr("class", "wiktku-dfn-subfield wiktku-start-narrow") .attr("placeholder", "Tercime…"); input.on("input", function () { var list = $(this).closest("ul.wiktku-zarava-words"); var item = $(this).parent(); var val = $.trim($(this).val()); if (val && item.is(list.children("li:last-child"))) { var next = steps.zarava.makeWordInput(); list.append($("<li></li>").append(next)); } }); return input; }, onLangChange: function (group, row) { var list = group.find("ul.wiktku-zarava-list"); var isLast = row.is(list.children("li.wiktku-zarava-row:last-child")); if (isLast) { var newRow = steps.zarava.buildRow(group); list.append(newRow); } steps.zarava.syncDisabledKeys(group); }, /** Disables already-selected dialects in all other dropdowns within one group. */ syncDisabledKeys: function (group) { var taken = $.extend({}, steps.zarava.disabledKeys); group.find("li.wiktku-zarava-row select").each(function () { var v = $(this).val(); if (v) taken[v] = true; }); group.find("li.wiktku-zarava-row select").each(function () { var self = $(this); var own = self.val(); self.find("option").each(function () { var code = $(this).val(); if (!code) return; $(this).prop("disabled", taken[code] && code !== own); }); }); }, /** Builds (or fetches) the .wiktku-zarava-group for one gloss. */ buildGroup: function (stepDiv, gi) { var group = $("<div class='wiktku-zarava-group'></div>").attr("data-gloss-pos", gi); var list = $("<ul class='wiktku-zarava-list wiktku-lang-row-list'></ul>"); list.append(steps.zarava.buildRow(group)); group.append(list); stepDiv.append(group); return group; }, /** Syncs one .wiktku-zarava-group per current gloss (same logic as steps.trans.build). */ build: function (stepDiv) { var glosses = steps.trans.glossList(); if (!glosses.length) { stepDiv.find(".wiktku-zarava-group").remove(); return null; } var existingGroups = stepDiv.find(".wiktku-zarava-group"); if (existingGroups.length > glosses.length) { existingGroups.slice(glosses.length).remove(); } $.each(glosses, function (gi, gloss) { var group = stepDiv.find(".wiktku-zarava-group[data-gloss-pos='" + gi + "']"); if (!group.length) group = steps.zarava.buildGroup(stepDiv, gi); var label = group.find(".wiktku-zarava-group-label"); if (glosses.length > 1) { if (!label.length) { label = $("<div class='wiktku-zarava-group-label'></div>"); group.prepend(label); } label.text(gloss.index + " " + gloss.text); } else if (label.length) { label.remove(); } }); return null; }, /** Reads the dialect rows for a single gloss group. */ getGroupTranslations: function (group) { var result = []; group.find("li.wiktku-zarava-row").each(function () { var lang = $(this).find("select").val(); if (!lang) return; var words = []; $(this).find("ul.wiktku-zarava-words textarea").each(function () { var v = $.trim($(this).val()); if (v) words.push(v); }); if (words.length) result.push([lang, words]); }); return result; }, /** Reads all rows from the DOM, grouped by gloss position. */ getTranslations: function (stepDiv) { var result = []; stepDiv.find(".wiktku-zarava-group").each(function () { result.push(steps.zarava.getGroupTranslations($(this))); }); return result; }, output: function (values) { if (values.lang !== "ku") return ""; var stepDiv = $("#wiktku-start-zarava"); var glosses = steps.trans.glossList(); if (!glosses.length) return ""; var blocks = $.map(glosses, function (gloss, gi) { var group = stepDiv.find(".wiktku-zarava-group[data-gloss-pos='" + gi + "']"); var rows = group.length ? steps.zarava.getGroupTranslations(group) : []; if (!gloss.text && !rows.length) return undefined; if (rows.length) { rows.sort(function (a, b) { var aLang = langsByCode[a[0]] || []; var bLang = langsByCode[b[0]] || []; return (aLang[2] || "").localeCompare(bLang[2] || "", "ku"); }); } var wordLines = $.map(rows, function (row) { var lang = row[0]; var words = row[1]; var wikiWords = words.map(function (w) { return "{{W|" + lang + "|" + w + "}}"; }).join(", "); return "* {{Z|" + lang + "}}: " + wikiWords; }).join("\n"); if (!wordLines) return undefined; var block = "{{werger-ser|" + (gloss.text || "?") + "|" + gloss.index + "}}"; block += "\n" + wordLines; block += "\n{{werger-bin}}"; return block; }); if (!blocks.length) return ""; return "\n==== Bi zaravayên din ====\n" + blocks.join("\n") + "\n"; } }, trans: { id: "trans", name: "werger", visible: function (values) { if (!(values.lang === "ku" && values.pos)) return false; // Hide Werger only when EVERY sense is a template sense (Guharto etc.) // with a title filled in — i.e. there is real content but no plain // gloss to attach a translation table to. A mix of real + template // senses still shows Werger; the template senses are simply skipped // in output(). // // "Real" here means a non-şablon sense with either mane text or // other filled-in fields (etîket/hevmane/nimûne/jêder…), since // dfn.getOutput() renders the latter too, as {{mane?|lang}} plus // whatever else was filled in. // // When nothing has been filled in at all, output() will emit // {{mane?|lang}} instead of a gloss — but Werger should still show, // since the user may want to add translations before they've // settled on a gloss. var dfnSenses = steps.dfn.getSenses($("#wiktku-start-dfn")); var hasRealSense = dfnSenses.some(function (s) { return !s.tpl && (s.mane !== "" || senseHasExtraContent(s)); }); var hasFilledTplSense = dfnSenses.some(function (s) { return s.tpl && s.tplTitle; }); return hasRealSense || !hasFilledTplSense; }, disabledKeys: { "navz": true, "ku": true, "ckb": true, "sdh": true, "lki": true, "hac": true, "zza": true }, /** * Builds one translation row: a language dropdown + a growing list * of word inputs. When the dropdown gets a value the next empty row * is appended automatically. * * @param group the specific .wiktku-trans-group this row belongs to * (each gloss has its own group and its own list of rows, so the * lookups below must stay scoped to that group rather than the * whole step — the step now holds one list per gloss). */ buildRow: function (group) { var row = $("<li class='wiktku-trans-row wiktku-lang-row'></li>"); // Language selector — chosen is applied after insertion into DOM. var langSel = $(mw.html.element("select", { "class": "wiktku-start-step-keyfield wiktku-start-narrow" })); langSel.attr("data-placeholder", "Zimanekî lê bigere"); populateMenus(langSel, steps.trans.keys || [], steps.trans.disabledKeys); // When a language is chosen, ensure a next empty row exists. langSel.on("change", function () { steps.trans.onLangChange(group, row); }); // Word list for this language. var wordList = $("<ul class='wiktku-trans-words wiktku-lang-row-words'></ul>"); var firstWord = steps.trans.makeWordInput(); wordList.append($("<li></li>").append(firstWord)); if (isMobile) { row.append(wrapNativeSelect(langSel)).append(wordList); } else { row.append(langSel).append(wordList); } return row; }, makeWordInput: function () { var input = $("<textarea></textarea>") .attr("name", "wiktku-trans-word-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 1) .attr("class", "wiktku-dfn-subfield wiktku-start-narrow") .attr("placeholder", "Tercime…"); input.on("input", function () { var list = $(this).closest("ul.wiktku-trans-words"); var item = $(this).parent(); var val = $.trim($(this).val()); if (val && item.is(list.children("li:last-child"))) { var next = steps.trans.makeWordInput(); list.append($("<li></li>").append(next)); } }); return input; }, onLangChange: function (group, row) { var list = group.find("ul.wiktku-trans-list"); var isLast = row.is(list.children("li.wiktku-trans-row:last-child")); if (isLast) { var newRow = steps.trans.buildRow(group); list.append(newRow); // Init chosen after the new row is in the DOM (desktop only). if (!isMobile) newRow.find("select").chosen(chosenOptions); } // Keep disabled keys in sync across this gloss's lang selectors // only — the same language can be used for different senses. steps.trans.syncDisabledKeys(group); }, /** Disables already-selected languages in all other dropdowns within one group. */ syncDisabledKeys: function (group) { var taken = $.extend({}, steps.trans.disabledKeys); group.find("li.wiktku-trans-row select").each(function () { var v = $(this).val(); if (v) taken[v] = true; }); group.find("li.wiktku-trans-row select").each(function () { var self = $(this); var own = self.val(); self.find("option").each(function () { var code = $(this).val(); if (!code) return; $(this).prop("disabled", taken[code] && code !== own); }); self.trigger("chosen:updated"); }); }, /** * Builds (or fetches) the .wiktku-trans-group for one gloss, with * its own label and its own list of translation rows. */ buildGroup: function (stepDiv, gi) { var group = $("<div class='wiktku-trans-group'></div>").attr("data-gloss-pos", gi); var list = $("<ul class='wiktku-trans-list wiktku-lang-row-list'></ul>"); list.append(steps.trans.buildRow(group)); group.append(list); stepDiv.append(group); // Init chosen after the select is in the DOM (desktop only). if (!isMobile) list.find("select").chosen(chosenOptions); return group; }, /** * Syncs one .wiktku-trans-group per current gloss, adding new * groups and removing stale ones as senses are added or removed, * while leaving existing groups (and whatever translations the * user has already typed into them) untouched. Groups are keyed * to their gloss's position in glossList() via data-gloss-pos, so * a group always matches the same sense across rebuilds as long * as senses aren't reordered relative to each other. */ build: function (stepDiv) { var glosses = steps.trans.glossList(); if (!glosses.length) { stepDiv.find(".wiktku-trans-group").remove(); return null; } // Drop groups for glosses that no longer exist (always from the // tail — groups are only ever appended in gloss order below). var existingGroups = stepDiv.find(".wiktku-trans-group"); if (existingGroups.length > glosses.length) { existingGroups.slice(glosses.length).remove(); } $.each(glosses, function (gi, gloss) { var group = stepDiv.find(".wiktku-trans-group[data-gloss-pos='" + gi + "']"); if (!group.length) group = steps.trans.buildGroup(stepDiv, gi); // Only label groups when there's more than one gloss to // distinguish between — a single gloss needs no caption. var label = group.find(".wiktku-trans-group-label"); if (glosses.length > 1) { if (!label.length) { label = $("<div class='wiktku-trans-group-label'></div>"); group.prepend(label); } label.text(gloss.index + " " + gloss.text); } else if (label.length) { label.remove(); } }); return null; }, /** Reads the translation rows for a single gloss group. */ getGroupTranslations: function (group) { var result = []; group.find("li.wiktku-trans-row").each(function () { var lang = $(this).find("select").val(); if (!lang) return; var words = []; $(this).find("ul.wiktku-trans-words textarea").each(function () { var v = $.trim($(this).val()); if (v) words.push(v); }); if (words.length) result.push([lang, words]); }); return result; }, /** * Reads all translation rows from the DOM, grouped by gloss * position — one array of [lang, words] rows per gloss group, in * the same order as the .wiktku-trans-group elements. */ getTranslations: function (stepDiv) { var result = []; stepDiv.find(".wiktku-trans-group").each(function () { result.push(steps.trans.getGroupTranslations($(this))); }); return result; }, /** * Builds the numbered "{ index, gloss }" list — one entry per dfn * sense that has a real mane (skips template senses like Guharto, * which have nothing to caption a translation table with). The * index matches the sense's actual position in the numbered "#" * definition list (1-based), including template senses in the count, * so the number printed next to {{werger-ser}} lines up with the * gloss the reader sees in the entry. * * When nothing has been filled in at all (dfn.getOutput() will emit * {{mane?|lang}} as sense 1), this returns a single placeholder * entry with empty text instead of an empty array, so Werger still * has one group to attach translations to before a gloss exists. * When every filled sense is a template sense instead, this stays * empty — that mirrors trans.visible()'s hidden case, where there's * no group in the DOM for a placeholder to attach to anyway. */ glossList: function () { var dfnSenses = steps.dfn.getSenses($("#wiktku-start-dfn")); var glosses = []; var hasFilledTplSense = false; $.each(dfnSenses, function (i, s) { if (s.tpl) { if (s.tplTitle) hasFilledTplSense = true; return; // template sense — no gloss to caption with } var dfn = s.mane; if (!dfn) { // No mane text, but other fields (etîket/hevmane/nimûne/ // jêder…) are filled — dfn.getOutput() still emits this // sense as a numbered line using {{mane?|lang}}, so it // needs its own gloss group too, just with no caption text. if (senseHasExtraContent(s)) glosses.push({ index: i + 1, text: "" }); return; } if (dfn[0] !== dfn[0].toLowerCase()) dfn = decapitalize(dfn); dfn = stripWikilinks(dfn).replace(/[.…?!)\]،؟]+$/, ""); glosses.push({ index: i + 1, text: dfn }); }); if (!glosses.length && !hasFilledTplSense) { glosses.push({ index: 1, text: "" }); } return glosses; }, output: function (values) { if (values.lang !== "ku") return ""; var stepDiv = $("#wiktku-start-trans"); var glosses = steps.trans.glossList(); // Every sense is a template sense — there's no real gloss // anywhere and no group in the DOM either (glossList() only // returns empty in that case), so skip the section entirely. if (!glosses.length) return ""; // Each gloss now has its own group of translation rows — // attach every gloss's own words under its own werger-ser/-bin // pair instead of dumping everything under the first one. var blocks = $.map(glosses, function (gloss, gi) { var group = stepDiv.find(".wiktku-trans-group[data-gloss-pos='" + gi + "']"); var rows = group.length ? steps.trans.getGroupTranslations(group) : []; // Placeholder gloss (no real mane entered yet) with nothing // translated into it — nothing to output, and gloss.text is // empty so there's no caption to give {{werger-ser}} anyway. if (!gloss.text && !rows.length) return undefined; if (rows.length) { // Sort by Kurdish sort key. rows.sort(function (a, b) { var aLang = langsByCode[a[0]] || []; var bLang = langsByCode[b[0]] || []; return (aLang[2] || "").localeCompare(bLang[2] || "", "ku"); }); } var wordLines = $.map(rows, function (row) { var lang = row[0]; var words = row[1]; var wikiWords = words.map(function (w) { return "{{W|" + lang + "|" + w + "}}"; }).join(", "); return "* {{Z|" + lang + "}}: " + wikiWords; }).join("\n"); var block = "{{werger-ser|" + (gloss.text || "?") + "|" + gloss.index + "}}"; if (wordLines) block += "\n" + wordLines; block += "\n{{werger-bin}}"; return block; }); if (!blocks.length) return ""; return "\n==== Werger ====\n" + blocks.join("\n") + "\n"; } }, }; steps.trans.keys = steps.lang.choices; steps.dunde.keys = steps.lang.choices; steps.zarava.keys = getZaravaKeys(steps.lang.choices); var ordered_steps = [ steps.lang, steps.pron, steps.pos, steps.cinsiyet, steps.lektur, steps.tr, steps.dfn, steps.je, steps.tekildar, steps.etym, steps.dunde, steps.binereherwiha, steps.zarava, steps.trans]; // Step ids that belong to each section (not shared across sections). var PER_SECTION_STEP_IDS = [ "pos", "cinsiyet", "lektur", "tr", "dfn", "je", "tekildar", "etym", "dunde", "binereherwiha", "zarava", "trans" ]; // ── Multi-section state ────────────────────────────────────────────────── // Each entry is a plain snapshot: { pos, cinsiyet, lektur, tr, dfn (senses[]), // je, tekildar, binereherwiha, trans (rows[]) }. var sections = [{}]; // section 0 starts empty (DOM is the truth) var activeSection = 0; function snapshotDfn() { return steps.dfn.getSenses($("#wiktku-start-dfn")); } /** * Rebuild the dfn DOM from a previously snapshotted senses array. */ function restoreDfn(senses) { var stepDiv = $("#wiktku-start-dfn"); // Tear down the existing list so build() recreates it cleanly. stepDiv.find("ol.wiktku-dfn-list").remove(); steps.dfn.build(stepDiv); var list = stepDiv.find("ol.wiktku-dfn-list"); $.each(senses, function (i, sense) { // Ensure enough blocks exist (build() seeds one). var blocks = list.find("li.wiktku-dfn-sense"); var block = blocks.eq(i); if (!block.length) { var nb = steps.dfn.buildSenseBlock(stepDiv); list.append(nb); block = list.find("li.wiktku-dfn-sense").last(); } // Template selector. block.find("select.wiktku-dfn-tpl-select").val(sense.tpl || ""); if (sense.tpl) { block.find("textarea.wiktku-dfn-mane").hide(); block.find("input.wiktku-dfn-tpl-title").val(sense.tplTitle || "").show(); } else { block.find("textarea.wiktku-dfn-mane").val(sense.mane || "").show(); block.find("input.wiktku-dfn-tpl-title").hide().val(""); } // Re-sync the formên alternatîv/hevmane/… hide state now that // tplSelect's value was set programmatically (its own "change" // handler doesn't fire from .val(), so this doesn't happen otherwise). var updateVis = block.data("updateFieldVisibility"); if (updateVis) updateVis(); // Restore a sub-list (etiket, formên alternatîv, hevmane …) from a values array. function restoreSubList(cls, values) { if (!values || !values.length) return; var groupDiv = block.find("." + cls + "-group"); var subList = groupDiv.find("ol, ul").first(); if (!subList.length) return; // group not found // Fill existing items, append new ones as needed. $.each(values, function (j, val) { var items = subList.find("li"); if (j < items.length) { items.eq(j).find("textarea").val(val); } else { var ta = $("<textarea></textarea>") .attr("name", "wiktku-dfn-restore-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 1) .attr("class", "wiktku-dfn-subfield wiktku-start-narrow") .val(val); ta.on("input", function () { steps.dfn.onSubInput(subList, this, 1, true); }); subList.append($("<li></li>").append(ta)); } }); } // Reveal and populate lazy groups that have data. var lazyMap = { "wiktku-dfn-etiket": sense.etiket, "wiktku-dfn-alternativ": sense.alternativ, "wiktku-dfn-hevmane": sense.hevmane, "wiktku-dfn-dijmane": sense.dijmane, "wiktku-dfn-koordine": sense.koordine, "wiktku-dfn-jornav": sense.jornav, "wiktku-dfn-jernav": sense.jernav }; $.each(lazyMap, function (cls, vals) { if (vals && vals.length) restoreSubList(cls, vals); }); // Nimûne items are objects { text, tr?, t? } — restore using the builder. if (sense.nimune && sense.nimune.length) { var nimuneGroupDiv = block.find(".wiktku-dfn-nimune-group"); var nimuneList = nimuneGroupDiv.find("ol.wiktku-dfn-nimune-list"); var buildFn = nimuneGroupDiv.data("buildNimuneLi"); nimuneList.empty(); $.each(sense.nimune, function (_, n) { var text = typeof n === "object" ? (n.text || "") : n; if (!text) return; var li = buildFn ? buildFn() : $("<li class='wiktku-dfn-nimune-li'></li>"); li.find(".wiktku-dfn-nimune-text").val(text); if (n.tr) li.find(".wiktku-dfn-nimune-tr").val(n.tr); if (n.t) li.find(".wiktku-dfn-nimune-t").val(n.t); nimuneList.append(li); }); // Always leave a blank trailing item. if (buildFn) nimuneList.append(buildFn()); } // Restore jêder (quote/citation) entries — a growing list, restored using the // builder just like Nimûne. Accepts either the current array shape or a // single legacy object (from older saved sections) for backwards compatibility. var jederArr = $.isArray(sense.jeder) ? sense.jeder : (sense.jeder ? [sense.jeder] : []); if (jederArr.length) { var jederGroupDiv = block.find(".wiktku-dfn-jeder-group"); var jederList = jederGroupDiv.find("ol.wiktku-dfn-jeder-list"); var buildJederFn = jederGroupDiv.data("buildJederLi"); jederList.empty(); $.each(jederArr, function (_, j) { if (!j || !j.quote) return; var li = buildJederFn ? buildJederFn() : $("<li class='wiktku-dfn-jeder-li'></li>"); li.find(".wiktku-dfn-nimune-quote").val(j.quote); if (j.quoteTr) li.find(".wiktku-dfn-nimune-quote-tr").val(j.quoteTr); if (j.quoteT) li.find(".wiktku-dfn-nimune-quote-t").val(j.quoteT); if (j.jederManual) { var manualSel = li.find(".wiktku-dfn-quote-src-sel"); manualSel.val("__manual__").trigger("change"); li.find(".wiktku-dfn-quote-src-manual").val(j.jederManual); } else if (j.jederTpl) { var srcSel = li.find(".wiktku-dfn-quote-src-sel"); srcSel.val(j.jederTpl).trigger("change"); if (j.jêderFields) { $.each(j.jêderFields, function (key, val) { li.find(".wiktku-dfn-quote-src-input[data-field-key='" + key + "']").val(val); }); } } jederList.append(li); }); // Always leave a blank trailing item, same as Nimûne. if (buildJederFn) jederList.append(buildJederFn()); } }); } /** * Snapshot simple (non-dfn) per-section steps from current DOM into obj. */ function saveCurrentSection() { var snap = {}; $.each(PER_SECTION_STEP_IDS, function (_, id) { if (id === "dfn") { snap.dfn = snapshotDfn(); return; } if (id === "etym") { snap.etym = $.trim($("#wiktku-start-etym .wiktku-etym-text").val()); return; } var step = steps[id]; if (!step) return; var stepDiv = $("#wiktku-start-" + id); if (id === "trans") { snap.trans = steps.trans.getTranslations(stepDiv); return; } if (id === "zarava") { snap.zarava = steps.zarava.getTranslations(stepDiv); return; } if (id === "dunde") { snap.dunde = steps.dunde.getRows(stepDiv); return; } // Generic: read all step fields. var fields = stepDiv.find(".wiktku-start-step-field"); if (step.multiple) { snap[id] = fields.map(function () { return $(this).val(); }).get(); } else { snap[id] = fields.val(); } }); sections[activeSection] = snap; } /** * Restore a previously saved snapshot into the form DOM. */ function restoreSection(snap) { $.each(PER_SECTION_STEP_IDS, function (_, id) { if (id === "dfn") { restoreDfn(snap.dfn || []); return; } if (id === "etym") { $("#wiktku-start-etym .wiktku-etym-wrap").remove(); steps.etym.build($("#wiktku-start-etym")); $("#wiktku-start-etym .wiktku-etym-text").val(snap.etym || ""); return; } if (id === "trans") { // Rebuild trans groups (dfn must already be restored by this // point in the $.each loop, so glossList() reflects it). var transDiv = $("#wiktku-start-trans"); transDiv.find(".wiktku-trans-group").remove(); steps.trans.build(transDiv); var groupsSnap = snap.trans || []; $.each(groupsSnap, function (gi, rows) { var group = transDiv.find(".wiktku-trans-group[data-gloss-pos='" + gi + "']"); if (!group.length) return; // gloss no longer exists — drop its rows var list = group.find("ul.wiktku-trans-list"); $.each(rows, function (j, row) { var lang = row[0], words = row[1]; var lastRow = list.find("li.wiktku-trans-row").last(); lastRow.find("select").val(lang).trigger("change"); var wordList = lastRow.find("ul.wiktku-trans-words"); $.each(words, function (k, word) { var wordItems = wordList.find("li"); if (k < wordItems.length) { wordItems.eq(k).find("textarea").val(word); } else { // .val() below doesn't fire "input", so the normal // auto-grow never runs — append a matching item // ourselves instead of silently dropping the word. var extraInput = steps.trans.makeWordInput(); wordList.append($("<li></li>").append(extraInput)); extraInput.val(word); } }); // Leave one trailing empty field so the row can still grow // when the user types, matching a freshly-built row. if ($.trim(wordList.children("li").last().find("textarea").val())) { wordList.append($("<li></li>").append(steps.trans.makeWordInput())); } }); }); return; } if (id === "zarava") { // Rebuild zarava groups (dfn must already be restored by this // point in the $.each loop, so glossList() reflects it). var zaravaDiv = $("#wiktku-start-zarava"); zaravaDiv.find(".wiktku-zarava-group").remove(); steps.zarava.build(zaravaDiv); var zaravaGroupsSnap = snap.zarava || []; $.each(zaravaGroupsSnap, function (gi, rows) { var group = zaravaDiv.find(".wiktku-zarava-group[data-gloss-pos='" + gi + "']"); if (!group.length) return; // gloss no longer exists — drop its rows var list = group.find("ul.wiktku-zarava-list"); $.each(rows, function (j, row) { var lang = row[0], words = row[1]; var lastRow = list.find("li.wiktku-zarava-row").last(); lastRow.find("select").val(lang).trigger("change"); var wordList = lastRow.find("ul.wiktku-zarava-words"); $.each(words, function (k, word) { var wordItems = wordList.find("li"); if (k < wordItems.length) { wordItems.eq(k).find("textarea").val(word); } else { var extraInput = steps.zarava.makeWordInput(); wordList.append($("<li></li>").append(extraInput)); extraInput.val(word); } }); if ($.trim(wordList.children("li").last().find("textarea").val())) { wordList.append($("<li></li>").append(steps.zarava.makeWordInput())); } }); }); return; } if (id === "dunde") { // Rebuild dunde rows. var dundeDiv = $("#wiktku-start-dunde"); dundeDiv.find("ul.wiktku-dunde-list").remove(); steps.dunde.build(dundeDiv); var dundeRows = snap.dunde || []; $.each(dundeRows, function (i, row) { var lang = row[0], words = row[1]; var list = dundeDiv.find("ul.wiktku-dunde-list"); var lastRow = list.find("li.wiktku-dunde-row").last(); lastRow.find("select").val(lang).trigger("change"); var wordList = lastRow.find("ul.wiktku-dunde-words"); $.each(words, function (j, word) { var wordItems = wordList.find("li"); if (j < wordItems.length) { wordItems.eq(j).find("textarea").val(word); } else { // .val() below doesn't fire "input", so the normal // auto-grow never runs — append a matching item // ourselves instead of silently dropping the word. var extraInput = steps.dunde.makeWordInput(); wordList.append($("<li></li>").append(extraInput)); extraInput.val(word); } }); // Leave one trailing empty field so the row can still grow // when the user types, matching a freshly-built row. if ($.trim(wordList.children("li").last().find("textarea").val())) { wordList.append($("<li></li>").append(steps.dunde.makeWordInput())); } }); return; } var step = steps[id]; if (!step) return; var stepDiv = $("#wiktku-start-" + id); var fields = stepDiv.find(".wiktku-start-step-field"); var val = snap[id]; if (val === undefined || val === null) return; if (step.multiple) { var arr = val; fields.each(function (i) { if (i < arr.length) $(this).val(arr[i]); }); } else { fields.val(val); } // Notify chosen widgets of the programmatic value change. if (!isMobile) fields.filter("select").trigger("chosen:updated"); }); } function getWikitextForCurrentSection(callback) { var values = getValues(); var entry = steps.pos.output(values); steps.dfn.getOutput(values, function (output) { entry += output; entry += steps.je.output(values); entry += steps.tekildar.output(values); entry += steps.etym.output(values); entry += steps.dunde.output(values); entry += steps.binereherwiha.output(values); entry += steps.zarava.output(values); entry += steps.trans.output(values); callback(entry, values); }); } function getWikitextAllSections(callback) { saveCurrentSection(); var results = new Array(sections.length); var sharedValues = getValues(); // lang/pron are shared function processSection(i) { if (i >= sections.length) { // All done — restore original active section. restoreSection(sections[activeSection]); refresh(); callback(results, sharedValues); return; } restoreSection(sections[i]); refresh(); getWikitextForCurrentSection(function (sectionText) { results[i] = sectionText; processSection(i + 1); }); } processSection(0); } /** * Assembles wikitext for all sections plus the shared lang/pron header. */ function getWikitext(callback) { getWikitextAllSections(function (sectionTexts, sharedValues) { var entry = steps.lang.output(sharedValues); entry += steps.pron.output(sharedValues); entry += sectionTexts.join("\n"); // Edit summary uses section 0's values. Read from the saved snapshot // (not the live DOM) so it doesn't mix section 0's pos with whichever // section happens to be active/restored at this point. var dfnSenses = (sections[0] && sections[0].dfn) || []; var dfnSummary = dfnSenses.map(function (s) { return s.mane; }).filter(Boolean).join("; "); var summaryLabel = addLangMode ? "WF:Ziman lê zêde" : "WF:Nû"; var summary = "([[Mediawiki:Gadget-start.js|" + summaryLabel + "]] v.2.0) +" + sharedValues.lang + ":" + sections[0].pos + ":" + dfnSummary; var summaryField = document.getElementById("wpSummary"); if (addLangMode && summaryField.value) { summary = summaryField.value + " " + summary; } summaryField.value = summary; callback(entry); }); } var continueBtn; function getValuesForStep(stepId) { var fields = $("#wiktku-start-" + stepId + " .wiktku-start-step-field"); var step = steps[stepId]; if (step.keys) { var values = {}; fields.each(function (i, field) { var key = $(field).prevAll(".wiktku-start-step-keyfield").val(); if (key) values[key] = $(field).val(); }); return values; } else if (step.multiple) { return fields.map(function () { return $(this).val(); }).get(); } return fields.val(); } function getValues() { var values = {}; $.each(steps, function (stepId) { values[stepId] = getValuesForStep(stepId); }); return values; } function populateMenus(inputs, choices, disabledValues) { if (!disabledValues) disabledValues = {}; var vals = inputs.map(function (i, input) { return $(input).val(); }); inputs.empty(); inputs.append($("<option></option>")); $.each(choices, function (j, choice) { // Append the language code in parentheses so that typing a code // (e.g. "ku") in the search box still finds the language name. var displayText = capitalize(choice[1]); if (choice[2] !== undefined) { // This is a language choice [code, name, sortKey] — show code. displayText = capitalize(choice[1]) + " (" + choice[0] + ")"; } var option = $(mw.html.element("option", { value: choice[0] }, displayText)); if (disabledValues[choice[0]]) option.prop("disabled", true); inputs.append(option); }); inputs.val(function (i) { return vals[i]; }); } /** * Returns a bitmap containing the keys that should be disabled for a key * menu in the given step because they are disabled or already taken by * another key menu. */ function getDisabledKeys(step) { var occupiedKeys = {}; $("#wiktku-start-" + step.id + " .wiktku-start-step-keyfield").each(function () { occupiedKeys[$(this).val()] = true; }); if (step.disabledKeys) $.extend(occupiedKeys, step.disabledKeys); return occupiedKeys; } function buildKeyInput(step) { if (!step.keys) return undefined; var input = $(mw.html.element("select", { "class": "wiktku-start-step-keyfield wiktku-start-narrow" })); input.attr("data-placeholder", "Hilbijêre " + step.keyName); if (isMobile) { populateMenus(input, step.keys, getDisabledKeys(step)); // On mobile return the wrapper; the select is inside it. // Change events still fire on the inner select. return wrapNativeSelect(input); } input.on("chosen:showing_dropdown", function () { $(this).data("wiktku-defaultValue", $(this).val()); }); input.change(function (_, context) { var inputs = $("#wiktku-start-" + step.id + " .wiktku-start-step-keyfield").not(this); var oldValue = $(this).data("wiktku-defaultValue"); var newValue = context.selected; inputs.find("option[value='" + oldValue + "']").prop('disabled', false); inputs.find("option[value='" + newValue + "']").prop('disabled', true); inputs.trigger("chosen:updated"); }); populateMenus(input, step.keys, getDisabledKeys(step)); return input; } /** * If the current text field has text and there are no more text fields after * the current text field in the list, add another text field to the list. */ function refreshForTextField(currentInput, step) { currentInput = $(currentInput); var value = currentInput.val(); var item = currentInput.parent(); if (value && !item.next("li").length) { var nextInput = $("<textarea></textarea>") .attr("name", "wiktku-field-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("class", currentInput.attr("class")) .attr("rows", currentInput.attr("rows") || 1); nextInput.on("input", function (evt) { refreshForTextField(evt.target, step); }); var nextKeyInput = buildKeyInput(step); var nextItem = $("<li></li>").append(nextKeyInput).append(nextInput); item.parent().append(nextItem); if (nextKeyInput) nextKeyInput.chosen(chosenOptions); } var canContinue = !continueBtn.isDisabled(); if ((value && !canContinue) || (!value && canContinue)) { refresh(step); } } function prepareInput(input, step) { if (!input) return; if (step.required) input.prop('required', true); input.change(step, refresh); } /** * Shows and hides all the steps based on whether their prerequisites are met, * and updates placeholders where applicable. */ function refresh(evt) { var values = getValues(); var changedStep = evt && evt.data; var didFocus = false; var canContinue = true; // Re-filter template options in every sense block whenever lang changes. $("#wiktku-start-dfn .wiktku-dfn-tpl-select").each(function () { var fn = $(this).data("updateOptions"); if (typeof fn === "function") fn(); }); // Re-filter pronunciation and etymology template dropdowns when language changes. steps.pron.refreshTplSelect(); steps.etym.refreshTplSelect(); // Sync tr/t sub-fields in every nimûne item to the current language. // tr shown when language needs transliteration; t shown when lang !== "ku". (function () { var lang = values.lang || ""; var showTr = needsTransliteration(lang); var showT = lang && lang !== "ku"; $("#wiktku-start-dfn .wiktku-dfn-nimune-list li.wiktku-dfn-nimune-li").each(function () { var li = $(this); // Ensure the sub-wrapper exists when we need it. var subWrap = li.find(".wiktku-dfn-nimune-sub"); // tr field var trTa = li.find(".wiktku-dfn-nimune-tr"); if (showTr && !trTa.length) { if (!subWrap.length) { subWrap = $("<div></div>").addClass("wiktku-dfn-nimune-sub"); li.append(subWrap); } trTa = $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-tr-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 5) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-tr") .attr("placeholder", "Transkrîpsiyon…"); subWrap.prepend(trTa); } else if (!showTr && trTa.length) { trTa.remove(); } // t field var tTa = li.find(".wiktku-dfn-nimune-t"); if (showT && !tTa.length) { if (!subWrap.length) { subWrap = $("<div></div>").addClass("wiktku-dfn-nimune-sub"); li.append(subWrap); } tTa = $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-t-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 5) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-t") .attr("placeholder", "Tercimeya nimûneyê kurmancî…"); subWrap.append(tTa); } else if (!showT && tTa.length) { tTa.remove(); } // Remove the wrapper if it ended up empty. subWrap = li.find(".wiktku-dfn-nimune-sub"); if (subWrap.length && !subWrap.children().length) subWrap.remove(); }); }()); // Sync tr/t sub-fields in every jêder citation to the current language. // tr shown when language needs transliteration; t shown when lang !== "ku". (function () { var lang = values.lang || ""; var showTr = needsTransliteration(lang); var showT = lang && lang !== "ku"; $("#wiktku-start-dfn .wiktku-dfn-jeder-list li.wiktku-dfn-jeder-li").each(function () { var li = $(this); // Ensure the sub-wrapper exists when we need it. It must sit right // after the quote textarea and before the source selector. var subWrap = li.find(".wiktku-dfn-quote-sub"); // tr field var trTa = li.find(".wiktku-dfn-nimune-quote-tr"); if (showTr && !trTa.length) { if (!subWrap.length) { subWrap = $("<div></div>").addClass("wiktku-dfn-quote-sub"); li.find(".wiktku-dfn-nimune-quote").after(subWrap); } trTa = $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-quote-tr-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 2) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-quote-tr") .attr("placeholder", "Transkrîpsiyona jêgirtinê…"); subWrap.prepend(trTa); } else if (!showTr && trTa.length) { trTa.remove(); } // t field var tTa = li.find(".wiktku-dfn-nimune-quote-t"); if (showT && !tTa.length) { if (!subWrap.length) { subWrap = $("<div></div>").addClass("wiktku-dfn-quote-sub"); li.find(".wiktku-dfn-nimune-quote").after(subWrap); } tTa = $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-quote-t-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 2) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-quote-t") .attr("placeholder", "Tercimeya jêgirtinê ya kurmancî…"); subWrap.append(tTa); } else if (!showT && tTa.length) { tTa.remove(); } // Remove the wrapper if it ended up empty. subWrap = li.find(".wiktku-dfn-quote-sub"); if (subWrap.length && !subWrap.children().length) subWrap.remove(); }); }()); $.each(steps, function (stepId, step) { if (typeof(step.visible) === "function" && !step.visible(values)) { $("#wiktku-start-" + stepId).slideUp(); } else { var stepDiv = $("#wiktku-start-" + stepId); if (changedStep !== step && typeof(step.build) === "function") { prepareInput(step.build(stepDiv, values), step); } var input = stepDiv.find(".wiktku-start-step-field"); if (typeof(step.example) === "function") { // .find() above already reaches nested fields (e.g. the dfn // step's mane textareas inside each sense block), so one // assignment covers every step; dfn keeps its own fallback. var exampleText = step.example(values) || (step.id === "dfn" ? "Mane…" : ""); input.attr("placeholder", exampleText); } var didSlideDown; if (!didFocus && stepDiv.css("display") === "none" && step.required) { didSlideDown = function (evt) { input.focus(); }; didFocus = true; } stepDiv.slideDown(didSlideDown); } if (step.required && (values[stepId] === "" || (step.multiple && values[stepId].join("") === ""))) { canContinue = false; } }); continueBtn.setDisabled(!canContinue); } function destroy() { $("#wiktku-start-form, .noafterwizard").slideUp(function () { $(this).remove(); }); $(".noarticletext .nowizard, #editform").slideDown(); $("#ca-edit").removeClass("selected"); $("#ca-wiktku-nowizard").addClass("selected"); } // Priority order for Kurdish dialects and the navz pseudo-code. // Codes listed here come before all other languages; unlisted codes // are sorted alphabetically by their display name via localeCompare. var LANG_PRIORITY = ["navz", "ku", "hac", "sdh", "lki", "ckb", "zza"]; /** * Inserts a new == {{ziman|code}} == section into existing page wikitext * at the correct sorted position: * 1. Any content before the first language section is preserved at the top. * 2. navz is always first, then ku/hac/sdh/lki/ckb/zza in that order, * then all other languages sorted by display name (localeCompare). */ function insertNewLangSection(existing, wikitext) { var newCodeMatch = wikitext.match(/^== \{\{ziman\|([^}]+)\}\} ==/); var newCode = newCodeMatch ? newCodeMatch[1] : ""; var sections = []; var preamble = ""; var firstMatch = existing.match(/(?:^|\n)== \{\{ziman\|/); if (!firstMatch) { // No existing lang sections at all — just append. var sep = existing && !/\n\s*$/.test(existing) ? "\n\n" : ""; return existing + sep + wikitext; } // Everything before the first == {{ziman|...}} == is the preamble. var firstSectionStart = existing.indexOf("== {{ziman|"); // Walk back to the start of that line. var lineStart = existing.lastIndexOf("\n", firstSectionStart - 1); var preambleEnd = lineStart !== -1 ? lineStart + 1 : 0; preamble = existing.slice(0, preambleEnd); // Parse each language section: header line + everything until the next header. var body = existing.slice(preambleEnd); // NOTE: with the /m flag, a bare "$" matches end-of-*line*, not just // end-of-string — that previously made the non-greedy content group // stop at the section's first line break instead of running to the // next language header (or the real end of the text), silently // dropping the rest of that section's wikitext. (?![\s\S]) matches // only the true end of the string, /m flag or not. var langSectionRe = /^(== \{\{ziman\|([^}]+)\}\} ==\n?)([\s\S]*?)(?=\n== \{\{ziman\||(?![\s\S]))/gm; var m; while ((m = langSectionRe.exec(body)) !== null) { sections.push({ code: m[2], content: m[0] // full text of this section including header }); } // Determine sort rank: priority list first (by index), then alphabetical. function getLangName(code) { var entry = langsByCode[code]; return entry ? entry[1] : code; } function sortRank(code) { var idx = LANG_PRIORITY.indexOf(code); return idx !== -1 ? idx : LANG_PRIORITY.length; } function compareLangs(a, b) { var ra = sortRank(a), rb = sortRank(b); if (ra !== rb) return ra - rb; // Both are outside priority list — sort by display name. return getLangName(a).localeCompare(getLangName(b), userLang); } // Insert the new section into the sorted list. var newSection = { code: newCode, content: wikitext }; var inserted = false; for (var i = 0; i < sections.length; i++) { if (compareLangs(newCode, sections[i].code) < 0) { sections.splice(i, 0, newSection); inserted = true; break; } } if (!inserted) sections.push(newSection); // Re-join: preamble + sections separated by newlines. var joined = sections.map(function (s) { // Ensure each section ends with exactly one newline before the next. return s.content.replace(/\n+$/, ""); }).join("\n"); return preamble + joined + "\n"; } function build() { $(".nowizard, .nowizard .noafterwizard").hide(); var callToAction = $("#wiktku-calltoaction"); var origCallToActionText = callToAction.text(); $(mw.util.addPortletLink("p-views", "#", "Edîtora çavkaniyê veke", "ca-wiktku-nowizard", "Vê rûpelê bi edîtora çavkaniyê çêke", undefined, "#ca-watch")).click(function (evt) { evt.preventDefault(); callToAction.text(origCallToActionText); destroy(); }); if (callToAction.length) { callToAction.text(origCallToActionText + " Forma li jêr ji bo çêkirina madeyeke nû bi kar bîne."); } var startForm = $("<form id='wiktku-start-form'></form>"); if (addLangMode) { startForm.append($("<p class='wiktku-addlang-notice'></p>").text( "Agahiyên zimanê nû yê hûnê li vê rûpelê zêde bikin dagirin. " + "Piştî temambûnê, beşa nû dê li dawiya nivîsa heyî were zêdekirin.")); } var spinner; // Tab bar for switching between POS sections. var sectionTabsDiv = $("<div id='wiktku-section-tabs'></div>"); startForm.submit(function (evt) { evt.preventDefault(); continueBtn.setDisabled(true); spinner.show(); getWikitext(function (wikitext) { if (addLangMode) { var textbox = $("#wpTextbox1"); var existing = textbox.val() || ""; // Check whether the generated lang header already exists in the page. // wikitext always starts with "== {{ziman|CODE}} ==\n" (from steps.lang.output). // If that exact section heading is already present in the existing content, // strip it from the new output and insert the remaining content at the end // of that lang section (just before the next == level-2 heading, or at the // very end of the page if there is no following section). var langHeaderMatch = wikitext.match(/^(== \{\{ziman\|[^}]+\}\} ==\n)/); if (langHeaderMatch) { var langHeader = langHeaderMatch[1]; // e.g. "== {{ziman|ku}} ==\n" // Escape for use in RegExp. var escapedHeader = langHeader.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); if (new RegExp(escapedHeader).test(existing)) { // Strip the header from the new output. var newContent = wikitext.slice(langHeader.length); // Find the insertion point: end of the existing lang section. // A new L2 heading marks the start of the next language block. var afterHeader = existing.indexOf(langHeader); var searchFrom = afterHeader + langHeader.length; // Find the next == … == heading after this section's start. var nextL2 = existing.indexOf("\n== ", searchFrom); var insertAt = nextL2 !== -1 ? nextL2 : existing.length; // Ensure there's a blank line before the inserted block. var before = existing.slice(0, insertAt); var after = existing.slice(insertAt); var sep = /\n\s*$/.test(before) ? "" : "\n"; textbox.val(before + sep + newContent + after); } else { // New language — insert at the correct sorted position. textbox.val(insertNewLangSection(existing, wikitext)); } } else { // Unexpected format — insert at sorted position anyway. textbox.val(insertNewLangSection(existing, wikitext)); } } else { $("#wpTextbox1").val(wikitext); } $("html, body").animate({scrollTop: 0}); callToAction.text("Hindik ma!"); $("#wiktku-preview-container").remove(); destroy(); }); }); $.each(ordered_steps, function (i, step) { var stepDiv = $(mw.html.element("div", { "class": "wiktku-start-step", id: "wiktku-start-" + step.id })); var name = capitalize(step.name); stepDiv.append($(mw.html.element("h3", { "class": "wiktku-start-step-name" }, new mw.html.Raw(mw.html.element("label", { "for": "wiktku-start-" + step.id + "-field" }, name))))); if (step.question_fmt) { stepDiv.append($(mw.html.element("label", { "class": "wiktku-start-step-question", "for": "wiktku-start-" + step.id + "-field" }, step.question_fmt))); if (step.question_br) stepDiv.append($("<br>")); } var input; if (step.choices) { input = $(mw.html.element("select", { "class": "wiktku-start-step-field", id: "wiktku-start-" + step.id + "-field" })); input.attr("data-placeholder", capitalize(step.name) + " hilbijêre "); populateMenus(input, step.choices); if (step.multiple) input.attr("multiple", true); if (isMobile) { stepDiv.append(wrapNativeSelect(input)); } else { stepDiv.append(input); } } else if (typeof(step.build) === "function") { input = step.build(stepDiv); } else { input = $("<textarea></textarea>") .attr("class", "wiktku-start-step-field") .attr("id", "wiktku-start-" + step.id + "-field") .attr("rows", step.rows || 2); if (step.narrow) input.addClass("wiktku-start-narrow"); if (step.multiple) { input.on("input", function (evt) { refreshForTextField(evt.target, step); }); var keyInput = buildKeyInput(step); var list = $(step.ordered ? "<ol></ol>" : "<ul></ul>") .append($("<li></li>").append(keyInput).append(input)); stepDiv.append(list); } else stepDiv.append(input); } prepareInput(input, step); stepDiv.hide(); // Insert tab bar just before the first per-section step. if (step.id === "pos") startForm.append(sectionTabsDiv); startForm.append(stepDiv); }); // ── Section tab helpers ────────────────────────────────────────────── // ── Add-section button — lives in the tab bar, disabled until pos chosen ── var addSectionBtn = new OO.ui.ButtonWidget({ label: "+ Beş zêde bike", disabled: true }); addSectionBtn.on("click", function () { saveCurrentSection(); sections.push({}); activeSection = sections.length - 1; $.each(PER_SECTION_STEP_IDS, function (_, id) { if (id === "dfn") { var stepDiv = $("#wiktku-start-dfn"); stepDiv.find("ol.wiktku-dfn-list").remove(); steps.dfn.build(stepDiv); return; } if (id === "etym") { $("#wiktku-start-etym .wiktku-etym-wrap").remove(); steps.etym.build($("#wiktku-start-etym")); return; } if (id === "trans") { var transDiv = $("#wiktku-start-trans"); transDiv.find(".wiktku-trans-group").remove(); return; } if (id === "zarava") { var zaravaDiv = $("#wiktku-start-zarava"); zaravaDiv.find(".wiktku-zarava-group").remove(); return; } if (id === "dunde") { var dundeDiv = $("#wiktku-start-dunde"); dundeDiv.find("ul.wiktku-dunde-list").remove(); return; } var stepDiv = $("#wiktku-start-" + id); stepDiv.find(".wiktku-start-step-field").val(""); if (!isMobile) stepDiv.find("select.wiktku-start-step-field").trigger("chosen:updated"); }); renderSectionTabs(); refresh(); $("html, body").animate({ scrollTop: sectionTabsDiv.offset().top - 20 }, 300); }); /** Re-render the tab bar to reflect current sections[] and activeSection. */ function renderSectionTabs() { // Detach (not remove) the button first: .empty() strips bound // event data from any children left inside it, which would // silently kill addSectionBtn's click handler on every re-render. addSectionBtn.$element.detach(); sectionTabsDiv.empty(); var lang = getValues().lang || ""; if (!lang) { sectionTabsDiv.hide(); return; } sectionTabsDiv.show(); $.each(sections, function (i) { var posVal = sections[i].pos || ""; var tabLabel = posVal ? capitalize(posVal) : ("Beş " + (i + 1)); var tab = $("<span></span>") .addClass("wiktku-section-tab") .text(tabLabel) .toggleClass("wiktku-tab-active", i === activeSection); (function (idx) { tab.on("click", function () { if (idx === activeSection) return; saveCurrentSection(); activeSection = idx; restoreSection(sections[activeSection]); refresh(); renderSectionTabs(); }); }(i)); sectionTabsDiv.append(tab); }); // Enable "Beş zêde bike" only when the active section has a pos chosen. var activePos = sections[activeSection] && sections[activeSection].pos ? sections[activeSection].pos : getValues().pos; addSectionBtn.setDisabled(!activePos); sectionTabsDiv.append(addSectionBtn.$element); } renderSectionTabs(); // Update the active tab's label whenever pos changes. startForm.on("change", "#wiktku-start-pos-field", function () { renderSectionTabs(); }); // Show the tab bar as soon as a language is selected. startForm.on("change", "#wiktku-start-lang-field", function () { renderSectionTabs(); }); var footer = $("<div id='wiktku-start-footer'></div>"); spinner = $(mw.html.element("img", { id: "wiktku-start-spinner", src: "//upload.wikimedia.org/wikipedia/commons/d/de/Ajax-loader.gif", alt: "Tê barkirin…", title: "Tê barkirin…" })); footer.append(spinner.hide()); continueBtn = new OO.ui.ButtonWidget({ id: "wiktku-unhide-editform", label: "Bişîne", flags: [ "primary", "progressive" ] }); continueBtn.on("click", function () { mw.notify("Tê şandin…", { type: "info", tag: "wiktku-submit" }); startForm.trigger("submit"); }); footer.append(continueBtn.$element); // ── Preview checkboxes ─────────────────────────────────────────────── // Wikitext preview (raw text panel) var previewCheck = $("<input type='checkbox' id='wiktku-preview-toggle'>"); var previewLabel = $("<label for='wiktku-preview-toggle'></label>") .text(" Pêşdîtina wîkîtekstê"); var previewPanel = $("<pre id='wiktku-preview-panel'></pre>").hide(); // Live rendered preview (parsed HTML panel, same logic as AjaxEdit). // Not available on mobile — API polling causes too many problems on small screens. var livePreviewCheck = null; var livePreviewPanel = null; if (!isMobile) { livePreviewCheck = $("<input type='checkbox' id='wiktku-live-preview-toggle'>"); livePreviewPanel = $("<div id='wiktku-live-preview-panel'></div>").hide(); } // Container that holds both panels and switches between stacked / side-by-side. var previewContainer = $("<div id='wiktku-preview-container'></div>"); previewContainer.append(previewPanel); if (!isMobile) previewContainer.append(livePreviewPanel); var previewTimer = null; var livePreviewIntervalId = -1; /** Rebuilds wikitext preview if its checkbox is checked. */ function schedulePreview() { if (!previewCheck.prop("checked")) return; clearTimeout(previewTimer); // Debounce: wait 400 ms after the last keystroke before rebuilding. previewTimer = setTimeout(function () { getWikitext(function (wikitext) { previewPanel.text(wikitext).show(); updatePanelLayout(); }); }, 400); } /** Fetches parsed HTML and populates the live preview panel. */ function loadLivePreview() { getWikitext(function (wikitext) { new mw.Api().parse(wikitext, { title: mw.config.get("wgPageName") }).done(function (html) { livePreviewPanel.html(html).show(); updatePanelLayout(); }); }); } /** Adjusts panel widths depending on which previews are visible. */ function updatePanelLayout() { var wikitextVisible = previewCheck.prop("checked"); var liveVisible = livePreviewCheck && livePreviewCheck.prop("checked"); if (wikitextVisible && liveVisible) { // Side by side — each panel takes roughly half the available width. previewPanel.css({ "flex": "1 1 45%", "min-width": "280px" }); livePreviewPanel.css({ "flex": "1 1 45%", "min-width": "280px" }); } else { // Full width for whichever is visible. previewPanel.css({ "flex": "1 1 100%", "min-width": "" }); if (livePreviewPanel) livePreviewPanel.css({ "flex": "1 1 100%", "min-width": "" }); } } previewCheck.on("change", function () { if ($(this).prop("checked")) { schedulePreview(); } else { clearTimeout(previewTimer); previewPanel.hide(); updatePanelLayout(); } }); if (!isMobile) { livePreviewCheck.on("change", function () { if ($(this).prop("checked")) { livePreviewPanel.show(); loadLivePreview(); livePreviewIntervalId = setInterval(loadLivePreview, 500); } else { clearInterval(livePreviewIntervalId); livePreviewIntervalId = -1; livePreviewPanel.hide().empty(); updatePanelLayout(); } }); } // Listen on all input/change events on the form and update both previews. startForm.on("input change", function () { schedulePreview(); }); footer.append($("<span style='margin-left:1em'></span>") .append(previewCheck).append(previewLabel)); if (!isMobile) { var livePreviewLabel = $("<label for='wiktku-live-preview-toggle'></label>") .text(" Pêşdîtina zindî"); footer.append($("<span style='margin-left:1em'></span>") .append(livePreviewCheck).append(livePreviewLabel)); } startForm.append(footer); $("#editform").hide().before(startForm); // Insert preview container (holds both panels) after the form. startForm.after(previewContainer); if (!isMobile) startForm.find("select").chosen(chosenOptions); refresh(); // Zimanan ji MediaWiki:Gadget-translation_editor.js/ziman.json bar bike. // Kodên ku bi "-pro" diqedin û navên ku "zimanê destan" tê de heye // tên derxistin. Zimanên xardkirî li serî dimînin, yên din // bi alfabeyê li dû wan tên. // Pinned choices come from MediaWiki:Gadget-start.js/data.json (langChoices), // already loaded into steps.lang.choices before build() runs. var pinnedChoices = steps.lang.choices.slice(); var pinnedCodes = $.map(pinnedChoices, function (choice) { return choice[0]; }); new mw.Api().get({ action: "query", prop: "revisions", titles: "MediaWiki:Gadget-translation_editor.js/ziman.json", rvprop: "content", rvslots: "main", formatversion: 2 }).then(function (data) { var page = data.query.pages[0]; var content = page && page.revisions && page.revisions[0].slots.main.content; var zimanData; try { zimanData = JSON.parse(content); } catch (e) { zimanData = {}; } var extraChoices = []; $.each(zimanData, function (code, name) { // Filter: skip proto-language codes and legendary/reconstructed langs. if (/-pro$/i.test(code)) return; if (/ziman[eê]\s+destan/i.test(name)) return; // Skip codes already in the pinned list (they are handled above). if (pinnedCodes.indexOf(code) !== -1) return; // sortKey: bare name without leading "zimanê " for sorting. var sortKey = name.replace(/^ziman[eê]\s+/i, ""); var choice = [code, name, sortKey]; extraChoices.push(choice); langsByCode[code] = choice; }); // Populate langsByCode for pinned choices too. $.each(pinnedChoices, function (i, choice) { // Ensure pinned choices have a sortKey (index 2). if (choice.length < 3) choice[2] = choice[1]; langsByCode[choice[0]] = choice; }); // Sort the extra choices alphabetically by sort key. extraChoices.sort(function (a, b) { return a[2].localeCompare(b[2], userLang); }); // Final list: pinned first, then the rest. var allChoices = pinnedChoices.concat(extraChoices); steps.lang.choices = allChoices; steps.trans.keys = allChoices; steps.dunde.keys = allChoices; steps.zarava.keys = getZaravaKeys(allChoices); var langMenu = $("#wiktku-start-lang-field"); populateMenus(langMenu, steps.lang.choices); langMenu.trigger("chosen:updated"); var transMenus = $("#wiktku-start-trans .wiktku-start-step-keyfield"); populateMenus(transMenus, steps.trans.keys, getDisabledKeys(steps.trans)); transMenus.trigger("chosen:updated"); var dundeMenus = $("#wiktku-start-dunde .wiktku-start-step-keyfield"); populateMenus(dundeMenus, steps.dunde.keys, getDisabledKeys(steps.dunde)); dundeMenus.trigger("chosen:updated"); var zaravaMenus = $("#wiktku-start-zarava .wiktku-start-step-keyfield"); populateMenus(zaravaMenus, steps.zarava.keys, getDisabledKeys(steps.zarava)); }); } mw.loader.using(["jquery.chosen", "mediawiki.api", "oojs-ui-core"], function () { // Load metadata, langChoices, posChoices and tplDefs from the companion // data page so they can be updated without touching this script. new mw.Api().get({ action: "query", prop: "revisions", titles: "MediaWiki:Gadget-start.js/data.json", rvprop: "content", rvslots: "main", formatversion: 2 }).then(function (data) { var page = data.query.pages[0]; var content = page && page.revisions && page.revisions[0].slots.main.content; var d; try { d = JSON.parse(content); } catch (e) { d = {}; } // Populate metadata. if (d.metadata) $.extend(metadata, d.metadata); // Populate lang choices (pinned list used by build() → ziman.json loader). if (d.langChoices) steps.lang.choices = d.langChoices; // Populate POS choices. if (d.posChoices) steps.pos.choices = d.posChoices; // Populate template definitions for the dfn sense-block builder. if (d.tplDefs) steps.dfn.tplDefs = d.tplDefs; // Populate pos placeholder examples. if (d.posExamples) steps.dfn.posExamples = d.posExamples; // Populate citation template definitions for the quote widget. if (d.jederDefs) steps.dfn.jederDefs = d.jederDefs; // Populate pronunciation and etymology template insert lists. if (d.pronTpls) { steps.pron.pronTpls = d.pronTpls; steps.pron.refreshTplSelect(); } if (d.etymTpls) { steps.etym.etymTpls = d.etymTpls; steps.etym.refreshTplSelect(); } // Sync trans/dunde/zarava keys with the (now populated) lang choices. steps.trans.keys = steps.lang.choices; steps.dunde.keys = steps.lang.choices; steps.zarava.keys = getZaravaKeys(steps.lang.choices); }).always(build); }); }); //</nowiki> nol4c97ww70mqw58cp3zugt9br9e9qi 6265560 6265559 2026-07-19T13:07:01Z Wikihez 7344 6265560 javascript text/javascript // Li ser [[vi:MediaWiki:Gadget-start.js]] hatiye refaktorkirin. //<nowiki> $(function () { var ns = mw.config.get("wgNamespaceNumber"); if (ns && !(ns === 2 && mw.config.get("wgPageName").match(/\/ceribandin$|\/test$/))) { return; } var action = mw.config.get("wgAction"); var pageExists = !!mw.config.get("wgArticleId"); // "Zimanek lê zêde bike" mode: triggered from the portlet link below. // Runs the same wizard on an EXISTING page's edit form, but appends the // generated section instead of replacing the textarea's content. var addLangMode = pageExists && mw.util.getParamValue("wiktkuaddlang") === "1"; // On a normal page view of an existing page, just add the portlet link // that takes the user into addLangMode; don't build anything else here. if (action === "view" && pageExists) { mw.util.addPortletLink("p-views", mw.util.getUrl(mw.config.get("wgPageName"), { action: "submit", wiktkuaddlang: "1" }), "+Ziman/beşeke din", "ca-wiktku-addlang", "Ji vê rûpelê re zimanekî nû zêde bike"); return; } if (!(action === "edit" || action === "submit")) { return; } if (!addLangMode && !$(".mw-newarticletext, .mw-newarticletextanon").length) { return; } if (window.location.href.includes("editintro=User:Wikihez/creation/intro")) { return; // Do not run the script wextê WF:Bilez dişuxile } function capitalize(str) { if (!str) return str; return str[0].toUpperCase() + str.substr(1); } function decapitalize(str) { if (!str) return str; return str[0].toLowerCase() + str.substr(1); } function escapeRegExp(str) { return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); } function stripWikilinks(str) { return str.replace(/\[\[([^\]|]+)(?:\|([^\]]+))?\]\]/g, function (m, target, display) { return display || target; }); } function insertAtCursor(el, text) { var start = el.selectionStart; var end = el.selectionEnd; var val = el.value; el.value = val.slice(0, start) + text + val.slice(end); var pos = start + text.length; el.selectionStart = el.selectionEnd = pos; } var pageName = mw.config.get("wgPageName").replaceAll(/_/g, " "); if (ns) pageName = pageName.replace(/.*\//, ""); var pageNameRe = escapeRegExp(pageName); var userLang = mw.config.get("wgUserLanguage"); // Mobile detection: MobileFrontend sets wgMFMode, or fall back to touch check. var isMobile = !!mw.config.get("wgMFMode") || window.matchMedia("(pointer: coarse)").matches; var chosenOptions = { width: "20em", disable_search_threshold: 0, placeholder_text_single: "Yekî hilbijêre", placeholder_text_multiple: "Hilbijêre", no_results_text: "Nehat dîtin", enable_split_word_search: true, search_contains: true }; function wrapNativeSelect(select) { var placeholder = select.attr("data-placeholder") || "Lê bigere…"; // Hide the native select — we drive it programmatically. select.hide(); var wrapper = $("<span class='wiktku-native-select-wrap'></span>"); var textInput = $("<input type='search' autocomplete='off'>") .attr("placeholder", placeholder) .addClass("wiktku-start-narrow wiktku-ac-input"); var resultsList = $("<ul class='wiktku-ac-results'></ul>").hide(); // Full option cache — rebuilt when chosen:updated fires. var allOptions = []; function cacheOptions() { allOptions = []; select.find("option").each(function () { var v = $(this).val(); if (!v) return; // skip the empty placeholder option allOptions.push({ value: v, text: $(this).text(), disabled: $(this).prop("disabled") }); }); } cacheOptions(); function showResults(query) { var q = query.trim().toLowerCase(); resultsList.empty(); var matched; if (q) { matched = []; $.each(allOptions, function (_, o) { if (o.disabled) return; var codeMatch = o.value.toLowerCase().indexOf(q) !== -1; var nameMatch = o.text.toLowerCase().indexOf(q) !== -1; if (codeMatch || nameMatch) { matched.push({ opt: o, codeMatch: codeMatch }); } }); // Code matches (especially prefix matches) come first. matched.sort(function (a, b) { var aCode = a.opt.value.toLowerCase(); var bCode = b.opt.value.toLowerCase(); var aPrefix = aCode.indexOf(q) === 0; var bPrefix = bCode.indexOf(q) === 0; if (aPrefix !== bPrefix) return aPrefix ? -1 : 1; if (a.codeMatch !== b.codeMatch) return a.codeMatch ? -1 : 1; return 0; }); matched = matched.map(function (item) { return item.opt; }); } else { matched = allOptions.filter(function (o) { return !o.disabled; }); } if (!matched.length) { resultsList.hide(); return; } $.each(matched.slice(0, 50), function (_, opt) { var li = $("<li></li>").text(opt.text).attr("data-value", opt.value); // Use touchend instead of touchstart so that a scroll gesture does // not accidentally select an item. We track whether the finger moved // between touchstart and touchend — if it did, it was a scroll. var touchMoved = false; li.on("touchstart", function () { touchMoved = false; }); li.on("touchmove", function () { touchMoved = true; }); li.on("touchend", function (e) { if (touchMoved) return; // was a scroll, not a tap e.preventDefault(); selectOption(opt.value, opt.text); }); // Keep mousedown for desktop fallback. li.on("mousedown", function (e) { e.preventDefault(); selectOption(opt.value, opt.text); }); resultsList.append(li); }); // Position the list above or below depending on available viewport space. var inputRect = textInput[0].getBoundingClientRect(); var viewportH = window.innerHeight; var spaceBelow = viewportH - inputRect.bottom - 8; var spaceAbove = inputRect.top - 8; var maxH = Math.min(224, Math.max(spaceBelow, spaceAbove)); // 224px ≈ 14em resultsList.css({ "max-height": maxH + "px", "top": spaceBelow >= spaceAbove ? "100%" : "auto", "bottom": spaceBelow >= spaceAbove ? "auto" : "100%" }); resultsList.show(); } function selectOption(value, text) { textInput.val(text); select.val(value); resultsList.hide(); select.trigger("change"); } textInput.on("input focus", function () { showResults($(this).val()); }); textInput.on("blur", function () { // Short delay so a touchstart on a result item fires first. setTimeout(function () { resultsList.hide(); }, 200); }); // chosen:updated → re-cache (called after ziman.json loads). select.on("chosen:updated", function () { cacheOptions(); // If a value is already selected, keep the display text in sync. var cur = select.val(); if (cur) { var match = $.grep(allOptions, function (o) { return o.value === cur; })[0]; if (match) textInput.val(match.text); } }); // No-op .chosen() so desktop call-sites don't need guarding. select.chosen = function () { return select; }; wrapper.append(textInput).append(resultsList).append(select); return wrapper; } var langsByCode = {}; // Populated from [[MediaWiki:Gadget-start.js/data.json]] at runtime. var metadata = {}; // Zaravayên kurdî yên ku di beşa "Bi zaravayên din" de tên pêşkêşkirin — // ev kod ji beşa Werger têne derxistin daku heman zimên du caran neyê xwendin. var ZARAVA_LANG_CODES = ["ckb", "sdh", "lki", "hac", "zza"]; function getZaravaKeys(choices) { var byCode = {}; $.each(choices || [], function (_, c) { byCode[c[0]] = c; }); var result = []; $.each(ZARAVA_LANG_CODES, function (_, code) { if (byCode[code]) result.push(byCode[code]); }); return result; } function needsTransliteration(langCode) { var meta = metadata[langCode]; if (!meta || !meta.sc) return false; var scripts = Array.isArray(meta.sc) ? meta.sc : [meta.sc]; return scripts.length > 0 && scripts[0] !== "Latn"; } // Kodên cinsiyetê yên di metadata.g de var GENDER_BASE_LABELS = { m: "mê", n: "nêr", nt: "nêtar", mn: "mê û nêr", mnmane: "mê yan nêr li gorî maneyê", g: "giştî", y: "yekjimar", p: "pirjimar" }; // Sub-lists that only make sense for a plain (non-şablon) sense — hidden // when a şablon (e.g. {{guharto|…}}) is chosen for that sense, since a // template-based sense has no "own" gloss for alternate forms, synonyms, // antonyms, coordinate terms, hypernyms or hyponyms to attach to. Etîket, // Nimûne and Jêgirtin stay visible either way. var HIDDEN_ON_TPL_GROUPS = [ "wiktku-dfn-alternativ", "wiktku-dfn-hevmane", "wiktku-dfn-dijmane", "wiktku-dfn-koordine", "wiktku-dfn-jornav", "wiktku-dfn-jernav" ]; function genderLabel(code) { if (code === "p") return "Pirjimar"; var pluralMatch = code.match(/^(.+)-p$/); if (pluralMatch && GENDER_BASE_LABELS[pluralMatch[1]]) { return GENDER_BASE_LABELS[pluralMatch[1]] + " (pirjimar)"; } return GENDER_BASE_LABELS[code] || code; } /** * True if a sense has any content worth keeping besides its mane text — * etîket, hevmane/dijmane/koordîne/etc. word lists, nimûne, or jêder * (quote). Used so a sense with an empty mane but filled-in extra * fields still gets emitted (with {{mane?}} standing in for the gloss) * instead of being silently dropped. */ function senseHasExtraContent(s) { if (s.etiket && $.grep(s.etiket, function (e) { return $.trim(e) !== ""; }).length) return true; if (s.alternativ.length || s.hevmane.length || s.dijmane.length || s.koordine.length || s.jornav.length || s.jernav.length) return true; if (s.nimune && $.grep(s.nimune, function (n) { return (typeof n === "object" ? n.text : n) !== ""; }).length > 0) return true; if (s.jeder && $.grep(s.jeder, function (j) { return j && j.quote; }).length > 0) return true; return false; } /** * formatNimune: each nimûne item can be { text, tr, t }: * text — example text * tr — transliteration (only when the language needs it) * t — Kurdish translation (third positional param, no key) */ function formatNimune(nimunes, lang, hasJeder) { var hasNimune = nimunes && $.grep(nimunes, function (n) { return (typeof n === "object" ? n.text : n) !== ""; }).length > 0; if (!hasNimune) { return hasJeder ? "" : "\n#* {{bênimûne|" + lang + "}}"; } return $.map(nimunes, function (n) { var text = typeof n === "object" ? n.text : n; if (!text) return undefined; var bolded = text.replace( new RegExp("(" + pageNameRe + "([^( |,|;|\\?|\\.|\\!)]+)?)", "ig"), "'''$1'''"); var tpl = "\n#: {{nm|" + lang + "|" + bolded; if (typeof n === "object") { if (n.tr) tpl += "|tr=" + n.tr; // Translation as third positional param (no key needed). if (n.t) tpl += "|" + n.t; } // Short examples fit on one line together with their translation. // rêz=1 is not used for ku — definitions are shown on separate lines there. if (text.length < 200 && lang !== "ku") tpl += "|rêz=1"; tpl += "}}"; return tpl; }).join(""); } /** * Formats a list of jêder (quote/citation) objects into wikitext lines. * Each entry that has no quote text is skipped. Returns "" when the list * is empty or every entry is blank. * * #* {{jêder-…|lang|jêgirtin=…|tr=…|tercime=…|…fields…}} * * When no template is chosen, the generic {{jêder|…}} template is used * instead. Its 2nd positional param is the user's freeform "bi destê xwe * binivîsim" source text when supplied, or the çavkanî? placeholder otherwise. * If that text contains "=" it is passed as |2=… instead of a bare * positional param, since MediaWiki would otherwise misparse it as its * own key=value pair and break the template: * #* {{jêder|lang|jêgirtin=…|tr=…|tercime=…|<manual source or çavkanî?>}} */ function formatJeder(jederList, lang) { if (!jederList || !jederList.length) return ""; return $.map(jederList, function (jeder) { if (!jeder || !jeder.quote) return undefined; if (jeder.jederTpl) { var cite = "\n#* {{" + jeder.jederTpl + "|" + lang; cite += "|jêgirtin=" + jeder.quote; if (jeder.quoteTr) cite += "|tr=" + jeder.quoteTr; if (jeder.quoteT) cite += "|tercime=" + jeder.quoteT; $.each(jeder.jêderFields || {}, function (key, val) { if (val) cite += "|" + key + "=" + val; }); cite += "}}"; return cite; } var out = "\n#* {{jêder|" + lang + "|jêgirtin=" + jeder.quote; if (jeder.quoteTr) out += "|tr=" + jeder.quoteTr; if (jeder.quoteT) out += "|tercime=" + jeder.quoteT; var srcParam = jeder.jederManual ? jeder.jederManual : "çavkanî?"; // A positional param containing "=" gets parsed as its own key=value // pair by MediaWiki and breaks the template, so force it to be // explicitly named (|2=) whenever that's the case. out += (srcParam.indexOf("=") !== -1 ? "|2=" : "|") + srcParam; out += "}}"; return out; }).join(""); } function makeWordListStep(id, name, question_fmt, header, templateName) { return { id: id, name: name, question_fmt: question_fmt, multiple: true, narrow: true, visible: function (values) { return values.lang && values.pos; }, output: function (values) { var words = $.grep(values[id] || [], function (w) { return !!w; }); if (!words.length) return ""; var lang = values.lang; var section = "\n==== " + header + " ====\n"; if (words.length === 1) { // Single word — keep the simple inline template. return section + "* {{" + templateName + "|" + lang + "|" + words[0] + "}}\n"; } // Multiple words — use {{kol3}} with one positional param per word. var params = "cure=" + header + "\n" + $.map(words, function (w) { return "|" + w; }).join("\n"); return section + "{{kol3|" + lang + "|" + params + "\n}}\n"; } }; } var steps = { lang: { id: "lang", required: true, name: "ziman", question_fmt: '"' + pageName + '" bi çi zimanî ye?', question_br: true, // Populated from [[MediaWiki:Gadget-start.js/data.json]] (langChoices). choices: [], output: function (values) { return "== {{ziman|" + values.lang + "}} ==\n"; } }, pron: { id: "pron", name: "bilêvkirin", question_fmt: '"' + pageName + '" çawa tê telafûzkirin?', // pronTpls populated from data.json pronTpls: [], visible: function (values) { if (!values.lang) return false; // In addLangMode, only skip pron when this langcode's section // already exists in the page — if it's a new language, show it. if (addLangMode) { var existing = $("#wpTextbox1").val() || ""; var header = "== {{ziman|" + values.lang + "}} =="; return existing.indexOf(header) === -1; } return true; }, /** Fills (or refills) the insert-dropdown from the current pronTpls array, filtering by language. */ refreshTplSelect: function () { var sel = $("#wiktku-start-pron .wiktku-tpl-insert-select"); if (!sel.length) return; var lang = getValues().lang || ""; sel.find("option[value!='']").remove(); $.each(steps.pron.pronTpls, function (_, tpl) { // Filter: if tpl.langs exists, only show if lang is in that list; otherwise show always var allowed = !tpl.langs || tpl.langs.indexOf(lang) !== -1; if (allowed) { sel.append($("<option></option>") .val(tpl.snippet) .text(tpl.name + " — " + tpl.desc) .attr("data-nolang", tpl.noLang ? "1" : "")); } }); // Notify Chosen that the option list has changed (no-op on mobile). if (!isMobile) sel.trigger("chosen:updated"); }, build: function (stepDiv) { if (stepDiv.find(".wiktku-pron-wrap").length) return null; var wrap = $("<div class='wiktku-pron-wrap'></div>"); var ta = $("<textarea></textarea>") .attr("name", "wiktku-pron-" + $.now()) .attr("class", "wiktku-start-step-field wiktku-pron-text") .attr("rows", 4) .attr("placeholder", "Nimûne: {{IPA|ku|/pɛɪ̯n/}} yan {{kîte|ku|he|ce|ki|rin}}"); // Template insert dropdown — filtered by language. var sel = $("<select class='wiktku-tpl-insert-select'></select>"); sel.append($("<option value=''>— şablonek lê zêde bike —</option>")); var lang = getValues().lang || ""; $.each(steps.pron.pronTpls, function (_, tpl) { // Filter: if tpl.langs exists, only show if lang is in that list; otherwise show always var allowed = !tpl.langs || tpl.langs.indexOf(lang) !== -1; if (allowed) { sel.append($("<option></option>") .val(tpl.snippet) .text(tpl.name + " — " + tpl.desc) .attr("data-nolang", tpl.noLang ? "1" : "")); } }); sel.on("change", function () { var snippet = $(this).val(); if (!snippet) return; var lang = getValues().lang || ""; // Check if the selected option has noLang flag var selectedOption = sel.find("option:selected"); var hasNoLang = selectedOption.attr("data-nolang") === "1"; if (!hasNoLang) { snippet = snippet.replace(/CODE/g, lang).replace(/SOURCELANG/g, "?"); } insertAtCursor(ta[0], snippet); $(this).val(""); ta.focus(); }); wrap.append(sel).append($("<br>")).append(ta); stepDiv.append(wrap); return ta; }, output: function () { var text = $.trim($("#wiktku-start-pron .wiktku-pron-text").val()); if (!text) return ""; var lines = text.split("\n"); var out = $.map(lines, function (line) { line = $.trim(line); if (!line) return undefined; return line.charAt(0) === "*" ? line : "* " + line; }).join("\n"); return "\n=== Bilêvkirin ===\n" + out + "\n"; } }, pos: { id: "pos", required: true, name: "Cureyê rêzimanî", question_fmt: 'Cureyê rêzimanî yê "' + pageName + '" çi ye?', visible: function (values) { return values.lang; }, question_br: true, // Populated from [[MediaWiki:Gadget-start.js/data.json]] (posChoices). choices: [], output: function (values) { var pos = values.pos || ""; var cinsiyet = values.cinsiyet || ""; // from the cinsiyet step var lekTur = values.lektur || ""; // from the lêker transitivity step var capitalizedPos = capitalize(pos); var outputString = "\n=== " + capitalizedPos + " ===\n"; // Add ku-tewîn-nav for single-word navdêr/serenav with known gender. if (!pageName.includes(" ") && cinsiyet && GENDER_BASE_LABELS[cinsiyet] && (pos === "navdêr" || pos === "serenav") && values.lang === "ku") { outputString += "{{ku-tewîn-nav|" + pageName + "|" + GENDER_BASE_LABELS[cinsiyet]; if (pos === "serenav") outputString += "|y"; outputString += "}}\n"; } outputString += "{{" + pos + "|" + values.lang; if (pos === "navdêr" || pos === "serenav") { if (cinsiyet) { outputString += "|c=" + cinsiyet; } else if (values.lang === "ku") { // Unknown gender — prompt editor to fill it in. outputString += "|c=?"; } } else if (/^lêker/.test(pos) && lekTur) { outputString += "|c=" + lekTur; } if (values.tr) { outputString += "|tr=" + values.tr; } outputString += "}}\n"; return outputString; } }, /** * cinsiyet (grammatical gender) — only shown for navdêr/serenav, û * tenê ger metadata ji bo zimanê hilbijartî lîsteyeke "g" (cinsiyet) * were dayîn. Opsiyonên vê gavê ne sabît in — ji metadata[values.lang].g * têne çêkirin, ji ber ku di hemû zimanan de cinsiyet tine. */ cinsiyet: { id: "cinsiyet", name: "cinsiyet", question_fmt: 'Cinsiyeta "' + pageName + '" çi ye?', question_br: true, visible: function (values) { var meta = metadata[values.lang]; return !!(values.lang && (values.pos === "navdêr" || values.pos === "serenav") && meta && meta.g && meta.g.length); }, build: function (stepDiv, values) { var select = stepDiv.find("select.wiktku-start-step-field"); if (!select.length) { select = $(mw.html.element("select", { "class": "wiktku-start-step-field", id: "wiktku-start-cinsiyet-field" })); stepDiv.append(select); } if (!values) return select; var meta = metadata[values.lang]; var codes = (meta && meta.g) || []; var prevVal = select.val(); var choices = $.map(codes, function (code) { return [[code, genderLabel(code)]]; }); populateMenus(select, choices); if ($.grep(choices, function (c) { return c[0] === prevVal; }).length) { select.val(prevVal); } if (!isMobile) select.trigger("chosen:updated"); return select; }, output: function () { return ""; } // consumed by pos.output }, /** * Lêker transitivity — only shown for any lêker variant. */ lektur: { id: "lektur", name: "Cureyê lêkerê (fiîlê)", question_fmt: "Cureyê lêkerê (fiîlê) çi ye?", question_br: true, visible: function (values) { return values.lang && values.pos && /^lêker/.test(values.pos); }, // Dictionary: value → display label. Add new types here. choices: [ ["gh", "gerguhêz"], ['x-gh', 'xwerû-gerguhêz'], ['p-gh', 'pêkhatî-gerguhêz'], ['h-gh', 'hevedudanî-gerguhêz'], ['b-gh', 'biwêjî-gerguhêz'], ["ngh", "negerguhêz"], ['x-ngh', 'xwerû-negerguhêz'], ['p-ngh', 'pêkhatî-negerguhêz'], ['h-ngh', 'hevedudanî-negerguhêz'], ['b-ngh', 'biwêjî-negerguhêz'] ], output: function () { return ""; } // consumed by pos.output }, tr: { id: "tr", name: "transkrîpsiyon", question_fmt: "Transkrîpsiyona kelîmeyê", multiple: false, narrow: true, visible: function (values) { return values.lang && values.pos && needsTransliteration(values.lang); } }, dfn: { id: "dfn", // required: true, ger mane tinebe [[Şablon:mane?]] bi kar bîne name: "Mane", question_fmt: "Maneya kelîmeyê binivîse. Mane otomatîk tê lînkkirin! Ji bo tercimeyan beşa 'Werger' bi kar bîne!", multiple: true, ordered: true, rows: 3, visible: function (values) { return values.lang && values.pos; }, example: function (values) { // posExamples loaded from [[MediaWiki:Gadget-start.js/data.json]]. var examples = steps.dfn.posExamples || {}; var full = values.pos || ""; return examples[full] || ""; }, /** * Builds one sense block (<li>) inside the ordered list. * Each block contains: * - a textarea for the definition * - an expandable nimûne list * - single-row sub-lists for formên alternatîv, hevmane, dijmane */ buildSenseBlock: function (stepDiv) { var block = $("<li class='wiktku-dfn-sense'></li>"); // — Mane textarea (declared first so the template handler can reference it) — var dfnArea = $("<textarea></textarea>") .attr("name", "wiktku-dfn-mane-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("class", "wiktku-start-step-field wiktku-dfn-mane") .attr("rows", 6) .attr("placeholder", "Mane…"); dfnArea.on("input", function () { steps.dfn.onDfnInput(stepDiv, block, this); }); // — Template selector (optional — replaces mane when chosen) — // Template definitions loaded from [[MediaWiki:Gadget-start.js/data.json]]. var tplDefs = steps.dfn.tplDefs || []; // Cache of all non-placeholder option elements — used by updateTplOptions // to remove/re-add options (the only approach compatible with Chosen.js). var _allTplOptions = []; var tplSelect = $(mw.html.element("select", { "class": "wiktku-dfn-tpl-select" })); tplSelect.append($("<option value=''>— yan jî şablonek hilbijêre —</option>")); $.each(tplDefs, function (_, tpl) { var opt = $("<option></option>") .val(tpl.name) .text(tpl.name) .attr("data-langs", tpl.langs ? tpl.langs.join(",") : "") .attr("data-nolang", tpl.noLang ? "1" : ""); tplSelect.append(opt); _allTplOptions.push(opt[0]); }); function updateTplOptions() { var lang = getValues().lang || ""; var currentVal = tplSelect.val(); var currentStillValid = false; // Detach all non-placeholder options, then re-attach only the visible ones. // This is the only approach that works correctly with both native <select> // and Chosen.js on desktop. tplSelect.find("option[value!='']").detach(); $.each(_allTplOptions, function (_, opt) { var allowed = $(opt).attr("data-langs"); var visible = !allowed || allowed.split(",").indexOf(lang) !== -1; if (visible) { tplSelect.append(opt); if ($(opt).val() === currentVal) currentStillValid = true; } }); if (!isMobile) tplSelect.trigger("chosen:updated"); if (currentVal && !currentStillValid) { tplSelect.val(""); dfnArea.show(); tplTitleInput.hide().val(""); } } // Store updater on the element so refresh() can call it for all blocks. tplSelect.data("updateOptions", updateTplOptions); var tplTitleInput = $("<input type='text'>") .addClass("wiktku-dfn-tpl-title wiktku-start-narrow") .attr("placeholder", "Navê rûpelê…") .hide(); // Grow the sense list when the title field of the last block gets content, // mirroring what onDfnInput does for the plain mane textarea. tplTitleInput.on("input", function () { steps.dfn.onDfnInput(stepDiv, block, this); }); /** * When a şablon sense is chosen, formên alternatîv/hevmane/dijmane/ * termên koordîne/jornav/jêrnav don't apply (there's no plain gloss * to hang them off), so hide those subgroups. Etîket, Nimûne and * Jêgirtin stay visible and still usable for a şablon sense. */ function updateFieldVisibility() { var isTpl = !!tplSelect.val(); $.each(HIDDEN_ON_TPL_GROUPS, function (_, cls) { block.find("." + cls + "-group").toggle(!isTpl); }); } // Store on the block so restoreDfn() can re-sync visibility // after programmatically setting tplSelect's value. block.data("updateFieldVisibility", updateFieldVisibility); tplSelect.on("change", function () { var chosen = $(this).val(); if (chosen) { dfnArea.hide(); tplTitleInput.show().focus(); } else { dfnArea.show(); tplTitleInput.hide().val(""); } updateFieldVisibility(); // Re-run refresh so the Werger step visibility updates. refresh(); }); var tplRow = $("<div></div>").addClass("wiktku-dfn-tpl-row") .append(tplSelect).append(" ").append(tplTitleInput); block.append(tplRow); block.append(dfnArea); // Apply lang filter on initial build. updateTplOptions(); // — Sub-field groups — // All groups are always visible with a placeholder textarea. // Nimûne is last in the DOM and last in the output. var allGroups = [ { cls: "wiktku-dfn-etiket", label: "Etîket", rows: 1, narrow: true, izah: "xisûsen, Mêrdîn, anatomî, Badînî" }, { cls: "wiktku-dfn-alternativ", label: "Formên alternatîv", rows: 1, narrow: true, izah: "Varyantên vê kelîmeyê" }, { cls: "wiktku-dfn-hevmane", label: "Hevmane", rows: 1, narrow: true, izah: "Spehî hevmaneya Bedew e." }, { cls: "wiktku-dfn-dijmane", label: "Dijmane", rows: 1, narrow: true, izah: "Zengîn dijmaneya feqîr e." }, { cls: "wiktku-dfn-koordine", label: "Termên koordîne", rows: 1, narrow: true, izah: "Pisîk û kûçik termên koordîne ne çunkî Jornavên wan gelek in" }, { cls: "wiktku-dfn-jornav", label: "Jornav", rows: 1, narrow: true, izah: "Heywan jornavê guhandar e" }, { cls: "wiktku-dfn-jernav", label: "Jêrnav", rows: 1, narrow: true, izah: "Guhandar jêrnavê heywan e" }, { cls: "wiktku-dfn-nimune", label: "Nimûne", rows: 2, narrow: false } ]; $.each(allGroups, function (_, g) { var groupDiv = $("<div></div>").addClass("wiktku-dfn-subgroup " + g.cls + "-group"); function buildNimuneLi() { var lang = getValues().lang || ""; var li = $("<li></li>").addClass("wiktku-dfn-nimune-li"); var mainTa = $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-text-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", g.rows) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-text") .attr("placeholder", "Nimûneya emilandina kelîmeyê tu bi xwe binivîse…"); mainTa.on("input", function () { var val = $.trim($(this).val()); var isLast = li.is(list.children("li:last-child")); if (val && isLast) { list.append(buildNimuneLi()); } }); li.append(mainTa); var subWrap = $("<div></div>").addClass("wiktku-dfn-nimune-sub"); if (needsTransliteration(lang)) { subWrap.append( $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-tr-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 5) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-tr") .attr("placeholder", "Transkrîpsiyona bi alfabeya latînî") ); } if (lang && lang !== "ku") { subWrap.append( $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-t-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 5) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-t") .attr("placeholder", "Tercimeya kurmancî") ); } if (subWrap.children().length) li.append(subWrap); return li; } if (g.cls === "wiktku-dfn-nimune") { // Nimûne — compound widget with tr/t sub-fields. var lbl = $("<span></span>").addClass("wiktku-dfn-sublabel").text(g.label + ": "); var list = $("<ol></ol>").addClass("wiktku-dfn-sublist " + g.cls + "-list"); groupDiv.data("buildNimuneLi", buildNimuneLi); list.append(buildNimuneLi()); groupDiv.append(lbl).append(list); block.append(groupDiv); } else { // Regular always-visible group — label + growing textarea list. var lbl = $("<span></span>").addClass("wiktku-dfn-sublabel").text(g.label + ": " + g.izah); var list = $("<ol></ol>").addClass("wiktku-dfn-sublist " + g.cls + "-list"); var firstInput = $("<textarea></textarea>") .attr("name", g.cls + "-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", g.rows) .attr("class", "wiktku-dfn-subfield" + (g.narrow ? " wiktku-start-narrow" : "")) .attr("placeholder", g.label + "…"); firstInput.on("input", function () { steps.dfn.onSubInput(list, this, g.rows, g.narrow); }); list.append($("<li></li>").append(firstInput)); groupDiv.append(lbl).append(list); block.append(groupDiv); } }); // — Jêder (quote / citation) group — a growing list, sibling to Nimûne — // Structured the same way as Nimûne (ol.wiktku-dfn-sublist > li) so it // lines up at the same indentation, and so that typing into the last // citation's Jêgirtin box automatically opens a fresh empty one below it. (function () { var jederGroupDiv = $("<div></div>").addClass("wiktku-dfn-subgroup wiktku-dfn-jeder-group"); var jederLbl = $("<span></span>").addClass("wiktku-dfn-sublabel").text("Jêgirtin: "); var jederList = $("<ol></ol>").addClass("wiktku-dfn-sublist wiktku-dfn-jeder-list"); function buildJederLi() { var lang = getValues().lang || ""; var li = $("<li></li>").addClass("wiktku-dfn-jeder-li"); var dragHandle = $("<span></span>") .addClass("wiktku-jeder-drag-handle") .attr("title", "Bişkûne û bikişîne da ku rêzê biguhezîne"); // Quote text textarea var quoteTa = $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-quote-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 2) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-quote") .attr("placeholder", "Nimûneya emilandinê ji kitêb an çavkaniyeke din binivîse"); quoteTa.on("input", function () { var val = $.trim($(this).val()); var isLast = li.is(jederList.children("li:last-child")); if (val && isLast) { jederList.append(buildJederLi()); } }); li.append(dragHandle).append(quoteTa); // tr/t sub-fields for the quote — shown as needed for the language. var quoteSubWrap = $("<div></div>").addClass("wiktku-dfn-quote-sub"); if (needsTransliteration(lang)) { quoteSubWrap.append( $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-quote-tr-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 2) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-quote-tr") .attr("placeholder", "Transkrîpsiyona jêgirtinê…") ); } if (lang && lang !== "ku") { quoteSubWrap.append( $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-quote-t-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 2) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-quote-t") .attr("placeholder", "Tercimeya jêgirtinê bi kurmancî") ); } if (quoteSubWrap.children().length) li.append(quoteSubWrap); // Citoid auto-fill: fetch citation data from a URL, DOI or ISBN and // prefill the source şablon + fields below (see Gadget-citoid-helper.js). var citoidWrap = $("<div></div>").addClass("wiktku-dfn-quote-citoid"); var citoidInput = $("<input type='text'>") .addClass("wiktku-dfn-quote-citoid-input wiktku-start-narrow") .attr("placeholder", "URL, DOI an ISBN binivîse ku otomatîk were tijekirin…"); var citoidBtn = new OO.ui.ButtonWidget({ label: "Bi Citoid bîne", classes: [ "wiktku-dfn-quote-citoid-btn" ] }); var citoidStatus = $("<span></span>").addClass("wiktku-dfn-quote-citoid-status"); /** * Fetches citation data from Citoid and applies it to this * citation's şablon selector + fields. Mirrors the logic in * Form.prototype._fillFromCitoid (Gadget-wikt.add-examples.js): * - only (re)selects the şablon when it actually differs from * what's already chosen, so a repeat fetch doesn't wipe out * a template the user already picked; * - only fills fields that are currently empty, so it never * overwrites something the user typed by hand; * - falls back to the freeform "bi destê xwe binivîsim" source * only when nothing was typed there yet. */ function runCitoidFetch() { var query = $.trim(citoidInput.val()); if (!query) { mw.notify("Ji kerema xwe re pêşî URL, DOI an ISBNyekê binivîse."); return; } citoidBtn.setDisabled(true); citoidStatus.text("Tê anîn…"); wikt.citoidHelper.ensure().then(function () { return wikt.citoid.fetchJederFields(query); }).then(function (result) { var jederKey = result.jederKey; var hasTpl = !!jederKey && srcSel.find("option[value='" + jederKey + "']").length > 0; var targetVal = hasTpl ? jederKey : "__manual__"; // Only (re)select — and thus rebuild — the field rows if // we're switching to a different şablon than what's // already chosen, so a second fetch doesn't clear fields // the user already filled in by hand. if (srcSel.val() !== targetVal) { srcSel.val(targetVal).trigger("change"); srcSel.trigger("chosen:updated"); } if (hasTpl) { // Tenê qadên vala tijî bike. $.each(result.fields, function (key, val) { var input = srcFields.find("[data-field-key='" + key + "']"); if (input.length && !$.trim(input.val())) { input.val(val); } }); } else { // Şablonek nehat naskirin ji bo vê itemType — rêzikeke // çavkaniyê ya bi destan a ji qadên Citoid tê çêkirin, // lê tenê ger qada destan vala be. var manualField = srcFields.find(".wiktku-dfn-quote-src-manual"); if (!$.trim(manualField.val())) { var parts = []; $.each(["nivîskar", "sernav", "websîte", "kovar", "weşanxane", "sal", "url"], function (_, k) { if (result.fields[k]) parts.push(result.fields[k]); }); manualField.val(parts.join(", ")); } } citoidStatus.text(""); }, function (errorMsg) { citoidStatus.text(typeof errorMsg === "string" ? errorMsg : "Nehat dîtin. Kontrol bike ka URL/DOI/ISBN rast e."); }).always(function () { citoidBtn.setDisabled(false); }); } citoidBtn.on("click", runCitoidFetch); citoidInput.on("keydown", function (e) { if (e.which === 13) { // Enter e.preventDefault(); runCitoidFetch(); } }); citoidWrap.append(citoidInput).append(citoidBtn.$element).append(citoidStatus); // Source template selector, specific to this citation. var srcSel = $("<select></select>").addClass("wiktku-dfn-quote-src-sel"); srcSel.append($("<option value=''>— Çavkaniyê hilbijêre —</option>")); srcSel.append($("<option></option>").val("__manual__").text("Bi destê xwe binivîsim")); var jederDefs = steps.dfn.jederDefs || {}; $.each(jederDefs, function (tplName, def) { srcSel.append($("<option></option>").val(tplName).text(def.label)); }); // Dynamic source fields container. var srcFields = $("<div></div>").addClass("wiktku-dfn-quote-src-fields"); srcSel.on("change", function () { srcFields.empty(); var chosen = $(this).val(); if (!chosen) return; if (chosen === "__manual__") { // Freeform source, written by the user — becomes the 2nd // positional param of {{jêder|lang|…}} instead of çavkanî?. srcFields.append( $("<textarea></textarea>") .attr("rows", 4) .addClass("wiktku-dfn-subfield wiktku-dfn-quote-src-manual") .attr("placeholder", "Çavkaniyê bi destê xwe binivîse…") ); return; } var def = (steps.dfn.jederDefs || {})[chosen]; if (!def) return; $.each(def.fields, function (_, f) { var row = $("<div></div>").addClass("wiktku-dfn-quote-src-row"); var fieldLbl = $("<label></label>").text(f.label + ": "); var inp = $("<textarea></textarea>") .attr("rows", 2) .addClass("wiktku-dfn-quote-src-input wiktku-start-narrow") .attr("data-field-key", f.key) .attr("placeholder", f.label + "…"); row.append(fieldLbl).append(inp); srcFields.append(row); }); }); li.append(citoidWrap).append(srcSel).append(srcFields); return li; } jederGroupDiv.data("buildJederLi", buildJederLi); jederList.append(buildJederLi()); // Make citation rows sortable (drag to reorder). // The last row is always the empty trailing row — cancel its drag. mw.loader.using("jquery.ui.sortable", function () { jederList.sortable({ handle: ".wiktku-jeder-drag-handle", axis: "y", items: "li:not(:last-child)", tolerance: "pointer" }); }); jederGroupDiv.append(jederLbl).append(jederList); block.append(jederGroupDiv); }()); // Apply the initial hide/show state for the sub-groups (matches // tplSelect's starting value, which is normally empty). updateFieldVisibility(); return block; }, /** Grows the sense list when the last mane textarea gets content. */ onDfnInput: function (stepDiv, block, textarea) { var val = $.trim($(textarea).val()); var list = stepDiv.find("ol.wiktku-dfn-list"); var isLast = block.is(list.children("li:last-child")); if (val && isLast) { var newBlock = steps.dfn.buildSenseBlock(stepDiv); list.append(newBlock); // Apply Chosen to the new block's template selector on desktop. if (!isMobile) newBlock.find("select.wiktku-dfn-tpl-select").chosen(chosenOptions); } refresh(); }, /** Grows a sub-list (nimûne/formên alternatîv/hevmane/dijmane/termên koordîne) on input. */ onSubInput: function (list, input, rows, narrow) { var val = $.trim($(input).val()); var item = $(input).parent(); var isLast = item.is(list.children("li:last-child")); if (val && isLast) { var next = $("<textarea></textarea>") .attr("name", "wiktku-dfn-sub-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", rows) .attr("class", "wiktku-dfn-subfield" + (narrow ? " wiktku-start-narrow" : "")); next.on("input", function () { steps.dfn.onSubInput(list, this, rows, narrow); }); list.append($("<li></li>").append(next)); } }, // Populated from [[MediaWiki:Gadget-start.js/data.json]] (tplDefs, posExamples, jederDefs). tplDefs: [], posExamples: {}, jederDefs: {}, build: function (stepDiv) { if (stepDiv.find("ol.wiktku-dfn-list").length) return null; var list = $("<ol class='wiktku-dfn-list'></ol>"); list.append(steps.dfn.buildSenseBlock(stepDiv)); stepDiv.append(list); return null; }, /** Reads all sense blocks from the DOM and returns an array of sense objects. */ getSenses: function (stepDiv) { var senses = []; stepDiv.find("li.wiktku-dfn-sense").each(function () { var block = $(this); var tplSel = block.find("select.wiktku-dfn-tpl-select"); var tpl = tplSel.val() || ""; // noLang: template already encodes the language — don't add |lang| param. var tplNoLang = tpl ? tplSel.find("option[value='" + tpl + "']").attr("data-nolang") === "1" : false; var tplTitle = $.trim(block.find("input.wiktku-dfn-tpl-title").val()); var mane = $.trim(block.find("textarea.wiktku-dfn-mane").val()); var etiket = (function () { var vals = []; block.find(".wiktku-dfn-etiket-list textarea").each(function () { var v = $.trim($(this).val()); if (v) vals.push(v); }); return vals; }()); function readList(cls) { var vals = []; block.find("." + cls + "-list textarea").each(function () { var v = $.trim($(this).val()); if (v) vals.push(v); }); return vals; } // Nimûne items are compound: { text, tr?, t? } function readNimuneList() { var items = []; block.find(".wiktku-dfn-nimune-list li.wiktku-dfn-nimune-li").each(function () { var text = $.trim($(this).find(".wiktku-dfn-nimune-text").val()); if (!text) return; var obj = { text: text }; var tr = $.trim($(this).find(".wiktku-dfn-nimune-tr").val()); var t = $.trim($(this).find(".wiktku-dfn-nimune-t").val()); if (tr) obj.tr = tr; if (t) obj.t = t; items.push(obj); }); return items; } // Jêder is a growing list of citations, one per li — mirrors readNimuneList(). function readJederList() { var items = []; block.find(".wiktku-dfn-jeder-list li.wiktku-dfn-jeder-li").each(function () { var li = $(this); var quote = $.trim(li.find(".wiktku-dfn-nimune-quote").val()); if (!quote) return; var obj = { quote: quote }; var qtr = $.trim(li.find(".wiktku-dfn-nimune-quote-tr").val()); var qt = $.trim(li.find(".wiktku-dfn-nimune-quote-t").val()); if (qtr) obj.quoteTr = qtr; if (qt) obj.quoteT = qt; var tplName = li.find(".wiktku-dfn-quote-src-sel").val(); if (tplName === "__manual__") { var manual = $.trim(li.find(".wiktku-dfn-quote-src-manual").val()); if (manual) obj.jederManual = manual; } else if (tplName) { obj.jederTpl = tplName; var fields = {}; li.find(".wiktku-dfn-quote-src-input").each(function () { var k = $(this).attr("data-field-key"); var v = $.trim($(this).val()); if (k && v) fields[k] = v; }); obj.jêderFields = fields; } items.push(obj); }); return items; } senses.push({ tpl: tpl, tplNoLang: tplNoLang, tplTitle: tplTitle, mane: mane, etiket: etiket, nimune: readNimuneList(), jeder: readJederList(), alternativ: readList("wiktku-dfn-alternativ"), hevmane: readList("wiktku-dfn-hevmane"), dijmane: readList("wiktku-dfn-dijmane"), koordine: readList("wiktku-dfn-koordine"), jornav: readList("wiktku-dfn-jornav"), jernav: readList("wiktku-dfn-jernav") }); }); return senses; }, getOutput: function (values, callback) { var stepDiv = $("#wiktku-start-dfn"); var senses = steps.dfn.getSenses(stepDiv); var lang = values.lang; // A sense counts as "filled" if it has a mane, a chosen template + title, // or any other content (etîket/hevmane/nimûne/jêder…) worth keeping. var hasMane = senses.some(function (s) { return s.mane !== "" || (s.tpl && s.tplTitle) || senseHasExtraContent(s); }); // True only when at least one sense has a regular mane (needs linkify). var hasRegularMane = senses.some(function (s) { return !s.tpl && s.mane !== ""; }); // nimûne and jêder lines must never pass through linkify — only // the plain mane text should be linkified. We build two parallel // arrays: defLines (sent to linkify) and citeLines (kept aside). // Each entry in citeLines corresponds 1-to-1 with a defLines entry; // a template token {{wiktku-cite-N}} is embedded in defLines so // that after linkify runs we know exactly where to splice them back. // Template-call syntax is guaranteed safe: linkifiers leave {{ }} // tokens completely untouched. var defLines = []; // one entry per kept sense (goes to linkify) var citeLines = []; // parallel — nimûne+jêder for that same sense $.each(senses, function (_, sense) { // — Template sense (e.g. {{guharto|ku|somepage}}) — if (sense.tpl) { if (!sense.tplTitle) return; // skip empty template senses var tplLabelTpl = ""; if (sense.etiket && sense.etiket.length) { var tplLabelParts = sense.etiket.map(function (part) { return $.trim(part); }).filter(function (part) { return part !== ""; }); if (tplLabelParts.length) { tplLabelTpl = " {{e|" + lang + "|" + tplLabelParts.join("|") + "}} "; } } var tplCall = sense.tplNoLang ? "{{" + sense.tpl + "|" + sense.tplTitle + "}}" : "{{" + sense.tpl + "|" + lang + "|" + sense.tplTitle + "}}"; var tplHasJeder = sense.jeder && $.grep(sense.jeder, function (j) { return j && j.quote; }).length > 0; var idx = defLines.length; var cite = formatNimune(sense.nimune, lang, tplHasJeder) + formatJeder(sense.jeder, lang); defLines.push("#" + (tplLabelTpl ? tplLabelTpl : " ") + tplCall + (cite ? "{{wiktku-cite-" + idx + "}}" : "")); citeLines.push(cite); return; } // — Normal mane sense — var dfn = sense.mane; if (!dfn && !senseHasExtraContent(sense)) return; // truly empty if (dfn) { dfn = stripWikilinks(dfn); if (dfn[0] !== dfn[0].toUpperCase()) dfn = capitalize(dfn); if (!dfn.match(/[.…?!)\]]$/)) dfn += "."; } else { dfn = "{{mane?|" + lang + "}}"; } var labelTpl = ""; if (sense.etiket && sense.etiket.length) { var labelParts = sense.etiket.map(function (part) { return $.trim(part); }).filter(function (part) { return part !== ""; }); if (labelParts.length) { labelTpl = " {{e|" + lang + "|" + labelParts.join("|") + "}} "; } } var out = "#" + (labelTpl ? labelTpl : " ") + dfn; function wordLine(tpl, words) { if (!words.length) return ""; return "\n#: {{" + tpl + "|" + lang + "|" + words.join("|") + "}}"; } out += wordLine("alt-r", sense.alternativ); out += wordLine("hevmane", sense.hevmane); out += wordLine("dijmane", sense.dijmane); out += wordLine("koordîne", sense.koordine); out += wordLine("jornav", sense.jornav); out += wordLine("jêrnav", sense.jernav); var hasJeder = sense.jeder && $.grep(sense.jeder, function (j) { return j && j.quote; }).length > 0; var cite = formatNimune(sense.nimune, lang, hasJeder) + formatJeder(sense.jeder, lang); var idx = defLines.length; defLines.push(out + (cite ? "{{wiktku-cite-" + idx + "}}" : "")); citeLines.push(cite); }); // Splice citeLines back into a linkified string, replacing each // {{wiktku-cite-N}} token with its stored nimûne/jêder block. function restoreCites(t) { return t.replace(/\{\{wiktku-cite-(\d+)\}\}/g, function (_, n) { return citeLines[parseInt(n, 10)] || ""; }); } var text = defLines.join("\n") + "\n"; if (!hasMane) { // No definitions entered — emit {{mane?}} with bênimûne. text = "# {{mane?|" + lang + "}}\n#* {{bênimûne|" + lang + "}}\n"; callback(text); return; } if (!hasRegularMane) { // All filled senses are template senses — no linkify needed. callback(restoreCites(text)); return; } var didTryToLoad = function () { if (typeof $.wiktviLinkify === "function") { $.wiktviLinkify(text, function (linked) { callback(restoreCites(linked)); }); } else { callback(restoreCites(text)); } }; mw.loader.using("ext.gadget.linkify", didTryToLoad, didTryToLoad); } }, je: makeWordListStep("je", "jê", "Kelîmeyên jê çêbûyî binivîse", "Jê", "g"), tekildar: makeWordListStep("tekildar", "têkildar", "Kelîmeyên ji aliyê etîmolojiyê ve têkildarî vê kelîmeyê binivîse", "Têkildar", "g"), binereherwiha: makeWordListStep("binereherwiha", "binêre herwiha", "Kelîmeyên din ên eleqedar binivîse", "Binêre herwiha", "g"), etym: { id: "etym", name: "etîmolojî", question_fmt: "Etîmolojiya kelîmeyê binivîse", // etymTpls populated from data.json etymTpls: [], visible: function (values) { return values.lang && values.pos; }, /** Fills (or refills) the insert-dropdown from the current etymTpls array. */ refreshTplSelect: function () { var sel = $("#wiktku-start-etym .wiktku-tpl-insert-select"); if (!sel.length) return; sel.find("option[value!='']").remove(); $.each(steps.etym.etymTpls, function (_, tpl) { sel.append($("<option></option>").val(tpl.snippet).text(tpl.name + " — " + tpl.desc)); }); // Notify Chosen that the option list has changed (no-op on mobile). if (!isMobile) sel.trigger("chosen:updated"); }, build: function (stepDiv) { if (stepDiv.find(".wiktku-etym-wrap").length) return null; var wrap = $("<div class='wiktku-etym-wrap'></div>"); var ta = $("<textarea></textarea>") .attr("name", "wiktku-etym-" + $.now()) .attr("class", "wiktku-start-step-field wiktku-etym-text") .attr("rows", 4) .attr("placeholder", "Nimûne: Ji {{ji|en|ku|apple}}. yan rasterast binivîse…"); // Template insert dropdown — options also refreshed after data.json loads. var sel = $("<select class='wiktku-tpl-insert-select'></select>"); sel.append($("<option value=''>— şablonek lê zêde bike —</option>")); $.each(steps.etym.etymTpls, function (_, tpl) { sel.append($("<option></option>").val(tpl.snippet).text(tpl.name + " — " + tpl.desc)); }); sel.on("change", function () { var snippet = $(this).val(); if (!snippet) return; var lang = getValues().lang || ""; snippet = snippet.replace(/CODE/g, lang).replace(/SOURCELANG/g, "?"); insertAtCursor(ta[0], snippet); $(this).val(""); ta.focus(); }); wrap.append(sel).append($("<br>")).append(ta); stepDiv.append(wrap); return ta; }, output: function (values) { var text = $.trim($("#wiktku-start-etym .wiktku-etym-text").val()); if (text) { return "\n==== Etîmolojî ====\n" + text + "\n"; } // No etymology entered — emit {{ji?|lang}} as a placeholder, // but only when the entry has at least one regular (non-şablon) // sense with content — either real mane text, or an empty mane // with other fields filled in (which dfn.getOutput() renders as // {{mane?|lang}} with those fields attached). A şablon sense // like {{guharto|…}} never counts, filled in or not. var dfnSenses = steps.dfn.getSenses($("#wiktku-start-dfn")); var hasRegularMane = dfnSenses.some(function (s) { return !s.tpl && (s.mane !== "" || senseHasExtraContent(s)); }); if (!hasRegularMane) return ""; return "\n==== Etîmolojî ====\n{{ji?|" + values.lang + "}}\n"; } }, dunde: { id: "dunde", name: "dûnde", question_fmt: "Eger ev kelîme ji vî zimanî ketibe zimanekî din, vî zimanî û kelîmeya wî binivîse", visible: function (values) { return !!values.pos; }, disabledKeys: { "navz": true}, /** * Builds one row: a language dropdown + a growing list of word * inputs. When the dropdown gets a value the next empty row is * appended automatically. Mirrors steps.trans's row widget, but * flat (one shared list — dûnde isn't tied to individual senses). */ buildRow: function (stepDiv) { var row = $("<li class='wiktku-dunde-row wiktku-lang-row'></li>"); // Language selector — chosen is applied after insertion into DOM. var langSel = $(mw.html.element("select", { "class": "wiktku-start-step-keyfield wiktku-start-narrow" })); langSel.attr("data-placeholder", "Zimanekî lê bigere"); populateMenus(langSel, steps.dunde.keys || [], steps.dunde.disabledKeys); // When a language is chosen, ensure a next empty row exists. langSel.on("change", function () { steps.dunde.onLangChange(stepDiv, row); }); // Word list for this language. var wordList = $("<ul class='wiktku-dunde-words wiktku-lang-row-words'></ul>"); var firstWord = steps.dunde.makeWordInput(); wordList.append($("<li></li>").append(firstWord)); if (isMobile) { row.append(wrapNativeSelect(langSel)).append(wordList); } else { row.append(langSel).append(wordList); } return row; }, makeWordInput: function () { var input = $("<textarea></textarea>") .attr("name", "wiktku-dunde-word-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 1) .attr("class", "wiktku-dfn-subfield wiktku-start-narrow") .attr("placeholder", "Kelîme…"); input.on("input", function () { var list = $(this).closest("ul.wiktku-dunde-words"); var item = $(this).parent(); var val = $.trim($(this).val()); if (val && item.is(list.children("li:last-child"))) { var next = steps.dunde.makeWordInput(); list.append($("<li></li>").append(next)); } }); return input; }, onLangChange: function (stepDiv, row) { var list = stepDiv.find("ul.wiktku-dunde-list"); var isLast = row.is(list.children("li.wiktku-dunde-row:last-child")); if (isLast) { var newRow = steps.dunde.buildRow(stepDiv); list.append(newRow); // Init chosen after the new row is in the DOM (desktop only). if (!isMobile) newRow.find("select").chosen(chosenOptions); } // Keep disabled keys in sync across all lang selectors. steps.dunde.syncDisabledKeys(stepDiv); }, /** Disables already-selected languages in all other dropdowns. */ syncDisabledKeys: function (stepDiv) { var taken = $.extend({}, steps.dunde.disabledKeys); stepDiv.find("li.wiktku-dunde-row select").each(function () { var v = $(this).val(); if (v) taken[v] = true; }); stepDiv.find("li.wiktku-dunde-row select").each(function () { var self = $(this); var own = self.val(); self.find("option").each(function () { var code = $(this).val(); if (!code) return; $(this).prop("disabled", taken[code] && code !== own); }); self.trigger("chosen:updated"); }); }, build: function (stepDiv) { if (stepDiv.find("ul.wiktku-dunde-list").length) return null; var list = $("<ul class='wiktku-dunde-list wiktku-lang-row-list'></ul>"); list.append(steps.dunde.buildRow(stepDiv)); stepDiv.append(list); // Init chosen after the select is in the DOM (desktop only). if (!isMobile) list.find("select").chosen(chosenOptions); return null; }, /** Reads all [langcode, words[]] rows from the DOM. */ getRows: function (stepDiv) { var result = []; stepDiv.find("li.wiktku-dunde-row").each(function () { var lang = $(this).find("select").val(); if (!lang) return; var words = []; $(this).find("ul.wiktku-dunde-words textarea").each(function () { var v = $.trim($(this).val()); if (v) words.push(v); }); if (words.length) result.push([lang, words]); }); return result; }, output: function () { var stepDiv = $("#wiktku-start-dunde"); var rows = steps.dunde.getRows(stepDiv); if (!rows.length) return ""; var lines = $.map(rows, function (row) { var lang = row[0], words = row[1]; return "* {{dû|" + lang + "|" + words.join("|") + "}}"; }); return "\n==== Dûnde ====\n" + lines.join("\n") + "\n"; } }, zarava: { id: "zarava", name: "bi zaravayên din", visible: function (values) { return steps.trans.visible(values); }, disabledKeys: { "navz": true }, buildRow: function (group) { var row = $("<li class='wiktku-zarava-row wiktku-lang-row'></li>"); var langSel = $(mw.html.element("select", { "class": "wiktku-start-step-keyfield wiktku-start-narrow" })); populateMenus(langSel, steps.zarava.keys || [], steps.zarava.disabledKeys); langSel.on("change", function () { steps.zarava.onLangChange(group, row); }); var wordList = $("<ul class='wiktku-zarava-words wiktku-lang-row-words'></ul>"); var firstWord = steps.zarava.makeWordInput(); wordList.append($("<li></li>").append(firstWord)); row.append(langSel).append(wordList); return row; }, makeWordInput: function () { var input = $("<textarea></textarea>") .attr("name", "wiktku-zarava-word-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 1) .attr("class", "wiktku-dfn-subfield wiktku-start-narrow") .attr("placeholder", "Tercime…"); input.on("input", function () { var list = $(this).closest("ul.wiktku-zarava-words"); var item = $(this).parent(); var val = $.trim($(this).val()); if (val && item.is(list.children("li:last-child"))) { var next = steps.zarava.makeWordInput(); list.append($("<li></li>").append(next)); } }); return input; }, onLangChange: function (group, row) { var list = group.find("ul.wiktku-zarava-list"); var isLast = row.is(list.children("li.wiktku-zarava-row:last-child")); if (isLast) { var newRow = steps.zarava.buildRow(group); list.append(newRow); } steps.zarava.syncDisabledKeys(group); }, /** Disables already-selected dialects in all other dropdowns within one group. */ syncDisabledKeys: function (group) { var taken = $.extend({}, steps.zarava.disabledKeys); group.find("li.wiktku-zarava-row select").each(function () { var v = $(this).val(); if (v) taken[v] = true; }); group.find("li.wiktku-zarava-row select").each(function () { var self = $(this); var own = self.val(); self.find("option").each(function () { var code = $(this).val(); if (!code) return; $(this).prop("disabled", taken[code] && code !== own); }); }); }, /** Builds (or fetches) the .wiktku-zarava-group for one gloss. */ buildGroup: function (stepDiv, gi) { var group = $("<div class='wiktku-zarava-group'></div>").attr("data-gloss-pos", gi); var list = $("<ul class='wiktku-zarava-list wiktku-lang-row-list'></ul>"); list.append(steps.zarava.buildRow(group)); group.append(list); stepDiv.append(group); return group; }, /** Syncs one .wiktku-zarava-group per current gloss (same logic as steps.trans.build). */ build: function (stepDiv) { var glosses = steps.trans.glossList(); if (!glosses.length) { stepDiv.find(".wiktku-zarava-group").remove(); return null; } var existingGroups = stepDiv.find(".wiktku-zarava-group"); if (existingGroups.length > glosses.length) { existingGroups.slice(glosses.length).remove(); } $.each(glosses, function (gi, gloss) { var group = stepDiv.find(".wiktku-zarava-group[data-gloss-pos='" + gi + "']"); if (!group.length) group = steps.zarava.buildGroup(stepDiv, gi); var label = group.find(".wiktku-zarava-group-label"); if (glosses.length > 1) { if (!label.length) { label = $("<div class='wiktku-zarava-group-label'></div>"); group.prepend(label); } label.text(gloss.index + " " + gloss.text); } else if (label.length) { label.remove(); } }); return null; }, /** Reads the dialect rows for a single gloss group. */ getGroupTranslations: function (group) { var result = []; group.find("li.wiktku-zarava-row").each(function () { var lang = $(this).find("select").val(); if (!lang) return; var words = []; $(this).find("ul.wiktku-zarava-words textarea").each(function () { var v = $.trim($(this).val()); if (v) words.push(v); }); if (words.length) result.push([lang, words]); }); return result; }, /** Reads all rows from the DOM, grouped by gloss position. */ getTranslations: function (stepDiv) { var result = []; stepDiv.find(".wiktku-zarava-group").each(function () { result.push(steps.zarava.getGroupTranslations($(this))); }); return result; }, output: function (values) { if (values.lang !== "ku") return ""; var stepDiv = $("#wiktku-start-zarava"); var glosses = steps.trans.glossList(); if (!glosses.length) return ""; var blocks = $.map(glosses, function (gloss, gi) { var group = stepDiv.find(".wiktku-zarava-group[data-gloss-pos='" + gi + "']"); var rows = group.length ? steps.zarava.getGroupTranslations(group) : []; if (!gloss.text && !rows.length) return undefined; if (rows.length) { rows.sort(function (a, b) { var aLang = langsByCode[a[0]] || []; var bLang = langsByCode[b[0]] || []; return (aLang[2] || "").localeCompare(bLang[2] || "", "ku"); }); } var wordLines = $.map(rows, function (row) { var lang = row[0]; var words = row[1]; var wikiWords = words.map(function (w) { return "{{W|" + lang + "|" + w + "}}"; }).join(", "); return "* {{Z|" + lang + "}}: " + wikiWords; }).join("\n"); if (!wordLines) return undefined; var block = "{{werger-ser|" + (gloss.text || "?") + "|" + gloss.index + "}}"; block += "\n" + wordLines; block += "\n{{werger-bin}}"; return block; }); if (!blocks.length) return ""; return "\n==== Bi zaravayên din ====\n" + blocks.join("\n") + "\n"; } }, trans: { id: "trans", name: "werger", visible: function (values) { if (!(values.lang === "ku" && values.pos)) return false; // Hide Werger only when EVERY sense is a template sense (Guharto etc.) // with a title filled in — i.e. there is real content but no plain // gloss to attach a translation table to. A mix of real + template // senses still shows Werger; the template senses are simply skipped // in output(). // // "Real" here means a non-şablon sense with either mane text or // other filled-in fields (etîket/hevmane/nimûne/jêder…), since // dfn.getOutput() renders the latter too, as {{mane?|lang}} plus // whatever else was filled in. // // When nothing has been filled in at all, output() will emit // {{mane?|lang}} instead of a gloss — but Werger should still show, // since the user may want to add translations before they've // settled on a gloss. var dfnSenses = steps.dfn.getSenses($("#wiktku-start-dfn")); var hasRealSense = dfnSenses.some(function (s) { return !s.tpl && (s.mane !== "" || senseHasExtraContent(s)); }); var hasFilledTplSense = dfnSenses.some(function (s) { return s.tpl && s.tplTitle; }); return hasRealSense || !hasFilledTplSense; }, disabledKeys: { "navz": true, "ku": true, "ckb": true, "sdh": true, "lki": true, "hac": true, "zza": true }, /** * Builds one translation row: a language dropdown + a growing list * of word inputs. When the dropdown gets a value the next empty row * is appended automatically. * * @param group the specific .wiktku-trans-group this row belongs to * (each gloss has its own group and its own list of rows, so the * lookups below must stay scoped to that group rather than the * whole step — the step now holds one list per gloss). */ buildRow: function (group) { var row = $("<li class='wiktku-trans-row wiktku-lang-row'></li>"); // Language selector — chosen is applied after insertion into DOM. var langSel = $(mw.html.element("select", { "class": "wiktku-start-step-keyfield wiktku-start-narrow" })); langSel.attr("data-placeholder", "Zimanekî lê bigere"); populateMenus(langSel, steps.trans.keys || [], steps.trans.disabledKeys); // When a language is chosen, ensure a next empty row exists. langSel.on("change", function () { steps.trans.onLangChange(group, row); }); // Word list for this language. var wordList = $("<ul class='wiktku-trans-words wiktku-lang-row-words'></ul>"); var firstWord = steps.trans.makeWordInput(); wordList.append($("<li></li>").append(firstWord)); if (isMobile) { row.append(wrapNativeSelect(langSel)).append(wordList); } else { row.append(langSel).append(wordList); } return row; }, makeWordInput: function () { var input = $("<textarea></textarea>") .attr("name", "wiktku-trans-word-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 1) .attr("class", "wiktku-dfn-subfield wiktku-start-narrow") .attr("placeholder", "Tercime…"); input.on("input", function () { var list = $(this).closest("ul.wiktku-trans-words"); var item = $(this).parent(); var val = $.trim($(this).val()); if (val && item.is(list.children("li:last-child"))) { var next = steps.trans.makeWordInput(); list.append($("<li></li>").append(next)); } }); return input; }, onLangChange: function (group, row) { var list = group.find("ul.wiktku-trans-list"); var isLast = row.is(list.children("li.wiktku-trans-row:last-child")); if (isLast) { var newRow = steps.trans.buildRow(group); list.append(newRow); // Init chosen after the new row is in the DOM (desktop only). if (!isMobile) newRow.find("select").chosen(chosenOptions); } // Keep disabled keys in sync across this gloss's lang selectors // only — the same language can be used for different senses. steps.trans.syncDisabledKeys(group); }, /** Disables already-selected languages in all other dropdowns within one group. */ syncDisabledKeys: function (group) { var taken = $.extend({}, steps.trans.disabledKeys); group.find("li.wiktku-trans-row select").each(function () { var v = $(this).val(); if (v) taken[v] = true; }); group.find("li.wiktku-trans-row select").each(function () { var self = $(this); var own = self.val(); self.find("option").each(function () { var code = $(this).val(); if (!code) return; $(this).prop("disabled", taken[code] && code !== own); }); self.trigger("chosen:updated"); }); }, /** * Builds (or fetches) the .wiktku-trans-group for one gloss, with * its own label and its own list of translation rows. */ buildGroup: function (stepDiv, gi) { var group = $("<div class='wiktku-trans-group'></div>").attr("data-gloss-pos", gi); var list = $("<ul class='wiktku-trans-list wiktku-lang-row-list'></ul>"); list.append(steps.trans.buildRow(group)); group.append(list); stepDiv.append(group); // Init chosen after the select is in the DOM (desktop only). if (!isMobile) list.find("select").chosen(chosenOptions); return group; }, /** * Syncs one .wiktku-trans-group per current gloss, adding new * groups and removing stale ones as senses are added or removed, * while leaving existing groups (and whatever translations the * user has already typed into them) untouched. Groups are keyed * to their gloss's position in glossList() via data-gloss-pos, so * a group always matches the same sense across rebuilds as long * as senses aren't reordered relative to each other. */ build: function (stepDiv) { var glosses = steps.trans.glossList(); if (!glosses.length) { stepDiv.find(".wiktku-trans-group").remove(); return null; } // Drop groups for glosses that no longer exist (always from the // tail — groups are only ever appended in gloss order below). var existingGroups = stepDiv.find(".wiktku-trans-group"); if (existingGroups.length > glosses.length) { existingGroups.slice(glosses.length).remove(); } $.each(glosses, function (gi, gloss) { var group = stepDiv.find(".wiktku-trans-group[data-gloss-pos='" + gi + "']"); if (!group.length) group = steps.trans.buildGroup(stepDiv, gi); // Only label groups when there's more than one gloss to // distinguish between — a single gloss needs no caption. var label = group.find(".wiktku-trans-group-label"); if (glosses.length > 1) { if (!label.length) { label = $("<div class='wiktku-trans-group-label'></div>"); group.prepend(label); } label.text(gloss.index + " " + gloss.text); } else if (label.length) { label.remove(); } }); return null; }, /** Reads the translation rows for a single gloss group. */ getGroupTranslations: function (group) { var result = []; group.find("li.wiktku-trans-row").each(function () { var lang = $(this).find("select").val(); if (!lang) return; var words = []; $(this).find("ul.wiktku-trans-words textarea").each(function () { var v = $.trim($(this).val()); if (v) words.push(v); }); if (words.length) result.push([lang, words]); }); return result; }, /** * Reads all translation rows from the DOM, grouped by gloss * position — one array of [lang, words] rows per gloss group, in * the same order as the .wiktku-trans-group elements. */ getTranslations: function (stepDiv) { var result = []; stepDiv.find(".wiktku-trans-group").each(function () { result.push(steps.trans.getGroupTranslations($(this))); }); return result; }, /** * Builds the numbered "{ index, gloss }" list — one entry per dfn * sense that has a real mane (skips template senses like Guharto, * which have nothing to caption a translation table with). The * index matches the sense's actual position in the numbered "#" * definition list (1-based), including template senses in the count, * so the number printed next to {{werger-ser}} lines up with the * gloss the reader sees in the entry. * * When nothing has been filled in at all (dfn.getOutput() will emit * {{mane?|lang}} as sense 1), this returns a single placeholder * entry with empty text instead of an empty array, so Werger still * has one group to attach translations to before a gloss exists. * When every filled sense is a template sense instead, this stays * empty — that mirrors trans.visible()'s hidden case, where there's * no group in the DOM for a placeholder to attach to anyway. */ glossList: function () { var dfnSenses = steps.dfn.getSenses($("#wiktku-start-dfn")); var glosses = []; var hasFilledTplSense = false; $.each(dfnSenses, function (i, s) { if (s.tpl) { if (s.tplTitle) hasFilledTplSense = true; return; // template sense — no gloss to caption with } var dfn = s.mane; if (!dfn) { // No mane text, but other fields (etîket/hevmane/nimûne/ // jêder…) are filled — dfn.getOutput() still emits this // sense as a numbered line using {{mane?|lang}}, so it // needs its own gloss group too, just with no caption text. if (senseHasExtraContent(s)) glosses.push({ index: i + 1, text: "" }); return; } if (dfn[0] !== dfn[0].toLowerCase()) dfn = decapitalize(dfn); dfn = stripWikilinks(dfn).replace(/[.…?!)\]،؟]+$/, ""); glosses.push({ index: i + 1, text: dfn }); }); if (!glosses.length && !hasFilledTplSense) { glosses.push({ index: 1, text: "" }); } return glosses; }, output: function (values) { if (values.lang !== "ku") return ""; var stepDiv = $("#wiktku-start-trans"); var glosses = steps.trans.glossList(); // Every sense is a template sense — there's no real gloss // anywhere and no group in the DOM either (glossList() only // returns empty in that case), so skip the section entirely. if (!glosses.length) return ""; // Each gloss now has its own group of translation rows — // attach every gloss's own words under its own werger-ser/-bin // pair instead of dumping everything under the first one. var blocks = $.map(glosses, function (gloss, gi) { var group = stepDiv.find(".wiktku-trans-group[data-gloss-pos='" + gi + "']"); var rows = group.length ? steps.trans.getGroupTranslations(group) : []; // Placeholder gloss (no real mane entered yet) with nothing // translated into it — nothing to output, and gloss.text is // empty so there's no caption to give {{werger-ser}} anyway. if (!gloss.text && !rows.length) return undefined; if (rows.length) { // Sort by Kurdish sort key. rows.sort(function (a, b) { var aLang = langsByCode[a[0]] || []; var bLang = langsByCode[b[0]] || []; return (aLang[2] || "").localeCompare(bLang[2] || "", "ku"); }); } var wordLines = $.map(rows, function (row) { var lang = row[0]; var words = row[1]; var wikiWords = words.map(function (w) { return "{{W|" + lang + "|" + w + "}}"; }).join(", "); return "* {{Z|" + lang + "}}: " + wikiWords; }).join("\n"); var block = "{{werger-ser|" + (gloss.text || "?") + "|" + gloss.index + "}}"; if (wordLines) block += "\n" + wordLines; block += "\n{{werger-bin}}"; return block; }); if (!blocks.length) return ""; return "\n==== Werger ====\n" + blocks.join("\n") + "\n"; } }, }; steps.trans.keys = steps.lang.choices; steps.dunde.keys = steps.lang.choices; steps.zarava.keys = getZaravaKeys(steps.lang.choices); var ordered_steps = [ steps.lang, steps.pron, steps.pos, steps.cinsiyet, steps.lektur, steps.tr, steps.dfn, steps.je, steps.tekildar, steps.etym, steps.dunde, steps.binereherwiha, steps.zarava, steps.trans]; // Step ids that belong to each section (not shared across sections). var PER_SECTION_STEP_IDS = [ "pos", "cinsiyet", "lektur", "tr", "dfn", "je", "tekildar", "etym", "dunde", "binereherwiha", "zarava", "trans" ]; // ── Multi-section state ────────────────────────────────────────────────── // Each entry is a plain snapshot: { pos, cinsiyet, lektur, tr, dfn (senses[]), // je, tekildar, binereherwiha, trans (rows[]) }. var sections = [{}]; // section 0 starts empty (DOM is the truth) var activeSection = 0; function snapshotDfn() { return steps.dfn.getSenses($("#wiktku-start-dfn")); } /** * Rebuild the dfn DOM from a previously snapshotted senses array. */ function restoreDfn(senses) { var stepDiv = $("#wiktku-start-dfn"); // Tear down the existing list so build() recreates it cleanly. stepDiv.find("ol.wiktku-dfn-list").remove(); steps.dfn.build(stepDiv); var list = stepDiv.find("ol.wiktku-dfn-list"); $.each(senses, function (i, sense) { // Ensure enough blocks exist (build() seeds one). var blocks = list.find("li.wiktku-dfn-sense"); var block = blocks.eq(i); if (!block.length) { var nb = steps.dfn.buildSenseBlock(stepDiv); list.append(nb); block = list.find("li.wiktku-dfn-sense").last(); } // Template selector. block.find("select.wiktku-dfn-tpl-select").val(sense.tpl || ""); if (sense.tpl) { block.find("textarea.wiktku-dfn-mane").hide(); block.find("input.wiktku-dfn-tpl-title").val(sense.tplTitle || "").show(); } else { block.find("textarea.wiktku-dfn-mane").val(sense.mane || "").show(); block.find("input.wiktku-dfn-tpl-title").hide().val(""); } // Re-sync the formên alternatîv/hevmane/… hide state now that // tplSelect's value was set programmatically (its own "change" // handler doesn't fire from .val(), so this doesn't happen otherwise). var updateVis = block.data("updateFieldVisibility"); if (updateVis) updateVis(); // Restore a sub-list (etiket, formên alternatîv, hevmane …) from a values array. function restoreSubList(cls, values) { if (!values || !values.length) return; var groupDiv = block.find("." + cls + "-group"); var subList = groupDiv.find("ol, ul").first(); if (!subList.length) return; // group not found // Fill existing items, append new ones as needed. $.each(values, function (j, val) { var items = subList.find("li"); if (j < items.length) { items.eq(j).find("textarea").val(val); } else { var ta = $("<textarea></textarea>") .attr("name", "wiktku-dfn-restore-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 1) .attr("class", "wiktku-dfn-subfield wiktku-start-narrow") .val(val); ta.on("input", function () { steps.dfn.onSubInput(subList, this, 1, true); }); subList.append($("<li></li>").append(ta)); } }); } // Reveal and populate lazy groups that have data. var lazyMap = { "wiktku-dfn-etiket": sense.etiket, "wiktku-dfn-alternativ": sense.alternativ, "wiktku-dfn-hevmane": sense.hevmane, "wiktku-dfn-dijmane": sense.dijmane, "wiktku-dfn-koordine": sense.koordine, "wiktku-dfn-jornav": sense.jornav, "wiktku-dfn-jernav": sense.jernav }; $.each(lazyMap, function (cls, vals) { if (vals && vals.length) restoreSubList(cls, vals); }); // Nimûne items are objects { text, tr?, t? } — restore using the builder. if (sense.nimune && sense.nimune.length) { var nimuneGroupDiv = block.find(".wiktku-dfn-nimune-group"); var nimuneList = nimuneGroupDiv.find("ol.wiktku-dfn-nimune-list"); var buildFn = nimuneGroupDiv.data("buildNimuneLi"); nimuneList.empty(); $.each(sense.nimune, function (_, n) { var text = typeof n === "object" ? (n.text || "") : n; if (!text) return; var li = buildFn ? buildFn() : $("<li class='wiktku-dfn-nimune-li'></li>"); li.find(".wiktku-dfn-nimune-text").val(text); if (n.tr) li.find(".wiktku-dfn-nimune-tr").val(n.tr); if (n.t) li.find(".wiktku-dfn-nimune-t").val(n.t); nimuneList.append(li); }); // Always leave a blank trailing item. if (buildFn) nimuneList.append(buildFn()); } // Restore jêder (quote/citation) entries — a growing list, restored using the // builder just like Nimûne. Accepts either the current array shape or a // single legacy object (from older saved sections) for backwards compatibility. var jederArr = $.isArray(sense.jeder) ? sense.jeder : (sense.jeder ? [sense.jeder] : []); if (jederArr.length) { var jederGroupDiv = block.find(".wiktku-dfn-jeder-group"); var jederList = jederGroupDiv.find("ol.wiktku-dfn-jeder-list"); var buildJederFn = jederGroupDiv.data("buildJederLi"); jederList.empty(); $.each(jederArr, function (_, j) { if (!j || !j.quote) return; var li = buildJederFn ? buildJederFn() : $("<li class='wiktku-dfn-jeder-li'></li>"); li.find(".wiktku-dfn-nimune-quote").val(j.quote); if (j.quoteTr) li.find(".wiktku-dfn-nimune-quote-tr").val(j.quoteTr); if (j.quoteT) li.find(".wiktku-dfn-nimune-quote-t").val(j.quoteT); if (j.jederManual) { var manualSel = li.find(".wiktku-dfn-quote-src-sel"); manualSel.val("__manual__").trigger("change"); li.find(".wiktku-dfn-quote-src-manual").val(j.jederManual); } else if (j.jederTpl) { var srcSel = li.find(".wiktku-dfn-quote-src-sel"); srcSel.val(j.jederTpl).trigger("change"); if (j.jêderFields) { $.each(j.jêderFields, function (key, val) { li.find(".wiktku-dfn-quote-src-input[data-field-key='" + key + "']").val(val); }); } } jederList.append(li); }); // Always leave a blank trailing item, same as Nimûne. if (buildJederFn) jederList.append(buildJederFn()); } }); } /** * Snapshot simple (non-dfn) per-section steps from current DOM into obj. */ function saveCurrentSection() { var snap = {}; $.each(PER_SECTION_STEP_IDS, function (_, id) { if (id === "dfn") { snap.dfn = snapshotDfn(); return; } if (id === "etym") { snap.etym = $.trim($("#wiktku-start-etym .wiktku-etym-text").val()); return; } var step = steps[id]; if (!step) return; var stepDiv = $("#wiktku-start-" + id); if (id === "trans") { snap.trans = steps.trans.getTranslations(stepDiv); return; } if (id === "zarava") { snap.zarava = steps.zarava.getTranslations(stepDiv); return; } if (id === "dunde") { snap.dunde = steps.dunde.getRows(stepDiv); return; } // Generic: read all step fields. var fields = stepDiv.find(".wiktku-start-step-field"); if (step.multiple) { snap[id] = fields.map(function () { return $(this).val(); }).get(); } else { snap[id] = fields.val(); } }); sections[activeSection] = snap; } /** * Restore a previously saved snapshot into the form DOM. */ function restoreSection(snap) { $.each(PER_SECTION_STEP_IDS, function (_, id) { if (id === "dfn") { restoreDfn(snap.dfn || []); return; } if (id === "etym") { $("#wiktku-start-etym .wiktku-etym-wrap").remove(); steps.etym.build($("#wiktku-start-etym")); $("#wiktku-start-etym .wiktku-etym-text").val(snap.etym || ""); return; } if (id === "trans") { // Rebuild trans groups (dfn must already be restored by this // point in the $.each loop, so glossList() reflects it). var transDiv = $("#wiktku-start-trans"); transDiv.find(".wiktku-trans-group").remove(); steps.trans.build(transDiv); var groupsSnap = snap.trans || []; $.each(groupsSnap, function (gi, rows) { var group = transDiv.find(".wiktku-trans-group[data-gloss-pos='" + gi + "']"); if (!group.length) return; // gloss no longer exists — drop its rows var list = group.find("ul.wiktku-trans-list"); $.each(rows, function (j, row) { var lang = row[0], words = row[1]; var lastRow = list.find("li.wiktku-trans-row").last(); lastRow.find("select").val(lang).trigger("change"); var wordList = lastRow.find("ul.wiktku-trans-words"); $.each(words, function (k, word) { var wordItems = wordList.find("li"); if (k < wordItems.length) { wordItems.eq(k).find("textarea").val(word); } else { // .val() below doesn't fire "input", so the normal // auto-grow never runs — append a matching item // ourselves instead of silently dropping the word. var extraInput = steps.trans.makeWordInput(); wordList.append($("<li></li>").append(extraInput)); extraInput.val(word); } }); // Leave one trailing empty field so the row can still grow // when the user types, matching a freshly-built row. if ($.trim(wordList.children("li").last().find("textarea").val())) { wordList.append($("<li></li>").append(steps.trans.makeWordInput())); } }); }); return; } if (id === "zarava") { // Rebuild zarava groups (dfn must already be restored by this // point in the $.each loop, so glossList() reflects it). var zaravaDiv = $("#wiktku-start-zarava"); zaravaDiv.find(".wiktku-zarava-group").remove(); steps.zarava.build(zaravaDiv); var zaravaGroupsSnap = snap.zarava || []; $.each(zaravaGroupsSnap, function (gi, rows) { var group = zaravaDiv.find(".wiktku-zarava-group[data-gloss-pos='" + gi + "']"); if (!group.length) return; // gloss no longer exists — drop its rows var list = group.find("ul.wiktku-zarava-list"); $.each(rows, function (j, row) { var lang = row[0], words = row[1]; var lastRow = list.find("li.wiktku-zarava-row").last(); lastRow.find("select").val(lang).trigger("change"); var wordList = lastRow.find("ul.wiktku-zarava-words"); $.each(words, function (k, word) { var wordItems = wordList.find("li"); if (k < wordItems.length) { wordItems.eq(k).find("textarea").val(word); } else { var extraInput = steps.zarava.makeWordInput(); wordList.append($("<li></li>").append(extraInput)); extraInput.val(word); } }); if ($.trim(wordList.children("li").last().find("textarea").val())) { wordList.append($("<li></li>").append(steps.zarava.makeWordInput())); } }); }); return; } if (id === "dunde") { // Rebuild dunde rows. var dundeDiv = $("#wiktku-start-dunde"); dundeDiv.find("ul.wiktku-dunde-list").remove(); steps.dunde.build(dundeDiv); var dundeRows = snap.dunde || []; $.each(dundeRows, function (i, row) { var lang = row[0], words = row[1]; var list = dundeDiv.find("ul.wiktku-dunde-list"); var lastRow = list.find("li.wiktku-dunde-row").last(); lastRow.find("select").val(lang).trigger("change"); var wordList = lastRow.find("ul.wiktku-dunde-words"); $.each(words, function (j, word) { var wordItems = wordList.find("li"); if (j < wordItems.length) { wordItems.eq(j).find("textarea").val(word); } else { // .val() below doesn't fire "input", so the normal // auto-grow never runs — append a matching item // ourselves instead of silently dropping the word. var extraInput = steps.dunde.makeWordInput(); wordList.append($("<li></li>").append(extraInput)); extraInput.val(word); } }); // Leave one trailing empty field so the row can still grow // when the user types, matching a freshly-built row. if ($.trim(wordList.children("li").last().find("textarea").val())) { wordList.append($("<li></li>").append(steps.dunde.makeWordInput())); } }); return; } var step = steps[id]; if (!step) return; var stepDiv = $("#wiktku-start-" + id); var fields = stepDiv.find(".wiktku-start-step-field"); var val = snap[id]; if (val === undefined || val === null) return; if (step.multiple) { var arr = val; fields.each(function (i) { if (i < arr.length) $(this).val(arr[i]); }); } else { fields.val(val); } // Notify chosen widgets of the programmatic value change. if (!isMobile) fields.filter("select").trigger("chosen:updated"); }); } function getWikitextForCurrentSection(callback) { var values = getValues(); var entry = steps.pos.output(values); steps.dfn.getOutput(values, function (output) { entry += output; entry += steps.je.output(values); entry += steps.tekildar.output(values); entry += steps.etym.output(values); entry += steps.dunde.output(values); entry += steps.binereherwiha.output(values); entry += steps.zarava.output(values); entry += steps.trans.output(values); callback(entry, values); }); } function getWikitextAllSections(callback) { saveCurrentSection(); var results = new Array(sections.length); var sharedValues = getValues(); // lang/pron are shared function processSection(i) { if (i >= sections.length) { // All done — restore original active section. restoreSection(sections[activeSection]); refresh(); callback(results, sharedValues); return; } restoreSection(sections[i]); refresh(); getWikitextForCurrentSection(function (sectionText) { results[i] = sectionText; processSection(i + 1); }); } processSection(0); } /** * Assembles wikitext for all sections plus the shared lang/pron header. */ function getWikitext(callback) { getWikitextAllSections(function (sectionTexts, sharedValues) { var entry = steps.lang.output(sharedValues); entry += steps.pron.output(sharedValues); entry += sectionTexts.join("\n"); // Edit summary uses section 0's values. Read from the saved snapshot // (not the live DOM) so it doesn't mix section 0's pos with whichever // section happens to be active/restored at this point. var dfnSenses = (sections[0] && sections[0].dfn) || []; var dfnSummary = dfnSenses.map(function (s) { return s.mane; }).filter(Boolean).join("; "); var summaryLabel = addLangMode ? "WF:Ziman lê zêde" : "WF:Nû"; var summary = "([[Mediawiki:Gadget-start.js|" + summaryLabel + "]] v.2.0) +" + sharedValues.lang + ":" + sections[0].pos + ":" + dfnSummary; var summaryField = document.getElementById("wpSummary"); if (addLangMode && summaryField.value) { summary = summaryField.value + " " + summary; } summaryField.value = summary; callback(entry); }); } var continueBtn; function getValuesForStep(stepId) { var fields = $("#wiktku-start-" + stepId + " .wiktku-start-step-field"); var step = steps[stepId]; if (step.keys) { var values = {}; fields.each(function (i, field) { var key = $(field).prevAll(".wiktku-start-step-keyfield").val(); if (key) values[key] = $(field).val(); }); return values; } else if (step.multiple) { return fields.map(function () { return $(this).val(); }).get(); } return fields.val(); } function getValues() { var values = {}; $.each(steps, function (stepId) { values[stepId] = getValuesForStep(stepId); }); return values; } function populateMenus(inputs, choices, disabledValues) { if (!disabledValues) disabledValues = {}; var vals = inputs.map(function (i, input) { return $(input).val(); }); inputs.empty(); inputs.append($("<option></option>")); $.each(choices, function (j, choice) { // Append the language code in parentheses so that typing a code // (e.g. "ku") in the search box still finds the language name. var displayText = capitalize(choice[1]); if (choice[2] !== undefined) { // This is a language choice [code, name, sortKey] — show code. displayText = capitalize(choice[1]) + " (" + choice[0] + ")"; } var option = $(mw.html.element("option", { value: choice[0] }, displayText)); if (disabledValues[choice[0]]) option.prop("disabled", true); inputs.append(option); }); inputs.val(function (i) { return vals[i]; }); } /** * Returns a bitmap containing the keys that should be disabled for a key * menu in the given step because they are disabled or already taken by * another key menu. */ function getDisabledKeys(step) { var occupiedKeys = {}; $("#wiktku-start-" + step.id + " .wiktku-start-step-keyfield").each(function () { occupiedKeys[$(this).val()] = true; }); if (step.disabledKeys) $.extend(occupiedKeys, step.disabledKeys); return occupiedKeys; } function buildKeyInput(step) { if (!step.keys) return undefined; var input = $(mw.html.element("select", { "class": "wiktku-start-step-keyfield wiktku-start-narrow" })); input.attr("data-placeholder", "Hilbijêre " + step.keyName); if (isMobile) { populateMenus(input, step.keys, getDisabledKeys(step)); // On mobile return the wrapper; the select is inside it. // Change events still fire on the inner select. return wrapNativeSelect(input); } input.on("chosen:showing_dropdown", function () { $(this).data("wiktku-defaultValue", $(this).val()); }); input.change(function (_, context) { var inputs = $("#wiktku-start-" + step.id + " .wiktku-start-step-keyfield").not(this); var oldValue = $(this).data("wiktku-defaultValue"); var newValue = context.selected; inputs.find("option[value='" + oldValue + "']").prop('disabled', false); inputs.find("option[value='" + newValue + "']").prop('disabled', true); inputs.trigger("chosen:updated"); }); populateMenus(input, step.keys, getDisabledKeys(step)); return input; } /** * If the current text field has text and there are no more text fields after * the current text field in the list, add another text field to the list. */ function refreshForTextField(currentInput, step) { currentInput = $(currentInput); var value = currentInput.val(); var item = currentInput.parent(); if (value && !item.next("li").length) { var nextInput = $("<textarea></textarea>") .attr("name", "wiktku-field-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("class", currentInput.attr("class")) .attr("rows", currentInput.attr("rows") || 1); nextInput.on("input", function (evt) { refreshForTextField(evt.target, step); }); var nextKeyInput = buildKeyInput(step); var nextItem = $("<li></li>").append(nextKeyInput).append(nextInput); item.parent().append(nextItem); if (nextKeyInput) nextKeyInput.chosen(chosenOptions); } var canContinue = !continueBtn.isDisabled(); if ((value && !canContinue) || (!value && canContinue)) { refresh(step); } } function prepareInput(input, step) { if (!input) return; if (step.required) input.prop('required', true); input.change(step, refresh); } /** * Shows and hides all the steps based on whether their prerequisites are met, * and updates placeholders where applicable. */ function refresh(evt) { var values = getValues(); var changedStep = evt && evt.data; var didFocus = false; var canContinue = true; // Re-filter template options in every sense block whenever lang changes. $("#wiktku-start-dfn .wiktku-dfn-tpl-select").each(function () { var fn = $(this).data("updateOptions"); if (typeof fn === "function") fn(); }); // Re-filter pronunciation and etymology template dropdowns when language changes. steps.pron.refreshTplSelect(); steps.etym.refreshTplSelect(); // Sync tr/t sub-fields in every nimûne item to the current language. // tr shown when language needs transliteration; t shown when lang !== "ku". (function () { var lang = values.lang || ""; var showTr = needsTransliteration(lang); var showT = lang && lang !== "ku"; $("#wiktku-start-dfn .wiktku-dfn-nimune-list li.wiktku-dfn-nimune-li").each(function () { var li = $(this); // Ensure the sub-wrapper exists when we need it. var subWrap = li.find(".wiktku-dfn-nimune-sub"); // tr field var trTa = li.find(".wiktku-dfn-nimune-tr"); if (showTr && !trTa.length) { if (!subWrap.length) { subWrap = $("<div></div>").addClass("wiktku-dfn-nimune-sub"); li.append(subWrap); } trTa = $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-tr-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 5) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-tr") .attr("placeholder", "Transkrîpsiyon…"); subWrap.prepend(trTa); } else if (!showTr && trTa.length) { trTa.remove(); } // t field var tTa = li.find(".wiktku-dfn-nimune-t"); if (showT && !tTa.length) { if (!subWrap.length) { subWrap = $("<div></div>").addClass("wiktku-dfn-nimune-sub"); li.append(subWrap); } tTa = $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-t-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 5) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-t") .attr("placeholder", "Tercimeya nimûneyê kurmancî…"); subWrap.append(tTa); } else if (!showT && tTa.length) { tTa.remove(); } // Remove the wrapper if it ended up empty. subWrap = li.find(".wiktku-dfn-nimune-sub"); if (subWrap.length && !subWrap.children().length) subWrap.remove(); }); }()); // Sync tr/t sub-fields in every jêder citation to the current language. // tr shown when language needs transliteration; t shown when lang !== "ku". (function () { var lang = values.lang || ""; var showTr = needsTransliteration(lang); var showT = lang && lang !== "ku"; $("#wiktku-start-dfn .wiktku-dfn-jeder-list li.wiktku-dfn-jeder-li").each(function () { var li = $(this); // Ensure the sub-wrapper exists when we need it. It must sit right // after the quote textarea and before the source selector. var subWrap = li.find(".wiktku-dfn-quote-sub"); // tr field var trTa = li.find(".wiktku-dfn-nimune-quote-tr"); if (showTr && !trTa.length) { if (!subWrap.length) { subWrap = $("<div></div>").addClass("wiktku-dfn-quote-sub"); li.find(".wiktku-dfn-nimune-quote").after(subWrap); } trTa = $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-quote-tr-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 2) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-quote-tr") .attr("placeholder", "Transkrîpsiyona jêgirtinê…"); subWrap.prepend(trTa); } else if (!showTr && trTa.length) { trTa.remove(); } // t field var tTa = li.find(".wiktku-dfn-nimune-quote-t"); if (showT && !tTa.length) { if (!subWrap.length) { subWrap = $("<div></div>").addClass("wiktku-dfn-quote-sub"); li.find(".wiktku-dfn-nimune-quote").after(subWrap); } tTa = $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-quote-t-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 2) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-quote-t") .attr("placeholder", "Tercimeya jêgirtinê ya kurmancî…"); subWrap.append(tTa); } else if (!showT && tTa.length) { tTa.remove(); } // Remove the wrapper if it ended up empty. subWrap = li.find(".wiktku-dfn-quote-sub"); if (subWrap.length && !subWrap.children().length) subWrap.remove(); }); }()); $.each(steps, function (stepId, step) { if (typeof(step.visible) === "function" && !step.visible(values)) { $("#wiktku-start-" + stepId).slideUp(); } else { var stepDiv = $("#wiktku-start-" + stepId); if (changedStep !== step && typeof(step.build) === "function") { prepareInput(step.build(stepDiv, values), step); } var input = stepDiv.find(".wiktku-start-step-field"); if (typeof(step.example) === "function") { // .find() above already reaches nested fields (e.g. the dfn // step's mane textareas inside each sense block), so one // assignment covers every step; dfn keeps its own fallback. var exampleText = step.example(values) || (step.id === "dfn" ? "Mane…" : ""); input.attr("placeholder", exampleText); } var didSlideDown; if (!didFocus && stepDiv.css("display") === "none" && step.required) { didSlideDown = function (evt) { input.focus(); }; didFocus = true; } stepDiv.slideDown(didSlideDown); } if (step.required && (values[stepId] === "" || (step.multiple && values[stepId].join("") === ""))) { canContinue = false; } }); continueBtn.setDisabled(!canContinue); } function destroy() { $("#wiktku-start-form, .noafterwizard").slideUp(function () { $(this).remove(); }); $(".noarticletext .nowizard, #editform").slideDown(); $("#ca-edit").removeClass("selected"); $("#ca-wiktku-nowizard").addClass("selected"); } // Priority order for Kurdish dialects and the navz pseudo-code. // Codes listed here come before all other languages; unlisted codes // are sorted alphabetically by their display name via localeCompare. var LANG_PRIORITY = ["navz", "ku", "hac", "sdh", "lki", "ckb", "zza"]; /** * Inserts a new == {{ziman|code}} == section into existing page wikitext * at the correct sorted position: * 1. Any content before the first language section is preserved at the top. * 2. navz is always first, then ku/hac/sdh/lki/ckb/zza in that order, * then all other languages sorted by display name (localeCompare). */ function insertNewLangSection(existing, wikitext) { var newCodeMatch = wikitext.match(/^== \{\{ziman\|([^}]+)\}\} ==/); var newCode = newCodeMatch ? newCodeMatch[1] : ""; var sections = []; var preamble = ""; var firstMatch = existing.match(/(?:^|\n)== \{\{ziman\|/); if (!firstMatch) { // No existing lang sections at all — just append. var sep = existing && !/\n\s*$/.test(existing) ? "\n\n" : ""; return existing + sep + wikitext; } // Everything before the first == {{ziman|...}} == is the preamble. var firstSectionStart = existing.indexOf("== {{ziman|"); // Walk back to the start of that line. var lineStart = existing.lastIndexOf("\n", firstSectionStart - 1); var preambleEnd = lineStart !== -1 ? lineStart + 1 : 0; preamble = existing.slice(0, preambleEnd); // Parse each language section: header line + everything until the next header. var body = existing.slice(preambleEnd); // NOTE: with the /m flag, a bare "$" matches end-of-*line*, not just // end-of-string — that previously made the non-greedy content group // stop at the section's first line break instead of running to the // next language header (or the real end of the text), silently // dropping the rest of that section's wikitext. (?![\s\S]) matches // only the true end of the string, /m flag or not. var langSectionRe = /^(== \{\{ziman\|([^}]+)\}\} ==\n?)([\s\S]*?)(?=\n== \{\{ziman\||(?![\s\S]))/gm; var m; while ((m = langSectionRe.exec(body)) !== null) { sections.push({ code: m[2], content: m[0] // full text of this section including header }); } // Determine sort rank: priority list first (by index), then alphabetical. function getLangName(code) { var entry = langsByCode[code]; return entry ? entry[1] : code; } function sortRank(code) { var idx = LANG_PRIORITY.indexOf(code); return idx !== -1 ? idx : LANG_PRIORITY.length; } function compareLangs(a, b) { var ra = sortRank(a), rb = sortRank(b); if (ra !== rb) return ra - rb; // Both are outside priority list — sort by display name. return getLangName(a).localeCompare(getLangName(b), userLang); } // Insert the new section into the sorted list. var newSection = { code: newCode, content: wikitext }; var inserted = false; for (var i = 0; i < sections.length; i++) { if (compareLangs(newCode, sections[i].code) < 0) { sections.splice(i, 0, newSection); inserted = true; break; } } if (!inserted) sections.push(newSection); // Re-join: preamble + sections separated by newlines. var joined = sections.map(function (s) { // Ensure each section ends with exactly one newline before the next. return s.content.replace(/\n+$/, ""); }).join("\n"); return preamble + joined + "\n"; } function build() { $(".nowizard, .nowizard .noafterwizard").hide(); var callToAction = $("#wiktku-calltoaction"); var origCallToActionText = callToAction.text(); $(mw.util.addPortletLink("p-views", "#", "Edîtora çavkaniyê veke", "ca-wiktku-nowizard", "Vê rûpelê bi edîtora çavkaniyê çêke", undefined, "#ca-watch")).click(function (evt) { evt.preventDefault(); callToAction.text(origCallToActionText); destroy(); }); if (callToAction.length) { callToAction.text(origCallToActionText + " Forma li jêr ji bo çêkirina madeyeke nû bi kar bîne."); } var startForm = $("<form id='wiktku-start-form'></form>"); if (addLangMode) { startForm.append($("<p class='wiktku-addlang-notice'></p>").text( "Agahiyên zimanê nû yê hûnê li vê rûpelê zêde bikin dagirin. " + "Piştî temambûnê, beşa nû dê li dawiya nivîsa heyî were zêdekirin.")); } var spinner; // Tab bar for switching between POS sections. var sectionTabsDiv = $("<div id='wiktku-section-tabs'></div>"); startForm.submit(function (evt) { evt.preventDefault(); continueBtn.setDisabled(true); spinner.show(); getWikitext(function (wikitext) { if (addLangMode) { var textbox = $("#wpTextbox1"); var existing = textbox.val() || ""; // Check whether the generated lang header already exists in the page. // wikitext always starts with "== {{ziman|CODE}} ==\n" (from steps.lang.output). // If that exact section heading is already present in the existing content, // strip it from the new output and insert the remaining content at the end // of that lang section (just before the next == level-2 heading, or at the // very end of the page if there is no following section). var langHeaderMatch = wikitext.match(/^(== \{\{ziman\|[^}]+\}\} ==\n)/); if (langHeaderMatch) { var langHeader = langHeaderMatch[1]; // e.g. "== {{ziman|ku}} ==\n" // Escape for use in RegExp. var escapedHeader = langHeader.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); if (new RegExp(escapedHeader).test(existing)) { // Strip the header from the new output. var newContent = wikitext.slice(langHeader.length); // Find the insertion point: end of the existing lang section. // A new L2 heading marks the start of the next language block. var afterHeader = existing.indexOf(langHeader); var searchFrom = afterHeader + langHeader.length; // Find the next == … == heading after this section's start. var nextL2 = existing.indexOf("\n== ", searchFrom); var insertAt = nextL2 !== -1 ? nextL2 : existing.length; // Ensure there's a blank line before the inserted block. var before = existing.slice(0, insertAt); var after = existing.slice(insertAt); var sep = /\n\s*$/.test(before) ? "" : "\n"; textbox.val(before + sep + newContent + after); } else { // New language — insert at the correct sorted position. textbox.val(insertNewLangSection(existing, wikitext)); } } else { // Unexpected format — insert at sorted position anyway. textbox.val(insertNewLangSection(existing, wikitext)); } } else { $("#wpTextbox1").val(wikitext); } $("html, body").animate({scrollTop: 0}); callToAction.text("Hindik ma!"); $("#wiktku-preview-container").remove(); destroy(); }); }); $.each(ordered_steps, function (i, step) { var stepDiv = $(mw.html.element("div", { "class": "wiktku-start-step", id: "wiktku-start-" + step.id })); var name = capitalize(step.name); stepDiv.append($(mw.html.element("h3", { "class": "wiktku-start-step-name" }, new mw.html.Raw(mw.html.element("label", { "for": "wiktku-start-" + step.id + "-field" }, name))))); if (step.question_fmt) { stepDiv.append($(mw.html.element("label", { "class": "wiktku-start-step-question", "for": "wiktku-start-" + step.id + "-field" }, step.question_fmt))); if (step.question_br) stepDiv.append($("<br>")); } var input; if (step.choices) { input = $(mw.html.element("select", { "class": "wiktku-start-step-field", id: "wiktku-start-" + step.id + "-field" })); input.attr("data-placeholder", capitalize(step.name) + " hilbijêre "); populateMenus(input, step.choices); if (step.multiple) input.attr("multiple", true); if (isMobile) { stepDiv.append(wrapNativeSelect(input)); } else { stepDiv.append(input); } } else if (typeof(step.build) === "function") { input = step.build(stepDiv); } else { input = $("<textarea></textarea>") .attr("class", "wiktku-start-step-field") .attr("id", "wiktku-start-" + step.id + "-field") .attr("rows", step.rows || 2); if (step.narrow) input.addClass("wiktku-start-narrow"); if (step.multiple) { input.on("input", function (evt) { refreshForTextField(evt.target, step); }); var keyInput = buildKeyInput(step); var list = $(step.ordered ? "<ol></ol>" : "<ul></ul>") .append($("<li></li>").append(keyInput).append(input)); stepDiv.append(list); } else stepDiv.append(input); } prepareInput(input, step); stepDiv.hide(); // Insert tab bar just before the first per-section step. if (step.id === "pos") startForm.append(sectionTabsDiv); startForm.append(stepDiv); }); // ── Section tab helpers ────────────────────────────────────────────── // ── Add-section button — lives in the tab bar, disabled until pos chosen ── var addSectionBtn = new OO.ui.ButtonWidget({ label: "+ Beş zêde bike", disabled: true }); addSectionBtn.on("click", function () { saveCurrentSection(); sections.push({}); activeSection = sections.length - 1; $.each(PER_SECTION_STEP_IDS, function (_, id) { if (id === "dfn") { var stepDiv = $("#wiktku-start-dfn"); stepDiv.find("ol.wiktku-dfn-list").remove(); steps.dfn.build(stepDiv); return; } if (id === "etym") { $("#wiktku-start-etym .wiktku-etym-wrap").remove(); steps.etym.build($("#wiktku-start-etym")); return; } if (id === "trans") { var transDiv = $("#wiktku-start-trans"); transDiv.find(".wiktku-trans-group").remove(); return; } if (id === "zarava") { var zaravaDiv = $("#wiktku-start-zarava"); zaravaDiv.find(".wiktku-zarava-group").remove(); return; } if (id === "dunde") { var dundeDiv = $("#wiktku-start-dunde"); dundeDiv.find("ul.wiktku-dunde-list").remove(); return; } var stepDiv = $("#wiktku-start-" + id); stepDiv.find(".wiktku-start-step-field").val(""); if (!isMobile) stepDiv.find("select.wiktku-start-step-field").trigger("chosen:updated"); }); renderSectionTabs(); refresh(); $("html, body").animate({ scrollTop: sectionTabsDiv.offset().top - 20 }, 300); }); /** Re-render the tab bar to reflect current sections[] and activeSection. */ function renderSectionTabs() { // Detach (not remove) the button first: .empty() strips bound // event data from any children left inside it, which would // silently kill addSectionBtn's click handler on every re-render. addSectionBtn.$element.detach(); sectionTabsDiv.empty(); var lang = getValues().lang || ""; if (!lang) { sectionTabsDiv.hide(); return; } sectionTabsDiv.show(); $.each(sections, function (i) { var posVal = sections[i].pos || ""; var tabLabel = posVal ? capitalize(posVal) : ("Beş " + (i + 1)); var tab = $("<span></span>") .addClass("wiktku-section-tab") .text(tabLabel) .toggleClass("wiktku-tab-active", i === activeSection); (function (idx) { tab.on("click", function () { if (idx === activeSection) return; saveCurrentSection(); activeSection = idx; restoreSection(sections[activeSection]); refresh(); renderSectionTabs(); }); }(i)); sectionTabsDiv.append(tab); }); // Enable "Beş zêde bike" only when the active section has a pos chosen. var activePos = sections[activeSection] && sections[activeSection].pos ? sections[activeSection].pos : getValues().pos; addSectionBtn.setDisabled(!activePos); sectionTabsDiv.append(addSectionBtn.$element); } renderSectionTabs(); // Update the active tab's label whenever pos changes. startForm.on("change", "#wiktku-start-pos-field", function () { renderSectionTabs(); }); // Show the tab bar as soon as a language is selected. startForm.on("change", "#wiktku-start-lang-field", function () { renderSectionTabs(); }); var footer = $("<div id='wiktku-start-footer'></div>"); spinner = $(mw.html.element("img", { id: "wiktku-start-spinner", src: "//upload.wikimedia.org/wikipedia/commons/d/de/Ajax-loader.gif", alt: "Tê barkirin…", title: "Tê barkirin…" })); footer.append(spinner.hide()); continueBtn = new OO.ui.ButtonWidget({ id: "wiktku-unhide-editform", label: "Bişîne", flags: [ "primary", "progressive" ] }); continueBtn.on("click", function () { mw.notify("Tê şandin…", { type: "info", tag: "wiktku-submit" }); startForm.trigger("submit"); }); footer.append(continueBtn.$element); // ── Preview checkboxes ─────────────────────────────────────────────── // Wikitext preview (raw text panel) var previewCheck = $("<input type='checkbox' id='wiktku-preview-toggle'>"); var previewLabel = $("<label for='wiktku-preview-toggle'></label>") .text(" Pêşdîtina wîkîtekstê"); var previewPanel = $("<pre id='wiktku-preview-panel'></pre>").hide(); // Live rendered preview (parsed HTML panel, same logic as AjaxEdit). // Not available on mobile — API polling causes too many problems on small screens. var livePreviewCheck = null; var livePreviewPanel = null; if (!isMobile) { livePreviewCheck = $("<input type='checkbox' id='wiktku-live-preview-toggle'>"); livePreviewPanel = $("<div id='wiktku-live-preview-panel'></div>").hide(); } // Container that holds both panels and switches between stacked / side-by-side. var previewContainer = $("<div id='wiktku-preview-container'></div>"); previewContainer.append(previewPanel); if (!isMobile) previewContainer.append(livePreviewPanel); var previewTimer = null; var livePreviewIntervalId = -1; /** Rebuilds wikitext preview if its checkbox is checked. */ function schedulePreview() { if (!previewCheck.prop("checked")) return; clearTimeout(previewTimer); // Debounce: wait 400 ms after the last keystroke before rebuilding. previewTimer = setTimeout(function () { getWikitext(function (wikitext) { previewPanel.text(wikitext).show(); updatePanelLayout(); }); }, 400); } /** Fetches parsed HTML and populates the live preview panel. */ function loadLivePreview() { getWikitext(function (wikitext) { new mw.Api().parse(wikitext, { title: mw.config.get("wgPageName") }).done(function (html) { livePreviewPanel.html(html).show(); updatePanelLayout(); }); }); } /** Adjusts panel widths depending on which previews are visible. */ function updatePanelLayout() { var wikitextVisible = previewCheck.prop("checked"); var liveVisible = livePreviewCheck && livePreviewCheck.prop("checked"); if (wikitextVisible && liveVisible) { // Side by side — each panel takes roughly half the available width. previewPanel.css({ "flex": "1 1 45%", "min-width": "280px" }); livePreviewPanel.css({ "flex": "1 1 45%", "min-width": "280px" }); } else { // Full width for whichever is visible — only touch panels that are // actually shown so that setting flex doesn't override display:none. if (wikitextVisible) previewPanel.css({ "flex": "1 1 100%", "min-width": "" }); if (liveVisible && livePreviewPanel) livePreviewPanel.css({ "flex": "1 1 100%", "min-width": "" }); } } previewCheck.on("change", function () { if ($(this).prop("checked")) { schedulePreview(); } else { clearTimeout(previewTimer); previewPanel.hide(); updatePanelLayout(); } }); if (!isMobile) { livePreviewCheck.on("change", function () { if ($(this).prop("checked")) { livePreviewPanel.show(); loadLivePreview(); livePreviewIntervalId = setInterval(loadLivePreview, 500); } else { clearInterval(livePreviewIntervalId); livePreviewIntervalId = -1; livePreviewPanel.hide().empty(); updatePanelLayout(); } }); } // Listen on all input/change events on the form and update both previews. startForm.on("input change", function () { schedulePreview(); }); footer.append($("<span style='margin-left:1em'></span>") .append(previewCheck).append(previewLabel)); if (!isMobile) { var livePreviewLabel = $("<label for='wiktku-live-preview-toggle'></label>") .text(" Pêşdîtina zindî"); footer.append($("<span style='margin-left:1em'></span>") .append(livePreviewCheck).append(livePreviewLabel)); } startForm.append(footer); $("#editform").hide().before(startForm); // Insert preview container (holds both panels) after the form. startForm.after(previewContainer); if (!isMobile) startForm.find("select").chosen(chosenOptions); refresh(); // Zimanan ji MediaWiki:Gadget-translation_editor.js/ziman.json bar bike. // Kodên ku bi "-pro" diqedin û navên ku "zimanê destan" tê de heye // tên derxistin. Zimanên xardkirî li serî dimînin, yên din // bi alfabeyê li dû wan tên. // Pinned choices come from MediaWiki:Gadget-start.js/data.json (langChoices), // already loaded into steps.lang.choices before build() runs. var pinnedChoices = steps.lang.choices.slice(); var pinnedCodes = $.map(pinnedChoices, function (choice) { return choice[0]; }); new mw.Api().get({ action: "query", prop: "revisions", titles: "MediaWiki:Gadget-translation_editor.js/ziman.json", rvprop: "content", rvslots: "main", formatversion: 2 }).then(function (data) { var page = data.query.pages[0]; var content = page && page.revisions && page.revisions[0].slots.main.content; var zimanData; try { zimanData = JSON.parse(content); } catch (e) { zimanData = {}; } var extraChoices = []; $.each(zimanData, function (code, name) { // Filter: skip proto-language codes and legendary/reconstructed langs. if (/-pro$/i.test(code)) return; if (/ziman[eê]\s+destan/i.test(name)) return; // Skip codes already in the pinned list (they are handled above). if (pinnedCodes.indexOf(code) !== -1) return; // sortKey: bare name without leading "zimanê " for sorting. var sortKey = name.replace(/^ziman[eê]\s+/i, ""); var choice = [code, name, sortKey]; extraChoices.push(choice); langsByCode[code] = choice; }); // Populate langsByCode for pinned choices too. $.each(pinnedChoices, function (i, choice) { // Ensure pinned choices have a sortKey (index 2). if (choice.length < 3) choice[2] = choice[1]; langsByCode[choice[0]] = choice; }); // Sort the extra choices alphabetically by sort key. extraChoices.sort(function (a, b) { return a[2].localeCompare(b[2], userLang); }); // Final list: pinned first, then the rest. var allChoices = pinnedChoices.concat(extraChoices); steps.lang.choices = allChoices; steps.trans.keys = allChoices; steps.dunde.keys = allChoices; steps.zarava.keys = getZaravaKeys(allChoices); var langMenu = $("#wiktku-start-lang-field"); populateMenus(langMenu, steps.lang.choices); langMenu.trigger("chosen:updated"); var transMenus = $("#wiktku-start-trans .wiktku-start-step-keyfield"); populateMenus(transMenus, steps.trans.keys, getDisabledKeys(steps.trans)); transMenus.trigger("chosen:updated"); var dundeMenus = $("#wiktku-start-dunde .wiktku-start-step-keyfield"); populateMenus(dundeMenus, steps.dunde.keys, getDisabledKeys(steps.dunde)); dundeMenus.trigger("chosen:updated"); var zaravaMenus = $("#wiktku-start-zarava .wiktku-start-step-keyfield"); populateMenus(zaravaMenus, steps.zarava.keys, getDisabledKeys(steps.zarava)); }); } mw.loader.using(["jquery.chosen", "mediawiki.api", "oojs-ui-core"], function () { // Load metadata, langChoices, posChoices and tplDefs from the companion // data page so they can be updated without touching this script. new mw.Api().get({ action: "query", prop: "revisions", titles: "MediaWiki:Gadget-start.js/data.json", rvprop: "content", rvslots: "main", formatversion: 2 }).then(function (data) { var page = data.query.pages[0]; var content = page && page.revisions && page.revisions[0].slots.main.content; var d; try { d = JSON.parse(content); } catch (e) { d = {}; } // Populate metadata. if (d.metadata) $.extend(metadata, d.metadata); // Populate lang choices (pinned list used by build() → ziman.json loader). if (d.langChoices) steps.lang.choices = d.langChoices; // Populate POS choices. if (d.posChoices) steps.pos.choices = d.posChoices; // Populate template definitions for the dfn sense-block builder. if (d.tplDefs) steps.dfn.tplDefs = d.tplDefs; // Populate pos placeholder examples. if (d.posExamples) steps.dfn.posExamples = d.posExamples; // Populate citation template definitions for the quote widget. if (d.jederDefs) steps.dfn.jederDefs = d.jederDefs; // Populate pronunciation and etymology template insert lists. if (d.pronTpls) { steps.pron.pronTpls = d.pronTpls; steps.pron.refreshTplSelect(); } if (d.etymTpls) { steps.etym.etymTpls = d.etymTpls; steps.etym.refreshTplSelect(); } // Sync trans/dunde/zarava keys with the (now populated) lang choices. steps.trans.keys = steps.lang.choices; steps.dunde.keys = steps.lang.choices; steps.zarava.keys = getZaravaKeys(steps.lang.choices); }).always(build); }); }); //</nowiki> 4jb55q2j8kr8zdfpumex7ntpdpwmy4v 6265562 6265560 2026-07-19T13:20:28Z Wikihez 7344 6265562 javascript text/javascript // Li ser [[vi:MediaWiki:Gadget-start.js]] hatiye refaktorkirin. //<nowiki> $(function () { var ns = mw.config.get("wgNamespaceNumber"); if (ns && !(ns === 2 && mw.config.get("wgPageName").match(/\/ceribandin$|\/test$/))) { return; } var action = mw.config.get("wgAction"); var pageExists = !!mw.config.get("wgArticleId"); // "Zimanek lê zêde bike" mode: triggered from the portlet link below. // Runs the same wizard on an EXISTING page's edit form, but appends the // generated section instead of replacing the textarea's content. var addLangMode = pageExists && mw.util.getParamValue("wiktkuaddlang") === "1"; // On a normal page view of an existing page, just add the portlet link // that takes the user into addLangMode; don't build anything else here. if (action === "view" && pageExists) { mw.util.addPortletLink("p-views", mw.util.getUrl(mw.config.get("wgPageName"), { action: "submit", wiktkuaddlang: "1" }), "+Ziman/beşeke din", "ca-wiktku-addlang", "Ji vê rûpelê re zimanekî nû zêde bike"); return; } if (!(action === "edit" || action === "submit")) { return; } if (!addLangMode && !$(".mw-newarticletext, .mw-newarticletextanon").length) { return; } if (window.location.href.includes("editintro=User:Wikihez/creation/intro")) { return; // Do not run the script wextê WF:Bilez dişuxile } function capitalize(str) { if (!str) return str; return str[0].toUpperCase() + str.substr(1); } function decapitalize(str) { if (!str) return str; return str[0].toLowerCase() + str.substr(1); } function escapeRegExp(str) { return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); } function stripWikilinks(str) { return str.replace(/\[\[([^\]|]+)(?:\|([^\]]+))?\]\]/g, function (m, target, display) { return display || target; }); } function insertAtCursor(el, text) { var start = el.selectionStart; var end = el.selectionEnd; var val = el.value; el.value = val.slice(0, start) + text + val.slice(end); var pos = start + text.length; el.selectionStart = el.selectionEnd = pos; } var pageName = mw.config.get("wgPageName").replaceAll(/_/g, " "); if (ns) pageName = pageName.replace(/.*\//, ""); var pageNameRe = escapeRegExp(pageName); var userLang = mw.config.get("wgUserLanguage"); // Mobile detection: MobileFrontend sets wgMFMode, or fall back to touch check. var isMobile = !!mw.config.get("wgMFMode") || window.matchMedia("(pointer: coarse)").matches; var chosenOptions = { width: "20em", disable_search_threshold: 0, placeholder_text_single: "Yekî hilbijêre", placeholder_text_multiple: "Hilbijêre", no_results_text: "Nehat dîtin", enable_split_word_search: true, search_contains: true }; function wrapNativeSelect(select) { var placeholder = select.attr("data-placeholder") || "Lê bigere…"; // Hide the native select — we drive it programmatically. select.hide(); var wrapper = $("<span class='wiktku-native-select-wrap'></span>"); var textInput = $("<input type='search' autocomplete='off'>") .attr("placeholder", placeholder) .addClass("wiktku-start-narrow wiktku-ac-input"); var resultsList = $("<ul class='wiktku-ac-results'></ul>").hide(); // Full option cache — rebuilt when chosen:updated fires. var allOptions = []; function cacheOptions() { allOptions = []; select.find("option").each(function () { var v = $(this).val(); if (!v) return; // skip the empty placeholder option allOptions.push({ value: v, text: $(this).text(), disabled: $(this).prop("disabled") }); }); } cacheOptions(); function showResults(query) { var q = query.trim().toLowerCase(); resultsList.empty(); var matched; if (q) { matched = []; $.each(allOptions, function (_, o) { if (o.disabled) return; var codeMatch = o.value.toLowerCase().indexOf(q) !== -1; var nameMatch = o.text.toLowerCase().indexOf(q) !== -1; if (codeMatch || nameMatch) { matched.push({ opt: o, codeMatch: codeMatch }); } }); // Code matches (especially prefix matches) come first. matched.sort(function (a, b) { var aCode = a.opt.value.toLowerCase(); var bCode = b.opt.value.toLowerCase(); var aPrefix = aCode.indexOf(q) === 0; var bPrefix = bCode.indexOf(q) === 0; if (aPrefix !== bPrefix) return aPrefix ? -1 : 1; if (a.codeMatch !== b.codeMatch) return a.codeMatch ? -1 : 1; return 0; }); matched = matched.map(function (item) { return item.opt; }); } else { matched = allOptions.filter(function (o) { return !o.disabled; }); } if (!matched.length) { resultsList.hide(); return; } $.each(matched.slice(0, 50), function (_, opt) { var li = $("<li></li>").text(opt.text).attr("data-value", opt.value); // Use touchend instead of touchstart so that a scroll gesture does // not accidentally select an item. We track whether the finger moved // between touchstart and touchend — if it did, it was a scroll. var touchMoved = false; li.on("touchstart", function () { touchMoved = false; }); li.on("touchmove", function () { touchMoved = true; }); li.on("touchend", function (e) { if (touchMoved) return; // was a scroll, not a tap e.preventDefault(); selectOption(opt.value, opt.text); }); // Keep mousedown for desktop fallback. li.on("mousedown", function (e) { e.preventDefault(); selectOption(opt.value, opt.text); }); resultsList.append(li); }); // Position the list above or below depending on available viewport space. var inputRect = textInput[0].getBoundingClientRect(); var viewportH = window.innerHeight; var spaceBelow = viewportH - inputRect.bottom - 8; var spaceAbove = inputRect.top - 8; var maxH = Math.min(224, Math.max(spaceBelow, spaceAbove)); // 224px ≈ 14em resultsList.css({ "max-height": maxH + "px", "top": spaceBelow >= spaceAbove ? "100%" : "auto", "bottom": spaceBelow >= spaceAbove ? "auto" : "100%" }); resultsList.show(); } function selectOption(value, text) { textInput.val(text); select.val(value); resultsList.hide(); select.trigger("change"); } textInput.on("input focus", function () { showResults($(this).val()); }); textInput.on("blur", function () { // Short delay so a touchstart on a result item fires first. setTimeout(function () { resultsList.hide(); }, 200); }); // chosen:updated → re-cache (called after ziman.json loads). select.on("chosen:updated", function () { cacheOptions(); // If a value is already selected, keep the display text in sync. var cur = select.val(); if (cur) { var match = $.grep(allOptions, function (o) { return o.value === cur; })[0]; if (match) textInput.val(match.text); } }); // No-op .chosen() so desktop call-sites don't need guarding. select.chosen = function () { return select; }; wrapper.append(textInput).append(resultsList).append(select); return wrapper; } var langsByCode = {}; // Populated from [[MediaWiki:Gadget-start.js/data.json]] at runtime. var metadata = {}; // Zaravayên kurdî yên ku di beşa "Bi zaravayên din" de tên pêşkêşkirin — // ev kod ji beşa Werger têne derxistin daku heman zimên du caran neyê xwendin. var ZARAVA_LANG_CODES = ["ckb", "sdh", "lki", "hac", "zza"]; function getZaravaKeys(choices) { var byCode = {}; $.each(choices || [], function (_, c) { byCode[c[0]] = c; }); var result = []; $.each(ZARAVA_LANG_CODES, function (_, code) { if (byCode[code]) result.push(byCode[code]); }); return result; } function needsTransliteration(langCode) { var meta = metadata[langCode]; if (!meta || !meta.sc) return false; var scripts = Array.isArray(meta.sc) ? meta.sc : [meta.sc]; return scripts.length > 0 && scripts[0] !== "Latn"; } // Kodên cinsiyetê yên di metadata.g de var GENDER_BASE_LABELS = { m: "mê", n: "nêr", nt: "nêtar", mn: "mê û nêr", mnmane: "mê yan nêr li gorî maneyê", g: "giştî", y: "yekjimar", p: "pirjimar" }; // Sub-lists that only make sense for a plain (non-şablon) sense — hidden // when a şablon (e.g. {{guharto|…}}) is chosen for that sense, since a // template-based sense has no "own" gloss for alternate forms, synonyms, // antonyms, coordinate terms, hypernyms or hyponyms to attach to. Etîket, // Nimûne and Jêgirtin stay visible either way. var HIDDEN_ON_TPL_GROUPS = [ "wiktku-dfn-alternativ", "wiktku-dfn-hevmane", "wiktku-dfn-dijmane", "wiktku-dfn-koordine", "wiktku-dfn-jornav", "wiktku-dfn-jernav" ]; function genderLabel(code) { if (code === "p") return "Pirjimar"; var pluralMatch = code.match(/^(.+)-p$/); if (pluralMatch && GENDER_BASE_LABELS[pluralMatch[1]]) { return GENDER_BASE_LABELS[pluralMatch[1]] + " (pirjimar)"; } return GENDER_BASE_LABELS[code] || code; } /** * True if a sense has any content worth keeping besides its mane text — * etîket, hevmane/dijmane/koordîne/etc. word lists, nimûne, or jêder * (quote). Used so a sense with an empty mane but filled-in extra * fields still gets emitted (with {{mane?}} standing in for the gloss) * instead of being silently dropped. */ function senseHasExtraContent(s) { if (s.etiket && $.grep(s.etiket, function (e) { return $.trim(e) !== ""; }).length) return true; if (s.alternativ.length || s.hevmane.length || s.dijmane.length || s.koordine.length || s.jornav.length || s.jernav.length) return true; if (s.nimune && $.grep(s.nimune, function (n) { return (typeof n === "object" ? n.text : n) !== ""; }).length > 0) return true; if (s.jeder && $.grep(s.jeder, function (j) { return j && j.quote; }).length > 0) return true; return false; } /** * formatNimune: each nimûne item can be { text, tr, t }: * text — example text * tr — transliteration (only when the language needs it) * t — Kurdish translation (third positional param, no key) */ function formatNimune(nimunes, lang, hasJeder) { var hasNimune = nimunes && $.grep(nimunes, function (n) { return (typeof n === "object" ? n.text : n) !== ""; }).length > 0; if (!hasNimune) { return hasJeder ? "" : "\n#* {{bênimûne|" + lang + "}}"; } return $.map(nimunes, function (n) { var text = typeof n === "object" ? n.text : n; if (!text) return undefined; var bolded = text.replace( new RegExp("(" + pageNameRe + "([^( |,|;|\\?|\\.|\\!)]+)?)", "ig"), "'''$1'''"); var tpl = "\n#: {{nm|" + lang + "|" + bolded; if (typeof n === "object") { if (n.tr) tpl += "|tr=" + n.tr; // Translation as third positional param (no key needed). if (n.t) tpl += "|" + n.t; } // Short examples fit on one line together with their translation. // rêz=1 is not used for ku — definitions are shown on separate lines there. if (text.length < 200 && lang !== "ku") tpl += "|rêz=1"; tpl += "}}"; return tpl; }).join(""); } /** * Formats a list of jêder (quote/citation) objects into wikitext lines. * Each entry that has no quote text is skipped. Returns "" when the list * is empty or every entry is blank. * * #* {{jêder-…|lang|jêgirtin=…|tr=…|tercime=…|…fields…}} * * When no template is chosen, the generic {{jêder|…}} template is used * instead. Its 2nd positional param is the user's freeform "bi destê xwe * binivîsim" source text when supplied, or the çavkanî? placeholder otherwise. * If that text contains "=" it is passed as |2=… instead of a bare * positional param, since MediaWiki would otherwise misparse it as its * own key=value pair and break the template: * #* {{jêder|lang|jêgirtin=…|tr=…|tercime=…|<manual source or çavkanî?>}} */ function formatJeder(jederList, lang) { if (!jederList || !jederList.length) return ""; return $.map(jederList, function (jeder) { if (!jeder || !jeder.quote) return undefined; if (jeder.jederTpl) { var cite = "\n#* {{" + jeder.jederTpl + "|" + lang; cite += "|jêgirtin=" + jeder.quote; if (jeder.quoteTr) cite += "|tr=" + jeder.quoteTr; if (jeder.quoteT) cite += "|tercime=" + jeder.quoteT; $.each(jeder.jêderFields || {}, function (key, val) { if (val) cite += "|" + key + "=" + val; }); cite += "}}"; return cite; } var out = "\n#* {{jêder|" + lang + "|jêgirtin=" + jeder.quote; if (jeder.quoteTr) out += "|tr=" + jeder.quoteTr; if (jeder.quoteT) out += "|tercime=" + jeder.quoteT; var srcParam = jeder.jederManual ? jeder.jederManual : "çavkanî?"; // A positional param containing "=" gets parsed as its own key=value // pair by MediaWiki and breaks the template, so force it to be // explicitly named (|2=) whenever that's the case. out += (srcParam.indexOf("=") !== -1 ? "|2=" : "|") + srcParam; out += "}}"; return out; }).join(""); } function makeWordListStep(id, name, question_fmt, header, templateName) { return { id: id, name: name, question_fmt: question_fmt, multiple: true, narrow: true, visible: function (values) { return values.lang && values.pos; }, output: function (values) { var words = $.grep(values[id] || [], function (w) { return !!w; }); if (!words.length) return ""; var lang = values.lang; var section = "\n==== " + header + " ====\n"; if (words.length === 1) { // Single word — keep the simple inline template. return section + "* {{" + templateName + "|" + lang + "|" + words[0] + "}}\n"; } // Multiple words — use {{kol3}} with one positional param per word. var params = "cure=" + header + "\n" + $.map(words, function (w) { return "|" + w; }).join("\n"); return section + "{{kol3|" + lang + "|" + params + "\n}}\n"; } }; } var steps = { lang: { id: "lang", required: true, name: "ziman", question_fmt: '"' + pageName + '" bi çi zimanî ye?', question_br: true, // Populated from [[MediaWiki:Gadget-start.js/data.json]] (langChoices). choices: [], output: function (values) { return "== {{ziman|" + values.lang + "}} ==\n"; } }, pron: { id: "pron", name: "bilêvkirin", question_fmt: '"' + pageName + '" çawa tê telafûzkirin?', // pronTpls populated from data.json pronTpls: [], visible: function (values) { if (!values.lang) return false; // In addLangMode, only skip pron when this langcode's section // already exists in the page — if it's a new language, show it. if (addLangMode) { var existing = $("#wpTextbox1").val() || ""; var header = "== {{ziman|" + values.lang + "}} =="; return existing.indexOf(header) === -1; } return true; }, /** Fills (or refills) the insert-dropdown from the current pronTpls array, filtering by language. */ refreshTplSelect: function () { var sel = $("#wiktku-start-pron .wiktku-tpl-insert-select"); if (!sel.length) return; var lang = getValues().lang || ""; sel.find("option[value!='']").remove(); $.each(steps.pron.pronTpls, function (_, tpl) { // Filter: if tpl.langs exists, only show if lang is in that list; otherwise show always var allowed = !tpl.langs || tpl.langs.indexOf(lang) !== -1; if (allowed) { sel.append($("<option></option>") .val(tpl.snippet) .text(tpl.name + " — " + tpl.desc) .attr("data-nolang", tpl.noLang ? "1" : "")); } }); // Notify Chosen that the option list has changed (no-op on mobile). if (!isMobile) sel.trigger("chosen:updated"); }, build: function (stepDiv) { if (stepDiv.find(".wiktku-pron-wrap").length) return null; var wrap = $("<div class='wiktku-pron-wrap'></div>"); var ta = $("<textarea></textarea>") .attr("name", "wiktku-pron-" + $.now()) .attr("class", "wiktku-start-step-field wiktku-pron-text") .attr("rows", 4) .attr("placeholder", "Nimûne: {{IPA|ku|/pɛɪ̯n/}} yan {{kîte|ku|he|ce|ki|rin}}"); // Template insert dropdown — filtered by language. var sel = $("<select class='wiktku-tpl-insert-select'></select>"); sel.append($("<option value=''>— şablonek lê zêde bike —</option>")); var lang = getValues().lang || ""; $.each(steps.pron.pronTpls, function (_, tpl) { // Filter: if tpl.langs exists, only show if lang is in that list; otherwise show always var allowed = !tpl.langs || tpl.langs.indexOf(lang) !== -1; if (allowed) { sel.append($("<option></option>") .val(tpl.snippet) .text(tpl.name + " — " + tpl.desc) .attr("data-nolang", tpl.noLang ? "1" : "")); } }); sel.on("change", function () { var snippet = $(this).val(); if (!snippet) return; var lang = getValues().lang || ""; // Check if the selected option has noLang flag var selectedOption = sel.find("option:selected"); var hasNoLang = selectedOption.attr("data-nolang") === "1"; if (!hasNoLang) { snippet = snippet.replace(/CODE/g, lang).replace(/SOURCELANG/g, "?"); } insertAtCursor(ta[0], snippet); $(this).val(""); ta.focus(); }); wrap.append(sel).append($("<br>")).append(ta); stepDiv.append(wrap); return ta; }, output: function () { var text = $.trim($("#wiktku-start-pron .wiktku-pron-text").val()); if (!text) return ""; var lines = text.split("\n"); var out = $.map(lines, function (line) { line = $.trim(line); if (!line) return undefined; return line.charAt(0) === "*" ? line : "* " + line; }).join("\n"); return "\n=== Bilêvkirin ===\n" + out + "\n"; } }, pos: { id: "pos", required: true, name: "Cureyê rêzimanî", question_fmt: 'Cureyê rêzimanî yê "' + pageName + '" çi ye?', visible: function (values) { return values.lang; }, question_br: true, // Populated from [[MediaWiki:Gadget-start.js/data.json]] (posChoices). choices: [], output: function (values) { var pos = values.pos || ""; var cinsiyet = values.cinsiyet || ""; // from the cinsiyet step var lekTur = values.lektur || ""; // from the lêker transitivity step var capitalizedPos = capitalize(pos); var outputString = "\n=== " + capitalizedPos + " ===\n"; // Add ku-tewîn-nav for single-word navdêr/serenav with known gender. if (!pageName.includes(" ") && cinsiyet && GENDER_BASE_LABELS[cinsiyet] && (pos === "navdêr" || pos === "serenav") && values.lang === "ku") { outputString += "{{ku-tewîn-nav|" + pageName + "|" + GENDER_BASE_LABELS[cinsiyet]; if (pos === "serenav") outputString += "|y"; outputString += "}}\n"; } outputString += "{{" + pos + "|" + values.lang; if (pos === "navdêr" || pos === "serenav") { if (cinsiyet) { outputString += "|c=" + cinsiyet; } else if (values.lang === "ku") { // Unknown gender — prompt editor to fill it in. outputString += "|c=?"; } } else if (/^lêker/.test(pos) && lekTur) { outputString += "|c=" + lekTur; } if (values.tr) { outputString += "|tr=" + values.tr; } outputString += "}}\n"; return outputString; } }, /** * cinsiyet (grammatical gender) — only shown for navdêr/serenav, û * tenê ger metadata ji bo zimanê hilbijartî lîsteyeke "g" (cinsiyet) * were dayîn. Opsiyonên vê gavê ne sabît in — ji metadata[values.lang].g * têne çêkirin, ji ber ku di hemû zimanan de cinsiyet tine. */ cinsiyet: { id: "cinsiyet", name: "cinsiyet", question_fmt: 'Cinsiyeta "' + pageName + '" çi ye?', question_br: true, visible: function (values) { var meta = metadata[values.lang]; return !!(values.lang && (values.pos === "navdêr" || values.pos === "serenav") && meta && meta.g && meta.g.length); }, build: function (stepDiv, values) { var select = stepDiv.find("select.wiktku-start-step-field"); if (!select.length) { select = $(mw.html.element("select", { "class": "wiktku-start-step-field", id: "wiktku-start-cinsiyet-field" })); stepDiv.append(select); } if (!values) return select; var meta = metadata[values.lang]; var codes = (meta && meta.g) || []; var prevVal = select.val(); var choices = $.map(codes, function (code) { return [[code, genderLabel(code)]]; }); populateMenus(select, choices); if ($.grep(choices, function (c) { return c[0] === prevVal; }).length) { select.val(prevVal); } if (!isMobile) select.trigger("chosen:updated"); return select; }, output: function () { return ""; } // consumed by pos.output }, /** * Lêker transitivity — only shown for any lêker variant. */ lektur: { id: "lektur", name: "Cureyê lêkerê (fiîlê)", question_fmt: "Cureyê lêkerê (fiîlê) çi ye?", question_br: true, visible: function (values) { return values.lang && values.pos && /^lêker/.test(values.pos); }, // Dictionary: value → display label. Add new types here. choices: [ ["gh", "gerguhêz"], ['x-gh', 'xwerû-gerguhêz'], ['p-gh', 'pêkhatî-gerguhêz'], ['h-gh', 'hevedudanî-gerguhêz'], ['b-gh', 'biwêjî-gerguhêz'], ["ngh", "negerguhêz"], ['x-ngh', 'xwerû-negerguhêz'], ['p-ngh', 'pêkhatî-negerguhêz'], ['h-ngh', 'hevedudanî-negerguhêz'], ['b-ngh', 'biwêjî-negerguhêz'] ], output: function () { return ""; } // consumed by pos.output }, tr: { id: "tr", name: "transkrîpsiyon", question_fmt: "Transkrîpsiyona kelîmeyê", multiple: false, narrow: true, visible: function (values) { return values.lang && values.pos && needsTransliteration(values.lang); } }, dfn: { id: "dfn", // required: true, ger mane tinebe [[Şablon:mane?]] bi kar bîne name: "Mane", question_fmt: "Maneya kelîmeyê binivîse. Mane otomatîk tê lînkkirin! Ji bo tercimeyan beşa 'Werger' bi kar bîne!", multiple: true, ordered: true, rows: 3, visible: function (values) { return values.lang && values.pos; }, example: function (values) { // posExamples loaded from [[MediaWiki:Gadget-start.js/data.json]]. var examples = steps.dfn.posExamples || {}; var full = values.pos || ""; return examples[full] || ""; }, /** * Builds one sense block (<li>) inside the ordered list. * Each block contains: * - a textarea for the definition * - an expandable nimûne list * - single-row sub-lists for formên alternatîv, hevmane, dijmane */ buildSenseBlock: function (stepDiv) { var block = $("<li class='wiktku-dfn-sense'></li>"); // — Mane textarea (declared first so the template handler can reference it) — var dfnArea = $("<textarea></textarea>") .attr("name", "wiktku-dfn-mane-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("class", "wiktku-start-step-field wiktku-dfn-mane") .attr("rows", 6) .attr("placeholder", "Mane…"); dfnArea.on("input", function () { steps.dfn.onDfnInput(stepDiv, block, this); }); // — Template selector (optional — replaces mane when chosen) — // Template definitions loaded from [[MediaWiki:Gadget-start.js/data.json]]. var tplDefs = steps.dfn.tplDefs || []; // Cache of all non-placeholder option elements — used by updateTplOptions // to remove/re-add options (the only approach compatible with Chosen.js). var _allTplOptions = []; var tplSelect = $(mw.html.element("select", { "class": "wiktku-dfn-tpl-select" })); tplSelect.append($("<option value=''>— yan jî şablonek hilbijêre —</option>")); $.each(tplDefs, function (_, tpl) { var opt = $("<option></option>") .val(tpl.name) .text(tpl.name) .attr("data-langs", tpl.langs ? tpl.langs.join(",") : "") .attr("data-nolang", tpl.noLang ? "1" : ""); tplSelect.append(opt); _allTplOptions.push(opt[0]); }); function updateTplOptions() { var lang = getValues().lang || ""; var currentVal = tplSelect.val(); var currentStillValid = false; // Detach all non-placeholder options, then re-attach only the visible ones. // This is the only approach that works correctly with both native <select> // and Chosen.js on desktop. tplSelect.find("option[value!='']").detach(); $.each(_allTplOptions, function (_, opt) { var allowed = $(opt).attr("data-langs"); var visible = !allowed || allowed.split(",").indexOf(lang) !== -1; if (visible) { tplSelect.append(opt); if ($(opt).val() === currentVal) currentStillValid = true; } }); if (!isMobile) tplSelect.trigger("chosen:updated"); if (currentVal && !currentStillValid) { tplSelect.val(""); dfnArea.show(); tplTitleInput.hide().val(""); } } // Store updater on the element so refresh() can call it for all blocks. tplSelect.data("updateOptions", updateTplOptions); var tplTitleInput = $("<input type='text'>") .addClass("wiktku-dfn-tpl-title wiktku-start-narrow") .attr("placeholder", "Navê rûpelê…") .hide(); // Grow the sense list when the title field of the last block gets content, // mirroring what onDfnInput does for the plain mane textarea. tplTitleInput.on("input", function () { steps.dfn.onDfnInput(stepDiv, block, this); }); /** * When a şablon sense is chosen, formên alternatîv/hevmane/dijmane/ * termên koordîne/jornav/jêrnav don't apply (there's no plain gloss * to hang them off), so hide those subgroups. Etîket, Nimûne and * Jêgirtin stay visible and still usable for a şablon sense. */ function updateFieldVisibility() { var isTpl = !!tplSelect.val(); $.each(HIDDEN_ON_TPL_GROUPS, function (_, cls) { block.find("." + cls + "-group").toggle(!isTpl); }); } // Store on the block so restoreDfn() can re-sync visibility // after programmatically setting tplSelect's value. block.data("updateFieldVisibility", updateFieldVisibility); tplSelect.on("change", function () { var chosen = $(this).val(); if (chosen) { dfnArea.hide(); tplTitleInput.show().focus(); } else { dfnArea.show(); tplTitleInput.hide().val(""); } updateFieldVisibility(); // Re-run refresh so the Werger step visibility updates. refresh(); }); var tplRow = $("<div></div>").addClass("wiktku-dfn-tpl-row") .append(tplSelect).append(" ").append(tplTitleInput); block.append(tplRow); block.append(dfnArea); // Apply lang filter on initial build. updateTplOptions(); // — Sub-field groups — // All groups are always visible with a placeholder textarea. // Nimûne is last in the DOM and last in the output. var allGroups = [ { cls: "wiktku-dfn-etiket", label: "Etîket", rows: 1, narrow: true, izah: "xisûsen, Mêrdîn, anatomî, Badînî" }, { cls: "wiktku-dfn-alternativ", label: "Formên alternatîv", rows: 1, narrow: true, izah: "Varyantên vê kelîmeyê" }, { cls: "wiktku-dfn-hevmane", label: "Hevmane", rows: 1, narrow: true, izah: "Spehî hevmaneya Bedew e." }, { cls: "wiktku-dfn-dijmane", label: "Dijmane", rows: 1, narrow: true, izah: "Zengîn dijmaneya feqîr e." }, { cls: "wiktku-dfn-koordine", label: "Termên koordîne", rows: 1, narrow: true, izah: "Pisîk û kûçik termên koordîne ne çunkî Jornavên wan gelek in" }, { cls: "wiktku-dfn-jornav", label: "Jornav", rows: 1, narrow: true, izah: "Heywan jornavê guhandar e" }, { cls: "wiktku-dfn-jernav", label: "Jêrnav", rows: 1, narrow: true, izah: "Guhandar jêrnavê heywan e" }, { cls: "wiktku-dfn-nimune", label: "Nimûne", rows: 2, narrow: false } ]; $.each(allGroups, function (_, g) { var groupDiv = $("<div></div>").addClass("wiktku-dfn-subgroup " + g.cls + "-group"); function buildNimuneLi() { var lang = getValues().lang || ""; var li = $("<li></li>").addClass("wiktku-dfn-nimune-li"); var mainTa = $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-text-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", g.rows) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-text") .attr("placeholder", "Nimûneya emilandina kelîmeyê tu bi xwe binivîse…"); mainTa.on("input", function () { var val = $.trim($(this).val()); var isLast = li.is(list.children("li:last-child")); if (val && isLast) { list.append(buildNimuneLi()); } }); li.append(mainTa); var subWrap = $("<div></div>").addClass("wiktku-dfn-nimune-sub"); if (needsTransliteration(lang)) { subWrap.append( $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-tr-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 5) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-tr") .attr("placeholder", "Transkrîpsiyona bi alfabeya latînî") ); } if (lang && lang !== "ku") { subWrap.append( $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-t-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 5) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-t") .attr("placeholder", "Tercimeya kurmancî") ); } if (subWrap.children().length) li.append(subWrap); return li; } if (g.cls === "wiktku-dfn-nimune") { // Nimûne — compound widget with tr/t sub-fields. var lbl = $("<span></span>").addClass("wiktku-dfn-sublabel").text(g.label + ": "); var list = $("<ol></ol>").addClass("wiktku-dfn-sublist " + g.cls + "-list"); groupDiv.data("buildNimuneLi", buildNimuneLi); list.append(buildNimuneLi()); groupDiv.append(lbl).append(list); block.append(groupDiv); } else { // Regular always-visible group — label + growing textarea list. var lbl = $("<span></span>").addClass("wiktku-dfn-sublabel").text(g.label + ": " + g.izah); var list = $("<ol></ol>").addClass("wiktku-dfn-sublist " + g.cls + "-list"); var firstInput = $("<textarea></textarea>") .attr("name", g.cls + "-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", g.rows) .attr("class", "wiktku-dfn-subfield" + (g.narrow ? " wiktku-start-narrow" : "")) .attr("placeholder", g.label + "…"); firstInput.on("input", function () { steps.dfn.onSubInput(list, this, g.rows, g.narrow); }); list.append($("<li></li>").append(firstInput)); groupDiv.append(lbl).append(list); block.append(groupDiv); } }); // — Jêder (quote / citation) group — a growing list, sibling to Nimûne — // Structured the same way as Nimûne (ol.wiktku-dfn-sublist > li) so it // lines up at the same indentation, and so that typing into the last // citation's Jêgirtin box automatically opens a fresh empty one below it. (function () { var jederGroupDiv = $("<div></div>").addClass("wiktku-dfn-subgroup wiktku-dfn-jeder-group"); var jederLbl = $("<span></span>").addClass("wiktku-dfn-sublabel").text("Jêgirtin: "); var jederList = $("<ol></ol>").addClass("wiktku-dfn-sublist wiktku-dfn-jeder-list"); function buildJederLi() { var lang = getValues().lang || ""; var li = $("<li></li>").addClass("wiktku-dfn-jeder-li"); var dragHandle = $("<span></span>") .addClass("wiktku-jeder-drag-handle") .attr("title", "Bişkûne û bikişîne da ku rêzê biguhezîne"); // Quote text textarea var quoteTa = $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-quote-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 2) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-quote") .attr("placeholder", "Nimûneya emilandinê ji kitêb an çavkaniyeke din binivîse"); quoteTa.on("input", function () { var val = $.trim($(this).val()); var isLast = li.is(jederList.children("li:last-child")); if (val && isLast) { jederList.append(buildJederLi()); } }); li.append(dragHandle).append(quoteTa); // tr/t sub-fields for the quote — shown as needed for the language. var quoteSubWrap = $("<div></div>").addClass("wiktku-dfn-quote-sub"); if (needsTransliteration(lang)) { quoteSubWrap.append( $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-quote-tr-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 2) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-quote-tr") .attr("placeholder", "Transkrîpsiyona jêgirtinê…") ); } if (lang && lang !== "ku") { quoteSubWrap.append( $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-quote-t-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 2) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-quote-t") .attr("placeholder", "Tercimeya jêgirtinê bi kurmancî") ); } if (quoteSubWrap.children().length) li.append(quoteSubWrap); // Citoid auto-fill: fetch citation data from a URL, DOI or ISBN and // prefill the source şablon + fields below (see Gadget-citoid-helper.js). var citoidWrap = $("<div></div>").addClass("wiktku-dfn-quote-citoid"); var citoidInput = $("<input type='text'>") .addClass("wiktku-dfn-quote-citoid-input wiktku-start-narrow") .attr("placeholder", "URL, DOI an ISBN binivîse ku otomatîk were tijekirin…"); var citoidBtn = new OO.ui.ButtonWidget({ label: "Bi Citoid bîne", classes: [ "wiktku-dfn-quote-citoid-btn" ] }); var citoidStatus = $("<span></span>").addClass("wiktku-dfn-quote-citoid-status"); /** * Fetches citation data from Citoid and applies it to this * citation's şablon selector + fields. Mirrors the logic in * Form.prototype._fillFromCitoid (Gadget-wikt.add-examples.js): * - only (re)selects the şablon when it actually differs from * what's already chosen, so a repeat fetch doesn't wipe out * a template the user already picked; * - only fills fields that are currently empty, so it never * overwrites something the user typed by hand; * - falls back to the freeform "bi destê xwe binivîsim" source * only when nothing was typed there yet. */ function runCitoidFetch() { var query = $.trim(citoidInput.val()); if (!query) { mw.notify("Ji kerema xwe re pêşî URL, DOI an ISBNyekê binivîse."); return; } citoidBtn.setDisabled(true); citoidStatus.text("Tê anîn…"); wikt.citoidHelper.ensure().then(function () { return wikt.citoid.fetchJederFields(query); }).then(function (result) { var jederKey = result.jederKey; var hasTpl = !!jederKey && srcSel.find("option[value='" + jederKey + "']").length > 0; var targetVal = hasTpl ? jederKey : "__manual__"; // Only (re)select — and thus rebuild — the field rows if // we're switching to a different şablon than what's // already chosen, so a second fetch doesn't clear fields // the user already filled in by hand. if (srcSel.val() !== targetVal) { srcSel.val(targetVal).trigger("change"); srcSel.trigger("chosen:updated"); } if (hasTpl) { // Tenê qadên vala tijî bike. $.each(result.fields, function (key, val) { var input = srcFields.find("[data-field-key='" + key + "']"); if (input.length && !$.trim(input.val())) { input.val(val); } }); } else { // Şablonek nehat naskirin ji bo vê itemType — rêzikeke // çavkaniyê ya bi destan a ji qadên Citoid tê çêkirin, // lê tenê ger qada destan vala be. var manualField = srcFields.find(".wiktku-dfn-quote-src-manual"); if (!$.trim(manualField.val())) { var parts = []; $.each(["nivîskar", "sernav", "websîte", "kovar", "weşanxane", "sal", "url"], function (_, k) { if (result.fields[k]) parts.push(result.fields[k]); }); manualField.val(parts.join(", ")); } } citoidStatus.text(""); }, function (errorMsg) { citoidStatus.text(typeof errorMsg === "string" ? errorMsg : "Nehat dîtin. Kontrol bike ka URL/DOI/ISBN rast e."); }).always(function () { citoidBtn.setDisabled(false); }); } citoidBtn.on("click", runCitoidFetch); citoidInput.on("keydown", function (e) { if (e.which === 13) { // Enter e.preventDefault(); runCitoidFetch(); } }); citoidWrap.append(citoidInput).append(citoidBtn.$element).append(citoidStatus); // Source template selector, specific to this citation. var srcSel = $("<select></select>").addClass("wiktku-dfn-quote-src-sel"); srcSel.append($("<option value=''>— Çavkaniyê hilbijêre —</option>")); srcSel.append($("<option></option>").val("__manual__").text("Bi destê xwe binivîsim")); var jederDefs = steps.dfn.jederDefs || {}; $.each(jederDefs, function (tplName, def) { srcSel.append($("<option></option>").val(tplName).text(def.label)); }); // Dynamic source fields container. var srcFields = $("<div></div>").addClass("wiktku-dfn-quote-src-fields"); srcSel.on("change", function () { srcFields.empty(); var chosen = $(this).val(); if (!chosen) return; if (chosen === "__manual__") { // Freeform source, written by the user — becomes the 2nd // positional param of {{jêder|lang|…}} instead of çavkanî?. srcFields.append( $("<textarea></textarea>") .attr("rows", 4) .addClass("wiktku-dfn-subfield wiktku-dfn-quote-src-manual") .attr("placeholder", "Çavkaniyê bi destê xwe binivîse…") ); return; } var def = (steps.dfn.jederDefs || {})[chosen]; if (!def) return; $.each(def.fields, function (_, f) { var row = $("<div></div>").addClass("wiktku-dfn-quote-src-row"); var fieldLbl = $("<label></label>").text(f.label + ": "); var inp = $("<textarea></textarea>") .attr("rows", 2) .addClass("wiktku-dfn-quote-src-input wiktku-start-narrow") .attr("data-field-key", f.key) .attr("placeholder", f.label + "…"); row.append(fieldLbl).append(inp); srcFields.append(row); }); }); li.append(citoidWrap).append(srcSel).append(srcFields); return li; } jederGroupDiv.data("buildJederLi", buildJederLi); jederList.append(buildJederLi()); // Make citation rows sortable (drag to reorder). // The last row is always the empty trailing row — cancel its drag. mw.loader.using("jquery.ui.sortable", function () { jederList.sortable({ handle: ".wiktku-jeder-drag-handle", axis: "y", items: "li:not(:last-child)", tolerance: "pointer" }); }); jederGroupDiv.append(jederLbl).append(jederList); block.append(jederGroupDiv); }()); // Apply the initial hide/show state for the sub-groups (matches // tplSelect's starting value, which is normally empty). updateFieldVisibility(); return block; }, /** Grows the sense list when the last mane textarea gets content. */ onDfnInput: function (stepDiv, block, textarea) { var val = $.trim($(textarea).val()); var list = stepDiv.find("ol.wiktku-dfn-list"); var isLast = block.is(list.children("li:last-child")); if (val && isLast) { var newBlock = steps.dfn.buildSenseBlock(stepDiv); list.append(newBlock); // Apply Chosen to the new block's template selector on desktop. if (!isMobile) newBlock.find("select.wiktku-dfn-tpl-select").chosen(chosenOptions); } refresh(); }, /** Grows a sub-list (nimûne/formên alternatîv/hevmane/dijmane/termên koordîne) on input. */ onSubInput: function (list, input, rows, narrow) { var val = $.trim($(input).val()); var item = $(input).parent(); var isLast = item.is(list.children("li:last-child")); if (val && isLast) { var next = $("<textarea></textarea>") .attr("name", "wiktku-dfn-sub-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", rows) .attr("class", "wiktku-dfn-subfield" + (narrow ? " wiktku-start-narrow" : "")); next.on("input", function () { steps.dfn.onSubInput(list, this, rows, narrow); }); list.append($("<li></li>").append(next)); } }, // Populated from [[MediaWiki:Gadget-start.js/data.json]] (tplDefs, posExamples, jederDefs). tplDefs: [], posExamples: {}, jederDefs: {}, build: function (stepDiv) { if (stepDiv.find("ol.wiktku-dfn-list").length) return null; var list = $("<ol class='wiktku-dfn-list'></ol>"); list.append(steps.dfn.buildSenseBlock(stepDiv)); stepDiv.append(list); return null; }, /** Reads all sense blocks from the DOM and returns an array of sense objects. */ getSenses: function (stepDiv) { var senses = []; stepDiv.find("li.wiktku-dfn-sense").each(function () { var block = $(this); var tplSel = block.find("select.wiktku-dfn-tpl-select"); var tpl = tplSel.val() || ""; // noLang: template already encodes the language — don't add |lang| param. var tplNoLang = tpl ? tplSel.find("option[value='" + tpl + "']").attr("data-nolang") === "1" : false; var tplTitle = $.trim(block.find("input.wiktku-dfn-tpl-title").val()); var mane = $.trim(block.find("textarea.wiktku-dfn-mane").val()); var etiket = (function () { var vals = []; block.find(".wiktku-dfn-etiket-list textarea").each(function () { var v = $.trim($(this).val()); if (v) vals.push(v); }); return vals; }()); function readList(cls) { var vals = []; block.find("." + cls + "-list textarea").each(function () { var v = $.trim($(this).val()); if (v) vals.push(v); }); return vals; } // Nimûne items are compound: { text, tr?, t? } function readNimuneList() { var items = []; block.find(".wiktku-dfn-nimune-list li.wiktku-dfn-nimune-li").each(function () { var text = $.trim($(this).find(".wiktku-dfn-nimune-text").val()); if (!text) return; var obj = { text: text }; var tr = $.trim($(this).find(".wiktku-dfn-nimune-tr").val()); var t = $.trim($(this).find(".wiktku-dfn-nimune-t").val()); if (tr) obj.tr = tr; if (t) obj.t = t; items.push(obj); }); return items; } // Jêder is a growing list of citations, one per li — mirrors readNimuneList(). function readJederList() { var items = []; block.find(".wiktku-dfn-jeder-list li.wiktku-dfn-jeder-li").each(function () { var li = $(this); var quote = $.trim(li.find(".wiktku-dfn-nimune-quote").val()); if (!quote) return; var obj = { quote: quote }; var qtr = $.trim(li.find(".wiktku-dfn-nimune-quote-tr").val()); var qt = $.trim(li.find(".wiktku-dfn-nimune-quote-t").val()); if (qtr) obj.quoteTr = qtr; if (qt) obj.quoteT = qt; var tplName = li.find(".wiktku-dfn-quote-src-sel").val(); if (tplName === "__manual__") { var manual = $.trim(li.find(".wiktku-dfn-quote-src-manual").val()); if (manual) obj.jederManual = manual; } else if (tplName) { obj.jederTpl = tplName; var fields = {}; li.find(".wiktku-dfn-quote-src-input").each(function () { var k = $(this).attr("data-field-key"); var v = $.trim($(this).val()); if (k && v) fields[k] = v; }); obj.jêderFields = fields; } items.push(obj); }); return items; } senses.push({ tpl: tpl, tplNoLang: tplNoLang, tplTitle: tplTitle, mane: mane, etiket: etiket, nimune: readNimuneList(), jeder: readJederList(), alternativ: readList("wiktku-dfn-alternativ"), hevmane: readList("wiktku-dfn-hevmane"), dijmane: readList("wiktku-dfn-dijmane"), koordine: readList("wiktku-dfn-koordine"), jornav: readList("wiktku-dfn-jornav"), jernav: readList("wiktku-dfn-jernav") }); }); return senses; }, getOutput: function (values, callback) { var stepDiv = $("#wiktku-start-dfn"); var senses = steps.dfn.getSenses(stepDiv); var lang = values.lang; // A sense counts as "filled" if it has a mane, a chosen template + title, // or any other content (etîket/hevmane/nimûne/jêder…) worth keeping. var hasMane = senses.some(function (s) { return s.mane !== "" || (s.tpl && s.tplTitle) || senseHasExtraContent(s); }); // True only when at least one sense has a regular mane (needs linkify). var hasRegularMane = senses.some(function (s) { return !s.tpl && s.mane !== ""; }); // nimûne and jêder lines must never pass through linkify — only // the plain mane text should be linkified. We build two parallel // arrays: defLines (sent to linkify) and citeLines (kept aside). // Each entry in citeLines corresponds 1-to-1 with a defLines entry; // a template token {{wiktku-cite-N}} is embedded in defLines so // that after linkify runs we know exactly where to splice them back. // Template-call syntax is guaranteed safe: linkifiers leave {{ }} // tokens completely untouched. var defLines = []; // one entry per kept sense (goes to linkify) var citeLines = []; // parallel — nimûne+jêder for that same sense $.each(senses, function (_, sense) { // — Template sense (e.g. {{guharto|ku|somepage}}) — if (sense.tpl) { if (!sense.tplTitle) return; // skip empty template senses var tplLabelTpl = ""; if (sense.etiket && sense.etiket.length) { var tplLabelParts = sense.etiket.map(function (part) { return $.trim(part); }).filter(function (part) { return part !== ""; }); if (tplLabelParts.length) { tplLabelTpl = " {{e|" + lang + "|" + tplLabelParts.join("|") + "}} "; } } var tplCall = sense.tplNoLang ? "{{" + sense.tpl + "|" + sense.tplTitle + "}}" : "{{" + sense.tpl + "|" + lang + "|" + sense.tplTitle + "}}"; var tplHasJeder = sense.jeder && $.grep(sense.jeder, function (j) { return j && j.quote; }).length > 0; var idx = defLines.length; var cite = formatNimune(sense.nimune, lang, tplHasJeder) + formatJeder(sense.jeder, lang); defLines.push("#" + (tplLabelTpl ? tplLabelTpl : " ") + tplCall + (cite ? "{{wiktku-cite-" + idx + "}}" : "")); citeLines.push(cite); return; } // — Normal mane sense — var dfn = sense.mane; if (!dfn && !senseHasExtraContent(sense)) return; // truly empty if (dfn) { dfn = stripWikilinks(dfn); if (dfn[0] !== dfn[0].toUpperCase()) dfn = capitalize(dfn); if (!dfn.match(/[.…?!)\]]$/)) dfn += "."; } else { dfn = "{{mane?|" + lang + "}}"; } var labelTpl = ""; if (sense.etiket && sense.etiket.length) { var labelParts = sense.etiket.map(function (part) { return $.trim(part); }).filter(function (part) { return part !== ""; }); if (labelParts.length) { labelTpl = " {{e|" + lang + "|" + labelParts.join("|") + "}} "; } } var out = "#" + (labelTpl ? labelTpl : " ") + dfn; function wordLine(tpl, words) { if (!words.length) return ""; return "\n#: {{" + tpl + "|" + lang + "|" + words.join("|") + "}}"; } out += wordLine("alt-r", sense.alternativ); out += wordLine("hevmane", sense.hevmane); out += wordLine("dijmane", sense.dijmane); out += wordLine("koordîne", sense.koordine); out += wordLine("jornav", sense.jornav); out += wordLine("jêrnav", sense.jernav); var hasJeder = sense.jeder && $.grep(sense.jeder, function (j) { return j && j.quote; }).length > 0; var cite = formatNimune(sense.nimune, lang, hasJeder) + formatJeder(sense.jeder, lang); var idx = defLines.length; defLines.push(out + (cite ? "{{wiktku-cite-" + idx + "}}" : "")); citeLines.push(cite); }); // Splice citeLines back into a linkified string, replacing each // {{wiktku-cite-N}} token with its stored nimûne/jêder block. function restoreCites(t) { return t.replace(/\{\{wiktku-cite-(\d+)\}\}/g, function (_, n) { return citeLines[parseInt(n, 10)] || ""; }); } var text = defLines.join("\n") + "\n"; if (!hasMane) { // No definitions entered — emit {{mane?}} with bênimûne. text = "# {{mane?|" + lang + "}}\n#* {{bênimûne|" + lang + "}}\n"; callback(text); return; } if (!hasRegularMane) { // All filled senses are template senses — no linkify needed. callback(restoreCites(text)); return; } var didTryToLoad = function () { if (typeof $.wiktviLinkify === "function") { $.wiktviLinkify(text, function (linked) { callback(restoreCites(linked)); }); } else { callback(restoreCites(text)); } }; mw.loader.using("ext.gadget.linkify", didTryToLoad, didTryToLoad); } }, je: makeWordListStep("je", "jê", "Kelîmeyên jê çêbûyî binivîse", "Jê", "g"), tekildar: makeWordListStep("tekildar", "têkildar", "Kelîmeyên ji aliyê etîmolojiyê ve têkildarî vê kelîmeyê binivîse", "Têkildar", "g"), binereherwiha: makeWordListStep("binereherwiha", "binêre herwiha", "Kelîmeyên din ên eleqedar binivîse", "Binêre herwiha", "g"), etym: { id: "etym", name: "etîmolojî", question_fmt: "Etîmolojiya kelîmeyê binivîse", // etymTpls populated from data.json etymTpls: [], visible: function (values) { return values.lang && values.pos; }, /** Fills (or refills) the insert-dropdown from the current etymTpls array. */ refreshTplSelect: function () { var sel = $("#wiktku-start-etym .wiktku-tpl-insert-select"); if (!sel.length) return; sel.find("option[value!='']").remove(); $.each(steps.etym.etymTpls, function (_, tpl) { sel.append($("<option></option>").val(tpl.snippet).text(tpl.name + " — " + tpl.desc)); }); // Notify Chosen that the option list has changed (no-op on mobile). if (!isMobile) sel.trigger("chosen:updated"); }, build: function (stepDiv) { if (stepDiv.find(".wiktku-etym-wrap").length) return null; var wrap = $("<div class='wiktku-etym-wrap'></div>"); var ta = $("<textarea></textarea>") .attr("name", "wiktku-etym-" + $.now()) .attr("class", "wiktku-start-step-field wiktku-etym-text") .attr("rows", 4) .attr("placeholder", "Nimûne: Ji {{ji|en|ku|apple}}. yan rasterast binivîse…"); // Template insert dropdown — options also refreshed after data.json loads. var sel = $("<select class='wiktku-tpl-insert-select'></select>"); sel.append($("<option value=''>— şablonek lê zêde bike —</option>")); $.each(steps.etym.etymTpls, function (_, tpl) { sel.append($("<option></option>").val(tpl.snippet).text(tpl.name + " — " + tpl.desc)); }); sel.on("change", function () { var snippet = $(this).val(); if (!snippet) return; var lang = getValues().lang || ""; snippet = snippet.replace(/CODE/g, lang).replace(/SOURCELANG/g, "?"); insertAtCursor(ta[0], snippet); $(this).val(""); ta.focus(); }); wrap.append(sel).append($("<br>")).append(ta); stepDiv.append(wrap); return ta; }, output: function (values) { var text = $.trim($("#wiktku-start-etym .wiktku-etym-text").val()); if (text) { return "\n==== Etîmolojî ====\n" + text + "\n"; } // No etymology entered — emit {{ji?|lang}} as a placeholder, // but only when the entry has at least one regular (non-şablon) // sense with content — either real mane text, or an empty mane // with other fields filled in (which dfn.getOutput() renders as // {{mane?|lang}} with those fields attached). A şablon sense // like {{guharto|…}} never counts, filled in or not. var dfnSenses = steps.dfn.getSenses($("#wiktku-start-dfn")); var hasRegularMane = dfnSenses.some(function (s) { return !s.tpl && (s.mane !== "" || senseHasExtraContent(s)); }); if (!hasRegularMane) return ""; return "\n==== Etîmolojî ====\n{{ji?|" + values.lang + "}}\n"; } }, dunde: { id: "dunde", name: "dûnde", question_fmt: "Eger ev kelîme ji vî zimanî ketibe zimanekî din, vî zimanî û kelîmeya wî binivîse", visible: function (values) { return !!values.pos; }, disabledKeys: { "navz": true}, /** * Builds one row: a language dropdown + a growing list of word * inputs. When the dropdown gets a value the next empty row is * appended automatically. Mirrors steps.trans's row widget, but * flat (one shared list — dûnde isn't tied to individual senses). */ buildRow: function (stepDiv) { var row = $("<li class='wiktku-dunde-row wiktku-lang-row'></li>"); // Language selector — chosen is applied after insertion into DOM. var langSel = $(mw.html.element("select", { "class": "wiktku-start-step-keyfield wiktku-start-narrow" })); langSel.attr("data-placeholder", "Zimanekî lê bigere"); populateMenus(langSel, steps.dunde.keys || [], steps.dunde.disabledKeys); // When a language is chosen, ensure a next empty row exists. langSel.on("change", function () { steps.dunde.onLangChange(stepDiv, row); }); // Word list for this language. var wordList = $("<ul class='wiktku-dunde-words wiktku-lang-row-words'></ul>"); var firstWord = steps.dunde.makeWordInput(); wordList.append($("<li></li>").append(firstWord)); if (isMobile) { row.append(wrapNativeSelect(langSel)).append(wordList); } else { row.append(langSel).append(wordList); } return row; }, makeWordInput: function () { var input = $("<textarea></textarea>") .attr("name", "wiktku-dunde-word-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 1) .attr("class", "wiktku-dfn-subfield wiktku-start-narrow") .attr("placeholder", "Kelîme…"); input.on("input", function () { var list = $(this).closest("ul.wiktku-dunde-words"); var item = $(this).parent(); var val = $.trim($(this).val()); if (val && item.is(list.children("li:last-child"))) { var next = steps.dunde.makeWordInput(); list.append($("<li></li>").append(next)); } }); return input; }, onLangChange: function (stepDiv, row) { var list = stepDiv.find("ul.wiktku-dunde-list"); var isLast = row.is(list.children("li.wiktku-dunde-row:last-child")); if (isLast) { var newRow = steps.dunde.buildRow(stepDiv); list.append(newRow); // Init chosen after the new row is in the DOM (desktop only). if (!isMobile) newRow.find("select").chosen(chosenOptions); } // Keep disabled keys in sync across all lang selectors. steps.dunde.syncDisabledKeys(stepDiv); }, /** Disables already-selected languages in all other dropdowns. */ syncDisabledKeys: function (stepDiv) { var taken = $.extend({}, steps.dunde.disabledKeys); stepDiv.find("li.wiktku-dunde-row select").each(function () { var v = $(this).val(); if (v) taken[v] = true; }); stepDiv.find("li.wiktku-dunde-row select").each(function () { var self = $(this); var own = self.val(); self.find("option").each(function () { var code = $(this).val(); if (!code) return; $(this).prop("disabled", taken[code] && code !== own); }); self.trigger("chosen:updated"); }); }, build: function (stepDiv) { if (stepDiv.find("ul.wiktku-dunde-list").length) return null; var list = $("<ul class='wiktku-dunde-list wiktku-lang-row-list'></ul>"); list.append(steps.dunde.buildRow(stepDiv)); stepDiv.append(list); // Init chosen after the select is in the DOM (desktop only). if (!isMobile) list.find("select").chosen(chosenOptions); return null; }, /** Reads all [langcode, words[]] rows from the DOM. */ getRows: function (stepDiv) { var result = []; stepDiv.find("li.wiktku-dunde-row").each(function () { var lang = $(this).find("select").val(); if (!lang) return; var words = []; $(this).find("ul.wiktku-dunde-words textarea").each(function () { var v = $.trim($(this).val()); if (v) words.push(v); }); if (words.length) result.push([lang, words]); }); return result; }, output: function () { var stepDiv = $("#wiktku-start-dunde"); var rows = steps.dunde.getRows(stepDiv); if (!rows.length) return ""; var lines = $.map(rows, function (row) { var lang = row[0], words = row[1]; return "* {{dû|" + lang + "|" + words.join("|") + "}}"; }); return "\n==== Dûnde ====\n" + lines.join("\n") + "\n"; } }, zarava: { id: "zarava", name: "bi zaravayên din", visible: function (values) { return steps.trans.visible(values); }, disabledKeys: { "navz": true }, buildRow: function (group) { var row = $("<li class='wiktku-zarava-row wiktku-lang-row'></li>"); var langSel = $(mw.html.element("select", { "class": "wiktku-start-step-keyfield wiktku-start-narrow" })); populateMenus(langSel, steps.zarava.keys || [], steps.zarava.disabledKeys); langSel.on("change", function () { steps.zarava.onLangChange(group, row); }); var wordList = $("<ul class='wiktku-zarava-words wiktku-lang-row-words'></ul>"); var firstWord = steps.zarava.makeWordInput(); wordList.append($("<li></li>").append(firstWord)); row.append(langSel).append(wordList); return row; }, makeWordInput: function () { var input = $("<textarea></textarea>") .attr("name", "wiktku-zarava-word-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 1) .attr("class", "wiktku-dfn-subfield wiktku-start-narrow") .attr("placeholder", "Tercime…"); input.on("input", function () { var list = $(this).closest("ul.wiktku-zarava-words"); var item = $(this).parent(); var val = $.trim($(this).val()); if (val && item.is(list.children("li:last-child"))) { var next = steps.zarava.makeWordInput(); list.append($("<li></li>").append(next)); } }); return input; }, onLangChange: function (group, row) { var list = group.find("ul.wiktku-zarava-list"); var isLast = row.is(list.children("li.wiktku-zarava-row:last-child")); if (isLast) { var newRow = steps.zarava.buildRow(group); list.append(newRow); } steps.zarava.syncDisabledKeys(group); }, /** Disables already-selected dialects in all other dropdowns within one group. */ syncDisabledKeys: function (group) { var taken = $.extend({}, steps.zarava.disabledKeys); group.find("li.wiktku-zarava-row select").each(function () { var v = $(this).val(); if (v) taken[v] = true; }); group.find("li.wiktku-zarava-row select").each(function () { var self = $(this); var own = self.val(); self.find("option").each(function () { var code = $(this).val(); if (!code) return; $(this).prop("disabled", taken[code] && code !== own); }); }); }, /** Builds (or fetches) the .wiktku-zarava-group for one gloss. */ buildGroup: function (stepDiv, gi) { var group = $("<div class='wiktku-zarava-group'></div>").attr("data-gloss-pos", gi); var list = $("<ul class='wiktku-zarava-list wiktku-lang-row-list'></ul>"); list.append(steps.zarava.buildRow(group)); group.append(list); stepDiv.append(group); return group; }, /** Syncs one .wiktku-zarava-group per current gloss (same logic as steps.trans.build). */ build: function (stepDiv) { var glosses = steps.trans.glossList(); if (!glosses.length) { stepDiv.find(".wiktku-zarava-group").remove(); return null; } var existingGroups = stepDiv.find(".wiktku-zarava-group"); if (existingGroups.length > glosses.length) { existingGroups.slice(glosses.length).remove(); } $.each(glosses, function (gi, gloss) { var group = stepDiv.find(".wiktku-zarava-group[data-gloss-pos='" + gi + "']"); if (!group.length) group = steps.zarava.buildGroup(stepDiv, gi); var label = group.find(".wiktku-zarava-group-label"); if (glosses.length > 1) { if (!label.length) { label = $("<div class='wiktku-zarava-group-label'></div>"); group.prepend(label); } label.text(gloss.index + " " + gloss.text); } else if (label.length) { label.remove(); } }); return null; }, /** Reads the dialect rows for a single gloss group. */ getGroupTranslations: function (group) { var result = []; group.find("li.wiktku-zarava-row").each(function () { var lang = $(this).find("select").val(); if (!lang) return; var words = []; $(this).find("ul.wiktku-zarava-words textarea").each(function () { var v = $.trim($(this).val()); if (v) words.push(v); }); if (words.length) result.push([lang, words]); }); return result; }, /** Reads all rows from the DOM, grouped by gloss position. */ getTranslations: function (stepDiv) { var result = []; stepDiv.find(".wiktku-zarava-group").each(function () { result.push(steps.zarava.getGroupTranslations($(this))); }); return result; }, output: function (values) { if (values.lang !== "ku") return ""; var stepDiv = $("#wiktku-start-zarava"); var glosses = steps.trans.glossList(); if (!glosses.length) return ""; var blocks = $.map(glosses, function (gloss, gi) { var group = stepDiv.find(".wiktku-zarava-group[data-gloss-pos='" + gi + "']"); var rows = group.length ? steps.zarava.getGroupTranslations(group) : []; if (!gloss.text && !rows.length) return undefined; if (rows.length) { rows.sort(function (a, b) { var aLang = langsByCode[a[0]] || []; var bLang = langsByCode[b[0]] || []; return (aLang[2] || "").localeCompare(bLang[2] || "", "ku"); }); } var wordLines = $.map(rows, function (row) { var lang = row[0]; var words = row[1]; var wikiWords = words.map(function (w) { return "{{W|" + lang + "|" + w + "}}"; }).join(", "); return "* {{Z|" + lang + "}}: " + wikiWords; }).join("\n"); if (!wordLines) return undefined; var block = "{{werger-ser|" + (gloss.text || "?") + "|" + gloss.index + "}}"; block += "\n" + wordLines; block += "\n{{werger-bin}}"; return block; }); if (!blocks.length) return ""; return "\n==== Bi zaravayên din ====\n" + blocks.join("\n") + "\n"; } }, trans: { id: "trans", name: "werger", visible: function (values) { if (!(values.lang === "ku" && values.pos)) return false; // Hide Werger only when EVERY sense is a template sense (Guharto etc.) // with a title filled in — i.e. there is real content but no plain // gloss to attach a translation table to. A mix of real + template // senses still shows Werger; the template senses are simply skipped // in output(). // // "Real" here means a non-şablon sense with either mane text or // other filled-in fields (etîket/hevmane/nimûne/jêder…), since // dfn.getOutput() renders the latter too, as {{mane?|lang}} plus // whatever else was filled in. // // When nothing has been filled in at all, output() will emit // {{mane?|lang}} instead of a gloss — but Werger should still show, // since the user may want to add translations before they've // settled on a gloss. var dfnSenses = steps.dfn.getSenses($("#wiktku-start-dfn")); var hasRealSense = dfnSenses.some(function (s) { return !s.tpl && (s.mane !== "" || senseHasExtraContent(s)); }); var hasFilledTplSense = dfnSenses.some(function (s) { return s.tpl && s.tplTitle; }); return hasRealSense || !hasFilledTplSense; }, disabledKeys: { "navz": true, "ku": true, "ckb": true, "sdh": true, "lki": true, "hac": true, "zza": true }, /** * Builds one translation row: a language dropdown + a growing list * of word inputs. When the dropdown gets a value the next empty row * is appended automatically. * * @param group the specific .wiktku-trans-group this row belongs to * (each gloss has its own group and its own list of rows, so the * lookups below must stay scoped to that group rather than the * whole step — the step now holds one list per gloss). */ buildRow: function (group) { var row = $("<li class='wiktku-trans-row wiktku-lang-row'></li>"); // Language selector — chosen is applied after insertion into DOM. var langSel = $(mw.html.element("select", { "class": "wiktku-start-step-keyfield wiktku-start-narrow" })); langSel.attr("data-placeholder", "Zimanekî lê bigere"); populateMenus(langSel, steps.trans.keys || [], steps.trans.disabledKeys); // When a language is chosen, ensure a next empty row exists. langSel.on("change", function () { steps.trans.onLangChange(group, row); }); // Word list for this language. var wordList = $("<ul class='wiktku-trans-words wiktku-lang-row-words'></ul>"); var firstWord = steps.trans.makeWordInput(); wordList.append($("<li></li>").append(firstWord)); if (isMobile) { row.append(wrapNativeSelect(langSel)).append(wordList); } else { row.append(langSel).append(wordList); } return row; }, makeWordInput: function () { var input = $("<textarea></textarea>") .attr("name", "wiktku-trans-word-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 1) .attr("class", "wiktku-dfn-subfield wiktku-start-narrow") .attr("placeholder", "Tercime…"); input.on("input", function () { var list = $(this).closest("ul.wiktku-trans-words"); var item = $(this).parent(); var val = $.trim($(this).val()); if (val && item.is(list.children("li:last-child"))) { var next = steps.trans.makeWordInput(); list.append($("<li></li>").append(next)); } }); return input; }, onLangChange: function (group, row) { var list = group.find("ul.wiktku-trans-list"); var isLast = row.is(list.children("li.wiktku-trans-row:last-child")); if (isLast) { var newRow = steps.trans.buildRow(group); list.append(newRow); // Init chosen after the new row is in the DOM (desktop only). if (!isMobile) newRow.find("select").chosen(chosenOptions); } // Keep disabled keys in sync across this gloss's lang selectors // only — the same language can be used for different senses. steps.trans.syncDisabledKeys(group); }, /** Disables already-selected languages in all other dropdowns within one group. */ syncDisabledKeys: function (group) { var taken = $.extend({}, steps.trans.disabledKeys); group.find("li.wiktku-trans-row select").each(function () { var v = $(this).val(); if (v) taken[v] = true; }); group.find("li.wiktku-trans-row select").each(function () { var self = $(this); var own = self.val(); self.find("option").each(function () { var code = $(this).val(); if (!code) return; $(this).prop("disabled", taken[code] && code !== own); }); self.trigger("chosen:updated"); }); }, /** * Builds (or fetches) the .wiktku-trans-group for one gloss, with * its own label and its own list of translation rows. */ buildGroup: function (stepDiv, gi) { var group = $("<div class='wiktku-trans-group'></div>").attr("data-gloss-pos", gi); var list = $("<ul class='wiktku-trans-list wiktku-lang-row-list'></ul>"); list.append(steps.trans.buildRow(group)); group.append(list); stepDiv.append(group); // Init chosen after the select is in the DOM (desktop only). if (!isMobile) list.find("select").chosen(chosenOptions); return group; }, /** * Syncs one .wiktku-trans-group per current gloss, adding new * groups and removing stale ones as senses are added or removed, * while leaving existing groups (and whatever translations the * user has already typed into them) untouched. Groups are keyed * to their gloss's position in glossList() via data-gloss-pos, so * a group always matches the same sense across rebuilds as long * as senses aren't reordered relative to each other. */ build: function (stepDiv) { var glosses = steps.trans.glossList(); if (!glosses.length) { stepDiv.find(".wiktku-trans-group").remove(); return null; } // Drop groups for glosses that no longer exist (always from the // tail — groups are only ever appended in gloss order below). var existingGroups = stepDiv.find(".wiktku-trans-group"); if (existingGroups.length > glosses.length) { existingGroups.slice(glosses.length).remove(); } $.each(glosses, function (gi, gloss) { var group = stepDiv.find(".wiktku-trans-group[data-gloss-pos='" + gi + "']"); if (!group.length) group = steps.trans.buildGroup(stepDiv, gi); // Only label groups when there's more than one gloss to // distinguish between — a single gloss needs no caption. var label = group.find(".wiktku-trans-group-label"); if (glosses.length > 1) { if (!label.length) { label = $("<div class='wiktku-trans-group-label'></div>"); group.prepend(label); } label.text(gloss.index + " " + gloss.text); } else if (label.length) { label.remove(); } }); return null; }, /** Reads the translation rows for a single gloss group. */ getGroupTranslations: function (group) { var result = []; group.find("li.wiktku-trans-row").each(function () { var lang = $(this).find("select").val(); if (!lang) return; var words = []; $(this).find("ul.wiktku-trans-words textarea").each(function () { var v = $.trim($(this).val()); if (v) words.push(v); }); if (words.length) result.push([lang, words]); }); return result; }, /** * Reads all translation rows from the DOM, grouped by gloss * position — one array of [lang, words] rows per gloss group, in * the same order as the .wiktku-trans-group elements. */ getTranslations: function (stepDiv) { var result = []; stepDiv.find(".wiktku-trans-group").each(function () { result.push(steps.trans.getGroupTranslations($(this))); }); return result; }, /** * Builds the numbered "{ index, gloss }" list — one entry per dfn * sense that has a real mane (skips template senses like Guharto, * which have nothing to caption a translation table with). The * index matches the sense's actual position in the numbered "#" * definition list (1-based), including template senses in the count, * so the number printed next to {{werger-ser}} lines up with the * gloss the reader sees in the entry. * * When nothing has been filled in at all (dfn.getOutput() will emit * {{mane?|lang}} as sense 1), this returns a single placeholder * entry with empty text instead of an empty array, so Werger still * has one group to attach translations to before a gloss exists. * When every filled sense is a template sense instead, this stays * empty — that mirrors trans.visible()'s hidden case, where there's * no group in the DOM for a placeholder to attach to anyway. */ glossList: function () { var dfnSenses = steps.dfn.getSenses($("#wiktku-start-dfn")); var glosses = []; var hasFilledTplSense = false; $.each(dfnSenses, function (i, s) { if (s.tpl) { if (s.tplTitle) hasFilledTplSense = true; return; // template sense — no gloss to caption with } var dfn = s.mane; if (!dfn) { // No mane text, but other fields (etîket/hevmane/nimûne/ // jêder…) are filled — dfn.getOutput() still emits this // sense as a numbered line using {{mane?|lang}}, so it // needs its own gloss group too, just with no caption text. if (senseHasExtraContent(s)) glosses.push({ index: i + 1, text: "" }); return; } if (dfn[0] !== dfn[0].toLowerCase()) dfn = decapitalize(dfn); dfn = stripWikilinks(dfn).replace(/[.…?!)\]،؟]+$/, ""); glosses.push({ index: i + 1, text: dfn }); }); if (!glosses.length && !hasFilledTplSense) { glosses.push({ index: 1, text: "" }); } return glosses; }, output: function (values) { if (values.lang !== "ku") return ""; var stepDiv = $("#wiktku-start-trans"); var glosses = steps.trans.glossList(); // Every sense is a template sense — there's no real gloss // anywhere and no group in the DOM either (glossList() only // returns empty in that case), so skip the section entirely. if (!glosses.length) return ""; // Each gloss now has its own group of translation rows — // attach every gloss's own words under its own werger-ser/-bin // pair instead of dumping everything under the first one. var blocks = $.map(glosses, function (gloss, gi) { var group = stepDiv.find(".wiktku-trans-group[data-gloss-pos='" + gi + "']"); var rows = group.length ? steps.trans.getGroupTranslations(group) : []; // Placeholder gloss (no real mane entered yet) with nothing // translated into it — nothing to output, and gloss.text is // empty so there's no caption to give {{werger-ser}} anyway. if (!gloss.text && !rows.length) return undefined; if (rows.length) { // Sort by Kurdish sort key. rows.sort(function (a, b) { var aLang = langsByCode[a[0]] || []; var bLang = langsByCode[b[0]] || []; return (aLang[2] || "").localeCompare(bLang[2] || "", "ku"); }); } var wordLines = $.map(rows, function (row) { var lang = row[0]; var words = row[1]; var wikiWords = words.map(function (w) { return "{{W|" + lang + "|" + w + "}}"; }).join(", "); return "* {{Z|" + lang + "}}: " + wikiWords; }).join("\n"); var block = "{{werger-ser|" + (gloss.text || "?") + "|" + gloss.index + "}}"; if (wordLines) block += "\n" + wordLines; block += "\n{{werger-bin}}"; return block; }); if (!blocks.length) return ""; return "\n==== Werger ====\n" + blocks.join("\n") + "\n"; } }, }; steps.trans.keys = steps.lang.choices; steps.dunde.keys = steps.lang.choices; steps.zarava.keys = getZaravaKeys(steps.lang.choices); var ordered_steps = [ steps.lang, steps.pron, steps.pos, steps.cinsiyet, steps.lektur, steps.tr, steps.dfn, steps.je, steps.tekildar, steps.etym, steps.dunde, steps.binereherwiha, steps.zarava, steps.trans]; // Step ids that belong to each section (not shared across sections). var PER_SECTION_STEP_IDS = [ "pos", "cinsiyet", "lektur", "tr", "dfn", "je", "tekildar", "etym", "dunde", "binereherwiha", "zarava", "trans" ]; // ── Multi-section state ────────────────────────────────────────────────── // Each entry is a plain snapshot: { pos, cinsiyet, lektur, tr, dfn (senses[]), // je, tekildar, binereherwiha, trans (rows[]) }. var sections = [{}]; // section 0 starts empty (DOM is the truth) var activeSection = 0; function snapshotDfn() { return steps.dfn.getSenses($("#wiktku-start-dfn")); } /** * Rebuild the dfn DOM from a previously snapshotted senses array. */ function restoreDfn(senses) { var stepDiv = $("#wiktku-start-dfn"); // Tear down the existing list so build() recreates it cleanly. stepDiv.find("ol.wiktku-dfn-list").remove(); steps.dfn.build(stepDiv); var list = stepDiv.find("ol.wiktku-dfn-list"); $.each(senses, function (i, sense) { // Ensure enough blocks exist (build() seeds one). var blocks = list.find("li.wiktku-dfn-sense"); var block = blocks.eq(i); if (!block.length) { var nb = steps.dfn.buildSenseBlock(stepDiv); list.append(nb); block = list.find("li.wiktku-dfn-sense").last(); } // Template selector. block.find("select.wiktku-dfn-tpl-select").val(sense.tpl || ""); if (sense.tpl) { block.find("textarea.wiktku-dfn-mane").hide(); block.find("input.wiktku-dfn-tpl-title").val(sense.tplTitle || "").show(); } else { block.find("textarea.wiktku-dfn-mane").val(sense.mane || "").show(); block.find("input.wiktku-dfn-tpl-title").hide().val(""); } // Re-sync the formên alternatîv/hevmane/… hide state now that // tplSelect's value was set programmatically (its own "change" // handler doesn't fire from .val(), so this doesn't happen otherwise). var updateVis = block.data("updateFieldVisibility"); if (updateVis) updateVis(); // Restore a sub-list (etiket, formên alternatîv, hevmane …) from a values array. function restoreSubList(cls, values) { if (!values || !values.length) return; var groupDiv = block.find("." + cls + "-group"); var subList = groupDiv.find("ol, ul").first(); if (!subList.length) return; // group not found // Fill existing items, append new ones as needed. $.each(values, function (j, val) { var items = subList.find("li"); if (j < items.length) { items.eq(j).find("textarea").val(val); } else { var ta = $("<textarea></textarea>") .attr("name", "wiktku-dfn-restore-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 1) .attr("class", "wiktku-dfn-subfield wiktku-start-narrow") .val(val); ta.on("input", function () { steps.dfn.onSubInput(subList, this, 1, true); }); subList.append($("<li></li>").append(ta)); } }); } // Reveal and populate lazy groups that have data. var lazyMap = { "wiktku-dfn-etiket": sense.etiket, "wiktku-dfn-alternativ": sense.alternativ, "wiktku-dfn-hevmane": sense.hevmane, "wiktku-dfn-dijmane": sense.dijmane, "wiktku-dfn-koordine": sense.koordine, "wiktku-dfn-jornav": sense.jornav, "wiktku-dfn-jernav": sense.jernav }; $.each(lazyMap, function (cls, vals) { if (vals && vals.length) restoreSubList(cls, vals); }); // Nimûne items are objects { text, tr?, t? } — restore using the builder. if (sense.nimune && sense.nimune.length) { var nimuneGroupDiv = block.find(".wiktku-dfn-nimune-group"); var nimuneList = nimuneGroupDiv.find("ol.wiktku-dfn-nimune-list"); var buildFn = nimuneGroupDiv.data("buildNimuneLi"); nimuneList.empty(); $.each(sense.nimune, function (_, n) { var text = typeof n === "object" ? (n.text || "") : n; if (!text) return; var li = buildFn ? buildFn() : $("<li class='wiktku-dfn-nimune-li'></li>"); li.find(".wiktku-dfn-nimune-text").val(text); if (n.tr) li.find(".wiktku-dfn-nimune-tr").val(n.tr); if (n.t) li.find(".wiktku-dfn-nimune-t").val(n.t); nimuneList.append(li); }); // Always leave a blank trailing item. if (buildFn) nimuneList.append(buildFn()); } // Restore jêder (quote/citation) entries — a growing list, restored using the // builder just like Nimûne. Accepts either the current array shape or a // single legacy object (from older saved sections) for backwards compatibility. var jederArr = $.isArray(sense.jeder) ? sense.jeder : (sense.jeder ? [sense.jeder] : []); if (jederArr.length) { var jederGroupDiv = block.find(".wiktku-dfn-jeder-group"); var jederList = jederGroupDiv.find("ol.wiktku-dfn-jeder-list"); var buildJederFn = jederGroupDiv.data("buildJederLi"); jederList.empty(); $.each(jederArr, function (_, j) { if (!j || !j.quote) return; var li = buildJederFn ? buildJederFn() : $("<li class='wiktku-dfn-jeder-li'></li>"); li.find(".wiktku-dfn-nimune-quote").val(j.quote); if (j.quoteTr) li.find(".wiktku-dfn-nimune-quote-tr").val(j.quoteTr); if (j.quoteT) li.find(".wiktku-dfn-nimune-quote-t").val(j.quoteT); if (j.jederManual) { var manualSel = li.find(".wiktku-dfn-quote-src-sel"); manualSel.val("__manual__").trigger("change"); li.find(".wiktku-dfn-quote-src-manual").val(j.jederManual); } else if (j.jederTpl) { var srcSel = li.find(".wiktku-dfn-quote-src-sel"); srcSel.val(j.jederTpl).trigger("change"); if (j.jêderFields) { $.each(j.jêderFields, function (key, val) { li.find(".wiktku-dfn-quote-src-input[data-field-key='" + key + "']").val(val); }); } } jederList.append(li); }); // Always leave a blank trailing item, same as Nimûne. if (buildJederFn) jederList.append(buildJederFn()); } }); } /** * Snapshot simple (non-dfn) per-section steps from current DOM into obj. */ function saveCurrentSection() { var snap = {}; $.each(PER_SECTION_STEP_IDS, function (_, id) { if (id === "dfn") { snap.dfn = snapshotDfn(); return; } if (id === "etym") { snap.etym = $.trim($("#wiktku-start-etym .wiktku-etym-text").val()); return; } var step = steps[id]; if (!step) return; var stepDiv = $("#wiktku-start-" + id); if (id === "trans") { snap.trans = steps.trans.getTranslations(stepDiv); return; } if (id === "zarava") { snap.zarava = steps.zarava.getTranslations(stepDiv); return; } if (id === "dunde") { snap.dunde = steps.dunde.getRows(stepDiv); return; } // Generic: read all step fields. var fields = stepDiv.find(".wiktku-start-step-field"); if (step.multiple) { snap[id] = fields.map(function () { return $(this).val(); }).get(); } else { snap[id] = fields.val(); } }); sections[activeSection] = snap; } /** * Restore a previously saved snapshot into the form DOM. */ function restoreSection(snap) { $.each(PER_SECTION_STEP_IDS, function (_, id) { if (id === "dfn") { restoreDfn(snap.dfn || []); return; } if (id === "etym") { $("#wiktku-start-etym .wiktku-etym-wrap").remove(); steps.etym.build($("#wiktku-start-etym")); $("#wiktku-start-etym .wiktku-etym-text").val(snap.etym || ""); return; } if (id === "trans") { // Rebuild trans groups (dfn must already be restored by this // point in the $.each loop, so glossList() reflects it). var transDiv = $("#wiktku-start-trans"); transDiv.find(".wiktku-trans-group").remove(); steps.trans.build(transDiv); var groupsSnap = snap.trans || []; $.each(groupsSnap, function (gi, rows) { var group = transDiv.find(".wiktku-trans-group[data-gloss-pos='" + gi + "']"); if (!group.length) return; // gloss no longer exists — drop its rows var list = group.find("ul.wiktku-trans-list"); $.each(rows, function (j, row) { var lang = row[0], words = row[1]; var lastRow = list.find("li.wiktku-trans-row").last(); lastRow.find("select").val(lang).trigger("change"); var wordList = lastRow.find("ul.wiktku-trans-words"); $.each(words, function (k, word) { var wordItems = wordList.find("li"); if (k < wordItems.length) { wordItems.eq(k).find("textarea").val(word); } else { // .val() below doesn't fire "input", so the normal // auto-grow never runs — append a matching item // ourselves instead of silently dropping the word. var extraInput = steps.trans.makeWordInput(); wordList.append($("<li></li>").append(extraInput)); extraInput.val(word); } }); // Leave one trailing empty field so the row can still grow // when the user types, matching a freshly-built row. if ($.trim(wordList.children("li").last().find("textarea").val())) { wordList.append($("<li></li>").append(steps.trans.makeWordInput())); } }); }); return; } if (id === "zarava") { // Rebuild zarava groups (dfn must already be restored by this // point in the $.each loop, so glossList() reflects it). var zaravaDiv = $("#wiktku-start-zarava"); zaravaDiv.find(".wiktku-zarava-group").remove(); steps.zarava.build(zaravaDiv); var zaravaGroupsSnap = snap.zarava || []; $.each(zaravaGroupsSnap, function (gi, rows) { var group = zaravaDiv.find(".wiktku-zarava-group[data-gloss-pos='" + gi + "']"); if (!group.length) return; // gloss no longer exists — drop its rows var list = group.find("ul.wiktku-zarava-list"); $.each(rows, function (j, row) { var lang = row[0], words = row[1]; var lastRow = list.find("li.wiktku-zarava-row").last(); lastRow.find("select").val(lang).trigger("change"); var wordList = lastRow.find("ul.wiktku-zarava-words"); $.each(words, function (k, word) { var wordItems = wordList.find("li"); if (k < wordItems.length) { wordItems.eq(k).find("textarea").val(word); } else { var extraInput = steps.zarava.makeWordInput(); wordList.append($("<li></li>").append(extraInput)); extraInput.val(word); } }); if ($.trim(wordList.children("li").last().find("textarea").val())) { wordList.append($("<li></li>").append(steps.zarava.makeWordInput())); } }); }); return; } if (id === "dunde") { // Rebuild dunde rows. var dundeDiv = $("#wiktku-start-dunde"); dundeDiv.find("ul.wiktku-dunde-list").remove(); steps.dunde.build(dundeDiv); var dundeRows = snap.dunde || []; $.each(dundeRows, function (i, row) { var lang = row[0], words = row[1]; var list = dundeDiv.find("ul.wiktku-dunde-list"); var lastRow = list.find("li.wiktku-dunde-row").last(); lastRow.find("select").val(lang).trigger("change"); var wordList = lastRow.find("ul.wiktku-dunde-words"); $.each(words, function (j, word) { var wordItems = wordList.find("li"); if (j < wordItems.length) { wordItems.eq(j).find("textarea").val(word); } else { // .val() below doesn't fire "input", so the normal // auto-grow never runs — append a matching item // ourselves instead of silently dropping the word. var extraInput = steps.dunde.makeWordInput(); wordList.append($("<li></li>").append(extraInput)); extraInput.val(word); } }); // Leave one trailing empty field so the row can still grow // when the user types, matching a freshly-built row. if ($.trim(wordList.children("li").last().find("textarea").val())) { wordList.append($("<li></li>").append(steps.dunde.makeWordInput())); } }); return; } var step = steps[id]; if (!step) return; var stepDiv = $("#wiktku-start-" + id); var fields = stepDiv.find(".wiktku-start-step-field"); var val = snap[id]; if (val === undefined || val === null) return; if (step.multiple) { var arr = val; fields.each(function (i) { if (i < arr.length) $(this).val(arr[i]); }); } else { fields.val(val); } // Notify chosen widgets of the programmatic value change. if (!isMobile) fields.filter("select").trigger("chosen:updated"); }); } function getWikitextForCurrentSection(callback) { var values = getValues(); var entry = steps.pos.output(values); steps.dfn.getOutput(values, function (output) { entry += output; entry += steps.je.output(values); entry += steps.tekildar.output(values); entry += steps.etym.output(values); entry += steps.dunde.output(values); entry += steps.binereherwiha.output(values); entry += steps.zarava.output(values); entry += steps.trans.output(values); callback(entry, values); }); } function getWikitextAllSections(callback) { saveCurrentSection(); var results = new Array(sections.length); var sharedValues = getValues(); // lang/pron are shared function processSection(i) { if (i >= sections.length) { // All done — restore original active section. restoreSection(sections[activeSection]); refresh(); callback(results, sharedValues); return; } restoreSection(sections[i]); refresh(); getWikitextForCurrentSection(function (sectionText) { results[i] = sectionText; processSection(i + 1); }); } processSection(0); } /** * Assembles wikitext for all sections plus the shared lang/pron header. */ function getWikitext(callback) { getWikitextAllSections(function (sectionTexts, sharedValues) { var entry = steps.lang.output(sharedValues); entry += steps.pron.output(sharedValues); entry += sectionTexts.join("\n"); // Edit summary uses section 0's values. Read from the saved snapshot // (not the live DOM) so it doesn't mix section 0's pos with whichever // section happens to be active/restored at this point. var dfnSenses = (sections[0] && sections[0].dfn) || []; var dfnSummary = dfnSenses.map(function (s) { return s.mane; }).filter(Boolean).join("; "); var summaryLabel = addLangMode ? "WF:Ziman lê zêde" : "WF:Nû"; var summary = "([[Mediawiki:Gadget-start.js|" + summaryLabel + "]] v.2.0) +" + sharedValues.lang + ":" + sections[0].pos + ":" + dfnSummary; var summaryField = document.getElementById("wpSummary"); if (addLangMode && summaryField.value) { summary = summaryField.value + " " + summary; } summaryField.value = summary; callback(entry); }); } var continueBtn; function getValuesForStep(stepId) { var fields = $("#wiktku-start-" + stepId + " .wiktku-start-step-field"); var step = steps[stepId]; if (step.keys) { var values = {}; fields.each(function (i, field) { var key = $(field).prevAll(".wiktku-start-step-keyfield").val(); if (key) values[key] = $(field).val(); }); return values; } else if (step.multiple) { return fields.map(function () { return $(this).val(); }).get(); } return fields.val(); } function getValues() { var values = {}; $.each(steps, function (stepId) { values[stepId] = getValuesForStep(stepId); }); return values; } function populateMenus(inputs, choices, disabledValues) { if (!disabledValues) disabledValues = {}; var vals = inputs.map(function (i, input) { return $(input).val(); }); inputs.empty(); inputs.append($("<option></option>")); $.each(choices, function (j, choice) { // Append the language code in parentheses so that typing a code // (e.g. "ku") in the search box still finds the language name. var displayText = capitalize(choice[1]); if (choice[2] !== undefined) { // This is a language choice [code, name, sortKey] — show code. displayText = capitalize(choice[1]) + " (" + choice[0] + ")"; } var option = $(mw.html.element("option", { value: choice[0] }, displayText)); if (disabledValues[choice[0]]) option.prop("disabled", true); inputs.append(option); }); inputs.val(function (i) { return vals[i]; }); } /** * Returns a bitmap containing the keys that should be disabled for a key * menu in the given step because they are disabled or already taken by * another key menu. */ function getDisabledKeys(step) { var occupiedKeys = {}; $("#wiktku-start-" + step.id + " .wiktku-start-step-keyfield").each(function () { occupiedKeys[$(this).val()] = true; }); if (step.disabledKeys) $.extend(occupiedKeys, step.disabledKeys); return occupiedKeys; } function buildKeyInput(step) { if (!step.keys) return undefined; var input = $(mw.html.element("select", { "class": "wiktku-start-step-keyfield wiktku-start-narrow" })); input.attr("data-placeholder", "Hilbijêre " + step.keyName); if (isMobile) { populateMenus(input, step.keys, getDisabledKeys(step)); // On mobile return the wrapper; the select is inside it. // Change events still fire on the inner select. return wrapNativeSelect(input); } input.on("chosen:showing_dropdown", function () { $(this).data("wiktku-defaultValue", $(this).val()); }); input.change(function (_, context) { var inputs = $("#wiktku-start-" + step.id + " .wiktku-start-step-keyfield").not(this); var oldValue = $(this).data("wiktku-defaultValue"); var newValue = context.selected; inputs.find("option[value='" + oldValue + "']").prop('disabled', false); inputs.find("option[value='" + newValue + "']").prop('disabled', true); inputs.trigger("chosen:updated"); }); populateMenus(input, step.keys, getDisabledKeys(step)); return input; } /** * If the current text field has text and there are no more text fields after * the current text field in the list, add another text field to the list. */ function refreshForTextField(currentInput, step) { currentInput = $(currentInput); var value = currentInput.val(); var item = currentInput.parent(); if (value && !item.next("li").length) { var nextInput = $("<textarea></textarea>") .attr("name", "wiktku-field-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("class", currentInput.attr("class")) .attr("rows", currentInput.attr("rows") || 1); nextInput.on("input", function (evt) { refreshForTextField(evt.target, step); }); var nextKeyInput = buildKeyInput(step); var nextItem = $("<li></li>").append(nextKeyInput).append(nextInput); item.parent().append(nextItem); if (nextKeyInput) nextKeyInput.chosen(chosenOptions); } var canContinue = !continueBtn.isDisabled(); if ((value && !canContinue) || (!value && canContinue)) { refresh(step); } } function prepareInput(input, step) { if (!input) return; if (step.required) input.prop('required', true); input.change(step, refresh); } /** * Shows and hides all the steps based on whether their prerequisites are met, * and updates placeholders where applicable. */ function refresh(evt) { var values = getValues(); var changedStep = evt && evt.data; var didFocus = false; var canContinue = true; // Re-filter template options in every sense block whenever lang changes. $("#wiktku-start-dfn .wiktku-dfn-tpl-select").each(function () { var fn = $(this).data("updateOptions"); if (typeof fn === "function") fn(); }); // Re-filter pronunciation and etymology template dropdowns when language changes. steps.pron.refreshTplSelect(); steps.etym.refreshTplSelect(); // Sync tr/t sub-fields in every nimûne item to the current language. // tr shown when language needs transliteration; t shown when lang !== "ku". (function () { var lang = values.lang || ""; var showTr = needsTransliteration(lang); var showT = lang && lang !== "ku"; $("#wiktku-start-dfn .wiktku-dfn-nimune-list li.wiktku-dfn-nimune-li").each(function () { var li = $(this); // Ensure the sub-wrapper exists when we need it. var subWrap = li.find(".wiktku-dfn-nimune-sub"); // tr field var trTa = li.find(".wiktku-dfn-nimune-tr"); if (showTr && !trTa.length) { if (!subWrap.length) { subWrap = $("<div></div>").addClass("wiktku-dfn-nimune-sub"); li.append(subWrap); } trTa = $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-tr-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 5) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-tr") .attr("placeholder", "Transkrîpsiyon…"); subWrap.prepend(trTa); } else if (!showTr && trTa.length) { trTa.remove(); } // t field var tTa = li.find(".wiktku-dfn-nimune-t"); if (showT && !tTa.length) { if (!subWrap.length) { subWrap = $("<div></div>").addClass("wiktku-dfn-nimune-sub"); li.append(subWrap); } tTa = $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-t-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 5) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-t") .attr("placeholder", "Tercimeya nimûneyê kurmancî…"); subWrap.append(tTa); } else if (!showT && tTa.length) { tTa.remove(); } // Remove the wrapper if it ended up empty. subWrap = li.find(".wiktku-dfn-nimune-sub"); if (subWrap.length && !subWrap.children().length) subWrap.remove(); }); }()); // Sync tr/t sub-fields in every jêder citation to the current language. // tr shown when language needs transliteration; t shown when lang !== "ku". (function () { var lang = values.lang || ""; var showTr = needsTransliteration(lang); var showT = lang && lang !== "ku"; $("#wiktku-start-dfn .wiktku-dfn-jeder-list li.wiktku-dfn-jeder-li").each(function () { var li = $(this); // Ensure the sub-wrapper exists when we need it. It must sit right // after the quote textarea and before the source selector. var subWrap = li.find(".wiktku-dfn-quote-sub"); // tr field var trTa = li.find(".wiktku-dfn-nimune-quote-tr"); if (showTr && !trTa.length) { if (!subWrap.length) { subWrap = $("<div></div>").addClass("wiktku-dfn-quote-sub"); li.find(".wiktku-dfn-nimune-quote").after(subWrap); } trTa = $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-quote-tr-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 2) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-quote-tr") .attr("placeholder", "Transkrîpsiyona jêgirtinê…"); subWrap.prepend(trTa); } else if (!showTr && trTa.length) { trTa.remove(); } // t field var tTa = li.find(".wiktku-dfn-nimune-quote-t"); if (showT && !tTa.length) { if (!subWrap.length) { subWrap = $("<div></div>").addClass("wiktku-dfn-quote-sub"); li.find(".wiktku-dfn-nimune-quote").after(subWrap); } tTa = $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-quote-t-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 2) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-quote-t") .attr("placeholder", "Tercimeya jêgirtinê ya kurmancî…"); subWrap.append(tTa); } else if (!showT && tTa.length) { tTa.remove(); } // Remove the wrapper if it ended up empty. subWrap = li.find(".wiktku-dfn-quote-sub"); if (subWrap.length && !subWrap.children().length) subWrap.remove(); }); }()); $.each(steps, function (stepId, step) { if (typeof(step.visible) === "function" && !step.visible(values)) { $("#wiktku-start-" + stepId).slideUp(); } else { var stepDiv = $("#wiktku-start-" + stepId); if (changedStep !== step && typeof(step.build) === "function") { prepareInput(step.build(stepDiv, values), step); } var input = stepDiv.find(".wiktku-start-step-field"); if (typeof(step.example) === "function") { // .find() above already reaches nested fields (e.g. the dfn // step's mane textareas inside each sense block), so one // assignment covers every step; dfn keeps its own fallback. var exampleText = step.example(values) || (step.id === "dfn" ? "Mane…" : ""); input.attr("placeholder", exampleText); } var didSlideDown; if (!didFocus && stepDiv.css("display") === "none" && step.required) { didSlideDown = function (evt) { input.focus(); }; didFocus = true; } stepDiv.slideDown(didSlideDown); } if (step.required && (values[stepId] === "" || (step.multiple && values[stepId].join("") === ""))) { canContinue = false; } }); continueBtn.setDisabled(!canContinue); } function destroy() { $("#wiktku-start-form, .noafterwizard").slideUp(function () { $(this).remove(); }); $(".noarticletext .nowizard, #editform").slideDown(); $("#ca-edit").removeClass("selected"); $("#ca-wiktku-nowizard").addClass("selected"); } // Priority order for Kurdish dialects and the navz pseudo-code. // Codes listed here come before all other languages; unlisted codes // are sorted alphabetically by their display name via localeCompare. var LANG_PRIORITY = ["navz", "ku", "hac", "sdh", "lki", "ckb", "zza"]; /** * Inserts a new == {{ziman|code}} == section into existing page wikitext * at the correct sorted position: * 1. Any content before the first language section is preserved at the top. * 2. navz is always first, then ku/hac/sdh/lki/ckb/zza in that order, * then all other languages sorted by display name (localeCompare). */ function insertNewLangSection(existing, wikitext) { var newCodeMatch = wikitext.match(/^== \{\{ziman\|([^}]+)\}\} ==/); var newCode = newCodeMatch ? newCodeMatch[1] : ""; var sections = []; var preamble = ""; var firstMatch = existing.match(/(?:^|\n)== \{\{ziman\|/); if (!firstMatch) { // No existing lang sections at all — just append. var sep = existing && !/\n\s*$/.test(existing) ? "\n\n" : ""; return existing + sep + wikitext; } // Everything before the first == {{ziman|...}} == is the preamble. var firstSectionStart = existing.indexOf("== {{ziman|"); // Walk back to the start of that line. var lineStart = existing.lastIndexOf("\n", firstSectionStart - 1); var preambleEnd = lineStart !== -1 ? lineStart + 1 : 0; preamble = existing.slice(0, preambleEnd); // Parse each language section: header line + everything until the next header. var body = existing.slice(preambleEnd); // NOTE: with the /m flag, a bare "$" matches end-of-*line*, not just // end-of-string — that previously made the non-greedy content group // stop at the section's first line break instead of running to the // next language header (or the real end of the text), silently // dropping the rest of that section's wikitext. (?![\s\S]) matches // only the true end of the string, /m flag or not. var langSectionRe = /^(== \{\{ziman\|([^}]+)\}\} ==\n?)([\s\S]*?)(?=\n== \{\{ziman\||(?![\s\S]))/gm; var m; while ((m = langSectionRe.exec(body)) !== null) { sections.push({ code: m[2], content: m[0] // full text of this section including header }); } // Determine sort rank: priority list first (by index), then alphabetical. function getLangName(code) { var entry = langsByCode[code]; return entry ? entry[1] : code; } function sortRank(code) { var idx = LANG_PRIORITY.indexOf(code); return idx !== -1 ? idx : LANG_PRIORITY.length; } function compareLangs(a, b) { var ra = sortRank(a), rb = sortRank(b); if (ra !== rb) return ra - rb; // Both are outside priority list — sort by display name. return getLangName(a).localeCompare(getLangName(b), userLang); } // Insert the new section into the sorted list. var newSection = { code: newCode, content: wikitext }; var inserted = false; for (var i = 0; i < sections.length; i++) { if (compareLangs(newCode, sections[i].code) < 0) { sections.splice(i, 0, newSection); inserted = true; break; } } if (!inserted) sections.push(newSection); // Re-join: preamble + sections separated by newlines. var joined = sections.map(function (s) { // Ensure each section ends with exactly one newline before the next. return s.content.replace(/\n+$/, ""); }).join("\n"); return preamble + joined + "\n"; } function build() { $(".nowizard, .nowizard .noafterwizard").hide(); var callToAction = $("#wiktku-calltoaction"); var origCallToActionText = callToAction.text(); $(mw.util.addPortletLink("p-views", "#", "Edîtora çavkaniyê veke", "ca-wiktku-nowizard", "Vê rûpelê bi edîtora çavkaniyê çêke", undefined, "#ca-watch")).click(function (evt) { evt.preventDefault(); callToAction.text(origCallToActionText); destroy(); }); if (callToAction.length) { callToAction.text(origCallToActionText + " Forma li jêr ji bo çêkirina madeyeke nû bi kar bîne."); } var startForm = $("<form id='wiktku-start-form'></form>"); if (addLangMode) { startForm.append($("<p class='wiktku-addlang-notice'></p>").text( "Agahiyên zimanê nû yê hûnê li vê rûpelê zêde bikin dagirin. " + "Piştî temambûnê, beşa nû dê li dawiya nivîsa heyî were zêdekirin.")); } var spinner; // Tab bar for switching between POS sections. var sectionTabsDiv = $("<div id='wiktku-section-tabs'></div>"); startForm.submit(function (evt) { evt.preventDefault(); continueBtn.setDisabled(true); spinner.show(); getWikitext(function (wikitext) { if (addLangMode) { var textbox = $("#wpTextbox1"); var existing = textbox.val() || ""; // Check whether the generated lang header already exists in the page. // wikitext always starts with "== {{ziman|CODE}} ==\n" (from steps.lang.output). // If that exact section heading is already present in the existing content, // strip it from the new output and insert the remaining content at the end // of that lang section (just before the next == level-2 heading, or at the // very end of the page if there is no following section). var langHeaderMatch = wikitext.match(/^(== \{\{ziman\|[^}]+\}\} ==\n)/); if (langHeaderMatch) { var langHeader = langHeaderMatch[1]; // e.g. "== {{ziman|ku}} ==\n" // Escape for use in RegExp. var escapedHeader = langHeader.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); if (new RegExp(escapedHeader).test(existing)) { // Strip the header from the new output. var newContent = wikitext.slice(langHeader.length); // Find the insertion point: end of the existing lang section. // A new L2 heading marks the start of the next language block. var afterHeader = existing.indexOf(langHeader); var searchFrom = afterHeader + langHeader.length; // Find the next == … == heading after this section's start. var nextL2 = existing.indexOf("\n== ", searchFrom); var insertAt = nextL2 !== -1 ? nextL2 : existing.length; // Ensure there's a blank line before the inserted block. var before = existing.slice(0, insertAt); var after = existing.slice(insertAt); var sep = /\n\s*$/.test(before) ? "" : "\n"; textbox.val(before + sep + newContent + after); } else { // New language — insert at the correct sorted position. textbox.val(insertNewLangSection(existing, wikitext)); } } else { // Unexpected format — insert at sorted position anyway. textbox.val(insertNewLangSection(existing, wikitext)); } } else { $("#wpTextbox1").val(wikitext); } $("html, body").animate({scrollTop: 0}); callToAction.text("Hindik ma!"); $("#wiktku-preview-container").remove(); destroy(); }); }); $.each(ordered_steps, function (i, step) { var stepDiv = $(mw.html.element("div", { "class": "wiktku-start-step", id: "wiktku-start-" + step.id })); var name = capitalize(step.name); stepDiv.append($(mw.html.element("h3", { "class": "wiktku-start-step-name" }, new mw.html.Raw(mw.html.element("label", { "for": "wiktku-start-" + step.id + "-field" }, name))))); if (step.question_fmt) { stepDiv.append($(mw.html.element("label", { "class": "wiktku-start-step-question", "for": "wiktku-start-" + step.id + "-field" }, step.question_fmt))); if (step.question_br) stepDiv.append($("<br>")); } var input; if (step.choices) { input = $(mw.html.element("select", { "class": "wiktku-start-step-field", id: "wiktku-start-" + step.id + "-field" })); input.attr("data-placeholder", capitalize(step.name) + " hilbijêre "); populateMenus(input, step.choices); if (step.multiple) input.attr("multiple", true); if (isMobile) { stepDiv.append(wrapNativeSelect(input)); } else { stepDiv.append(input); } } else if (typeof(step.build) === "function") { input = step.build(stepDiv); } else { input = $("<textarea></textarea>") .attr("class", "wiktku-start-step-field") .attr("id", "wiktku-start-" + step.id + "-field") .attr("rows", step.rows || 2); if (step.narrow) input.addClass("wiktku-start-narrow"); if (step.multiple) { input.on("input", function (evt) { refreshForTextField(evt.target, step); }); var keyInput = buildKeyInput(step); var list = $(step.ordered ? "<ol></ol>" : "<ul></ul>") .append($("<li></li>").append(keyInput).append(input)); stepDiv.append(list); } else stepDiv.append(input); } prepareInput(input, step); stepDiv.hide(); // Insert tab bar just before the first per-section step. if (step.id === "pos") startForm.append(sectionTabsDiv); startForm.append(stepDiv); }); // ── Section tab helpers ────────────────────────────────────────────── // ── Add-section button — lives in the tab bar, disabled until pos chosen ── var addSectionBtn = new OO.ui.ButtonWidget({ label: "+ Beş zêde bike", disabled: true }); addSectionBtn.on("click", function () { saveCurrentSection(); sections.push({}); activeSection = sections.length - 1; $.each(PER_SECTION_STEP_IDS, function (_, id) { if (id === "dfn") { var stepDiv = $("#wiktku-start-dfn"); stepDiv.find("ol.wiktku-dfn-list").remove(); steps.dfn.build(stepDiv); return; } if (id === "etym") { $("#wiktku-start-etym .wiktku-etym-wrap").remove(); steps.etym.build($("#wiktku-start-etym")); return; } if (id === "trans") { var transDiv = $("#wiktku-start-trans"); transDiv.find(".wiktku-trans-group").remove(); return; } if (id === "zarava") { var zaravaDiv = $("#wiktku-start-zarava"); zaravaDiv.find(".wiktku-zarava-group").remove(); return; } if (id === "dunde") { var dundeDiv = $("#wiktku-start-dunde"); dundeDiv.find("ul.wiktku-dunde-list").remove(); return; } var stepDiv = $("#wiktku-start-" + id); stepDiv.find(".wiktku-start-step-field").val(""); if (!isMobile) stepDiv.find("select.wiktku-start-step-field").trigger("chosen:updated"); }); renderSectionTabs(); refresh(); $("html, body").animate({ scrollTop: sectionTabsDiv.offset().top - 20 }, 300); }); /** Re-render the tab bar to reflect current sections[] and activeSection. */ function renderSectionTabs() { // Detach (not remove) the button first: .empty() strips bound // event data from any children left inside it, which would // silently kill addSectionBtn's click handler on every re-render. addSectionBtn.$element.detach(); sectionTabsDiv.empty(); var lang = getValues().lang || ""; if (!lang) { sectionTabsDiv.hide(); return; } sectionTabsDiv.show(); $.each(sections, function (i) { var posVal = sections[i].pos || ""; var tabLabel = posVal ? capitalize(posVal) : ("Beş " + (i + 1)); var tab = $("<span></span>") .addClass("wiktku-section-tab") .text(tabLabel) .toggleClass("wiktku-tab-active", i === activeSection); (function (idx) { tab.on("click", function () { if (idx === activeSection) return; saveCurrentSection(); activeSection = idx; restoreSection(sections[activeSection]); refresh(); renderSectionTabs(); }); }(i)); sectionTabsDiv.append(tab); }); // Enable "Beş zêde bike" only when the active section has a pos chosen. var activePos = sections[activeSection] && sections[activeSection].pos ? sections[activeSection].pos : getValues().pos; addSectionBtn.setDisabled(!activePos); sectionTabsDiv.append(addSectionBtn.$element); } renderSectionTabs(); // Update the active tab's label whenever pos changes. startForm.on("change", "#wiktku-start-pos-field", function () { renderSectionTabs(); }); // Show the tab bar as soon as a language is selected. startForm.on("change", "#wiktku-start-lang-field", function () { renderSectionTabs(); }); var footer = $("<div id='wiktku-start-footer'></div>"); spinner = $(mw.html.element("img", { id: "wiktku-start-spinner", src: "//upload.wikimedia.org/wikipedia/commons/d/de/Ajax-loader.gif", alt: "Tê barkirin…", title: "Tê barkirin…" })); footer.append(spinner.hide()); continueBtn = new OO.ui.ButtonWidget({ id: "wiktku-unhide-editform", label: "Bişîne", flags: [ "primary", "progressive" ] }); continueBtn.on("click", function () { mw.notify("Tê şandin…", { type: "info", tag: "wiktku-submit" }); startForm.trigger("submit"); }); footer.append(continueBtn.$element); // "Edîtora çavkaniyê veke" button — inline fallback for the portlet link // which is invisible on mobile and easy to miss on desktop. var sourceEditorBtn = new OO.ui.ButtonWidget({ label: "Edîtora çavkaniyê veke", framed: false }); sourceEditorBtn.on("click", function () { destroy(); }); footer.append(sourceEditorBtn.$element); // ── Preview checkboxes ─────────────────────────────────────────────── // Wikitext preview (raw text panel) var previewCheck = $("<input type='checkbox' id='wiktku-preview-toggle'>"); var previewLabel = $("<label for='wiktku-preview-toggle'></label>") .text(" Pêşdîtina wîkîtekstê"); var previewPanel = $("<pre id='wiktku-preview-panel'></pre>").hide(); // Live rendered preview (parsed HTML panel, same logic as AjaxEdit). // Not available on mobile — API polling causes too many problems on small screens. var livePreviewCheck = null; var livePreviewPanel = null; if (!isMobile) { livePreviewCheck = $("<input type='checkbox' id='wiktku-live-preview-toggle'>"); livePreviewPanel = $("<div id='wiktku-live-preview-panel'></div>").hide(); } // Container that holds both panels and switches between stacked / side-by-side. var previewContainer = $("<div id='wiktku-preview-container'></div>"); previewContainer.append(previewPanel); if (!isMobile) previewContainer.append(livePreviewPanel); var previewTimer = null; var livePreviewIntervalId = -1; var livePreviewActive = false; // guards in-flight fetches after uncheck /** Rebuilds wikitext preview if its checkbox is checked. */ function schedulePreview() { if (!previewCheck.prop("checked")) return; clearTimeout(previewTimer); // Debounce: wait 400 ms after the last keystroke before rebuilding. previewTimer = setTimeout(function () { getWikitext(function (wikitext) { previewPanel.text(wikitext).show(); updatePanelLayout(); }); }, 400); } /** Fetches parsed HTML and populates the live preview panel. */ function loadLivePreview() { getWikitext(function (wikitext) { new mw.Api().parse(wikitext, { title: mw.config.get("wgPageName") }).done(function (html) { // Discard result if the user unchecked while the fetch was in flight. if (!livePreviewActive) return; livePreviewPanel.html(html).show(); updatePanelLayout(); }); }); } /** Adjusts panel widths depending on which previews are visible. */ function updatePanelLayout() { var wikitextVisible = previewCheck.prop("checked"); var liveVisible = livePreviewCheck && livePreviewCheck.prop("checked"); if (wikitextVisible && liveVisible) { // Side by side — each panel takes roughly half the available width. previewPanel.css({ "flex": "1 1 45%", "min-width": "280px" }); livePreviewPanel.css({ "flex": "1 1 45%", "min-width": "280px" }); } else { // Full width for whichever is visible — only touch panels that are // actually shown so that setting flex doesn't override display:none. if (wikitextVisible) previewPanel.css({ "flex": "1 1 100%", "min-width": "" }); if (liveVisible && livePreviewPanel) livePreviewPanel.css({ "flex": "1 1 100%", "min-width": "" }); } } previewCheck.on("change", function () { if ($(this).prop("checked")) { schedulePreview(); } else { clearTimeout(previewTimer); previewPanel.hide(); updatePanelLayout(); } }); if (!isMobile) { livePreviewCheck.on("change", function () { if ($(this).prop("checked")) { livePreviewActive = true; livePreviewPanel.show(); loadLivePreview(); livePreviewIntervalId = setInterval(loadLivePreview, 500); } else { livePreviewActive = false; clearInterval(livePreviewIntervalId); livePreviewIntervalId = -1; livePreviewPanel.hide().empty(); updatePanelLayout(); } }); } // Listen on all input/change events on the form and update both previews. startForm.on("input change", function () { schedulePreview(); }); footer.append($("<span style='margin-left:1em'></span>") .append(previewCheck).append(previewLabel)); if (!isMobile) { var livePreviewLabel = $("<label for='wiktku-live-preview-toggle'></label>") .text(" Pêşdîtina zindî"); footer.append($("<span style='margin-left:1em'></span>") .append(livePreviewCheck).append(livePreviewLabel)); } startForm.append(footer); $("#editform").hide().before(startForm); // Insert preview container (holds both panels) after the form. startForm.after(previewContainer); if (!isMobile) startForm.find("select").chosen(chosenOptions); refresh(); // Zimanan ji MediaWiki:Gadget-translation_editor.js/ziman.json bar bike. // Kodên ku bi "-pro" diqedin û navên ku "zimanê destan" tê de heye // tên derxistin. Zimanên xardkirî li serî dimînin, yên din // bi alfabeyê li dû wan tên. // Pinned choices come from MediaWiki:Gadget-start.js/data.json (langChoices), // already loaded into steps.lang.choices before build() runs. var pinnedChoices = steps.lang.choices.slice(); var pinnedCodes = $.map(pinnedChoices, function (choice) { return choice[0]; }); new mw.Api().get({ action: "query", prop: "revisions", titles: "MediaWiki:Gadget-translation_editor.js/ziman.json", rvprop: "content", rvslots: "main", formatversion: 2 }).then(function (data) { var page = data.query.pages[0]; var content = page && page.revisions && page.revisions[0].slots.main.content; var zimanData; try { zimanData = JSON.parse(content); } catch (e) { zimanData = {}; } var extraChoices = []; $.each(zimanData, function (code, name) { // Filter: skip proto-language codes and legendary/reconstructed langs. if (/-pro$/i.test(code)) return; if (/ziman[eê]\s+destan/i.test(name)) return; // Skip codes already in the pinned list (they are handled above). if (pinnedCodes.indexOf(code) !== -1) return; // sortKey: bare name without leading "zimanê " for sorting. var sortKey = name.replace(/^ziman[eê]\s+/i, ""); var choice = [code, name, sortKey]; extraChoices.push(choice); langsByCode[code] = choice; }); // Populate langsByCode for pinned choices too. $.each(pinnedChoices, function (i, choice) { // Ensure pinned choices have a sortKey (index 2). if (choice.length < 3) choice[2] = choice[1]; langsByCode[choice[0]] = choice; }); // Sort the extra choices alphabetically by sort key. extraChoices.sort(function (a, b) { return a[2].localeCompare(b[2], userLang); }); // Final list: pinned first, then the rest. var allChoices = pinnedChoices.concat(extraChoices); steps.lang.choices = allChoices; steps.trans.keys = allChoices; steps.dunde.keys = allChoices; steps.zarava.keys = getZaravaKeys(allChoices); var langMenu = $("#wiktku-start-lang-field"); populateMenus(langMenu, steps.lang.choices); langMenu.trigger("chosen:updated"); var transMenus = $("#wiktku-start-trans .wiktku-start-step-keyfield"); populateMenus(transMenus, steps.trans.keys, getDisabledKeys(steps.trans)); transMenus.trigger("chosen:updated"); var dundeMenus = $("#wiktku-start-dunde .wiktku-start-step-keyfield"); populateMenus(dundeMenus, steps.dunde.keys, getDisabledKeys(steps.dunde)); dundeMenus.trigger("chosen:updated"); var zaravaMenus = $("#wiktku-start-zarava .wiktku-start-step-keyfield"); populateMenus(zaravaMenus, steps.zarava.keys, getDisabledKeys(steps.zarava)); }); } mw.loader.using(["jquery.chosen", "mediawiki.api", "oojs-ui-core"], function () { // Load metadata, langChoices, posChoices and tplDefs from the companion // data page so they can be updated without touching this script. new mw.Api().get({ action: "query", prop: "revisions", titles: "MediaWiki:Gadget-start.js/data.json", rvprop: "content", rvslots: "main", formatversion: 2 }).then(function (data) { var page = data.query.pages[0]; var content = page && page.revisions && page.revisions[0].slots.main.content; var d; try { d = JSON.parse(content); } catch (e) { d = {}; } // Populate metadata. if (d.metadata) $.extend(metadata, d.metadata); // Populate lang choices (pinned list used by build() → ziman.json loader). if (d.langChoices) steps.lang.choices = d.langChoices; // Populate POS choices. if (d.posChoices) steps.pos.choices = d.posChoices; // Populate template definitions for the dfn sense-block builder. if (d.tplDefs) steps.dfn.tplDefs = d.tplDefs; // Populate pos placeholder examples. if (d.posExamples) steps.dfn.posExamples = d.posExamples; // Populate citation template definitions for the quote widget. if (d.jederDefs) steps.dfn.jederDefs = d.jederDefs; // Populate pronunciation and etymology template insert lists. if (d.pronTpls) { steps.pron.pronTpls = d.pronTpls; steps.pron.refreshTplSelect(); } if (d.etymTpls) { steps.etym.etymTpls = d.etymTpls; steps.etym.refreshTplSelect(); } // Sync trans/dunde/zarava keys with the (now populated) lang choices. steps.trans.keys = steps.lang.choices; steps.dunde.keys = steps.lang.choices; steps.zarava.keys = getZaravaKeys(steps.lang.choices); }).always(build); }); }); //</nowiki> 6xvaqpvuox7h60a0t49bgvx5jtdexra 6265563 6265562 2026-07-19T13:28:53Z Wikihez 7344 6265563 javascript text/javascript // Li ser [[vi:MediaWiki:Gadget-start.js]] hatiye refaktorkirin. //<nowiki> $(function () { var ns = mw.config.get("wgNamespaceNumber"); if (ns && !(ns === 2 && mw.config.get("wgPageName").match(/\/ceribandin$|\/test$/))) { return; } var action = mw.config.get("wgAction"); var pageExists = !!mw.config.get("wgArticleId"); // "Zimanek lê zêde bike" mode: triggered from the portlet link below. // Runs the same wizard on an EXISTING page's edit form, but appends the // generated section instead of replacing the textarea's content. var addLangMode = pageExists && mw.util.getParamValue("wiktkuaddlang") === "1"; // On a normal page view of an existing page, just add the portlet link // that takes the user into addLangMode; don't build anything else here. if (action === "view" && pageExists) { mw.util.addPortletLink("p-views", mw.util.getUrl(mw.config.get("wgPageName"), { action: "submit", wiktkuaddlang: "1" }), "+Ziman/beşeke din", "ca-wiktku-addlang", "Ji vê rûpelê re zimanekî nû zêde bike"); return; } if (!(action === "edit" || action === "submit")) { return; } if (!addLangMode && !$(".mw-newarticletext, .mw-newarticletextanon").length) { return; } if (window.location.href.includes("editintro=User:Wikihez/creation/intro")) { return; // Do not run the script wextê WF:Bilez dişuxile } function capitalize(str) { if (!str) return str; return str[0].toUpperCase() + str.substr(1); } function decapitalize(str) { if (!str) return str; return str[0].toLowerCase() + str.substr(1); } function escapeRegExp(str) { return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); } function stripWikilinks(str) { return str.replace(/\[\[([^\]|]+)(?:\|([^\]]+))?\]\]/g, function (m, target, display) { return display || target; }); } function insertAtCursor(el, text) { var start = el.selectionStart; var end = el.selectionEnd; var val = el.value; el.value = val.slice(0, start) + text + val.slice(end); var pos = start + text.length; el.selectionStart = el.selectionEnd = pos; } var pageName = mw.config.get("wgPageName").replaceAll(/_/g, " "); if (ns) pageName = pageName.replace(/.*\//, ""); var pageNameRe = escapeRegExp(pageName); var userLang = mw.config.get("wgUserLanguage"); // Mobile detection: MobileFrontend sets wgMFMode, or fall back to touch check. var isMobile = !!mw.config.get("wgMFMode") || window.matchMedia("(pointer: coarse)").matches; var chosenOptions = { width: "20em", disable_search_threshold: 0, placeholder_text_single: "Yekî hilbijêre", placeholder_text_multiple: "Hilbijêre", no_results_text: "Nehat dîtin", enable_split_word_search: true, search_contains: true }; function wrapNativeSelect(select) { var placeholder = select.attr("data-placeholder") || "Lê bigere…"; // Hide the native select — we drive it programmatically. select.hide(); var wrapper = $("<span class='wiktku-native-select-wrap'></span>"); var textInput = $("<input type='search' autocomplete='off'>") .attr("placeholder", placeholder) .addClass("wiktku-start-narrow wiktku-ac-input"); var resultsList = $("<ul class='wiktku-ac-results'></ul>").hide(); // Full option cache — rebuilt when chosen:updated fires. var allOptions = []; function cacheOptions() { allOptions = []; select.find("option").each(function () { var v = $(this).val(); if (!v) return; // skip the empty placeholder option allOptions.push({ value: v, text: $(this).text(), disabled: $(this).prop("disabled") }); }); } cacheOptions(); function showResults(query) { var q = query.trim().toLowerCase(); resultsList.empty(); var matched; if (q) { matched = []; $.each(allOptions, function (_, o) { if (o.disabled) return; var codeMatch = o.value.toLowerCase().indexOf(q) !== -1; var nameMatch = o.text.toLowerCase().indexOf(q) !== -1; if (codeMatch || nameMatch) { matched.push({ opt: o, codeMatch: codeMatch }); } }); // Code matches (especially prefix matches) come first. matched.sort(function (a, b) { var aCode = a.opt.value.toLowerCase(); var bCode = b.opt.value.toLowerCase(); var aPrefix = aCode.indexOf(q) === 0; var bPrefix = bCode.indexOf(q) === 0; if (aPrefix !== bPrefix) return aPrefix ? -1 : 1; if (a.codeMatch !== b.codeMatch) return a.codeMatch ? -1 : 1; return 0; }); matched = matched.map(function (item) { return item.opt; }); } else { matched = allOptions.filter(function (o) { return !o.disabled; }); } if (!matched.length) { resultsList.hide(); return; } $.each(matched.slice(0, 50), function (_, opt) { var li = $("<li></li>").text(opt.text).attr("data-value", opt.value); // Use touchend instead of touchstart so that a scroll gesture does // not accidentally select an item. We track whether the finger moved // between touchstart and touchend — if it did, it was a scroll. var touchMoved = false; li.on("touchstart", function () { touchMoved = false; }); li.on("touchmove", function () { touchMoved = true; }); li.on("touchend", function (e) { if (touchMoved) return; // was a scroll, not a tap e.preventDefault(); selectOption(opt.value, opt.text); }); // Keep mousedown for desktop fallback. li.on("mousedown", function (e) { e.preventDefault(); selectOption(opt.value, opt.text); }); resultsList.append(li); }); // Position the list above or below depending on available viewport space. var inputRect = textInput[0].getBoundingClientRect(); var viewportH = window.innerHeight; var spaceBelow = viewportH - inputRect.bottom - 8; var spaceAbove = inputRect.top - 8; var maxH = Math.min(224, Math.max(spaceBelow, spaceAbove)); // 224px ≈ 14em resultsList.css({ "max-height": maxH + "px", "top": spaceBelow >= spaceAbove ? "100%" : "auto", "bottom": spaceBelow >= spaceAbove ? "auto" : "100%" }); resultsList.show(); } function selectOption(value, text) { textInput.val(text); select.val(value); resultsList.hide(); select.trigger("change"); } textInput.on("input focus", function () { showResults($(this).val()); }); textInput.on("blur", function () { // Short delay so a touchstart on a result item fires first. setTimeout(function () { resultsList.hide(); }, 200); }); // chosen:updated → re-cache (called after ziman.json loads). select.on("chosen:updated", function () { cacheOptions(); // If a value is already selected, keep the display text in sync. var cur = select.val(); if (cur) { var match = $.grep(allOptions, function (o) { return o.value === cur; })[0]; if (match) textInput.val(match.text); } }); // No-op .chosen() so desktop call-sites don't need guarding. select.chosen = function () { return select; }; wrapper.append(textInput).append(resultsList).append(select); return wrapper; } var langsByCode = {}; // Populated from [[MediaWiki:Gadget-start.js/data.json]] at runtime. var metadata = {}; // Zaravayên kurdî yên ku di beşa "Bi zaravayên din" de tên pêşkêşkirin — // ev kod ji beşa Werger têne derxistin daku heman zimên du caran neyê xwendin. var ZARAVA_LANG_CODES = ["ckb", "sdh", "lki", "hac", "zza"]; function getZaravaKeys(choices) { var byCode = {}; $.each(choices || [], function (_, c) { byCode[c[0]] = c; }); var result = []; $.each(ZARAVA_LANG_CODES, function (_, code) { if (byCode[code]) result.push(byCode[code]); }); return result; } function needsTransliteration(langCode) { var meta = metadata[langCode]; if (!meta || !meta.sc) return false; var scripts = Array.isArray(meta.sc) ? meta.sc : [meta.sc]; return scripts.length > 0 && scripts[0] !== "Latn"; } // Kodên cinsiyetê yên di metadata.g de var GENDER_BASE_LABELS = { m: "mê", n: "nêr", nt: "nêtar", mn: "mê û nêr", mnmane: "mê yan nêr li gorî maneyê", g: "giştî", y: "yekjimar", p: "pirjimar" }; // Sub-lists that only make sense for a plain (non-şablon) sense — hidden // when a şablon (e.g. {{guharto|…}}) is chosen for that sense, since a // template-based sense has no "own" gloss for alternate forms, synonyms, // antonyms, coordinate terms, hypernyms or hyponyms to attach to. Etîket, // Nimûne and Jêgirtin stay visible either way. var HIDDEN_ON_TPL_GROUPS = [ "wiktku-dfn-alternativ", "wiktku-dfn-hevmane", "wiktku-dfn-dijmane", "wiktku-dfn-koordine", "wiktku-dfn-jornav", "wiktku-dfn-jernav" ]; function genderLabel(code) { if (code === "p") return "Pirjimar"; var pluralMatch = code.match(/^(.+)-p$/); if (pluralMatch && GENDER_BASE_LABELS[pluralMatch[1]]) { return GENDER_BASE_LABELS[pluralMatch[1]] + " (pirjimar)"; } return GENDER_BASE_LABELS[code] || code; } /** * True if a sense has any content worth keeping besides its mane text — * etîket, hevmane/dijmane/koordîne/etc. word lists, nimûne, or jêder * (quote). Used so a sense with an empty mane but filled-in extra * fields still gets emitted (with {{mane?}} standing in for the gloss) * instead of being silently dropped. */ function senseHasExtraContent(s) { if (s.etiket && $.grep(s.etiket, function (e) { return $.trim(e) !== ""; }).length) return true; if (s.alternativ.length || s.hevmane.length || s.dijmane.length || s.koordine.length || s.jornav.length || s.jernav.length) return true; if (s.nimune && $.grep(s.nimune, function (n) { return (typeof n === "object" ? n.text : n) !== ""; }).length > 0) return true; if (s.jeder && $.grep(s.jeder, function (j) { return j && j.quote; }).length > 0) return true; return false; } /** * formatNimune: each nimûne item can be { text, tr, t }: * text — example text * tr — transliteration (only when the language needs it) * t — Kurdish translation (third positional param, no key) */ function formatNimune(nimunes, lang, hasJeder) { var hasNimune = nimunes && $.grep(nimunes, function (n) { return (typeof n === "object" ? n.text : n) !== ""; }).length > 0; if (!hasNimune) { return hasJeder ? "" : "\n#* {{bênimûne|" + lang + "}}"; } return $.map(nimunes, function (n) { var text = typeof n === "object" ? n.text : n; if (!text) return undefined; var bolded = text.replace( new RegExp("(" + pageNameRe + "([^( |,|;|\\?|\\.|\\!)]+)?)", "ig"), "'''$1'''"); var tpl = "\n#: {{nm|" + lang + "|" + bolded; if (typeof n === "object") { if (n.tr) tpl += "|tr=" + n.tr; // Translation as third positional param (no key needed). if (n.t) tpl += "|" + n.t; } // Short examples fit on one line together with their translation. // rêz=1 is not used for ku — definitions are shown on separate lines there. if (text.length < 200 && lang !== "ku") tpl += "|rêz=1"; tpl += "}}"; return tpl; }).join(""); } /** * Formats a list of jêder (quote/citation) objects into wikitext lines. * Each entry that has no quote text is skipped. Returns "" when the list * is empty or every entry is blank. * * #* {{jêder-…|lang|jêgirtin=…|tr=…|tercime=…|…fields…}} * * When no template is chosen, the generic {{jêder|…}} template is used * instead. Its 2nd positional param is the user's freeform "bi destê xwe * binivîsim" source text when supplied, or the çavkanî? placeholder otherwise. * If that text contains "=" it is passed as |2=… instead of a bare * positional param, since MediaWiki would otherwise misparse it as its * own key=value pair and break the template: * #* {{jêder|lang|jêgirtin=…|tr=…|tercime=…|<manual source or çavkanî?>}} */ function formatJeder(jederList, lang) { if (!jederList || !jederList.length) return ""; return $.map(jederList, function (jeder) { if (!jeder || !jeder.quote) return undefined; if (jeder.jederTpl) { var cite = "\n#* {{" + jeder.jederTpl + "|" + lang; cite += "|jêgirtin=" + jeder.quote; if (jeder.quoteTr) cite += "|tr=" + jeder.quoteTr; if (jeder.quoteT) cite += "|tercime=" + jeder.quoteT; $.each(jeder.jêderFields || {}, function (key, val) { if (val) cite += "|" + key + "=" + val; }); cite += "}}"; return cite; } var out = "\n#* {{jêder|" + lang + "|jêgirtin=" + jeder.quote; if (jeder.quoteTr) out += "|tr=" + jeder.quoteTr; if (jeder.quoteT) out += "|tercime=" + jeder.quoteT; var srcParam = jeder.jederManual ? jeder.jederManual : "çavkanî?"; // A positional param containing "=" gets parsed as its own key=value // pair by MediaWiki and breaks the template, so force it to be // explicitly named (|2=) whenever that's the case. out += (srcParam.indexOf("=") !== -1 ? "|2=" : "|") + srcParam; out += "}}"; return out; }).join(""); } function makeWordListStep(id, name, question_fmt, header, templateName) { return { id: id, name: name, question_fmt: question_fmt, multiple: true, narrow: true, visible: function (values) { return values.lang && values.pos; }, output: function (values) { var words = $.grep(values[id] || [], function (w) { return !!w; }); if (!words.length) return ""; var lang = values.lang; var section = "\n==== " + header + " ====\n"; if (words.length === 1) { // Single word — keep the simple inline template. return section + "* {{" + templateName + "|" + lang + "|" + words[0] + "}}\n"; } // Multiple words — use {{kol3}} with one positional param per word. var params = "cure=" + header + "\n" + $.map(words, function (w) { return "|" + w; }).join("\n"); return section + "{{kol3|" + lang + "|" + params + "\n}}\n"; } }; } var steps = { lang: { id: "lang", required: true, name: "ziman", question_fmt: '"' + pageName + '" bi çi zimanî ye?', question_br: true, // Populated from [[MediaWiki:Gadget-start.js/data.json]] (langChoices). choices: [], output: function (values) { return "== {{ziman|" + values.lang + "}} ==\n"; } }, pron: { id: "pron", name: "bilêvkirin", question_fmt: '"' + pageName + '" çawa tê telafûzkirin?', // pronTpls populated from data.json pronTpls: [], visible: function (values) { if (!values.lang) return false; // In addLangMode, only skip pron when this langcode's section // already exists in the page — if it's a new language, show it. if (addLangMode) { var existing = $("#wpTextbox1").val() || ""; var header = "== {{ziman|" + values.lang + "}} =="; return existing.indexOf(header) === -1; } return true; }, /** Fills (or refills) the insert-dropdown from the current pronTpls array, filtering by language. */ refreshTplSelect: function () { var sel = $("#wiktku-start-pron .wiktku-tpl-insert-select"); if (!sel.length) return; var lang = getValues().lang || ""; sel.find("option[value!='']").remove(); $.each(steps.pron.pronTpls, function (_, tpl) { // Filter: if tpl.langs exists, only show if lang is in that list; otherwise show always var allowed = !tpl.langs || tpl.langs.indexOf(lang) !== -1; if (allowed) { sel.append($("<option></option>") .val(tpl.snippet) .text(tpl.name + " — " + tpl.desc) .attr("data-nolang", tpl.noLang ? "1" : "")); } }); // Notify Chosen that the option list has changed (no-op on mobile). if (!isMobile) sel.trigger("chosen:updated"); }, build: function (stepDiv) { if (stepDiv.find(".wiktku-pron-wrap").length) return null; var wrap = $("<div class='wiktku-pron-wrap'></div>"); var ta = $("<textarea></textarea>") .attr("name", "wiktku-pron-" + $.now()) .attr("class", "wiktku-start-step-field wiktku-pron-text") .attr("rows", 4) .attr("placeholder", "Nimûne: {{IPA|ku|/pɛɪ̯n/}} yan {{kîte|ku|he|ce|ki|rin}}"); // Template insert dropdown — filtered by language. var sel = $("<select class='wiktku-tpl-insert-select'></select>"); sel.append($("<option value=''>— şablonek lê zêde bike —</option>")); var lang = getValues().lang || ""; $.each(steps.pron.pronTpls, function (_, tpl) { // Filter: if tpl.langs exists, only show if lang is in that list; otherwise show always var allowed = !tpl.langs || tpl.langs.indexOf(lang) !== -1; if (allowed) { sel.append($("<option></option>") .val(tpl.snippet) .text(tpl.name + " — " + tpl.desc) .attr("data-nolang", tpl.noLang ? "1" : "")); } }); sel.on("change", function () { var snippet = $(this).val(); if (!snippet) return; var lang = getValues().lang || ""; // Check if the selected option has noLang flag var selectedOption = sel.find("option:selected"); var hasNoLang = selectedOption.attr("data-nolang") === "1"; if (!hasNoLang) { snippet = snippet.replace(/CODE/g, lang).replace(/SOURCELANG/g, "?"); } insertAtCursor(ta[0], snippet); $(this).val(""); ta.focus(); }); wrap.append(sel).append($("<br>")).append(ta); stepDiv.append(wrap); return ta; }, output: function () { var text = $.trim($("#wiktku-start-pron .wiktku-pron-text").val()); if (!text) return ""; var lines = text.split("\n"); var out = $.map(lines, function (line) { line = $.trim(line); if (!line) return undefined; return line.charAt(0) === "*" ? line : "* " + line; }).join("\n"); return "\n=== Bilêvkirin ===\n" + out + "\n"; } }, pos: { id: "pos", required: true, name: "Cureyê rêzimanî", question_fmt: 'Cureyê rêzimanî yê "' + pageName + '" çi ye?', visible: function (values) { return values.lang; }, question_br: true, // Populated from [[MediaWiki:Gadget-start.js/data.json]] (posChoices). choices: [], output: function (values) { var pos = values.pos || ""; var cinsiyet = values.cinsiyet || ""; // from the cinsiyet step var lekTur = values.lektur || ""; // from the lêker transitivity step var capitalizedPos = capitalize(pos); var outputString = "\n=== " + capitalizedPos + " ===\n"; // Add ku-tewîn-nav for single-word navdêr/serenav with known gender. if (!pageName.includes(" ") && cinsiyet && GENDER_BASE_LABELS[cinsiyet] && (pos === "navdêr" || pos === "serenav") && values.lang === "ku") { outputString += "{{ku-tewîn-nav|" + pageName + "|" + GENDER_BASE_LABELS[cinsiyet]; if (pos === "serenav") outputString += "|y"; outputString += "}}\n"; } outputString += "{{" + pos + "|" + values.lang; if (pos === "navdêr" || pos === "serenav") { if (cinsiyet) { outputString += "|c=" + cinsiyet; } else if (values.lang === "ku") { // Unknown gender — prompt editor to fill it in. outputString += "|c=?"; } } else if (/^lêker/.test(pos) && lekTur) { outputString += "|c=" + lekTur; } if (values.tr) { outputString += "|tr=" + values.tr; } outputString += "}}\n"; return outputString; } }, /** * cinsiyet (grammatical gender) — only shown for navdêr/serenav, û * tenê ger metadata ji bo zimanê hilbijartî lîsteyeke "g" (cinsiyet) * were dayîn. Opsiyonên vê gavê ne sabît in — ji metadata[values.lang].g * têne çêkirin, ji ber ku di hemû zimanan de cinsiyet tine. */ cinsiyet: { id: "cinsiyet", name: "cinsiyet", question_fmt: 'Cinsiyeta "' + pageName + '" çi ye?', question_br: true, visible: function (values) { var meta = metadata[values.lang]; return !!(values.lang && (values.pos === "navdêr" || values.pos === "serenav") && meta && meta.g && meta.g.length); }, build: function (stepDiv, values) { var select = stepDiv.find("select.wiktku-start-step-field"); if (!select.length) { select = $(mw.html.element("select", { "class": "wiktku-start-step-field", id: "wiktku-start-cinsiyet-field" })); stepDiv.append(select); } if (!values) return select; var meta = metadata[values.lang]; var codes = (meta && meta.g) || []; var prevVal = select.val(); var choices = $.map(codes, function (code) { return [[code, genderLabel(code)]]; }); populateMenus(select, choices); if ($.grep(choices, function (c) { return c[0] === prevVal; }).length) { select.val(prevVal); } if (!isMobile) select.trigger("chosen:updated"); return select; }, output: function () { return ""; } // consumed by pos.output }, /** * Lêker transitivity — only shown for any lêker variant. */ lektur: { id: "lektur", name: "Cureyê lêkerê (fiîlê)", question_fmt: "Cureyê lêkerê (fiîlê) çi ye?", question_br: true, visible: function (values) { return values.lang && values.pos && /^lêker/.test(values.pos); }, // Dictionary: value → display label. Add new types here. choices: [ ["gh", "gerguhêz"], ['x-gh', 'xwerû-gerguhêz'], ['p-gh', 'pêkhatî-gerguhêz'], ['h-gh', 'hevedudanî-gerguhêz'], ['b-gh', 'biwêjî-gerguhêz'], ["ngh", "negerguhêz"], ['x-ngh', 'xwerû-negerguhêz'], ['p-ngh', 'pêkhatî-negerguhêz'], ['h-ngh', 'hevedudanî-negerguhêz'], ['b-ngh', 'biwêjî-negerguhêz'] ], output: function () { return ""; } // consumed by pos.output }, tr: { id: "tr", name: "transkrîpsiyon", question_fmt: "Transkrîpsiyona kelîmeyê", multiple: false, narrow: true, visible: function (values) { return values.lang && values.pos && needsTransliteration(values.lang); } }, dfn: { id: "dfn", // required: true, ger mane tinebe [[Şablon:mane?]] bi kar bîne name: "Mane", question_fmt: "Maneya kelîmeyê binivîse. Mane otomatîk tê lînkkirin! Ji bo tercimeyan beşa 'Werger' bi kar bîne!", multiple: true, ordered: true, rows: 3, visible: function (values) { return values.lang && values.pos; }, example: function (values) { // posExamples loaded from [[MediaWiki:Gadget-start.js/data.json]]. var examples = steps.dfn.posExamples || {}; var full = values.pos || ""; return examples[full] || ""; }, /** * Builds one sense block (<li>) inside the ordered list. * Each block contains: * - a textarea for the definition * - an expandable nimûne list * - single-row sub-lists for formên alternatîv, hevmane, dijmane */ buildSenseBlock: function (stepDiv) { var block = $("<li class='wiktku-dfn-sense'></li>"); // — Mane textarea (declared first so the template handler can reference it) — var dfnArea = $("<textarea></textarea>") .attr("name", "wiktku-dfn-mane-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("class", "wiktku-start-step-field wiktku-dfn-mane") .attr("rows", 6) .attr("placeholder", "Mane…"); dfnArea.on("input", function () { steps.dfn.onDfnInput(stepDiv, block, this); }); // — Template selector (optional — replaces mane when chosen) — // Template definitions loaded from [[MediaWiki:Gadget-start.js/data.json]]. var tplDefs = steps.dfn.tplDefs || []; // Cache of all non-placeholder option elements — used by updateTplOptions // to remove/re-add options (the only approach compatible with Chosen.js). var _allTplOptions = []; var tplSelect = $(mw.html.element("select", { "class": "wiktku-dfn-tpl-select" })); tplSelect.append($("<option value=''>— yan jî şablonek hilbijêre —</option>")); $.each(tplDefs, function (_, tpl) { var opt = $("<option></option>") .val(tpl.name) .text(tpl.name) .attr("data-langs", tpl.langs ? tpl.langs.join(",") : "") .attr("data-nolang", tpl.noLang ? "1" : ""); tplSelect.append(opt); _allTplOptions.push(opt[0]); }); function updateTplOptions() { var lang = getValues().lang || ""; var currentVal = tplSelect.val(); var currentStillValid = false; // Detach all non-placeholder options, then re-attach only the visible ones. // This is the only approach that works correctly with both native <select> // and Chosen.js on desktop. tplSelect.find("option[value!='']").detach(); $.each(_allTplOptions, function (_, opt) { var allowed = $(opt).attr("data-langs"); var visible = !allowed || allowed.split(",").indexOf(lang) !== -1; if (visible) { tplSelect.append(opt); if ($(opt).val() === currentVal) currentStillValid = true; } }); if (!isMobile) tplSelect.trigger("chosen:updated"); if (currentVal && !currentStillValid) { tplSelect.val(""); dfnArea.show(); tplTitleInput.hide().val(""); } } // Store updater on the element so refresh() can call it for all blocks. tplSelect.data("updateOptions", updateTplOptions); var tplTitleInput = $("<input type='text'>") .addClass("wiktku-dfn-tpl-title wiktku-start-narrow") .attr("placeholder", "Navê rûpelê…") .hide(); // Grow the sense list when the title field of the last block gets content, // mirroring what onDfnInput does for the plain mane textarea. tplTitleInput.on("input", function () { steps.dfn.onDfnInput(stepDiv, block, this); }); /** * When a şablon sense is chosen, formên alternatîv/hevmane/dijmane/ * termên koordîne/jornav/jêrnav don't apply (there's no plain gloss * to hang them off), so hide those subgroups. Etîket, Nimûne and * Jêgirtin stay visible and still usable for a şablon sense. */ function updateFieldVisibility() { var isTpl = !!tplSelect.val(); $.each(HIDDEN_ON_TPL_GROUPS, function (_, cls) { block.find("." + cls + "-group").toggle(!isTpl); }); } // Store on the block so restoreDfn() can re-sync visibility // after programmatically setting tplSelect's value. block.data("updateFieldVisibility", updateFieldVisibility); tplSelect.on("change", function () { var chosen = $(this).val(); if (chosen) { dfnArea.hide(); tplTitleInput.show().focus(); } else { dfnArea.show(); tplTitleInput.hide().val(""); } updateFieldVisibility(); // Re-run refresh so the Werger step visibility updates. refresh(); }); var tplRow = $("<div></div>").addClass("wiktku-dfn-tpl-row") .append(tplSelect).append(" ").append(tplTitleInput); block.append(tplRow); block.append(dfnArea); // Apply lang filter on initial build. updateTplOptions(); // — Sub-field groups — // All groups are always visible with a placeholder textarea. // Nimûne is last in the DOM and last in the output. var allGroups = [ { cls: "wiktku-dfn-etiket", label: "Etîket", rows: 1, narrow: true, izah: "xisûsen, Mêrdîn, anatomî, Badînî" }, { cls: "wiktku-dfn-alternativ", label: "Formên alternatîv", rows: 1, narrow: true, izah: "Varyantên vê kelîmeyê" }, { cls: "wiktku-dfn-hevmane", label: "Hevmane", rows: 1, narrow: true, izah: "Spehî hevmaneya Bedew e." }, { cls: "wiktku-dfn-dijmane", label: "Dijmane", rows: 1, narrow: true, izah: "Zengîn dijmaneya feqîr e." }, { cls: "wiktku-dfn-koordine", label: "Termên koordîne", rows: 1, narrow: true, izah: "Pisîk û kûçik termên koordîne ne çunkî Jornavên wan gelek in" }, { cls: "wiktku-dfn-jornav", label: "Jornav", rows: 1, narrow: true, izah: "Heywan jornavê guhandar e" }, { cls: "wiktku-dfn-jernav", label: "Jêrnav", rows: 1, narrow: true, izah: "Guhandar jêrnavê heywan e" }, { cls: "wiktku-dfn-nimune", label: "Nimûne", rows: 2, narrow: false } ]; $.each(allGroups, function (_, g) { var groupDiv = $("<div></div>").addClass("wiktku-dfn-subgroup " + g.cls + "-group"); function buildNimuneLi() { var lang = getValues().lang || ""; var li = $("<li></li>").addClass("wiktku-dfn-nimune-li"); var mainTa = $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-text-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", g.rows) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-text") .attr("placeholder", "Nimûneya emilandina kelîmeyê tu bi xwe binivîse…"); mainTa.on("input", function () { var val = $.trim($(this).val()); var isLast = li.is(list.children("li:last-child")); if (val && isLast) { list.append(buildNimuneLi()); } }); li.append(mainTa); var subWrap = $("<div></div>").addClass("wiktku-dfn-nimune-sub"); if (needsTransliteration(lang)) { subWrap.append( $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-tr-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 5) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-tr") .attr("placeholder", "Transkrîpsiyona bi alfabeya latînî") ); } if (lang && lang !== "ku") { subWrap.append( $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-t-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 5) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-t") .attr("placeholder", "Tercimeya kurmancî") ); } if (subWrap.children().length) li.append(subWrap); return li; } if (g.cls === "wiktku-dfn-nimune") { // Nimûne — compound widget with tr/t sub-fields. var lbl = $("<span></span>").addClass("wiktku-dfn-sublabel").text(g.label + ": "); var list = $("<ol></ol>").addClass("wiktku-dfn-sublist " + g.cls + "-list"); groupDiv.data("buildNimuneLi", buildNimuneLi); list.append(buildNimuneLi()); groupDiv.append(lbl).append(list); block.append(groupDiv); } else { // Regular always-visible group — label + growing textarea list. var lbl = $("<span></span>").addClass("wiktku-dfn-sublabel").text(g.label + ": " + g.izah); var list = $("<ol></ol>").addClass("wiktku-dfn-sublist " + g.cls + "-list"); var firstInput = $("<textarea></textarea>") .attr("name", g.cls + "-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", g.rows) .attr("class", "wiktku-dfn-subfield" + (g.narrow ? " wiktku-start-narrow" : "")) .attr("placeholder", g.label + "…"); firstInput.on("input", function () { steps.dfn.onSubInput(list, this, g.rows, g.narrow); }); list.append($("<li></li>").append(firstInput)); groupDiv.append(lbl).append(list); block.append(groupDiv); } }); // — Jêder (quote / citation) group — a growing list, sibling to Nimûne — // Structured the same way as Nimûne (ol.wiktku-dfn-sublist > li) so it // lines up at the same indentation, and so that typing into the last // citation's Jêgirtin box automatically opens a fresh empty one below it. (function () { var jederGroupDiv = $("<div></div>").addClass("wiktku-dfn-subgroup wiktku-dfn-jeder-group"); var jederLbl = $("<span></span>").addClass("wiktku-dfn-sublabel").text("Jêgirtin: "); var jederList = $("<ol></ol>").addClass("wiktku-dfn-sublist wiktku-dfn-jeder-list"); function buildJederLi() { var lang = getValues().lang || ""; var li = $("<li></li>").addClass("wiktku-dfn-jeder-li"); var dragHandle = $("<span></span>") .addClass("wiktku-jeder-drag-handle") .attr("title", "Bişkûne û bikişîne da ku rêzê biguhezîne"); // Quote text textarea var quoteTa = $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-quote-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 2) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-quote") .attr("placeholder", "Nimûneya emilandinê ji kitêb an çavkaniyeke din binivîse"); quoteTa.on("input", function () { var val = $.trim($(this).val()); var isLast = li.is(jederList.children("li:last-child")); if (val && isLast) { jederList.append(buildJederLi()); } }); li.append(dragHandle).append(quoteTa); // tr/t sub-fields for the quote — shown as needed for the language. var quoteSubWrap = $("<div></div>").addClass("wiktku-dfn-quote-sub"); if (needsTransliteration(lang)) { quoteSubWrap.append( $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-quote-tr-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 2) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-quote-tr") .attr("placeholder", "Transkrîpsiyona jêgirtinê…") ); } if (lang && lang !== "ku") { quoteSubWrap.append( $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-quote-t-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 2) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-quote-t") .attr("placeholder", "Tercimeya jêgirtinê bi kurmancî") ); } if (quoteSubWrap.children().length) li.append(quoteSubWrap); // Citoid auto-fill: fetch citation data from a URL, DOI or ISBN and // prefill the source şablon + fields below (see Gadget-citoid-helper.js). var citoidWrap = $("<div></div>").addClass("wiktku-dfn-quote-citoid"); var citoidInput = $("<input type='text'>") .addClass("wiktku-dfn-quote-citoid-input wiktku-start-narrow") .attr("placeholder", "URL, DOI an ISBN binivîse ku otomatîk were tijekirin…"); var citoidBtn = new OO.ui.ButtonWidget({ label: "Bi Citoid bîne", classes: [ "wiktku-dfn-quote-citoid-btn" ] }); var citoidStatus = $("<span></span>").addClass("wiktku-dfn-quote-citoid-status"); /** * Fetches citation data from Citoid and applies it to this * citation's şablon selector + fields. Mirrors the logic in * Form.prototype._fillFromCitoid (Gadget-wikt.add-examples.js): * - only (re)selects the şablon when it actually differs from * what's already chosen, so a repeat fetch doesn't wipe out * a template the user already picked; * - only fills fields that are currently empty, so it never * overwrites something the user typed by hand; * - falls back to the freeform "bi destê xwe binivîsim" source * only when nothing was typed there yet. */ function runCitoidFetch() { var query = $.trim(citoidInput.val()); if (!query) { mw.notify("Ji kerema xwe re pêşî URL, DOI an ISBNyekê binivîse."); return; } citoidBtn.setDisabled(true); citoidStatus.text("Tê anîn…"); wikt.citoidHelper.ensure().then(function () { return wikt.citoid.fetchJederFields(query); }).then(function (result) { var jederKey = result.jederKey; var hasTpl = !!jederKey && srcSel.find("option[value='" + jederKey + "']").length > 0; var targetVal = hasTpl ? jederKey : "__manual__"; // Only (re)select — and thus rebuild — the field rows if // we're switching to a different şablon than what's // already chosen, so a second fetch doesn't clear fields // the user already filled in by hand. if (srcSel.val() !== targetVal) { srcSel.val(targetVal).trigger("change"); srcSel.trigger("chosen:updated"); } if (hasTpl) { // Tenê qadên vala tijî bike. $.each(result.fields, function (key, val) { var input = srcFields.find("[data-field-key='" + key + "']"); if (input.length && !$.trim(input.val())) { input.val(val); } }); } else { // Şablonek nehat naskirin ji bo vê itemType — rêzikeke // çavkaniyê ya bi destan a ji qadên Citoid tê çêkirin, // lê tenê ger qada destan vala be. var manualField = srcFields.find(".wiktku-dfn-quote-src-manual"); if (!$.trim(manualField.val())) { var parts = []; $.each(["nivîskar", "sernav", "websîte", "kovar", "weşanxane", "sal", "url"], function (_, k) { if (result.fields[k]) parts.push(result.fields[k]); }); manualField.val(parts.join(", ")); } } citoidStatus.text(""); }, function (errorMsg) { citoidStatus.text(typeof errorMsg === "string" ? errorMsg : "Nehat dîtin. Kontrol bike ka URL/DOI/ISBN rast e."); }).always(function () { citoidBtn.setDisabled(false); }); } citoidBtn.on("click", runCitoidFetch); citoidInput.on("keydown", function (e) { if (e.which === 13) { // Enter e.preventDefault(); runCitoidFetch(); } }); citoidWrap.append(citoidInput).append(citoidBtn.$element).append(citoidStatus); // Source template selector, specific to this citation. var srcSel = $("<select></select>").addClass("wiktku-dfn-quote-src-sel"); srcSel.append($("<option value=''>— Çavkaniyê hilbijêre —</option>")); srcSel.append($("<option></option>").val("__manual__").text("Bi destê xwe binivîsim")); var jederDefs = steps.dfn.jederDefs || {}; $.each(jederDefs, function (tplName, def) { srcSel.append($("<option></option>").val(tplName).text(def.label)); }); // Dynamic source fields container. var srcFields = $("<div></div>").addClass("wiktku-dfn-quote-src-fields"); srcSel.on("change", function () { srcFields.empty(); var chosen = $(this).val(); if (!chosen) return; if (chosen === "__manual__") { // Freeform source, written by the user — becomes the 2nd // positional param of {{jêder|lang|…}} instead of çavkanî?. srcFields.append( $("<textarea></textarea>") .attr("rows", 4) .addClass("wiktku-dfn-subfield wiktku-dfn-quote-src-manual") .attr("placeholder", "Çavkaniyê bi destê xwe binivîse…") ); return; } var def = (steps.dfn.jederDefs || {})[chosen]; if (!def) return; $.each(def.fields, function (_, f) { var row = $("<div></div>").addClass("wiktku-dfn-quote-src-row"); var fieldLbl = $("<label></label>").text(f.label + ": "); var inp = $("<textarea></textarea>") .attr("rows", 2) .addClass("wiktku-dfn-quote-src-input wiktku-start-narrow") .attr("data-field-key", f.key) .attr("placeholder", f.label + "…"); row.append(fieldLbl).append(inp); srcFields.append(row); }); }); li.append(citoidWrap).append(srcSel).append(srcFields); return li; } jederGroupDiv.data("buildJederLi", buildJederLi); jederList.append(buildJederLi()); // Make citation rows sortable (drag to reorder). // The last row is always the empty trailing row — cancel its drag. mw.loader.using("jquery.ui.sortable", function () { jederList.sortable({ handle: ".wiktku-jeder-drag-handle", axis: "y", items: "li:not(:last-child)", tolerance: "pointer" }); }); jederGroupDiv.append(jederLbl).append(jederList); block.append(jederGroupDiv); }()); // Apply the initial hide/show state for the sub-groups (matches // tplSelect's starting value, which is normally empty). updateFieldVisibility(); return block; }, /** Grows the sense list when the last mane textarea gets content. */ onDfnInput: function (stepDiv, block, textarea) { var val = $.trim($(textarea).val()); var list = stepDiv.find("ol.wiktku-dfn-list"); var isLast = block.is(list.children("li:last-child")); if (val && isLast) { var newBlock = steps.dfn.buildSenseBlock(stepDiv); list.append(newBlock); // Apply Chosen to the new block's template selector on desktop. if (!isMobile) newBlock.find("select.wiktku-dfn-tpl-select").chosen(chosenOptions); } refresh(); }, /** Grows a sub-list (nimûne/formên alternatîv/hevmane/dijmane/termên koordîne) on input. */ onSubInput: function (list, input, rows, narrow) { var val = $.trim($(input).val()); var item = $(input).parent(); var isLast = item.is(list.children("li:last-child")); if (val && isLast) { var next = $("<textarea></textarea>") .attr("name", "wiktku-dfn-sub-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", rows) .attr("class", "wiktku-dfn-subfield" + (narrow ? " wiktku-start-narrow" : "")); next.on("input", function () { steps.dfn.onSubInput(list, this, rows, narrow); }); list.append($("<li></li>").append(next)); } }, // Populated from [[MediaWiki:Gadget-start.js/data.json]] (tplDefs, posExamples, jederDefs). tplDefs: [], posExamples: {}, jederDefs: {}, build: function (stepDiv) { if (stepDiv.find("ol.wiktku-dfn-list").length) return null; var list = $("<ol class='wiktku-dfn-list'></ol>"); list.append(steps.dfn.buildSenseBlock(stepDiv)); stepDiv.append(list); return null; }, /** Reads all sense blocks from the DOM and returns an array of sense objects. */ getSenses: function (stepDiv) { var senses = []; stepDiv.find("li.wiktku-dfn-sense").each(function () { var block = $(this); var tplSel = block.find("select.wiktku-dfn-tpl-select"); var tpl = tplSel.val() || ""; // noLang: template already encodes the language — don't add |lang| param. var tplNoLang = tpl ? tplSel.find("option[value='" + tpl + "']").attr("data-nolang") === "1" : false; var tplTitle = $.trim(block.find("input.wiktku-dfn-tpl-title").val()); var mane = $.trim(block.find("textarea.wiktku-dfn-mane").val()); var etiket = (function () { var vals = []; block.find(".wiktku-dfn-etiket-list textarea").each(function () { var v = $.trim($(this).val()); if (v) vals.push(v); }); return vals; }()); function readList(cls) { var vals = []; block.find("." + cls + "-list textarea").each(function () { var v = $.trim($(this).val()); if (v) vals.push(v); }); return vals; } // Nimûne items are compound: { text, tr?, t? } function readNimuneList() { var items = []; block.find(".wiktku-dfn-nimune-list li.wiktku-dfn-nimune-li").each(function () { var text = $.trim($(this).find(".wiktku-dfn-nimune-text").val()); if (!text) return; var obj = { text: text }; var tr = $.trim($(this).find(".wiktku-dfn-nimune-tr").val()); var t = $.trim($(this).find(".wiktku-dfn-nimune-t").val()); if (tr) obj.tr = tr; if (t) obj.t = t; items.push(obj); }); return items; } // Jêder is a growing list of citations, one per li — mirrors readNimuneList(). function readJederList() { var items = []; block.find(".wiktku-dfn-jeder-list li.wiktku-dfn-jeder-li").each(function () { var li = $(this); var quote = $.trim(li.find(".wiktku-dfn-nimune-quote").val()); if (!quote) return; var obj = { quote: quote }; var qtr = $.trim(li.find(".wiktku-dfn-nimune-quote-tr").val()); var qt = $.trim(li.find(".wiktku-dfn-nimune-quote-t").val()); if (qtr) obj.quoteTr = qtr; if (qt) obj.quoteT = qt; var tplName = li.find(".wiktku-dfn-quote-src-sel").val(); if (tplName === "__manual__") { var manual = $.trim(li.find(".wiktku-dfn-quote-src-manual").val()); if (manual) obj.jederManual = manual; } else if (tplName) { obj.jederTpl = tplName; var fields = {}; li.find(".wiktku-dfn-quote-src-input").each(function () { var k = $(this).attr("data-field-key"); var v = $.trim($(this).val()); if (k && v) fields[k] = v; }); obj.jêderFields = fields; } items.push(obj); }); return items; } senses.push({ tpl: tpl, tplNoLang: tplNoLang, tplTitle: tplTitle, mane: mane, etiket: etiket, nimune: readNimuneList(), jeder: readJederList(), alternativ: readList("wiktku-dfn-alternativ"), hevmane: readList("wiktku-dfn-hevmane"), dijmane: readList("wiktku-dfn-dijmane"), koordine: readList("wiktku-dfn-koordine"), jornav: readList("wiktku-dfn-jornav"), jernav: readList("wiktku-dfn-jernav") }); }); return senses; }, getOutput: function (values, callback) { var stepDiv = $("#wiktku-start-dfn"); var senses = steps.dfn.getSenses(stepDiv); var lang = values.lang; // A sense counts as "filled" if it has a mane, a chosen template + title, // or any other content (etîket/hevmane/nimûne/jêder…) worth keeping. var hasMane = senses.some(function (s) { return s.mane !== "" || (s.tpl && s.tplTitle) || senseHasExtraContent(s); }); // True only when at least one sense has a regular mane (needs linkify). var hasRegularMane = senses.some(function (s) { return !s.tpl && s.mane !== ""; }); // nimûne and jêder lines must never pass through linkify — only // the plain mane text should be linkified. We build two parallel // arrays: defLines (sent to linkify) and citeLines (kept aside). // Each entry in citeLines corresponds 1-to-1 with a defLines entry; // a template token {{wiktku-cite-N}} is embedded in defLines so // that after linkify runs we know exactly where to splice them back. // Template-call syntax is guaranteed safe: linkifiers leave {{ }} // tokens completely untouched. var defLines = []; // one entry per kept sense (goes to linkify) var citeLines = []; // parallel — nimûne+jêder for that same sense $.each(senses, function (_, sense) { // — Template sense (e.g. {{guharto|ku|somepage}}) — if (sense.tpl) { if (!sense.tplTitle) return; // skip empty template senses var tplLabelTpl = ""; if (sense.etiket && sense.etiket.length) { var tplLabelParts = sense.etiket.map(function (part) { return $.trim(part); }).filter(function (part) { return part !== ""; }); if (tplLabelParts.length) { tplLabelTpl = " {{e|" + lang + "|" + tplLabelParts.join("|") + "}} "; } } var tplCall = sense.tplNoLang ? "{{" + sense.tpl + "|" + sense.tplTitle + "}}" : "{{" + sense.tpl + "|" + lang + "|" + sense.tplTitle + "}}"; var tplHasJeder = sense.jeder && $.grep(sense.jeder, function (j) { return j && j.quote; }).length > 0; var idx = defLines.length; var cite = formatNimune(sense.nimune, lang, tplHasJeder) + formatJeder(sense.jeder, lang); defLines.push("#" + (tplLabelTpl ? tplLabelTpl : " ") + tplCall + (cite ? "{{wiktku-cite-" + idx + "}}" : "")); citeLines.push(cite); return; } // — Normal mane sense — var dfn = sense.mane; if (!dfn && !senseHasExtraContent(sense)) return; // truly empty if (dfn) { dfn = stripWikilinks(dfn); if (dfn[0] !== dfn[0].toUpperCase()) dfn = capitalize(dfn); if (!dfn.match(/[.…?!)\]]$/)) dfn += "."; } else { dfn = "{{mane?|" + lang + "}}"; } var labelTpl = ""; if (sense.etiket && sense.etiket.length) { var labelParts = sense.etiket.map(function (part) { return $.trim(part); }).filter(function (part) { return part !== ""; }); if (labelParts.length) { labelTpl = " {{e|" + lang + "|" + labelParts.join("|") + "}} "; } } var out = "#" + (labelTpl ? labelTpl : " ") + dfn; function wordLine(tpl, words) { if (!words.length) return ""; return "\n#: {{" + tpl + "|" + lang + "|" + words.join("|") + "}}"; } out += wordLine("alt-r", sense.alternativ); out += wordLine("hevmane", sense.hevmane); out += wordLine("dijmane", sense.dijmane); out += wordLine("koordîne", sense.koordine); out += wordLine("jornav", sense.jornav); out += wordLine("jêrnav", sense.jernav); var hasJeder = sense.jeder && $.grep(sense.jeder, function (j) { return j && j.quote; }).length > 0; var cite = formatNimune(sense.nimune, lang, hasJeder) + formatJeder(sense.jeder, lang); var idx = defLines.length; defLines.push(out + (cite ? "{{wiktku-cite-" + idx + "}}" : "")); citeLines.push(cite); }); // Splice citeLines back into a linkified string, replacing each // {{wiktku-cite-N}} token with its stored nimûne/jêder block. function restoreCites(t) { return t.replace(/\{\{wiktku-cite-(\d+)\}\}/g, function (_, n) { return citeLines[parseInt(n, 10)] || ""; }); } var text = defLines.join("\n") + "\n"; if (!hasMane) { // No definitions entered — emit {{mane?}} with bênimûne. text = "# {{mane?|" + lang + "}}\n#* {{bênimûne|" + lang + "}}\n"; callback(text); return; } if (!hasRegularMane) { // All filled senses are template senses — no linkify needed. callback(restoreCites(text)); return; } var didTryToLoad = function () { if (typeof $.wiktviLinkify === "function") { $.wiktviLinkify(text, function (linked) { callback(restoreCites(linked)); }); } else { callback(restoreCites(text)); } }; mw.loader.using("ext.gadget.linkify", didTryToLoad, didTryToLoad); } }, je: makeWordListStep("je", "jê", "Kelîmeyên jê çêbûyî binivîse", "Jê", "g"), tekildar: makeWordListStep("tekildar", "têkildar", "Kelîmeyên ji aliyê etîmolojiyê ve têkildarî vê kelîmeyê binivîse", "Têkildar", "g"), binereherwiha: makeWordListStep("binereherwiha", "binêre herwiha", "Kelîmeyên din ên eleqedar binivîse", "Binêre herwiha", "g"), etym: { id: "etym", name: "etîmolojî", question_fmt: "Etîmolojiya kelîmeyê binivîse", // etymTpls populated from data.json etymTpls: [], visible: function (values) { return values.lang && values.pos; }, /** Fills (or refills) the insert-dropdown from the current etymTpls array. */ refreshTplSelect: function () { var sel = $("#wiktku-start-etym .wiktku-tpl-insert-select"); if (!sel.length) return; sel.find("option[value!='']").remove(); $.each(steps.etym.etymTpls, function (_, tpl) { sel.append($("<option></option>").val(tpl.snippet).text(tpl.name + " — " + tpl.desc)); }); // Notify Chosen that the option list has changed (no-op on mobile). if (!isMobile) sel.trigger("chosen:updated"); }, build: function (stepDiv) { if (stepDiv.find(".wiktku-etym-wrap").length) return null; var wrap = $("<div class='wiktku-etym-wrap'></div>"); var ta = $("<textarea></textarea>") .attr("name", "wiktku-etym-" + $.now()) .attr("class", "wiktku-start-step-field wiktku-etym-text") .attr("rows", 4) .attr("placeholder", "Nimûne: Ji {{ji|en|ku|apple}}. yan rasterast binivîse…"); // Template insert dropdown — options also refreshed after data.json loads. var sel = $("<select class='wiktku-tpl-insert-select'></select>"); sel.append($("<option value=''>— şablonek lê zêde bike —</option>")); $.each(steps.etym.etymTpls, function (_, tpl) { sel.append($("<option></option>").val(tpl.snippet).text(tpl.name + " — " + tpl.desc)); }); sel.on("change", function () { var snippet = $(this).val(); if (!snippet) return; var lang = getValues().lang || ""; snippet = snippet.replace(/CODE/g, lang).replace(/SOURCELANG/g, "?"); insertAtCursor(ta[0], snippet); $(this).val(""); ta.focus(); }); wrap.append(sel).append($("<br>")).append(ta); stepDiv.append(wrap); return ta; }, output: function (values) { var text = $.trim($("#wiktku-start-etym .wiktku-etym-text").val()); if (text) { return "\n==== Etîmolojî ====\n" + text + "\n"; } // No etymology entered — emit {{ji?|lang}} as a placeholder, // but only when the entry has at least one regular (non-şablon) // sense with content — either real mane text, or an empty mane // with other fields filled in (which dfn.getOutput() renders as // {{mane?|lang}} with those fields attached). A şablon sense // like {{guharto|…}} never counts, filled in or not. var dfnSenses = steps.dfn.getSenses($("#wiktku-start-dfn")); var hasRegularMane = dfnSenses.some(function (s) { return !s.tpl && (s.mane !== "" || senseHasExtraContent(s)); }); if (!hasRegularMane) return ""; return "\n==== Etîmolojî ====\n{{ji?|" + values.lang + "}}\n"; } }, dunde: { id: "dunde", name: "dûnde", question_fmt: "Eger ev kelîme ji vî zimanî ketibe zimanekî din, vî zimanî û kelîmeya wî binivîse", visible: function (values) { return !!values.pos; }, disabledKeys: { "navz": true}, /** * Builds one row: a language dropdown + a growing list of word * inputs. When the dropdown gets a value the next empty row is * appended automatically. Mirrors steps.trans's row widget, but * flat (one shared list — dûnde isn't tied to individual senses). */ buildRow: function (stepDiv) { var row = $("<li class='wiktku-dunde-row wiktku-lang-row'></li>"); // Language selector — chosen is applied after insertion into DOM. var langSel = $(mw.html.element("select", { "class": "wiktku-start-step-keyfield wiktku-start-narrow" })); langSel.attr("data-placeholder", "Zimanekî lê bigere"); populateMenus(langSel, steps.dunde.keys || [], steps.dunde.disabledKeys); // When a language is chosen, ensure a next empty row exists. langSel.on("change", function () { steps.dunde.onLangChange(stepDiv, row); }); // Word list for this language. var wordList = $("<ul class='wiktku-dunde-words wiktku-lang-row-words'></ul>"); var firstWord = steps.dunde.makeWordInput(); wordList.append($("<li></li>").append(firstWord)); if (isMobile) { row.append(wrapNativeSelect(langSel)).append(wordList); } else { row.append(langSel).append(wordList); } return row; }, makeWordInput: function () { var input = $("<textarea></textarea>") .attr("name", "wiktku-dunde-word-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 1) .attr("class", "wiktku-dfn-subfield wiktku-start-narrow") .attr("placeholder", "Kelîme…"); input.on("input", function () { var list = $(this).closest("ul.wiktku-dunde-words"); var item = $(this).parent(); var val = $.trim($(this).val()); if (val && item.is(list.children("li:last-child"))) { var next = steps.dunde.makeWordInput(); list.append($("<li></li>").append(next)); } }); return input; }, onLangChange: function (stepDiv, row) { var list = stepDiv.find("ul.wiktku-dunde-list"); var isLast = row.is(list.children("li.wiktku-dunde-row:last-child")); if (isLast) { var newRow = steps.dunde.buildRow(stepDiv); list.append(newRow); // Init chosen after the new row is in the DOM (desktop only). if (!isMobile) newRow.find("select").chosen(chosenOptions); } // Keep disabled keys in sync across all lang selectors. steps.dunde.syncDisabledKeys(stepDiv); }, /** Disables already-selected languages in all other dropdowns. */ syncDisabledKeys: function (stepDiv) { var taken = $.extend({}, steps.dunde.disabledKeys); stepDiv.find("li.wiktku-dunde-row select").each(function () { var v = $(this).val(); if (v) taken[v] = true; }); stepDiv.find("li.wiktku-dunde-row select").each(function () { var self = $(this); var own = self.val(); self.find("option").each(function () { var code = $(this).val(); if (!code) return; $(this).prop("disabled", taken[code] && code !== own); }); self.trigger("chosen:updated"); }); }, build: function (stepDiv) { if (stepDiv.find("ul.wiktku-dunde-list").length) return null; var list = $("<ul class='wiktku-dunde-list wiktku-lang-row-list'></ul>"); list.append(steps.dunde.buildRow(stepDiv)); stepDiv.append(list); // Init chosen after the select is in the DOM (desktop only). if (!isMobile) list.find("select").chosen(chosenOptions); return null; }, /** Reads all [langcode, words[]] rows from the DOM. */ getRows: function (stepDiv) { var result = []; stepDiv.find("li.wiktku-dunde-row").each(function () { var lang = $(this).find("select").val(); if (!lang) return; var words = []; $(this).find("ul.wiktku-dunde-words textarea").each(function () { var v = $.trim($(this).val()); if (v) words.push(v); }); if (words.length) result.push([lang, words]); }); return result; }, output: function () { var stepDiv = $("#wiktku-start-dunde"); var rows = steps.dunde.getRows(stepDiv); if (!rows.length) return ""; var lines = $.map(rows, function (row) { var lang = row[0], words = row[1]; return "* {{dû|" + lang + "|" + words.join("|") + "}}"; }); return "\n==== Dûnde ====\n" + lines.join("\n") + "\n"; } }, zarava: { id: "zarava", name: "bi zaravayên din", visible: function (values) { return steps.trans.visible(values); }, disabledKeys: { "navz": true }, buildRow: function (group) { var row = $("<li class='wiktku-zarava-row wiktku-lang-row'></li>"); var langSel = $(mw.html.element("select", { "class": "wiktku-start-step-keyfield wiktku-start-narrow" })); populateMenus(langSel, steps.zarava.keys || [], steps.zarava.disabledKeys); langSel.on("change", function () { steps.zarava.onLangChange(group, row); }); var wordList = $("<ul class='wiktku-zarava-words wiktku-lang-row-words'></ul>"); var firstWord = steps.zarava.makeWordInput(); wordList.append($("<li></li>").append(firstWord)); row.append(langSel).append(wordList); return row; }, makeWordInput: function () { var input = $("<textarea></textarea>") .attr("name", "wiktku-zarava-word-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 1) .attr("class", "wiktku-dfn-subfield wiktku-start-narrow") .attr("placeholder", "Tercime…"); input.on("input", function () { var list = $(this).closest("ul.wiktku-zarava-words"); var item = $(this).parent(); var val = $.trim($(this).val()); if (val && item.is(list.children("li:last-child"))) { var next = steps.zarava.makeWordInput(); list.append($("<li></li>").append(next)); } }); return input; }, onLangChange: function (group, row) { var list = group.find("ul.wiktku-zarava-list"); var isLast = row.is(list.children("li.wiktku-zarava-row:last-child")); if (isLast) { var newRow = steps.zarava.buildRow(group); list.append(newRow); } steps.zarava.syncDisabledKeys(group); }, /** Disables already-selected dialects in all other dropdowns within one group. */ syncDisabledKeys: function (group) { var taken = $.extend({}, steps.zarava.disabledKeys); group.find("li.wiktku-zarava-row select").each(function () { var v = $(this).val(); if (v) taken[v] = true; }); group.find("li.wiktku-zarava-row select").each(function () { var self = $(this); var own = self.val(); self.find("option").each(function () { var code = $(this).val(); if (!code) return; $(this).prop("disabled", taken[code] && code !== own); }); }); }, /** Builds (or fetches) the .wiktku-zarava-group for one gloss. */ buildGroup: function (stepDiv, gi) { var group = $("<div class='wiktku-zarava-group'></div>").attr("data-gloss-pos", gi); var list = $("<ul class='wiktku-zarava-list wiktku-lang-row-list'></ul>"); list.append(steps.zarava.buildRow(group)); group.append(list); stepDiv.append(group); return group; }, /** Syncs one .wiktku-zarava-group per current gloss (same logic as steps.trans.build). */ build: function (stepDiv) { var glosses = steps.trans.glossList(); if (!glosses.length) { stepDiv.find(".wiktku-zarava-group").remove(); return null; } var existingGroups = stepDiv.find(".wiktku-zarava-group"); if (existingGroups.length > glosses.length) { existingGroups.slice(glosses.length).remove(); } $.each(glosses, function (gi, gloss) { var group = stepDiv.find(".wiktku-zarava-group[data-gloss-pos='" + gi + "']"); if (!group.length) group = steps.zarava.buildGroup(stepDiv, gi); var label = group.find(".wiktku-zarava-group-label"); if (glosses.length > 1) { if (!label.length) { label = $("<div class='wiktku-zarava-group-label'></div>"); group.prepend(label); } label.text(gloss.index + " " + gloss.text); } else if (label.length) { label.remove(); } }); return null; }, /** Reads the dialect rows for a single gloss group. */ getGroupTranslations: function (group) { var result = []; group.find("li.wiktku-zarava-row").each(function () { var lang = $(this).find("select").val(); if (!lang) return; var words = []; $(this).find("ul.wiktku-zarava-words textarea").each(function () { var v = $.trim($(this).val()); if (v) words.push(v); }); if (words.length) result.push([lang, words]); }); return result; }, /** Reads all rows from the DOM, grouped by gloss position. */ getTranslations: function (stepDiv) { var result = []; stepDiv.find(".wiktku-zarava-group").each(function () { result.push(steps.zarava.getGroupTranslations($(this))); }); return result; }, output: function (values) { if (values.lang !== "ku") return ""; var stepDiv = $("#wiktku-start-zarava"); var glosses = steps.trans.glossList(); if (!glosses.length) return ""; var blocks = $.map(glosses, function (gloss, gi) { var group = stepDiv.find(".wiktku-zarava-group[data-gloss-pos='" + gi + "']"); var rows = group.length ? steps.zarava.getGroupTranslations(group) : []; if (!gloss.text && !rows.length) return undefined; if (rows.length) { rows.sort(function (a, b) { var aLang = langsByCode[a[0]] || []; var bLang = langsByCode[b[0]] || []; return (aLang[2] || "").localeCompare(bLang[2] || "", "ku"); }); } var wordLines = $.map(rows, function (row) { var lang = row[0]; var words = row[1]; var wikiWords = words.map(function (w) { return "{{W|" + lang + "|" + w + "}}"; }).join(", "); return "* {{Z|" + lang + "}}: " + wikiWords; }).join("\n"); if (!wordLines) return undefined; var block = "{{werger-ser|" + (gloss.text || "?") + "|" + gloss.index + "}}"; block += "\n" + wordLines; block += "\n{{werger-bin}}"; return block; }); if (!blocks.length) return ""; return "\n==== Bi zaravayên din ====\n" + blocks.join("\n") + "\n"; } }, trans: { id: "trans", name: "werger", visible: function (values) { if (!(values.lang === "ku" && values.pos)) return false; // Hide Werger only when EVERY sense is a template sense (Guharto etc.) // with a title filled in — i.e. there is real content but no plain // gloss to attach a translation table to. A mix of real + template // senses still shows Werger; the template senses are simply skipped // in output(). // // "Real" here means a non-şablon sense with either mane text or // other filled-in fields (etîket/hevmane/nimûne/jêder…), since // dfn.getOutput() renders the latter too, as {{mane?|lang}} plus // whatever else was filled in. // // When nothing has been filled in at all, output() will emit // {{mane?|lang}} instead of a gloss — but Werger should still show, // since the user may want to add translations before they've // settled on a gloss. var dfnSenses = steps.dfn.getSenses($("#wiktku-start-dfn")); var hasRealSense = dfnSenses.some(function (s) { return !s.tpl && (s.mane !== "" || senseHasExtraContent(s)); }); var hasFilledTplSense = dfnSenses.some(function (s) { return s.tpl && s.tplTitle; }); return hasRealSense || !hasFilledTplSense; }, disabledKeys: { "navz": true, "ku": true, "ckb": true, "sdh": true, "lki": true, "hac": true, "zza": true }, /** * Builds one translation row: a language dropdown + a growing list * of word inputs. When the dropdown gets a value the next empty row * is appended automatically. * * @param group the specific .wiktku-trans-group this row belongs to * (each gloss has its own group and its own list of rows, so the * lookups below must stay scoped to that group rather than the * whole step — the step now holds one list per gloss). */ buildRow: function (group) { var row = $("<li class='wiktku-trans-row wiktku-lang-row'></li>"); // Language selector — chosen is applied after insertion into DOM. var langSel = $(mw.html.element("select", { "class": "wiktku-start-step-keyfield wiktku-start-narrow" })); langSel.attr("data-placeholder", "Zimanekî lê bigere"); populateMenus(langSel, steps.trans.keys || [], steps.trans.disabledKeys); // When a language is chosen, ensure a next empty row exists. langSel.on("change", function () { steps.trans.onLangChange(group, row); }); // Word list for this language. var wordList = $("<ul class='wiktku-trans-words wiktku-lang-row-words'></ul>"); var firstWord = steps.trans.makeWordInput(); wordList.append($("<li></li>").append(firstWord)); if (isMobile) { row.append(wrapNativeSelect(langSel)).append(wordList); } else { row.append(langSel).append(wordList); } return row; }, makeWordInput: function () { var input = $("<textarea></textarea>") .attr("name", "wiktku-trans-word-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 1) .attr("class", "wiktku-dfn-subfield wiktku-start-narrow") .attr("placeholder", "Tercime…"); input.on("input", function () { var list = $(this).closest("ul.wiktku-trans-words"); var item = $(this).parent(); var val = $.trim($(this).val()); if (val && item.is(list.children("li:last-child"))) { var next = steps.trans.makeWordInput(); list.append($("<li></li>").append(next)); } }); return input; }, onLangChange: function (group, row) { var list = group.find("ul.wiktku-trans-list"); var isLast = row.is(list.children("li.wiktku-trans-row:last-child")); if (isLast) { var newRow = steps.trans.buildRow(group); list.append(newRow); // Init chosen after the new row is in the DOM (desktop only). if (!isMobile) newRow.find("select").chosen(chosenOptions); } // Keep disabled keys in sync across this gloss's lang selectors // only — the same language can be used for different senses. steps.trans.syncDisabledKeys(group); }, /** Disables already-selected languages in all other dropdowns within one group. */ syncDisabledKeys: function (group) { var taken = $.extend({}, steps.trans.disabledKeys); group.find("li.wiktku-trans-row select").each(function () { var v = $(this).val(); if (v) taken[v] = true; }); group.find("li.wiktku-trans-row select").each(function () { var self = $(this); var own = self.val(); self.find("option").each(function () { var code = $(this).val(); if (!code) return; $(this).prop("disabled", taken[code] && code !== own); }); self.trigger("chosen:updated"); }); }, /** * Builds (or fetches) the .wiktku-trans-group for one gloss, with * its own label and its own list of translation rows. */ buildGroup: function (stepDiv, gi) { var group = $("<div class='wiktku-trans-group'></div>").attr("data-gloss-pos", gi); var list = $("<ul class='wiktku-trans-list wiktku-lang-row-list'></ul>"); list.append(steps.trans.buildRow(group)); group.append(list); stepDiv.append(group); // Init chosen after the select is in the DOM (desktop only). if (!isMobile) list.find("select").chosen(chosenOptions); return group; }, /** * Syncs one .wiktku-trans-group per current gloss, adding new * groups and removing stale ones as senses are added or removed, * while leaving existing groups (and whatever translations the * user has already typed into them) untouched. Groups are keyed * to their gloss's position in glossList() via data-gloss-pos, so * a group always matches the same sense across rebuilds as long * as senses aren't reordered relative to each other. */ build: function (stepDiv) { var glosses = steps.trans.glossList(); if (!glosses.length) { stepDiv.find(".wiktku-trans-group").remove(); return null; } // Drop groups for glosses that no longer exist (always from the // tail — groups are only ever appended in gloss order below). var existingGroups = stepDiv.find(".wiktku-trans-group"); if (existingGroups.length > glosses.length) { existingGroups.slice(glosses.length).remove(); } $.each(glosses, function (gi, gloss) { var group = stepDiv.find(".wiktku-trans-group[data-gloss-pos='" + gi + "']"); if (!group.length) group = steps.trans.buildGroup(stepDiv, gi); // Only label groups when there's more than one gloss to // distinguish between — a single gloss needs no caption. var label = group.find(".wiktku-trans-group-label"); if (glosses.length > 1) { if (!label.length) { label = $("<div class='wiktku-trans-group-label'></div>"); group.prepend(label); } label.text(gloss.index + " " + gloss.text); } else if (label.length) { label.remove(); } }); return null; }, /** Reads the translation rows for a single gloss group. */ getGroupTranslations: function (group) { var result = []; group.find("li.wiktku-trans-row").each(function () { var lang = $(this).find("select").val(); if (!lang) return; var words = []; $(this).find("ul.wiktku-trans-words textarea").each(function () { var v = $.trim($(this).val()); if (v) words.push(v); }); if (words.length) result.push([lang, words]); }); return result; }, /** * Reads all translation rows from the DOM, grouped by gloss * position — one array of [lang, words] rows per gloss group, in * the same order as the .wiktku-trans-group elements. */ getTranslations: function (stepDiv) { var result = []; stepDiv.find(".wiktku-trans-group").each(function () { result.push(steps.trans.getGroupTranslations($(this))); }); return result; }, /** * Builds the numbered "{ index, gloss }" list — one entry per dfn * sense that has a real mane (skips template senses like Guharto, * which have nothing to caption a translation table with). The * index matches the sense's actual position in the numbered "#" * definition list (1-based), including template senses in the count, * so the number printed next to {{werger-ser}} lines up with the * gloss the reader sees in the entry. * * When nothing has been filled in at all (dfn.getOutput() will emit * {{mane?|lang}} as sense 1), this returns a single placeholder * entry with empty text instead of an empty array, so Werger still * has one group to attach translations to before a gloss exists. * When every filled sense is a template sense instead, this stays * empty — that mirrors trans.visible()'s hidden case, where there's * no group in the DOM for a placeholder to attach to anyway. */ glossList: function () { var dfnSenses = steps.dfn.getSenses($("#wiktku-start-dfn")); var glosses = []; var hasFilledTplSense = false; $.each(dfnSenses, function (i, s) { if (s.tpl) { if (s.tplTitle) hasFilledTplSense = true; return; // template sense — no gloss to caption with } var dfn = s.mane; if (!dfn) { // No mane text, but other fields (etîket/hevmane/nimûne/ // jêder…) are filled — dfn.getOutput() still emits this // sense as a numbered line using {{mane?|lang}}, so it // needs its own gloss group too, just with no caption text. if (senseHasExtraContent(s)) glosses.push({ index: i + 1, text: "" }); return; } if (dfn[0] !== dfn[0].toLowerCase()) dfn = decapitalize(dfn); dfn = stripWikilinks(dfn).replace(/[.…?!)\]،؟]+$/, ""); glosses.push({ index: i + 1, text: dfn }); }); if (!glosses.length && !hasFilledTplSense) { glosses.push({ index: 1, text: "" }); } return glosses; }, output: function (values) { if (values.lang !== "ku") return ""; var stepDiv = $("#wiktku-start-trans"); var glosses = steps.trans.glossList(); // Every sense is a template sense — there's no real gloss // anywhere and no group in the DOM either (glossList() only // returns empty in that case), so skip the section entirely. if (!glosses.length) return ""; // Each gloss now has its own group of translation rows — // attach every gloss's own words under its own werger-ser/-bin // pair instead of dumping everything under the first one. var blocks = $.map(glosses, function (gloss, gi) { var group = stepDiv.find(".wiktku-trans-group[data-gloss-pos='" + gi + "']"); var rows = group.length ? steps.trans.getGroupTranslations(group) : []; // Placeholder gloss (no real mane entered yet) with nothing // translated into it — nothing to output, and gloss.text is // empty so there's no caption to give {{werger-ser}} anyway. if (!gloss.text && !rows.length) return undefined; if (rows.length) { // Sort by Kurdish sort key. rows.sort(function (a, b) { var aLang = langsByCode[a[0]] || []; var bLang = langsByCode[b[0]] || []; return (aLang[2] || "").localeCompare(bLang[2] || "", "ku"); }); } var wordLines = $.map(rows, function (row) { var lang = row[0]; var words = row[1]; var wikiWords = words.map(function (w) { return "{{W|" + lang + "|" + w + "}}"; }).join(", "); return "* {{Z|" + lang + "}}: " + wikiWords; }).join("\n"); var block = "{{werger-ser|" + (gloss.text || "?") + "|" + gloss.index + "}}"; if (wordLines) block += "\n" + wordLines; block += "\n{{werger-bin}}"; return block; }); if (!blocks.length) return ""; return "\n==== Werger ====\n" + blocks.join("\n") + "\n"; } }, }; steps.trans.keys = steps.lang.choices; steps.dunde.keys = steps.lang.choices; steps.zarava.keys = getZaravaKeys(steps.lang.choices); var ordered_steps = [ steps.lang, steps.pron, steps.pos, steps.cinsiyet, steps.lektur, steps.tr, steps.dfn, steps.je, steps.tekildar, steps.etym, steps.dunde, steps.binereherwiha, steps.zarava, steps.trans]; // Step ids that belong to each section (not shared across sections). var PER_SECTION_STEP_IDS = [ "pos", "cinsiyet", "lektur", "tr", "dfn", "je", "tekildar", "etym", "dunde", "binereherwiha", "zarava", "trans" ]; // ── Multi-section state ────────────────────────────────────────────────── // Each entry is a plain snapshot: { pos, cinsiyet, lektur, tr, dfn (senses[]), // je, tekildar, binereherwiha, trans (rows[]) }. var sections = [{}]; // section 0 starts empty (DOM is the truth) var activeSection = 0; function snapshotDfn() { return steps.dfn.getSenses($("#wiktku-start-dfn")); } /** * Rebuild the dfn DOM from a previously snapshotted senses array. */ function restoreDfn(senses) { var stepDiv = $("#wiktku-start-dfn"); // Tear down the existing list so build() recreates it cleanly. stepDiv.find("ol.wiktku-dfn-list").remove(); steps.dfn.build(stepDiv); var list = stepDiv.find("ol.wiktku-dfn-list"); $.each(senses, function (i, sense) { // Ensure enough blocks exist (build() seeds one). var blocks = list.find("li.wiktku-dfn-sense"); var block = blocks.eq(i); if (!block.length) { var nb = steps.dfn.buildSenseBlock(stepDiv); list.append(nb); block = list.find("li.wiktku-dfn-sense").last(); } // Template selector. block.find("select.wiktku-dfn-tpl-select").val(sense.tpl || ""); if (sense.tpl) { block.find("textarea.wiktku-dfn-mane").hide(); block.find("input.wiktku-dfn-tpl-title").val(sense.tplTitle || "").show(); } else { block.find("textarea.wiktku-dfn-mane").val(sense.mane || "").show(); block.find("input.wiktku-dfn-tpl-title").hide().val(""); } // Re-sync the formên alternatîv/hevmane/… hide state now that // tplSelect's value was set programmatically (its own "change" // handler doesn't fire from .val(), so this doesn't happen otherwise). var updateVis = block.data("updateFieldVisibility"); if (updateVis) updateVis(); // Restore a sub-list (etiket, formên alternatîv, hevmane …) from a values array. function restoreSubList(cls, values) { if (!values || !values.length) return; var groupDiv = block.find("." + cls + "-group"); var subList = groupDiv.find("ol, ul").first(); if (!subList.length) return; // group not found // Fill existing items, append new ones as needed. $.each(values, function (j, val) { var items = subList.find("li"); if (j < items.length) { items.eq(j).find("textarea").val(val); } else { var ta = $("<textarea></textarea>") .attr("name", "wiktku-dfn-restore-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 1) .attr("class", "wiktku-dfn-subfield wiktku-start-narrow") .val(val); ta.on("input", function () { steps.dfn.onSubInput(subList, this, 1, true); }); subList.append($("<li></li>").append(ta)); } }); } // Reveal and populate lazy groups that have data. var lazyMap = { "wiktku-dfn-etiket": sense.etiket, "wiktku-dfn-alternativ": sense.alternativ, "wiktku-dfn-hevmane": sense.hevmane, "wiktku-dfn-dijmane": sense.dijmane, "wiktku-dfn-koordine": sense.koordine, "wiktku-dfn-jornav": sense.jornav, "wiktku-dfn-jernav": sense.jernav }; $.each(lazyMap, function (cls, vals) { if (vals && vals.length) restoreSubList(cls, vals); }); // Nimûne items are objects { text, tr?, t? } — restore using the builder. if (sense.nimune && sense.nimune.length) { var nimuneGroupDiv = block.find(".wiktku-dfn-nimune-group"); var nimuneList = nimuneGroupDiv.find("ol.wiktku-dfn-nimune-list"); var buildFn = nimuneGroupDiv.data("buildNimuneLi"); nimuneList.empty(); $.each(sense.nimune, function (_, n) { var text = typeof n === "object" ? (n.text || "") : n; if (!text) return; var li = buildFn ? buildFn() : $("<li class='wiktku-dfn-nimune-li'></li>"); li.find(".wiktku-dfn-nimune-text").val(text); if (n.tr) li.find(".wiktku-dfn-nimune-tr").val(n.tr); if (n.t) li.find(".wiktku-dfn-nimune-t").val(n.t); nimuneList.append(li); }); // Always leave a blank trailing item. if (buildFn) nimuneList.append(buildFn()); } // Restore jêder (quote/citation) entries — a growing list, restored using the // builder just like Nimûne. Accepts either the current array shape or a // single legacy object (from older saved sections) for backwards compatibility. var jederArr = $.isArray(sense.jeder) ? sense.jeder : (sense.jeder ? [sense.jeder] : []); if (jederArr.length) { var jederGroupDiv = block.find(".wiktku-dfn-jeder-group"); var jederList = jederGroupDiv.find("ol.wiktku-dfn-jeder-list"); var buildJederFn = jederGroupDiv.data("buildJederLi"); jederList.empty(); $.each(jederArr, function (_, j) { if (!j || !j.quote) return; var li = buildJederFn ? buildJederFn() : $("<li class='wiktku-dfn-jeder-li'></li>"); li.find(".wiktku-dfn-nimune-quote").val(j.quote); if (j.quoteTr) li.find(".wiktku-dfn-nimune-quote-tr").val(j.quoteTr); if (j.quoteT) li.find(".wiktku-dfn-nimune-quote-t").val(j.quoteT); if (j.jederManual) { var manualSel = li.find(".wiktku-dfn-quote-src-sel"); manualSel.val("__manual__").trigger("change"); li.find(".wiktku-dfn-quote-src-manual").val(j.jederManual); } else if (j.jederTpl) { var srcSel = li.find(".wiktku-dfn-quote-src-sel"); srcSel.val(j.jederTpl).trigger("change"); if (j.jêderFields) { $.each(j.jêderFields, function (key, val) { li.find(".wiktku-dfn-quote-src-input[data-field-key='" + key + "']").val(val); }); } } jederList.append(li); }); // Always leave a blank trailing item, same as Nimûne. if (buildJederFn) jederList.append(buildJederFn()); } }); } /** * Snapshot simple (non-dfn) per-section steps from current DOM into obj. */ function saveCurrentSection() { var snap = {}; $.each(PER_SECTION_STEP_IDS, function (_, id) { if (id === "dfn") { snap.dfn = snapshotDfn(); return; } if (id === "etym") { snap.etym = $.trim($("#wiktku-start-etym .wiktku-etym-text").val()); return; } var step = steps[id]; if (!step) return; var stepDiv = $("#wiktku-start-" + id); if (id === "trans") { snap.trans = steps.trans.getTranslations(stepDiv); return; } if (id === "zarava") { snap.zarava = steps.zarava.getTranslations(stepDiv); return; } if (id === "dunde") { snap.dunde = steps.dunde.getRows(stepDiv); return; } // Generic: read all step fields. var fields = stepDiv.find(".wiktku-start-step-field"); if (step.multiple) { snap[id] = fields.map(function () { return $(this).val(); }).get(); } else { snap[id] = fields.val(); } }); sections[activeSection] = snap; } /** * Restore a previously saved snapshot into the form DOM. */ function restoreSection(snap) { $.each(PER_SECTION_STEP_IDS, function (_, id) { if (id === "dfn") { restoreDfn(snap.dfn || []); return; } if (id === "etym") { $("#wiktku-start-etym .wiktku-etym-wrap").remove(); steps.etym.build($("#wiktku-start-etym")); $("#wiktku-start-etym .wiktku-etym-text").val(snap.etym || ""); return; } if (id === "trans") { // Rebuild trans groups (dfn must already be restored by this // point in the $.each loop, so glossList() reflects it). var transDiv = $("#wiktku-start-trans"); transDiv.find(".wiktku-trans-group").remove(); steps.trans.build(transDiv); var groupsSnap = snap.trans || []; $.each(groupsSnap, function (gi, rows) { var group = transDiv.find(".wiktku-trans-group[data-gloss-pos='" + gi + "']"); if (!group.length) return; // gloss no longer exists — drop its rows var list = group.find("ul.wiktku-trans-list"); $.each(rows, function (j, row) { var lang = row[0], words = row[1]; var lastRow = list.find("li.wiktku-trans-row").last(); lastRow.find("select").val(lang).trigger("change"); var wordList = lastRow.find("ul.wiktku-trans-words"); $.each(words, function (k, word) { var wordItems = wordList.find("li"); if (k < wordItems.length) { wordItems.eq(k).find("textarea").val(word); } else { // .val() below doesn't fire "input", so the normal // auto-grow never runs — append a matching item // ourselves instead of silently dropping the word. var extraInput = steps.trans.makeWordInput(); wordList.append($("<li></li>").append(extraInput)); extraInput.val(word); } }); // Leave one trailing empty field so the row can still grow // when the user types, matching a freshly-built row. if ($.trim(wordList.children("li").last().find("textarea").val())) { wordList.append($("<li></li>").append(steps.trans.makeWordInput())); } }); }); return; } if (id === "zarava") { // Rebuild zarava groups (dfn must already be restored by this // point in the $.each loop, so glossList() reflects it). var zaravaDiv = $("#wiktku-start-zarava"); zaravaDiv.find(".wiktku-zarava-group").remove(); steps.zarava.build(zaravaDiv); var zaravaGroupsSnap = snap.zarava || []; $.each(zaravaGroupsSnap, function (gi, rows) { var group = zaravaDiv.find(".wiktku-zarava-group[data-gloss-pos='" + gi + "']"); if (!group.length) return; // gloss no longer exists — drop its rows var list = group.find("ul.wiktku-zarava-list"); $.each(rows, function (j, row) { var lang = row[0], words = row[1]; var lastRow = list.find("li.wiktku-zarava-row").last(); lastRow.find("select").val(lang).trigger("change"); var wordList = lastRow.find("ul.wiktku-zarava-words"); $.each(words, function (k, word) { var wordItems = wordList.find("li"); if (k < wordItems.length) { wordItems.eq(k).find("textarea").val(word); } else { var extraInput = steps.zarava.makeWordInput(); wordList.append($("<li></li>").append(extraInput)); extraInput.val(word); } }); if ($.trim(wordList.children("li").last().find("textarea").val())) { wordList.append($("<li></li>").append(steps.zarava.makeWordInput())); } }); }); return; } if (id === "dunde") { // Rebuild dunde rows. var dundeDiv = $("#wiktku-start-dunde"); dundeDiv.find("ul.wiktku-dunde-list").remove(); steps.dunde.build(dundeDiv); var dundeRows = snap.dunde || []; $.each(dundeRows, function (i, row) { var lang = row[0], words = row[1]; var list = dundeDiv.find("ul.wiktku-dunde-list"); var lastRow = list.find("li.wiktku-dunde-row").last(); lastRow.find("select").val(lang).trigger("change"); var wordList = lastRow.find("ul.wiktku-dunde-words"); $.each(words, function (j, word) { var wordItems = wordList.find("li"); if (j < wordItems.length) { wordItems.eq(j).find("textarea").val(word); } else { // .val() below doesn't fire "input", so the normal // auto-grow never runs — append a matching item // ourselves instead of silently dropping the word. var extraInput = steps.dunde.makeWordInput(); wordList.append($("<li></li>").append(extraInput)); extraInput.val(word); } }); // Leave one trailing empty field so the row can still grow // when the user types, matching a freshly-built row. if ($.trim(wordList.children("li").last().find("textarea").val())) { wordList.append($("<li></li>").append(steps.dunde.makeWordInput())); } }); return; } var step = steps[id]; if (!step) return; var stepDiv = $("#wiktku-start-" + id); var fields = stepDiv.find(".wiktku-start-step-field"); var val = snap[id]; if (val === undefined || val === null) return; if (step.multiple) { var arr = val; fields.each(function (i) { if (i < arr.length) $(this).val(arr[i]); }); } else { fields.val(val); } // Notify chosen widgets of the programmatic value change. if (!isMobile) fields.filter("select").trigger("chosen:updated"); }); } function getWikitextForCurrentSection(callback) { var values = getValues(); var entry = steps.pos.output(values); steps.dfn.getOutput(values, function (output) { entry += output; entry += steps.je.output(values); entry += steps.tekildar.output(values); entry += steps.etym.output(values); entry += steps.dunde.output(values); entry += steps.binereherwiha.output(values); entry += steps.zarava.output(values); entry += steps.trans.output(values); callback(entry, values); }); } function getWikitextAllSections(callback) { saveCurrentSection(); var results = new Array(sections.length); var sharedValues = getValues(); // lang/pron are shared function processSection(i) { if (i >= sections.length) { // All done — restore original active section. restoreSection(sections[activeSection]); refresh(); callback(results, sharedValues); return; } restoreSection(sections[i]); refresh(); getWikitextForCurrentSection(function (sectionText) { results[i] = sectionText; processSection(i + 1); }); } processSection(0); } /** * Assembles wikitext for all sections plus the shared lang/pron header. */ function getWikitext(callback) { getWikitextAllSections(function (sectionTexts, sharedValues) { var entry = steps.lang.output(sharedValues); entry += steps.pron.output(sharedValues); entry += sectionTexts.join("\n"); // Edit summary uses section 0's values. Read from the saved snapshot // (not the live DOM) so it doesn't mix section 0's pos with whichever // section happens to be active/restored at this point. var dfnSenses = (sections[0] && sections[0].dfn) || []; var dfnSummary = dfnSenses.map(function (s) { return s.mane; }).filter(Boolean).join("; "); var summaryLabel = addLangMode ? "WF:Ziman lê zêde" : "WF:Nû"; var summary = "([[Mediawiki:Gadget-start.js|" + summaryLabel + "]] v.2.0) +" + sharedValues.lang + ":" + sections[0].pos + ":" + dfnSummary; var summaryField = document.getElementById("wpSummary"); if (addLangMode && summaryField.value) { summary = summaryField.value + " " + summary; } summaryField.value = summary; callback(entry); }); } var continueBtn; function getValuesForStep(stepId) { var fields = $("#wiktku-start-" + stepId + " .wiktku-start-step-field"); var step = steps[stepId]; if (step.keys) { var values = {}; fields.each(function (i, field) { var key = $(field).prevAll(".wiktku-start-step-keyfield").val(); if (key) values[key] = $(field).val(); }); return values; } else if (step.multiple) { return fields.map(function () { return $(this).val(); }).get(); } return fields.val(); } function getValues() { var values = {}; $.each(steps, function (stepId) { values[stepId] = getValuesForStep(stepId); }); return values; } function populateMenus(inputs, choices, disabledValues) { if (!disabledValues) disabledValues = {}; var vals = inputs.map(function (i, input) { return $(input).val(); }); inputs.empty(); inputs.append($("<option></option>")); $.each(choices, function (j, choice) { // Append the language code in parentheses so that typing a code // (e.g. "ku") in the search box still finds the language name. var displayText = capitalize(choice[1]); if (choice[2] !== undefined) { // This is a language choice [code, name, sortKey] — show code. displayText = capitalize(choice[1]) + " (" + choice[0] + ")"; } var option = $(mw.html.element("option", { value: choice[0] }, displayText)); if (disabledValues[choice[0]]) option.prop("disabled", true); inputs.append(option); }); inputs.val(function (i) { return vals[i]; }); } /** * Returns a bitmap containing the keys that should be disabled for a key * menu in the given step because they are disabled or already taken by * another key menu. */ function getDisabledKeys(step) { var occupiedKeys = {}; $("#wiktku-start-" + step.id + " .wiktku-start-step-keyfield").each(function () { occupiedKeys[$(this).val()] = true; }); if (step.disabledKeys) $.extend(occupiedKeys, step.disabledKeys); return occupiedKeys; } function buildKeyInput(step) { if (!step.keys) return undefined; var input = $(mw.html.element("select", { "class": "wiktku-start-step-keyfield wiktku-start-narrow" })); input.attr("data-placeholder", "Hilbijêre " + step.keyName); if (isMobile) { populateMenus(input, step.keys, getDisabledKeys(step)); // On mobile return the wrapper; the select is inside it. // Change events still fire on the inner select. return wrapNativeSelect(input); } input.on("chosen:showing_dropdown", function () { $(this).data("wiktku-defaultValue", $(this).val()); }); input.change(function (_, context) { var inputs = $("#wiktku-start-" + step.id + " .wiktku-start-step-keyfield").not(this); var oldValue = $(this).data("wiktku-defaultValue"); var newValue = context.selected; inputs.find("option[value='" + oldValue + "']").prop('disabled', false); inputs.find("option[value='" + newValue + "']").prop('disabled', true); inputs.trigger("chosen:updated"); }); populateMenus(input, step.keys, getDisabledKeys(step)); return input; } /** * If the current text field has text and there are no more text fields after * the current text field in the list, add another text field to the list. */ function refreshForTextField(currentInput, step) { currentInput = $(currentInput); var value = currentInput.val(); var item = currentInput.parent(); if (value && !item.next("li").length) { var nextInput = $("<textarea></textarea>") .attr("name", "wiktku-field-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("class", currentInput.attr("class")) .attr("rows", currentInput.attr("rows") || 1); nextInput.on("input", function (evt) { refreshForTextField(evt.target, step); }); var nextKeyInput = buildKeyInput(step); var nextItem = $("<li></li>").append(nextKeyInput).append(nextInput); item.parent().append(nextItem); if (nextKeyInput) nextKeyInput.chosen(chosenOptions); } var canContinue = !continueBtn.isDisabled(); if ((value && !canContinue) || (!value && canContinue)) { refresh(step); } } function prepareInput(input, step) { if (!input) return; if (step.required) input.prop('required', true); input.change(step, refresh); } /** * Shows and hides all the steps based on whether their prerequisites are met, * and updates placeholders where applicable. */ function refresh(evt) { var values = getValues(); var changedStep = evt && evt.data; var didFocus = false; var canContinue = true; // Re-filter template options in every sense block whenever lang changes. $("#wiktku-start-dfn .wiktku-dfn-tpl-select").each(function () { var fn = $(this).data("updateOptions"); if (typeof fn === "function") fn(); }); // Re-filter pronunciation and etymology template dropdowns when language changes. steps.pron.refreshTplSelect(); steps.etym.refreshTplSelect(); // Sync tr/t sub-fields in every nimûne item to the current language. // tr shown when language needs transliteration; t shown when lang !== "ku". (function () { var lang = values.lang || ""; var showTr = needsTransliteration(lang); var showT = lang && lang !== "ku"; $("#wiktku-start-dfn .wiktku-dfn-nimune-list li.wiktku-dfn-nimune-li").each(function () { var li = $(this); // Ensure the sub-wrapper exists when we need it. var subWrap = li.find(".wiktku-dfn-nimune-sub"); // tr field var trTa = li.find(".wiktku-dfn-nimune-tr"); if (showTr && !trTa.length) { if (!subWrap.length) { subWrap = $("<div></div>").addClass("wiktku-dfn-nimune-sub"); li.append(subWrap); } trTa = $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-tr-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 5) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-tr") .attr("placeholder", "Transkrîpsiyon…"); subWrap.prepend(trTa); } else if (!showTr && trTa.length) { trTa.remove(); } // t field var tTa = li.find(".wiktku-dfn-nimune-t"); if (showT && !tTa.length) { if (!subWrap.length) { subWrap = $("<div></div>").addClass("wiktku-dfn-nimune-sub"); li.append(subWrap); } tTa = $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-t-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 5) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-t") .attr("placeholder", "Tercimeya nimûneyê kurmancî…"); subWrap.append(tTa); } else if (!showT && tTa.length) { tTa.remove(); } // Remove the wrapper if it ended up empty. subWrap = li.find(".wiktku-dfn-nimune-sub"); if (subWrap.length && !subWrap.children().length) subWrap.remove(); }); }()); // Sync tr/t sub-fields in every jêder citation to the current language. // tr shown when language needs transliteration; t shown when lang !== "ku". (function () { var lang = values.lang || ""; var showTr = needsTransliteration(lang); var showT = lang && lang !== "ku"; $("#wiktku-start-dfn .wiktku-dfn-jeder-list li.wiktku-dfn-jeder-li").each(function () { var li = $(this); // Ensure the sub-wrapper exists when we need it. It must sit right // after the quote textarea and before the source selector. var subWrap = li.find(".wiktku-dfn-quote-sub"); // tr field var trTa = li.find(".wiktku-dfn-nimune-quote-tr"); if (showTr && !trTa.length) { if (!subWrap.length) { subWrap = $("<div></div>").addClass("wiktku-dfn-quote-sub"); li.find(".wiktku-dfn-nimune-quote").after(subWrap); } trTa = $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-quote-tr-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 2) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-quote-tr") .attr("placeholder", "Transkrîpsiyona jêgirtinê…"); subWrap.prepend(trTa); } else if (!showTr && trTa.length) { trTa.remove(); } // t field var tTa = li.find(".wiktku-dfn-nimune-quote-t"); if (showT && !tTa.length) { if (!subWrap.length) { subWrap = $("<div></div>").addClass("wiktku-dfn-quote-sub"); li.find(".wiktku-dfn-nimune-quote").after(subWrap); } tTa = $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-quote-t-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 2) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-quote-t") .attr("placeholder", "Tercimeya jêgirtinê ya kurmancî…"); subWrap.append(tTa); } else if (!showT && tTa.length) { tTa.remove(); } // Remove the wrapper if it ended up empty. subWrap = li.find(".wiktku-dfn-quote-sub"); if (subWrap.length && !subWrap.children().length) subWrap.remove(); }); }()); $.each(steps, function (stepId, step) { if (typeof(step.visible) === "function" && !step.visible(values)) { $("#wiktku-start-" + stepId).slideUp(); } else { var stepDiv = $("#wiktku-start-" + stepId); if (changedStep !== step && typeof(step.build) === "function") { prepareInput(step.build(stepDiv, values), step); } var input = stepDiv.find(".wiktku-start-step-field"); if (typeof(step.example) === "function") { // .find() above already reaches nested fields (e.g. the dfn // step's mane textareas inside each sense block), so one // assignment covers every step; dfn keeps its own fallback. var exampleText = step.example(values) || (step.id === "dfn" ? "Mane…" : ""); input.attr("placeholder", exampleText); } var didSlideDown; if (!didFocus && stepDiv.css("display") === "none" && step.required) { didSlideDown = function (evt) { input.focus(); }; didFocus = true; } stepDiv.slideDown(didSlideDown); } if (step.required && (values[stepId] === "" || (step.multiple && values[stepId].join("") === ""))) { canContinue = false; } }); continueBtn.setDisabled(!canContinue); } function destroy() { $("#wiktku-start-form, .noafterwizard").slideUp(function () { $(this).remove(); }); $(".noarticletext .nowizard, #editform").slideDown(); $("#ca-edit").removeClass("selected"); $("#ca-wiktku-nowizard").addClass("selected"); } // Priority order for Kurdish dialects and the navz pseudo-code. // Codes listed here come before all other languages; unlisted codes // are sorted alphabetically by their display name via localeCompare. var LANG_PRIORITY = ["navz", "ku", "hac", "sdh", "lki", "ckb", "zza"]; /** * Inserts a new == {{ziman|code}} == section into existing page wikitext * at the correct sorted position: * 1. Any content before the first language section is preserved at the top. * 2. navz is always first, then ku/hac/sdh/lki/ckb/zza in that order, * then all other languages sorted by display name (localeCompare). */ function insertNewLangSection(existing, wikitext) { var newCodeMatch = wikitext.match(/^== \{\{ziman\|([^}]+)\}\} ==/); var newCode = newCodeMatch ? newCodeMatch[1] : ""; var sections = []; var preamble = ""; var firstMatch = existing.match(/(?:^|\n)== \{\{ziman\|/); if (!firstMatch) { // No existing lang sections at all — just append. var sep = existing && !/\n\s*$/.test(existing) ? "\n\n" : ""; return existing + sep + wikitext; } // Everything before the first == {{ziman|...}} == is the preamble. var firstSectionStart = existing.indexOf("== {{ziman|"); // Walk back to the start of that line. var lineStart = existing.lastIndexOf("\n", firstSectionStart - 1); var preambleEnd = lineStart !== -1 ? lineStart + 1 : 0; preamble = existing.slice(0, preambleEnd); // Parse each language section: header line + everything until the next header. var body = existing.slice(preambleEnd); // NOTE: with the /m flag, a bare "$" matches end-of-*line*, not just // end-of-string — that previously made the non-greedy content group // stop at the section's first line break instead of running to the // next language header (or the real end of the text), silently // dropping the rest of that section's wikitext. (?![\s\S]) matches // only the true end of the string, /m flag or not. var langSectionRe = /^(== \{\{ziman\|([^}]+)\}\} ==\n?)([\s\S]*?)(?=\n== \{\{ziman\||(?![\s\S]))/gm; var m; while ((m = langSectionRe.exec(body)) !== null) { sections.push({ code: m[2], content: m[0] // full text of this section including header }); } // Determine sort rank: priority list first (by index), then alphabetical. function getLangName(code) { var entry = langsByCode[code]; return entry ? entry[1] : code; } function sortRank(code) { var idx = LANG_PRIORITY.indexOf(code); return idx !== -1 ? idx : LANG_PRIORITY.length; } function compareLangs(a, b) { var ra = sortRank(a), rb = sortRank(b); if (ra !== rb) return ra - rb; // Both are outside priority list — sort by display name. return getLangName(a).localeCompare(getLangName(b), userLang); } // Insert the new section into the sorted list. var newSection = { code: newCode, content: wikitext }; var inserted = false; for (var i = 0; i < sections.length; i++) { if (compareLangs(newCode, sections[i].code) < 0) { sections.splice(i, 0, newSection); inserted = true; break; } } if (!inserted) sections.push(newSection); // Re-join: preamble + sections separated by newlines. var joined = sections.map(function (s) { // Ensure each section ends with exactly one newline before the next. return s.content.replace(/\n+$/, ""); }).join("\n"); return preamble + joined + "\n"; } function build() { $(".nowizard, .nowizard .noafterwizard").hide(); var callToAction = $("#wiktku-calltoaction"); var origCallToActionText = callToAction.text(); $(mw.util.addPortletLink("p-views", "#", "Edîtora çavkaniyê veke", "ca-wiktku-nowizard", "Vê rûpelê bi edîtora çavkaniyê çêke", undefined, "#ca-watch")).click(function (evt) { evt.preventDefault(); callToAction.text(origCallToActionText); destroy(); }); if (callToAction.length) { callToAction.text(origCallToActionText + " Forma li jêr ji bo çêkirina madeyeke nû bi kar bîne."); } var startForm = $("<form id='wiktku-start-form'></form>"); if (addLangMode) { startForm.append($("<p class='wiktku-addlang-notice'></p>").text( "Bi vê formê tu yê beşeke nû li rûpelê îlaw bikî. Eger ev zimanê ku tu îlawe dikî jixwe di rûpelê de hebe, beşa nû li dawiya vî zimanî dê were îlawekirin. " + "Ji kerema xwe netîceya dawî kontrol bikin, eger problemek derkeve, li [[Mediawiki talk:Gadget-start.js|nîqaşa vê amûrê]] problemê ragihîne.")); } var spinner; // Tab bar for switching between POS sections. var sectionTabsDiv = $("<div id='wiktku-section-tabs'></div>"); startForm.submit(function (evt) { evt.preventDefault(); continueBtn.setDisabled(true); spinner.show(); getWikitext(function (wikitext) { if (addLangMode) { var textbox = $("#wpTextbox1"); var existing = textbox.val() || ""; // Check whether the generated lang header already exists in the page. // wikitext always starts with "== {{ziman|CODE}} ==\n" (from steps.lang.output). // If that exact section heading is already present in the existing content, // strip it from the new output and insert the remaining content at the end // of that lang section (just before the next == level-2 heading, or at the // very end of the page if there is no following section). var langHeaderMatch = wikitext.match(/^(== \{\{ziman\|[^}]+\}\} ==\n)/); if (langHeaderMatch) { var langHeader = langHeaderMatch[1]; // e.g. "== {{ziman|ku}} ==\n" // Escape for use in RegExp. var escapedHeader = langHeader.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); if (new RegExp(escapedHeader).test(existing)) { // Strip the header from the new output. var newContent = wikitext.slice(langHeader.length); // Find the insertion point: end of the existing lang section. // A new L2 heading marks the start of the next language block. var afterHeader = existing.indexOf(langHeader); var searchFrom = afterHeader + langHeader.length; // Find the next == … == heading after this section's start. var nextL2 = existing.indexOf("\n== ", searchFrom); var insertAt = nextL2 !== -1 ? nextL2 : existing.length; // Ensure there's a blank line before the inserted block. var before = existing.slice(0, insertAt); var after = existing.slice(insertAt); var sep = /\n\s*$/.test(before) ? "" : "\n"; textbox.val(before + sep + newContent + after); } else { // New language — insert at the correct sorted position. textbox.val(insertNewLangSection(existing, wikitext)); } } else { // Unexpected format — insert at sorted position anyway. textbox.val(insertNewLangSection(existing, wikitext)); } } else { $("#wpTextbox1").val(wikitext); } $("html, body").animate({scrollTop: 0}); callToAction.text("Hindik ma!"); $("#wiktku-preview-container").remove(); destroy(); }); }); $.each(ordered_steps, function (i, step) { var stepDiv = $(mw.html.element("div", { "class": "wiktku-start-step", id: "wiktku-start-" + step.id })); var name = capitalize(step.name); stepDiv.append($(mw.html.element("h3", { "class": "wiktku-start-step-name" }, new mw.html.Raw(mw.html.element("label", { "for": "wiktku-start-" + step.id + "-field" }, name))))); if (step.question_fmt) { stepDiv.append($(mw.html.element("label", { "class": "wiktku-start-step-question", "for": "wiktku-start-" + step.id + "-field" }, step.question_fmt))); if (step.question_br) stepDiv.append($("<br>")); } var input; if (step.choices) { input = $(mw.html.element("select", { "class": "wiktku-start-step-field", id: "wiktku-start-" + step.id + "-field" })); input.attr("data-placeholder", capitalize(step.name) + " hilbijêre "); populateMenus(input, step.choices); if (step.multiple) input.attr("multiple", true); if (isMobile) { stepDiv.append(wrapNativeSelect(input)); } else { stepDiv.append(input); } } else if (typeof(step.build) === "function") { input = step.build(stepDiv); } else { input = $("<textarea></textarea>") .attr("class", "wiktku-start-step-field") .attr("id", "wiktku-start-" + step.id + "-field") .attr("rows", step.rows || 2); if (step.narrow) input.addClass("wiktku-start-narrow"); if (step.multiple) { input.on("input", function (evt) { refreshForTextField(evt.target, step); }); var keyInput = buildKeyInput(step); var list = $(step.ordered ? "<ol></ol>" : "<ul></ul>") .append($("<li></li>").append(keyInput).append(input)); stepDiv.append(list); } else stepDiv.append(input); } prepareInput(input, step); stepDiv.hide(); // Insert tab bar just before the first per-section step. if (step.id === "pos") startForm.append(sectionTabsDiv); startForm.append(stepDiv); }); // ── Section tab helpers ────────────────────────────────────────────── // ── Add-section button — lives in the tab bar, disabled until pos chosen ── var addSectionBtn = new OO.ui.ButtonWidget({ label: "+ Beş zêde bike", disabled: true }); addSectionBtn.on("click", function () { saveCurrentSection(); sections.push({}); activeSection = sections.length - 1; $.each(PER_SECTION_STEP_IDS, function (_, id) { if (id === "dfn") { var stepDiv = $("#wiktku-start-dfn"); stepDiv.find("ol.wiktku-dfn-list").remove(); steps.dfn.build(stepDiv); return; } if (id === "etym") { $("#wiktku-start-etym .wiktku-etym-wrap").remove(); steps.etym.build($("#wiktku-start-etym")); return; } if (id === "trans") { var transDiv = $("#wiktku-start-trans"); transDiv.find(".wiktku-trans-group").remove(); return; } if (id === "zarava") { var zaravaDiv = $("#wiktku-start-zarava"); zaravaDiv.find(".wiktku-zarava-group").remove(); return; } if (id === "dunde") { var dundeDiv = $("#wiktku-start-dunde"); dundeDiv.find("ul.wiktku-dunde-list").remove(); return; } var stepDiv = $("#wiktku-start-" + id); stepDiv.find(".wiktku-start-step-field").val(""); if (!isMobile) stepDiv.find("select.wiktku-start-step-field").trigger("chosen:updated"); }); renderSectionTabs(); refresh(); $("html, body").animate({ scrollTop: sectionTabsDiv.offset().top - 20 }, 300); }); /** Re-render the tab bar to reflect current sections[] and activeSection. */ function renderSectionTabs() { // Detach (not remove) the button first: .empty() strips bound // event data from any children left inside it, which would // silently kill addSectionBtn's click handler on every re-render. addSectionBtn.$element.detach(); sectionTabsDiv.empty(); var lang = getValues().lang || ""; if (!lang) { sectionTabsDiv.hide(); return; } sectionTabsDiv.show(); $.each(sections, function (i) { var posVal = sections[i].pos || ""; var tabLabel = posVal ? capitalize(posVal) : ("Beş " + (i + 1)); var tab = $("<span></span>") .addClass("wiktku-section-tab") .text(tabLabel) .toggleClass("wiktku-tab-active", i === activeSection); (function (idx) { tab.on("click", function () { if (idx === activeSection) return; saveCurrentSection(); activeSection = idx; restoreSection(sections[activeSection]); refresh(); renderSectionTabs(); }); }(i)); sectionTabsDiv.append(tab); }); // Enable "Beş zêde bike" only when the active section has a pos chosen. var activePos = sections[activeSection] && sections[activeSection].pos ? sections[activeSection].pos : getValues().pos; addSectionBtn.setDisabled(!activePos); sectionTabsDiv.append(addSectionBtn.$element); } renderSectionTabs(); // Update the active tab's label whenever pos changes. startForm.on("change", "#wiktku-start-pos-field", function () { renderSectionTabs(); }); // Show the tab bar as soon as a language is selected. startForm.on("change", "#wiktku-start-lang-field", function () { renderSectionTabs(); }); var footer = $("<div id='wiktku-start-footer'></div>"); spinner = $(mw.html.element("img", { id: "wiktku-start-spinner", src: "//upload.wikimedia.org/wikipedia/commons/d/de/Ajax-loader.gif", alt: "Tê barkirin…", title: "Tê barkirin…" })); footer.append(spinner.hide()); continueBtn = new OO.ui.ButtonWidget({ id: "wiktku-unhide-editform", label: "Bişîne", flags: [ "primary", "progressive" ] }); continueBtn.on("click", function () { mw.notify("Tê şandin…", { type: "info", tag: "wiktku-submit" }); startForm.trigger("submit"); }); footer.append(continueBtn.$element); // "Edîtora çavkaniyê veke" button — inline fallback for the portlet link // which is invisible on mobile and easy to miss on desktop. var sourceEditorBtn = new OO.ui.ButtonWidget({ label: "Edîtora çavkaniyê veke", framed: false }); sourceEditorBtn.on("click", function () { destroy(); }); footer.append(sourceEditorBtn.$element); // ── Preview checkboxes ─────────────────────────────────────────────── // Wikitext preview (raw text panel) var previewCheck = $("<input type='checkbox' id='wiktku-preview-toggle'>"); var previewLabel = $("<label for='wiktku-preview-toggle'></label>") .text(" Pêşdîtina wîkîtekstê"); var previewPanel = $("<pre id='wiktku-preview-panel'></pre>").hide(); // Live rendered preview (parsed HTML panel, same logic as AjaxEdit). // Not available on mobile — API polling causes too many problems on small screens. var livePreviewCheck = null; var livePreviewPanel = null; if (!isMobile) { livePreviewCheck = $("<input type='checkbox' id='wiktku-live-preview-toggle'>"); livePreviewPanel = $("<div id='wiktku-live-preview-panel'></div>").hide(); } // Container that holds both panels and switches between stacked / side-by-side. var previewContainer = $("<div id='wiktku-preview-container'></div>"); previewContainer.append(previewPanel); if (!isMobile) previewContainer.append(livePreviewPanel); var previewTimer = null; var livePreviewIntervalId = -1; var livePreviewActive = false; // guards in-flight fetches after uncheck /** Rebuilds wikitext preview if its checkbox is checked. */ function schedulePreview() { if (!previewCheck.prop("checked")) return; clearTimeout(previewTimer); // Debounce: wait 400 ms after the last keystroke before rebuilding. previewTimer = setTimeout(function () { getWikitext(function (wikitext) { previewPanel.text(wikitext).show(); updatePanelLayout(); }); }, 400); } /** Fetches parsed HTML and populates the live preview panel. */ function loadLivePreview() { getWikitext(function (wikitext) { new mw.Api().parse(wikitext, { title: mw.config.get("wgPageName") }).done(function (html) { // Discard result if the user unchecked while the fetch was in flight. if (!livePreviewActive) return; livePreviewPanel.html(html).show(); updatePanelLayout(); }); }); } /** Adjusts panel widths depending on which previews are visible. */ function updatePanelLayout() { var wikitextVisible = previewCheck.prop("checked"); var liveVisible = livePreviewCheck && livePreviewCheck.prop("checked"); if (wikitextVisible && liveVisible) { // Side by side — each panel takes roughly half the available width. previewPanel.css({ "flex": "1 1 45%", "min-width": "280px" }); livePreviewPanel.css({ "flex": "1 1 45%", "min-width": "280px" }); } else { // Full width for whichever is visible — only touch panels that are // actually shown so that setting flex doesn't override display:none. if (wikitextVisible) previewPanel.css({ "flex": "1 1 100%", "min-width": "" }); if (liveVisible && livePreviewPanel) livePreviewPanel.css({ "flex": "1 1 100%", "min-width": "" }); } } previewCheck.on("change", function () { if ($(this).prop("checked")) { schedulePreview(); } else { clearTimeout(previewTimer); previewPanel.hide(); updatePanelLayout(); } }); if (!isMobile) { livePreviewCheck.on("change", function () { if ($(this).prop("checked")) { livePreviewActive = true; livePreviewPanel.show(); loadLivePreview(); livePreviewIntervalId = setInterval(loadLivePreview, 500); } else { livePreviewActive = false; clearInterval(livePreviewIntervalId); livePreviewIntervalId = -1; livePreviewPanel.hide().empty(); updatePanelLayout(); } }); } // Listen on all input/change events on the form and update both previews. startForm.on("input change", function () { schedulePreview(); }); footer.append($("<span style='margin-left:1em'></span>") .append(previewCheck).append(previewLabel)); if (!isMobile) { var livePreviewLabel = $("<label for='wiktku-live-preview-toggle'></label>") .text(" Pêşdîtina zindî"); footer.append($("<span style='margin-left:1em'></span>") .append(livePreviewCheck).append(livePreviewLabel)); } startForm.append(footer); $("#editform").hide().before(startForm); // Insert preview container (holds both panels) after the form. startForm.after(previewContainer); if (!isMobile) startForm.find("select").chosen(chosenOptions); refresh(); // Zimanan ji MediaWiki:Gadget-translation_editor.js/ziman.json bar bike. // Kodên ku bi "-pro" diqedin û navên ku "zimanê destan" tê de heye // tên derxistin. Zimanên xardkirî li serî dimînin, yên din // bi alfabeyê li dû wan tên. // Pinned choices come from MediaWiki:Gadget-start.js/data.json (langChoices), // already loaded into steps.lang.choices before build() runs. var pinnedChoices = steps.lang.choices.slice(); var pinnedCodes = $.map(pinnedChoices, function (choice) { return choice[0]; }); new mw.Api().get({ action: "query", prop: "revisions", titles: "MediaWiki:Gadget-translation_editor.js/ziman.json", rvprop: "content", rvslots: "main", formatversion: 2 }).then(function (data) { var page = data.query.pages[0]; var content = page && page.revisions && page.revisions[0].slots.main.content; var zimanData; try { zimanData = JSON.parse(content); } catch (e) { zimanData = {}; } var extraChoices = []; $.each(zimanData, function (code, name) { // Filter: skip proto-language codes and legendary/reconstructed langs. if (/-pro$/i.test(code)) return; if (/ziman[eê]\s+destan/i.test(name)) return; // Skip codes already in the pinned list (they are handled above). if (pinnedCodes.indexOf(code) !== -1) return; // sortKey: bare name without leading "zimanê " for sorting. var sortKey = name.replace(/^ziman[eê]\s+/i, ""); var choice = [code, name, sortKey]; extraChoices.push(choice); langsByCode[code] = choice; }); // Populate langsByCode for pinned choices too. $.each(pinnedChoices, function (i, choice) { // Ensure pinned choices have a sortKey (index 2). if (choice.length < 3) choice[2] = choice[1]; langsByCode[choice[0]] = choice; }); // Sort the extra choices alphabetically by sort key. extraChoices.sort(function (a, b) { return a[2].localeCompare(b[2], userLang); }); // Final list: pinned first, then the rest. var allChoices = pinnedChoices.concat(extraChoices); steps.lang.choices = allChoices; steps.trans.keys = allChoices; steps.dunde.keys = allChoices; steps.zarava.keys = getZaravaKeys(allChoices); var langMenu = $("#wiktku-start-lang-field"); populateMenus(langMenu, steps.lang.choices); langMenu.trigger("chosen:updated"); var transMenus = $("#wiktku-start-trans .wiktku-start-step-keyfield"); populateMenus(transMenus, steps.trans.keys, getDisabledKeys(steps.trans)); transMenus.trigger("chosen:updated"); var dundeMenus = $("#wiktku-start-dunde .wiktku-start-step-keyfield"); populateMenus(dundeMenus, steps.dunde.keys, getDisabledKeys(steps.dunde)); dundeMenus.trigger("chosen:updated"); var zaravaMenus = $("#wiktku-start-zarava .wiktku-start-step-keyfield"); populateMenus(zaravaMenus, steps.zarava.keys, getDisabledKeys(steps.zarava)); }); } mw.loader.using(["jquery.chosen", "mediawiki.api", "oojs-ui-core"], function () { // Load metadata, langChoices, posChoices and tplDefs from the companion // data page so they can be updated without touching this script. new mw.Api().get({ action: "query", prop: "revisions", titles: "MediaWiki:Gadget-start.js/data.json", rvprop: "content", rvslots: "main", formatversion: 2 }).then(function (data) { var page = data.query.pages[0]; var content = page && page.revisions && page.revisions[0].slots.main.content; var d; try { d = JSON.parse(content); } catch (e) { d = {}; } // Populate metadata. if (d.metadata) $.extend(metadata, d.metadata); // Populate lang choices (pinned list used by build() → ziman.json loader). if (d.langChoices) steps.lang.choices = d.langChoices; // Populate POS choices. if (d.posChoices) steps.pos.choices = d.posChoices; // Populate template definitions for the dfn sense-block builder. if (d.tplDefs) steps.dfn.tplDefs = d.tplDefs; // Populate pos placeholder examples. if (d.posExamples) steps.dfn.posExamples = d.posExamples; // Populate citation template definitions for the quote widget. if (d.jederDefs) steps.dfn.jederDefs = d.jederDefs; // Populate pronunciation and etymology template insert lists. if (d.pronTpls) { steps.pron.pronTpls = d.pronTpls; steps.pron.refreshTplSelect(); } if (d.etymTpls) { steps.etym.etymTpls = d.etymTpls; steps.etym.refreshTplSelect(); } // Sync trans/dunde/zarava keys with the (now populated) lang choices. steps.trans.keys = steps.lang.choices; steps.dunde.keys = steps.lang.choices; steps.zarava.keys = getZaravaKeys(steps.lang.choices); }).always(build); }); }); //</nowiki> 7wtgkn2fxkxoe18vkb8baiir2xfzy7z 6265564 6265563 2026-07-19T13:40:10Z Wikihez 7344 6265564 javascript text/javascript // Li ser [[vi:MediaWiki:Gadget-start.js]] hatiye refaktorkirin. //<nowiki> $(function () { var ns = mw.config.get("wgNamespaceNumber"); if (ns && !(ns === 2 && mw.config.get("wgPageName").match(/\/ceribandin$|\/test$/))) { return; } var action = mw.config.get("wgAction"); var pageExists = !!mw.config.get("wgArticleId"); // "Zimanek lê zêde bike" mode: triggered from the portlet link below. // Runs the same wizard on an EXISTING page's edit form, but appends the // generated section instead of replacing the textarea's content. var addLangMode = pageExists && mw.util.getParamValue("wiktkuaddlang") === "1"; // On a normal page view of an existing page, just add the portlet link // that takes the user into addLangMode; don't build anything else here. if (action === "view" && pageExists) { mw.util.addPortletLink("p-views", mw.util.getUrl(mw.config.get("wgPageName"), { action: "submit", wiktkuaddlang: "1" }), "+Ziman/beşeke din", "ca-wiktku-addlang", "Ji vê rûpelê re zimanekî nû zêde bike"); return; } if (!(action === "edit" || action === "submit")) { return; } if (!addLangMode && !$(".mw-newarticletext, .mw-newarticletextanon").length) { return; } if (window.location.href.includes("editintro=User:Wikihez/creation/intro")) { return; // Do not run the script wextê WF:Bilez dişuxile } function capitalize(str) { if (!str) return str; return str[0].toUpperCase() + str.substr(1); } function decapitalize(str) { if (!str) return str; return str[0].toLowerCase() + str.substr(1); } function escapeRegExp(str) { return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); } function stripWikilinks(str) { return str.replace(/\[\[([^\]|]+)(?:\|([^\]]+))?\]\]/g, function (m, target, display) { return display || target; }); } function insertAtCursor(el, text) { var start = el.selectionStart; var end = el.selectionEnd; var val = el.value; el.value = val.slice(0, start) + text + val.slice(end); var pos = start + text.length; el.selectionStart = el.selectionEnd = pos; } var pageName = mw.config.get("wgPageName").replaceAll(/_/g, " "); if (ns) pageName = pageName.replace(/.*\//, ""); var pageNameRe = escapeRegExp(pageName); var userLang = mw.config.get("wgUserLanguage"); // Mobile detection: MobileFrontend sets wgMFMode, or fall back to touch check. var isMobile = !!mw.config.get("wgMFMode") || window.matchMedia("(pointer: coarse)").matches; var chosenOptions = { width: "20em", disable_search_threshold: 0, placeholder_text_single: "Yekî hilbijêre", placeholder_text_multiple: "Hilbijêre", no_results_text: "Nehat dîtin", enable_split_word_search: true, search_contains: true }; function wrapNativeSelect(select) { var placeholder = select.attr("data-placeholder") || "Lê bigere…"; // Hide the native select — we drive it programmatically. select.hide(); var wrapper = $("<span class='wiktku-native-select-wrap'></span>"); var textInput = $("<input type='search' autocomplete='off'>") .attr("placeholder", placeholder) .addClass("wiktku-start-narrow wiktku-ac-input"); var resultsList = $("<ul class='wiktku-ac-results'></ul>").hide(); // Full option cache — rebuilt when chosen:updated fires. var allOptions = []; function cacheOptions() { allOptions = []; select.find("option").each(function () { var v = $(this).val(); if (!v) return; // skip the empty placeholder option allOptions.push({ value: v, text: $(this).text(), disabled: $(this).prop("disabled") }); }); } cacheOptions(); function showResults(query) { var q = query.trim().toLowerCase(); resultsList.empty(); var matched; if (q) { matched = []; $.each(allOptions, function (_, o) { if (o.disabled) return; var codeMatch = o.value.toLowerCase().indexOf(q) !== -1; var nameMatch = o.text.toLowerCase().indexOf(q) !== -1; if (codeMatch || nameMatch) { matched.push({ opt: o, codeMatch: codeMatch }); } }); // Code matches (especially prefix matches) come first. matched.sort(function (a, b) { var aCode = a.opt.value.toLowerCase(); var bCode = b.opt.value.toLowerCase(); var aPrefix = aCode.indexOf(q) === 0; var bPrefix = bCode.indexOf(q) === 0; if (aPrefix !== bPrefix) return aPrefix ? -1 : 1; if (a.codeMatch !== b.codeMatch) return a.codeMatch ? -1 : 1; return 0; }); matched = matched.map(function (item) { return item.opt; }); } else { matched = allOptions.filter(function (o) { return !o.disabled; }); } if (!matched.length) { resultsList.hide(); return; } $.each(matched.slice(0, 50), function (_, opt) { var li = $("<li></li>").text(opt.text).attr("data-value", opt.value); // Use touchend instead of touchstart so that a scroll gesture does // not accidentally select an item. We track whether the finger moved // between touchstart and touchend — if it did, it was a scroll. var touchMoved = false; li.on("touchstart", function () { touchMoved = false; }); li.on("touchmove", function () { touchMoved = true; }); li.on("touchend", function (e) { if (touchMoved) return; // was a scroll, not a tap e.preventDefault(); selectOption(opt.value, opt.text); }); // Keep mousedown for desktop fallback. li.on("mousedown", function (e) { e.preventDefault(); selectOption(opt.value, opt.text); }); resultsList.append(li); }); // Position the list above or below depending on available viewport space. var inputRect = textInput[0].getBoundingClientRect(); var viewportH = window.innerHeight; var spaceBelow = viewportH - inputRect.bottom - 8; var spaceAbove = inputRect.top - 8; var maxH = Math.min(224, Math.max(spaceBelow, spaceAbove)); // 224px ≈ 14em resultsList.css({ "max-height": maxH + "px", "top": spaceBelow >= spaceAbove ? "100%" : "auto", "bottom": spaceBelow >= spaceAbove ? "auto" : "100%" }); resultsList.show(); } function selectOption(value, text) { textInput.val(text); select.val(value); resultsList.hide(); select.trigger("change"); } textInput.on("input focus", function () { showResults($(this).val()); }); textInput.on("blur", function () { // Short delay so a touchstart on a result item fires first. setTimeout(function () { resultsList.hide(); }, 200); }); // chosen:updated → re-cache (called after ziman.json loads). select.on("chosen:updated", function () { cacheOptions(); // If a value is already selected, keep the display text in sync. var cur = select.val(); if (cur) { var match = $.grep(allOptions, function (o) { return o.value === cur; })[0]; if (match) textInput.val(match.text); } }); // No-op .chosen() so desktop call-sites don't need guarding. select.chosen = function () { return select; }; wrapper.append(textInput).append(resultsList).append(select); return wrapper; } var langsByCode = {}; // Populated from [[MediaWiki:Gadget-start.js/data.json]] at runtime. var metadata = {}; // Zaravayên kurdî yên ku di beşa "Bi zaravayên din" de tên pêşkêşkirin — // ev kod ji beşa Werger têne derxistin daku heman zimên du caran neyê xwendin. var ZARAVA_LANG_CODES = ["ckb", "sdh", "lki", "hac", "zza"]; function getZaravaKeys(choices) { var byCode = {}; $.each(choices || [], function (_, c) { byCode[c[0]] = c; }); var result = []; $.each(ZARAVA_LANG_CODES, function (_, code) { if (byCode[code]) result.push(byCode[code]); }); return result; } function needsTransliteration(langCode) { var meta = metadata[langCode]; if (!meta || !meta.sc) return false; var scripts = Array.isArray(meta.sc) ? meta.sc : [meta.sc]; return scripts.length > 0 && scripts[0] !== "Latn"; } // Kodên cinsiyetê yên di metadata.g de — ji data.json tê dagirtin var GENDER_BASE_LABELS = {}; // Sub-lists that only make sense for a plain (non-şablon) sense — hidden // when a şablon (e.g. {{guharto|…}}) is chosen for that sense, since a // template-based sense has no "own" gloss for alternate forms, synonyms, // antonyms, coordinate terms, hypernyms or hyponyms to attach to. Etîket, // Nimûne and Jêgirtin stay visible either way. var HIDDEN_ON_TPL_GROUPS = [ "wiktku-dfn-alternativ", "wiktku-dfn-hevmane", "wiktku-dfn-dijmane", "wiktku-dfn-koordine", "wiktku-dfn-jornav", "wiktku-dfn-jernav" ]; function genderLabel(code) { if (code === "p") return "Pirjimar"; var pluralMatch = code.match(/^(.+)-p$/); if (pluralMatch && GENDER_BASE_LABELS[pluralMatch[1]]) { return GENDER_BASE_LABELS[pluralMatch[1]] + " (pirjimar)"; } return GENDER_BASE_LABELS[code] || code; } /** * True if a sense has any content worth keeping besides its mane text — * etîket, hevmane/dijmane/koordîne/etc. word lists, nimûne, or jêder * (quote). Used so a sense with an empty mane but filled-in extra * fields still gets emitted (with {{mane?}} standing in for the gloss) * instead of being silently dropped. */ function senseHasExtraContent(s) { if (s.etiket && $.grep(s.etiket, function (e) { return $.trim(e) !== ""; }).length) return true; if (s.alternativ.length || s.hevmane.length || s.dijmane.length || s.koordine.length || s.jornav.length || s.jernav.length) return true; if (s.nimune && $.grep(s.nimune, function (n) { return (typeof n === "object" ? n.text : n) !== ""; }).length > 0) return true; if (s.jeder && $.grep(s.jeder, function (j) { return j && j.quote; }).length > 0) return true; return false; } /** * formatNimune: each nimûne item can be { text, tr, t }: * text — example text * tr — transliteration (only when the language needs it) * t — Kurdish translation (third positional param, no key) */ function formatNimune(nimunes, lang, hasJeder) { var hasNimune = nimunes && $.grep(nimunes, function (n) { return (typeof n === "object" ? n.text : n) !== ""; }).length > 0; if (!hasNimune) { return hasJeder ? "" : "\n#* {{bênimûne|" + lang + "}}"; } return $.map(nimunes, function (n) { var text = typeof n === "object" ? n.text : n; if (!text) return undefined; var bolded = text.replace( new RegExp("(" + pageNameRe + "([^( |,|;|\\?|\\.|\\!)]+)?)", "ig"), "'''$1'''"); var tpl = "\n#: {{nm|" + lang + "|" + bolded; if (typeof n === "object") { if (n.tr) tpl += "|tr=" + n.tr; // Translation as third positional param (no key needed). if (n.t) tpl += "|" + n.t; } // Short examples fit on one line together with their translation. // rêz=1 is not used for ku — definitions are shown on separate lines there. if (text.length < 200 && lang !== "ku") tpl += "|rêz=1"; tpl += "}}"; return tpl; }).join(""); } /** * Formats a list of jêder (quote/citation) objects into wikitext lines. * Each entry that has no quote text is skipped. Returns "" when the list * is empty or every entry is blank. * * #* {{jêder-…|lang|jêgirtin=…|tr=…|tercime=…|…fields…}} * * When no template is chosen, the generic {{jêder|…}} template is used * instead. Its 2nd positional param is the user's freeform "bi destê xwe * binivîsim" source text when supplied, or the çavkanî? placeholder otherwise. * If that text contains "=" it is passed as |2=… instead of a bare * positional param, since MediaWiki would otherwise misparse it as its * own key=value pair and break the template: * #* {{jêder|lang|jêgirtin=…|tr=…|tercime=…|<manual source or çavkanî?>}} */ function formatJeder(jederList, lang) { if (!jederList || !jederList.length) return ""; return $.map(jederList, function (jeder) { if (!jeder || !jeder.quote) return undefined; if (jeder.jederTpl) { var cite = "\n#* {{" + jeder.jederTpl + "|" + lang; cite += "|jêgirtin=" + jeder.quote; if (jeder.quoteTr) cite += "|tr=" + jeder.quoteTr; if (jeder.quoteT) cite += "|tercime=" + jeder.quoteT; $.each(jeder.jêderFields || {}, function (key, val) { if (val) cite += "|" + key + "=" + val; }); cite += "}}"; return cite; } var out = "\n#* {{jêder|" + lang + "|jêgirtin=" + jeder.quote; if (jeder.quoteTr) out += "|tr=" + jeder.quoteTr; if (jeder.quoteT) out += "|tercime=" + jeder.quoteT; var srcParam = jeder.jederManual ? jeder.jederManual : "çavkanî?"; // A positional param containing "=" gets parsed as its own key=value // pair by MediaWiki and breaks the template, so force it to be // explicitly named (|2=) whenever that's the case. out += (srcParam.indexOf("=") !== -1 ? "|2=" : "|") + srcParam; out += "}}"; return out; }).join(""); } function makeWordListStep(id, name, question_fmt, header, templateName) { return { id: id, name: name, question_fmt: question_fmt, multiple: true, narrow: true, visible: function (values) { return values.lang && values.pos; }, output: function (values) { var words = $.grep(values[id] || [], function (w) { return !!w; }); if (!words.length) return ""; var lang = values.lang; var section = "\n==== " + header + " ====\n"; if (words.length === 1) { // Single word — keep the simple inline template. return section + "* {{" + templateName + "|" + lang + "|" + words[0] + "}}\n"; } // Multiple words — use {{kol3}} with one positional param per word. var params = "cure=" + header + "\n" + $.map(words, function (w) { return "|" + w; }).join("\n"); return section + "{{kol3|" + lang + "|" + params + "\n}}\n"; } }; } var steps = { lang: { id: "lang", required: true, name: "ziman", question_fmt: '"' + pageName + '" bi çi zimanî ye?', question_br: true, // Populated from [[MediaWiki:Gadget-start.js/data.json]] (langChoices). choices: [], output: function (values) { return "== {{ziman|" + values.lang + "}} ==\n"; } }, pron: { id: "pron", name: "bilêvkirin", question_fmt: '"' + pageName + '" çawa tê telafûzkirin?', // pronTpls populated from data.json pronTpls: [], visible: function (values) { if (!values.lang) return false; // In addLangMode, only skip pron when this langcode's section // already exists in the page — if it's a new language, show it. if (addLangMode) { var existing = $("#wpTextbox1").val() || ""; var header = "== {{ziman|" + values.lang + "}} =="; return existing.indexOf(header) === -1; } return true; }, /** Fills (or refills) the insert-dropdown from the current pronTpls array, filtering by language. */ refreshTplSelect: function () { var sel = $("#wiktku-start-pron .wiktku-tpl-insert-select"); if (!sel.length) return; var lang = getValues().lang || ""; sel.find("option[value!='']").remove(); $.each(steps.pron.pronTpls, function (_, tpl) { // Filter: if tpl.langs exists, only show if lang is in that list; otherwise show always var allowed = !tpl.langs || tpl.langs.indexOf(lang) !== -1; if (allowed) { sel.append($("<option></option>") .val(tpl.snippet) .text(tpl.name + " — " + tpl.desc) .attr("data-nolang", tpl.noLang ? "1" : "")); } }); // Notify Chosen that the option list has changed (no-op on mobile). if (!isMobile) sel.trigger("chosen:updated"); }, build: function (stepDiv) { if (stepDiv.find(".wiktku-pron-wrap").length) return null; var wrap = $("<div class='wiktku-pron-wrap'></div>"); var ta = $("<textarea></textarea>") .attr("name", "wiktku-pron-" + $.now()) .attr("class", "wiktku-start-step-field wiktku-pron-text") .attr("rows", 4) .attr("placeholder", "Nimûne: {{IPA|ku|/pɛɪ̯n/}} yan {{kîte|ku|he|ce|ki|rin}}"); // Template insert dropdown — filtered by language. var sel = $("<select class='wiktku-tpl-insert-select'></select>"); sel.append($("<option value=''>— şablonek lê zêde bike —</option>")); var lang = getValues().lang || ""; $.each(steps.pron.pronTpls, function (_, tpl) { // Filter: if tpl.langs exists, only show if lang is in that list; otherwise show always var allowed = !tpl.langs || tpl.langs.indexOf(lang) !== -1; if (allowed) { sel.append($("<option></option>") .val(tpl.snippet) .text(tpl.name + " — " + tpl.desc) .attr("data-nolang", tpl.noLang ? "1" : "")); } }); sel.on("change", function () { var snippet = $(this).val(); if (!snippet) return; var lang = getValues().lang || ""; // Check if the selected option has noLang flag var selectedOption = sel.find("option:selected"); var hasNoLang = selectedOption.attr("data-nolang") === "1"; if (!hasNoLang) { snippet = snippet.replace(/CODE/g, lang).replace(/SOURCELANG/g, "?"); } insertAtCursor(ta[0], snippet); $(this).val(""); ta.focus(); }); wrap.append(sel).append($("<br>")).append(ta); stepDiv.append(wrap); return ta; }, output: function () { var text = $.trim($("#wiktku-start-pron .wiktku-pron-text").val()); if (!text) return ""; var lines = text.split("\n"); var out = $.map(lines, function (line) { line = $.trim(line); if (!line) return undefined; return line.charAt(0) === "*" ? line : "* " + line; }).join("\n"); return "\n=== Bilêvkirin ===\n" + out + "\n"; } }, pos: { id: "pos", required: true, name: "Cureyê rêzimanî", question_fmt: 'Cureyê rêzimanî yê "' + pageName + '" çi ye?', visible: function (values) { return values.lang; }, question_br: true, // Populated from [[MediaWiki:Gadget-start.js/data.json]] (posChoices). choices: [], output: function (values) { var pos = values.pos || ""; var cinsiyet = values.cinsiyet || ""; // from the cinsiyet step var lekTur = values.lektur || ""; // from the lêker transitivity step var capitalizedPos = capitalize(pos); var outputString = "\n=== " + capitalizedPos + " ===\n"; // Add ku-tewîn-nav for single-word navdêr/serenav with known gender. if (!pageName.includes(" ") && cinsiyet && GENDER_BASE_LABELS[cinsiyet] && (pos === "navdêr" || pos === "serenav") && values.lang === "ku") { outputString += "{{ku-tewîn-nav|" + pageName + "|" + GENDER_BASE_LABELS[cinsiyet]; if (pos === "serenav") outputString += "|y"; outputString += "}}\n"; } outputString += "{{" + pos + "|" + values.lang; if (pos === "navdêr" || pos === "serenav") { if (cinsiyet) { outputString += "|c=" + cinsiyet; } else if (values.lang === "ku") { // Unknown gender — prompt editor to fill it in. outputString += "|c=?"; } } else if (/^lêker/.test(pos) && lekTur) { outputString += "|c=" + lekTur; } if (values.tr) { outputString += "|tr=" + values.tr; } outputString += "}}\n"; return outputString; } }, /** * cinsiyet (grammatical gender) — only shown for navdêr/serenav, û * tenê ger metadata ji bo zimanê hilbijartî lîsteyeke "g" (cinsiyet) * were dayîn. Opsiyonên vê gavê ne sabît in — ji metadata[values.lang].g * têne çêkirin, ji ber ku di hemû zimanan de cinsiyet tine. */ cinsiyet: { id: "cinsiyet", name: "cinsiyet", question_fmt: 'Cinsiyeta "' + pageName + '" çi ye?', question_br: true, visible: function (values) { var meta = metadata[values.lang]; return !!(values.lang && (values.pos === "navdêr" || values.pos === "serenav") && meta && meta.g && meta.g.length); }, build: function (stepDiv, values) { var select = stepDiv.find("select.wiktku-start-step-field"); if (!select.length) { select = $(mw.html.element("select", { "class": "wiktku-start-step-field", id: "wiktku-start-cinsiyet-field" })); stepDiv.append(select); } if (!values) return select; var meta = metadata[values.lang]; var codes = (meta && meta.g) || []; var prevVal = select.val(); var choices = $.map(codes, function (code) { return [[code, genderLabel(code)]]; }); populateMenus(select, choices); if ($.grep(choices, function (c) { return c[0] === prevVal; }).length) { select.val(prevVal); } if (!isMobile) select.trigger("chosen:updated"); return select; }, output: function () { return ""; } // consumed by pos.output }, /** * Lêker transitivity — only shown for any lêker variant. */ lektur: { id: "lektur", name: "Cureyê lêkerê (fiîlê)", question_fmt: "Cureyê lêkerê (fiîlê) çi ye?", question_br: true, visible: function (values) { return values.lang && values.pos && /^lêker/.test(values.pos); }, // Dictionary: value → display label. Add new types here. choices: [ ["gh", "gerguhêz"], ['x-gh', 'xwerû-gerguhêz'], ['p-gh', 'pêkhatî-gerguhêz'], ['h-gh', 'hevedudanî-gerguhêz'], ['b-gh', 'biwêjî-gerguhêz'], ["ngh", "negerguhêz"], ['x-ngh', 'xwerû-negerguhêz'], ['p-ngh', 'pêkhatî-negerguhêz'], ['h-ngh', 'hevedudanî-negerguhêz'], ['b-ngh', 'biwêjî-negerguhêz'] ], output: function () { return ""; } // consumed by pos.output }, tr: { id: "tr", name: "transkrîpsiyon", question_fmt: "Transkrîpsiyona kelîmeyê", multiple: false, narrow: true, visible: function (values) { return values.lang && values.pos && needsTransliteration(values.lang); } }, dfn: { id: "dfn", // required: true, ger mane tinebe [[Şablon:mane?]] bi kar bîne name: "Mane", question_fmt: "Maneya kelîmeyê binivîse. Mane otomatîk tê lînkkirin! Ji bo tercimeyan beşa 'Werger' bi kar bîne!", multiple: true, ordered: true, rows: 3, visible: function (values) { return values.lang && values.pos; }, example: function (values) { // posExamples loaded from [[MediaWiki:Gadget-start.js/data.json]]. var examples = steps.dfn.posExamples || {}; var full = values.pos || ""; return examples[full] || ""; }, /** * Builds one sense block (<li>) inside the ordered list. * Each block contains: * - a textarea for the definition * - an expandable nimûne list * - single-row sub-lists for formên alternatîv, hevmane, dijmane */ buildSenseBlock: function (stepDiv) { var block = $("<li class='wiktku-dfn-sense'></li>"); // — Mane textarea (declared first so the template handler can reference it) — var dfnArea = $("<textarea></textarea>") .attr("name", "wiktku-dfn-mane-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("class", "wiktku-start-step-field wiktku-dfn-mane") .attr("rows", 6) .attr("placeholder", "Mane…"); dfnArea.on("input", function () { steps.dfn.onDfnInput(stepDiv, block, this); }); // — Template selector (optional — replaces mane when chosen) — // Template definitions loaded from [[MediaWiki:Gadget-start.js/data.json]]. var tplDefs = steps.dfn.tplDefs || []; // Cache of all non-placeholder option elements — used by updateTplOptions // to remove/re-add options (the only approach compatible with Chosen.js). var _allTplOptions = []; var tplSelect = $(mw.html.element("select", { "class": "wiktku-dfn-tpl-select" })); tplSelect.append($("<option value=''>— yan jî şablonek hilbijêre —</option>")); $.each(tplDefs, function (_, tpl) { var opt = $("<option></option>") .val(tpl.name) .text(tpl.name) .attr("data-langs", tpl.langs ? tpl.langs.join(",") : "") .attr("data-nolang", tpl.noLang ? "1" : ""); tplSelect.append(opt); _allTplOptions.push(opt[0]); }); function updateTplOptions() { var lang = getValues().lang || ""; var currentVal = tplSelect.val(); var currentStillValid = false; // Detach all non-placeholder options, then re-attach only the visible ones. // This is the only approach that works correctly with both native <select> // and Chosen.js on desktop. tplSelect.find("option[value!='']").detach(); $.each(_allTplOptions, function (_, opt) { var allowed = $(opt).attr("data-langs"); var visible = !allowed || allowed.split(",").indexOf(lang) !== -1; if (visible) { tplSelect.append(opt); if ($(opt).val() === currentVal) currentStillValid = true; } }); if (!isMobile) tplSelect.trigger("chosen:updated"); if (currentVal && !currentStillValid) { tplSelect.val(""); dfnArea.show(); tplTitleInput.hide().val(""); } } // Store updater on the element so refresh() can call it for all blocks. tplSelect.data("updateOptions", updateTplOptions); var tplTitleInput = $("<input type='text'>") .addClass("wiktku-dfn-tpl-title wiktku-start-narrow") .attr("placeholder", "Navê rûpelê…") .hide(); // Grow the sense list when the title field of the last block gets content, // mirroring what onDfnInput does for the plain mane textarea. tplTitleInput.on("input", function () { steps.dfn.onDfnInput(stepDiv, block, this); }); /** * When a şablon sense is chosen, formên alternatîv/hevmane/dijmane/ * termên koordîne/jornav/jêrnav don't apply (there's no plain gloss * to hang them off), so hide those subgroups. Etîket, Nimûne and * Jêgirtin stay visible and still usable for a şablon sense. */ function updateFieldVisibility() { var isTpl = !!tplSelect.val(); $.each(HIDDEN_ON_TPL_GROUPS, function (_, cls) { block.find("." + cls + "-group").toggle(!isTpl); }); } // Store on the block so restoreDfn() can re-sync visibility // after programmatically setting tplSelect's value. block.data("updateFieldVisibility", updateFieldVisibility); tplSelect.on("change", function () { var chosen = $(this).val(); if (chosen) { dfnArea.hide(); tplTitleInput.show().focus(); } else { dfnArea.show(); tplTitleInput.hide().val(""); } updateFieldVisibility(); // Re-run refresh so the Werger step visibility updates. refresh(); }); var tplRow = $("<div></div>").addClass("wiktku-dfn-tpl-row") .append(tplSelect).append(" ").append(tplTitleInput); block.append(tplRow); block.append(dfnArea); // Apply lang filter on initial build. updateTplOptions(); // — Sub-field groups — // All groups are always visible with a placeholder textarea. // Nimûne is last in the DOM and last in the output. var allGroups = [ { cls: "wiktku-dfn-etiket", label: "Etîket", rows: 1, narrow: true, izah: "xisûsen, Mêrdîn, anatomî, Badînî" }, { cls: "wiktku-dfn-alternativ", label: "Formên alternatîv", rows: 1, narrow: true, izah: "Varyantên vê kelîmeyê" }, { cls: "wiktku-dfn-hevmane", label: "Hevmane", rows: 1, narrow: true, izah: "Spehî hevmaneya Bedew e." }, { cls: "wiktku-dfn-dijmane", label: "Dijmane", rows: 1, narrow: true, izah: "Zengîn dijmaneya feqîr e." }, { cls: "wiktku-dfn-koordine", label: "Termên koordîne", rows: 1, narrow: true, izah: "Pisîk û kûçik termên koordîne ne çunkî Jornavên wan gelek in" }, { cls: "wiktku-dfn-jornav", label: "Jornav", rows: 1, narrow: true, izah: "Heywan jornavê guhandar e" }, { cls: "wiktku-dfn-jernav", label: "Jêrnav", rows: 1, narrow: true, izah: "Guhandar jêrnavê heywan e" }, { cls: "wiktku-dfn-nimune", label: "Nimûne", rows: 2, narrow: false } ]; $.each(allGroups, function (_, g) { var groupDiv = $("<div></div>").addClass("wiktku-dfn-subgroup " + g.cls + "-group"); function buildNimuneLi() { var lang = getValues().lang || ""; var li = $("<li></li>").addClass("wiktku-dfn-nimune-li"); var mainTa = $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-text-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", g.rows) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-text") .attr("placeholder", "Nimûneya emilandina kelîmeyê tu bi xwe binivîse…"); mainTa.on("input", function () { var val = $.trim($(this).val()); var isLast = li.is(list.children("li:last-child")); if (val && isLast) { list.append(buildNimuneLi()); } }); li.append(mainTa); var subWrap = $("<div></div>").addClass("wiktku-dfn-nimune-sub"); if (needsTransliteration(lang)) { subWrap.append( $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-tr-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 5) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-tr") .attr("placeholder", "Transkrîpsiyona bi alfabeya latînî") ); } if (lang && lang !== "ku") { subWrap.append( $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-t-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 5) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-t") .attr("placeholder", "Tercimeya kurmancî") ); } if (subWrap.children().length) li.append(subWrap); return li; } if (g.cls === "wiktku-dfn-nimune") { // Nimûne — compound widget with tr/t sub-fields. var lbl = $("<span></span>").addClass("wiktku-dfn-sublabel").text(g.label + ": "); var list = $("<ol></ol>").addClass("wiktku-dfn-sublist " + g.cls + "-list"); groupDiv.data("buildNimuneLi", buildNimuneLi); list.append(buildNimuneLi()); groupDiv.append(lbl).append(list); block.append(groupDiv); } else { // Regular always-visible group — label + growing textarea list. var lbl = $("<span></span>").addClass("wiktku-dfn-sublabel").text(g.label + ": " + g.izah); var list = $("<ol></ol>").addClass("wiktku-dfn-sublist " + g.cls + "-list"); var firstInput = $("<textarea></textarea>") .attr("name", g.cls + "-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", g.rows) .attr("class", "wiktku-dfn-subfield" + (g.narrow ? " wiktku-start-narrow" : "")) .attr("placeholder", g.label + "…"); firstInput.on("input", function () { steps.dfn.onSubInput(list, this, g.rows, g.narrow); }); list.append($("<li></li>").append(firstInput)); groupDiv.append(lbl).append(list); block.append(groupDiv); } }); // — Jêder (quote / citation) group — a growing list, sibling to Nimûne — // Structured the same way as Nimûne (ol.wiktku-dfn-sublist > li) so it // lines up at the same indentation, and so that typing into the last // citation's Jêgirtin box automatically opens a fresh empty one below it. (function () { var jederGroupDiv = $("<div></div>").addClass("wiktku-dfn-subgroup wiktku-dfn-jeder-group"); var jederLbl = $("<span></span>").addClass("wiktku-dfn-sublabel").text("Jêgirtin: "); var jederList = $("<ol></ol>").addClass("wiktku-dfn-sublist wiktku-dfn-jeder-list"); function buildJederLi() { var lang = getValues().lang || ""; var li = $("<li></li>").addClass("wiktku-dfn-jeder-li"); var dragHandle = $("<span></span>") .addClass("wiktku-jeder-drag-handle") .attr("title", "Bişkûne û bikişîne da ku rêzê biguhezîne"); // Quote text textarea var quoteTa = $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-quote-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 2) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-quote") .attr("placeholder", "Nimûneya emilandinê ji kitêb an çavkaniyeke din binivîse"); quoteTa.on("input", function () { var val = $.trim($(this).val()); var isLast = li.is(jederList.children("li:last-child")); if (val && isLast) { jederList.append(buildJederLi()); } }); li.append(dragHandle).append(quoteTa); // tr/t sub-fields for the quote — shown as needed for the language. var quoteSubWrap = $("<div></div>").addClass("wiktku-dfn-quote-sub"); if (needsTransliteration(lang)) { quoteSubWrap.append( $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-quote-tr-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 2) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-quote-tr") .attr("placeholder", "Transkrîpsiyona jêgirtinê…") ); } if (lang && lang !== "ku") { quoteSubWrap.append( $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-quote-t-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 2) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-quote-t") .attr("placeholder", "Tercimeya jêgirtinê bi kurmancî") ); } if (quoteSubWrap.children().length) li.append(quoteSubWrap); // Citoid auto-fill: fetch citation data from a URL, DOI or ISBN and // prefill the source şablon + fields below (see Gadget-citoid-helper.js). var citoidWrap = $("<div></div>").addClass("wiktku-dfn-quote-citoid"); var citoidInput = $("<input type='text'>") .addClass("wiktku-dfn-quote-citoid-input wiktku-start-narrow") .attr("placeholder", "URL, DOI an ISBN binivîse ku otomatîk were tijekirin…"); var citoidBtn = new OO.ui.ButtonWidget({ label: "Bi Citoid bîne", classes: [ "wiktku-dfn-quote-citoid-btn" ] }); var citoidStatus = $("<span></span>").addClass("wiktku-dfn-quote-citoid-status"); /** * Fetches citation data from Citoid and applies it to this * citation's şablon selector + fields. Mirrors the logic in * Form.prototype._fillFromCitoid (Gadget-wikt.add-examples.js): * - only (re)selects the şablon when it actually differs from * what's already chosen, so a repeat fetch doesn't wipe out * a template the user already picked; * - only fills fields that are currently empty, so it never * overwrites something the user typed by hand; * - falls back to the freeform "bi destê xwe binivîsim" source * only when nothing was typed there yet. */ function runCitoidFetch() { var query = $.trim(citoidInput.val()); if (!query) { mw.notify("Ji kerema xwe re pêşî URL, DOI an ISBNyekê binivîse."); return; } citoidBtn.setDisabled(true); citoidStatus.text("Tê anîn…"); wikt.citoidHelper.ensure().then(function () { return wikt.citoid.fetchJederFields(query); }).then(function (result) { var jederKey = result.jederKey; var hasTpl = !!jederKey && srcSel.find("option[value='" + jederKey + "']").length > 0; var targetVal = hasTpl ? jederKey : "__manual__"; // Only (re)select — and thus rebuild — the field rows if // we're switching to a different şablon than what's // already chosen, so a second fetch doesn't clear fields // the user already filled in by hand. if (srcSel.val() !== targetVal) { srcSel.val(targetVal).trigger("change"); srcSel.trigger("chosen:updated"); } if (hasTpl) { // Tenê qadên vala tijî bike. $.each(result.fields, function (key, val) { var input = srcFields.find("[data-field-key='" + key + "']"); if (input.length && !$.trim(input.val())) { input.val(val); } }); } else { // Şablonek nehat naskirin ji bo vê itemType — rêzikeke // çavkaniyê ya bi destan a ji qadên Citoid tê çêkirin, // lê tenê ger qada destan vala be. var manualField = srcFields.find(".wiktku-dfn-quote-src-manual"); if (!$.trim(manualField.val())) { var parts = []; $.each(["nivîskar", "sernav", "websîte", "kovar", "weşanxane", "sal", "url"], function (_, k) { if (result.fields[k]) parts.push(result.fields[k]); }); manualField.val(parts.join(", ")); } } citoidStatus.text(""); }, function (errorMsg) { citoidStatus.text(typeof errorMsg === "string" ? errorMsg : "Nehat dîtin. Kontrol bike ka URL/DOI/ISBN rast e."); }).always(function () { citoidBtn.setDisabled(false); }); } citoidBtn.on("click", runCitoidFetch); citoidInput.on("keydown", function (e) { if (e.which === 13) { // Enter e.preventDefault(); runCitoidFetch(); } }); citoidWrap.append(citoidInput).append(citoidBtn.$element).append(citoidStatus); // Source template selector, specific to this citation. var srcSel = $("<select></select>").addClass("wiktku-dfn-quote-src-sel"); srcSel.append($("<option value=''>— Çavkaniyê hilbijêre —</option>")); srcSel.append($("<option></option>").val("__manual__").text("Bi destê xwe binivîsim")); var jederDefs = steps.dfn.jederDefs || {}; $.each(jederDefs, function (tplName, def) { srcSel.append($("<option></option>").val(tplName).text(def.label)); }); // Dynamic source fields container. var srcFields = $("<div></div>").addClass("wiktku-dfn-quote-src-fields"); srcSel.on("change", function () { srcFields.empty(); var chosen = $(this).val(); if (!chosen) return; if (chosen === "__manual__") { // Freeform source, written by the user — becomes the 2nd // positional param of {{jêder|lang|…}} instead of çavkanî?. srcFields.append( $("<textarea></textarea>") .attr("rows", 4) .addClass("wiktku-dfn-subfield wiktku-dfn-quote-src-manual") .attr("placeholder", "Çavkaniyê bi destê xwe binivîse…") ); return; } var def = (steps.dfn.jederDefs || {})[chosen]; if (!def) return; $.each(def.fields, function (_, f) { var row = $("<div></div>").addClass("wiktku-dfn-quote-src-row"); var fieldLbl = $("<label></label>").text(f.label + ": "); var inp = $("<textarea></textarea>") .attr("rows", 2) .addClass("wiktku-dfn-quote-src-input wiktku-start-narrow") .attr("data-field-key", f.key) .attr("placeholder", f.label + "…"); row.append(fieldLbl).append(inp); srcFields.append(row); }); }); li.append(citoidWrap).append(srcSel).append(srcFields); return li; } jederGroupDiv.data("buildJederLi", buildJederLi); jederList.append(buildJederLi()); // Make citation rows sortable (drag to reorder). // The last row is always the empty trailing row — cancel its drag. mw.loader.using("jquery.ui.sortable", function () { jederList.sortable({ handle: ".wiktku-jeder-drag-handle", axis: "y", items: "li:not(:last-child)", tolerance: "pointer" }); }); jederGroupDiv.append(jederLbl).append(jederList); block.append(jederGroupDiv); }()); // Apply the initial hide/show state for the sub-groups (matches // tplSelect's starting value, which is normally empty). updateFieldVisibility(); return block; }, /** Grows the sense list when the last mane textarea gets content. */ onDfnInput: function (stepDiv, block, textarea) { var val = $.trim($(textarea).val()); var list = stepDiv.find("ol.wiktku-dfn-list"); var isLast = block.is(list.children("li:last-child")); if (val && isLast) { var newBlock = steps.dfn.buildSenseBlock(stepDiv); list.append(newBlock); // Apply Chosen to the new block's template selector on desktop. if (!isMobile) newBlock.find("select.wiktku-dfn-tpl-select").chosen(chosenOptions); } refresh(); }, /** Grows a sub-list (nimûne/formên alternatîv/hevmane/dijmane/termên koordîne) on input. */ onSubInput: function (list, input, rows, narrow) { var val = $.trim($(input).val()); var item = $(input).parent(); var isLast = item.is(list.children("li:last-child")); if (val && isLast) { var next = $("<textarea></textarea>") .attr("name", "wiktku-dfn-sub-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", rows) .attr("class", "wiktku-dfn-subfield" + (narrow ? " wiktku-start-narrow" : "")); next.on("input", function () { steps.dfn.onSubInput(list, this, rows, narrow); }); list.append($("<li></li>").append(next)); } }, // Populated from [[MediaWiki:Gadget-start.js/data.json]] (tplDefs, posExamples, jederDefs). tplDefs: [], posExamples: {}, jederDefs: {}, build: function (stepDiv) { if (stepDiv.find("ol.wiktku-dfn-list").length) return null; var list = $("<ol class='wiktku-dfn-list'></ol>"); list.append(steps.dfn.buildSenseBlock(stepDiv)); stepDiv.append(list); return null; }, /** Reads all sense blocks from the DOM and returns an array of sense objects. */ getSenses: function (stepDiv) { var senses = []; stepDiv.find("li.wiktku-dfn-sense").each(function () { var block = $(this); var tplSel = block.find("select.wiktku-dfn-tpl-select"); var tpl = tplSel.val() || ""; // noLang: template already encodes the language — don't add |lang| param. var tplNoLang = tpl ? tplSel.find("option[value='" + tpl + "']").attr("data-nolang") === "1" : false; var tplTitle = $.trim(block.find("input.wiktku-dfn-tpl-title").val()); var mane = $.trim(block.find("textarea.wiktku-dfn-mane").val()); var etiket = (function () { var vals = []; block.find(".wiktku-dfn-etiket-list textarea").each(function () { var v = $.trim($(this).val()); if (v) vals.push(v); }); return vals; }()); function readList(cls) { var vals = []; block.find("." + cls + "-list textarea").each(function () { var v = $.trim($(this).val()); if (v) vals.push(v); }); return vals; } // Nimûne items are compound: { text, tr?, t? } function readNimuneList() { var items = []; block.find(".wiktku-dfn-nimune-list li.wiktku-dfn-nimune-li").each(function () { var text = $.trim($(this).find(".wiktku-dfn-nimune-text").val()); if (!text) return; var obj = { text: text }; var tr = $.trim($(this).find(".wiktku-dfn-nimune-tr").val()); var t = $.trim($(this).find(".wiktku-dfn-nimune-t").val()); if (tr) obj.tr = tr; if (t) obj.t = t; items.push(obj); }); return items; } // Jêder is a growing list of citations, one per li — mirrors readNimuneList(). function readJederList() { var items = []; block.find(".wiktku-dfn-jeder-list li.wiktku-dfn-jeder-li").each(function () { var li = $(this); var quote = $.trim(li.find(".wiktku-dfn-nimune-quote").val()); if (!quote) return; var obj = { quote: quote }; var qtr = $.trim(li.find(".wiktku-dfn-nimune-quote-tr").val()); var qt = $.trim(li.find(".wiktku-dfn-nimune-quote-t").val()); if (qtr) obj.quoteTr = qtr; if (qt) obj.quoteT = qt; var tplName = li.find(".wiktku-dfn-quote-src-sel").val(); if (tplName === "__manual__") { var manual = $.trim(li.find(".wiktku-dfn-quote-src-manual").val()); if (manual) obj.jederManual = manual; } else if (tplName) { obj.jederTpl = tplName; var fields = {}; li.find(".wiktku-dfn-quote-src-input").each(function () { var k = $(this).attr("data-field-key"); var v = $.trim($(this).val()); if (k && v) fields[k] = v; }); obj.jêderFields = fields; } items.push(obj); }); return items; } senses.push({ tpl: tpl, tplNoLang: tplNoLang, tplTitle: tplTitle, mane: mane, etiket: etiket, nimune: readNimuneList(), jeder: readJederList(), alternativ: readList("wiktku-dfn-alternativ"), hevmane: readList("wiktku-dfn-hevmane"), dijmane: readList("wiktku-dfn-dijmane"), koordine: readList("wiktku-dfn-koordine"), jornav: readList("wiktku-dfn-jornav"), jernav: readList("wiktku-dfn-jernav") }); }); return senses; }, getOutput: function (values, callback) { var stepDiv = $("#wiktku-start-dfn"); var senses = steps.dfn.getSenses(stepDiv); var lang = values.lang; // A sense counts as "filled" if it has a mane, a chosen template + title, // or any other content (etîket/hevmane/nimûne/jêder…) worth keeping. var hasMane = senses.some(function (s) { return s.mane !== "" || (s.tpl && s.tplTitle) || senseHasExtraContent(s); }); // True only when at least one sense has a regular mane (needs linkify). var hasRegularMane = senses.some(function (s) { return !s.tpl && s.mane !== ""; }); // nimûne and jêder lines must never pass through linkify — only // the plain mane text should be linkified. We build two parallel // arrays: defLines (sent to linkify) and citeLines (kept aside). // Each entry in citeLines corresponds 1-to-1 with a defLines entry; // a template token {{wiktku-cite-N}} is embedded in defLines so // that after linkify runs we know exactly where to splice them back. // Template-call syntax is guaranteed safe: linkifiers leave {{ }} // tokens completely untouched. var defLines = []; // one entry per kept sense (goes to linkify) var citeLines = []; // parallel — nimûne+jêder for that same sense $.each(senses, function (_, sense) { // — Template sense (e.g. {{guharto|ku|somepage}}) — if (sense.tpl) { if (!sense.tplTitle) return; // skip empty template senses var tplLabelTpl = ""; if (sense.etiket && sense.etiket.length) { var tplLabelParts = sense.etiket.map(function (part) { return $.trim(part); }).filter(function (part) { return part !== ""; }); if (tplLabelParts.length) { tplLabelTpl = " {{e|" + lang + "|" + tplLabelParts.join("|") + "}} "; } } var tplCall = sense.tplNoLang ? "{{" + sense.tpl + "|" + sense.tplTitle + "}}" : "{{" + sense.tpl + "|" + lang + "|" + sense.tplTitle + "}}"; var tplHasJeder = sense.jeder && $.grep(sense.jeder, function (j) { return j && j.quote; }).length > 0; var idx = defLines.length; var cite = formatNimune(sense.nimune, lang, tplHasJeder) + formatJeder(sense.jeder, lang); defLines.push("#" + (tplLabelTpl ? tplLabelTpl : " ") + tplCall + (cite ? "{{wiktku-cite-" + idx + "}}" : "")); citeLines.push(cite); return; } // — Normal mane sense — var dfn = sense.mane; if (!dfn && !senseHasExtraContent(sense)) return; // truly empty if (dfn) { dfn = stripWikilinks(dfn); if (dfn[0] !== dfn[0].toUpperCase()) dfn = capitalize(dfn); if (!dfn.match(/[.…?!)\]]$/)) dfn += "."; } else { dfn = "{{mane?|" + lang + "}}"; } var labelTpl = ""; if (sense.etiket && sense.etiket.length) { var labelParts = sense.etiket.map(function (part) { return $.trim(part); }).filter(function (part) { return part !== ""; }); if (labelParts.length) { labelTpl = " {{e|" + lang + "|" + labelParts.join("|") + "}} "; } } var out = "#" + (labelTpl ? labelTpl : " ") + dfn; function wordLine(tpl, words) { if (!words.length) return ""; return "\n#: {{" + tpl + "|" + lang + "|" + words.join("|") + "}}"; } out += wordLine("alt-r", sense.alternativ); out += wordLine("hevmane", sense.hevmane); out += wordLine("dijmane", sense.dijmane); out += wordLine("koordîne", sense.koordine); out += wordLine("jornav", sense.jornav); out += wordLine("jêrnav", sense.jernav); var hasJeder = sense.jeder && $.grep(sense.jeder, function (j) { return j && j.quote; }).length > 0; var cite = formatNimune(sense.nimune, lang, hasJeder) + formatJeder(sense.jeder, lang); var idx = defLines.length; defLines.push(out + (cite ? "{{wiktku-cite-" + idx + "}}" : "")); citeLines.push(cite); }); // Splice citeLines back into a linkified string, replacing each // {{wiktku-cite-N}} token with its stored nimûne/jêder block. function restoreCites(t) { return t.replace(/\{\{wiktku-cite-(\d+)\}\}/g, function (_, n) { return citeLines[parseInt(n, 10)] || ""; }); } var text = defLines.join("\n") + "\n"; if (!hasMane) { // No definitions entered — emit {{mane?}} with bênimûne. text = "# {{mane?|" + lang + "}}\n#* {{bênimûne|" + lang + "}}\n"; callback(text); return; } if (!hasRegularMane) { // All filled senses are template senses — no linkify needed. callback(restoreCites(text)); return; } var didTryToLoad = function () { if (typeof $.wiktviLinkify === "function") { $.wiktviLinkify(text, function (linked) { callback(restoreCites(linked)); }); } else { callback(restoreCites(text)); } }; mw.loader.using("ext.gadget.linkify", didTryToLoad, didTryToLoad); } }, je: makeWordListStep("je", "jê", "Kelîmeyên jê çêbûyî binivîse", "Jê", "g"), tekildar: makeWordListStep("tekildar", "têkildar", "Kelîmeyên ji aliyê etîmolojiyê ve têkildarî vê kelîmeyê binivîse", "Têkildar", "g"), binereherwiha: makeWordListStep("binereherwiha", "binêre herwiha", "Kelîmeyên din ên eleqedar binivîse", "Binêre herwiha", "g"), etym: { id: "etym", name: "etîmolojî", question_fmt: "Etîmolojiya kelîmeyê binivîse", // etymTpls populated from data.json etymTpls: [], visible: function (values) { return values.lang && values.pos; }, /** Fills (or refills) the insert-dropdown from the current etymTpls array. */ refreshTplSelect: function () { var sel = $("#wiktku-start-etym .wiktku-tpl-insert-select"); if (!sel.length) return; sel.find("option[value!='']").remove(); $.each(steps.etym.etymTpls, function (_, tpl) { sel.append($("<option></option>").val(tpl.snippet).text(tpl.name + " — " + tpl.desc)); }); // Notify Chosen that the option list has changed (no-op on mobile). if (!isMobile) sel.trigger("chosen:updated"); }, build: function (stepDiv) { if (stepDiv.find(".wiktku-etym-wrap").length) return null; var wrap = $("<div class='wiktku-etym-wrap'></div>"); var ta = $("<textarea></textarea>") .attr("name", "wiktku-etym-" + $.now()) .attr("class", "wiktku-start-step-field wiktku-etym-text") .attr("rows", 4) .attr("placeholder", "Nimûne: Ji {{ji|en|ku|apple}}. yan rasterast binivîse…"); // Template insert dropdown — options also refreshed after data.json loads. var sel = $("<select class='wiktku-tpl-insert-select'></select>"); sel.append($("<option value=''>— şablonek lê zêde bike —</option>")); $.each(steps.etym.etymTpls, function (_, tpl) { sel.append($("<option></option>").val(tpl.snippet).text(tpl.name + " — " + tpl.desc)); }); sel.on("change", function () { var snippet = $(this).val(); if (!snippet) return; var lang = getValues().lang || ""; snippet = snippet.replace(/CODE/g, lang).replace(/SOURCELANG/g, "?"); insertAtCursor(ta[0], snippet); $(this).val(""); ta.focus(); }); wrap.append(sel).append($("<br>")).append(ta); stepDiv.append(wrap); return ta; }, output: function (values) { var text = $.trim($("#wiktku-start-etym .wiktku-etym-text").val()); if (text) { return "\n==== Etîmolojî ====\n" + text + "\n"; } // No etymology entered — emit {{ji?|lang}} as a placeholder, // but only when the entry has at least one regular (non-şablon) // sense with content — either real mane text, or an empty mane // with other fields filled in (which dfn.getOutput() renders as // {{mane?|lang}} with those fields attached). A şablon sense // like {{guharto|…}} never counts, filled in or not. var dfnSenses = steps.dfn.getSenses($("#wiktku-start-dfn")); var hasRegularMane = dfnSenses.some(function (s) { return !s.tpl && (s.mane !== "" || senseHasExtraContent(s)); }); if (!hasRegularMane) return ""; return "\n==== Etîmolojî ====\n{{ji?|" + values.lang + "}}\n"; } }, dunde: { id: "dunde", name: "dûnde", question_fmt: "Eger ev kelîme ji vî zimanî ketibe zimanekî din, vî zimanî û kelîmeya wî binivîse", visible: function (values) { return !!values.pos; }, disabledKeys: { "navz": true}, /** * Builds one row: a language dropdown + a growing list of word * inputs. When the dropdown gets a value the next empty row is * appended automatically. Mirrors steps.trans's row widget, but * flat (one shared list — dûnde isn't tied to individual senses). */ buildRow: function (stepDiv) { var row = $("<li class='wiktku-dunde-row wiktku-lang-row'></li>"); // Language selector — chosen is applied after insertion into DOM. var langSel = $(mw.html.element("select", { "class": "wiktku-start-step-keyfield wiktku-start-narrow" })); langSel.attr("data-placeholder", "Zimanekî lê bigere"); populateMenus(langSel, steps.dunde.keys || [], steps.dunde.disabledKeys); // When a language is chosen, ensure a next empty row exists. langSel.on("change", function () { steps.dunde.onLangChange(stepDiv, row); }); // Word list for this language. var wordList = $("<ul class='wiktku-dunde-words wiktku-lang-row-words'></ul>"); var firstWord = steps.dunde.makeWordInput(); wordList.append($("<li></li>").append(firstWord)); if (isMobile) { row.append(wrapNativeSelect(langSel)).append(wordList); } else { row.append(langSel).append(wordList); } return row; }, makeWordInput: function () { var input = $("<textarea></textarea>") .attr("name", "wiktku-dunde-word-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 1) .attr("class", "wiktku-dfn-subfield wiktku-start-narrow") .attr("placeholder", "Kelîme…"); input.on("input", function () { var list = $(this).closest("ul.wiktku-dunde-words"); var item = $(this).parent(); var val = $.trim($(this).val()); if (val && item.is(list.children("li:last-child"))) { var next = steps.dunde.makeWordInput(); list.append($("<li></li>").append(next)); } }); return input; }, onLangChange: function (stepDiv, row) { var list = stepDiv.find("ul.wiktku-dunde-list"); var isLast = row.is(list.children("li.wiktku-dunde-row:last-child")); if (isLast) { var newRow = steps.dunde.buildRow(stepDiv); list.append(newRow); // Init chosen after the new row is in the DOM (desktop only). if (!isMobile) newRow.find("select").chosen(chosenOptions); } // Keep disabled keys in sync across all lang selectors. steps.dunde.syncDisabledKeys(stepDiv); }, /** Disables already-selected languages in all other dropdowns. */ syncDisabledKeys: function (stepDiv) { var taken = $.extend({}, steps.dunde.disabledKeys); stepDiv.find("li.wiktku-dunde-row select").each(function () { var v = $(this).val(); if (v) taken[v] = true; }); stepDiv.find("li.wiktku-dunde-row select").each(function () { var self = $(this); var own = self.val(); self.find("option").each(function () { var code = $(this).val(); if (!code) return; $(this).prop("disabled", taken[code] && code !== own); }); self.trigger("chosen:updated"); }); }, build: function (stepDiv) { if (stepDiv.find("ul.wiktku-dunde-list").length) return null; var list = $("<ul class='wiktku-dunde-list wiktku-lang-row-list'></ul>"); list.append(steps.dunde.buildRow(stepDiv)); stepDiv.append(list); // Init chosen after the select is in the DOM (desktop only). if (!isMobile) list.find("select").chosen(chosenOptions); return null; }, /** Reads all [langcode, words[]] rows from the DOM. */ getRows: function (stepDiv) { var result = []; stepDiv.find("li.wiktku-dunde-row").each(function () { var lang = $(this).find("select").val(); if (!lang) return; var words = []; $(this).find("ul.wiktku-dunde-words textarea").each(function () { var v = $.trim($(this).val()); if (v) words.push(v); }); if (words.length) result.push([lang, words]); }); return result; }, output: function () { var stepDiv = $("#wiktku-start-dunde"); var rows = steps.dunde.getRows(stepDiv); if (!rows.length) return ""; var lines = $.map(rows, function (row) { var lang = row[0], words = row[1]; return "* {{dû|" + lang + "|" + words.join("|") + "}}"; }); return "\n==== Dûnde ====\n" + lines.join("\n") + "\n"; } }, zarava: { id: "zarava", name: "bi zaravayên din", visible: function (values) { return steps.trans.visible(values); }, disabledKeys: { "navz": true }, buildRow: function (group) { var row = $("<li class='wiktku-zarava-row wiktku-lang-row'></li>"); var langSel = $(mw.html.element("select", { "class": "wiktku-start-step-keyfield wiktku-start-narrow" })); populateMenus(langSel, steps.zarava.keys || [], steps.zarava.disabledKeys); langSel.on("change", function () { steps.zarava.onLangChange(group, row); }); var wordList = $("<ul class='wiktku-zarava-words wiktku-lang-row-words'></ul>"); var firstWord = steps.zarava.makeWordInput(); wordList.append($("<li></li>").append(firstWord)); row.append(langSel).append(wordList); return row; }, makeWordInput: function () { var input = $("<textarea></textarea>") .attr("name", "wiktku-zarava-word-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 1) .attr("class", "wiktku-dfn-subfield wiktku-start-narrow") .attr("placeholder", "Tercime…"); input.on("input", function () { var list = $(this).closest("ul.wiktku-zarava-words"); var item = $(this).parent(); var val = $.trim($(this).val()); if (val && item.is(list.children("li:last-child"))) { var next = steps.zarava.makeWordInput(); list.append($("<li></li>").append(next)); } }); return input; }, onLangChange: function (group, row) { var list = group.find("ul.wiktku-zarava-list"); var isLast = row.is(list.children("li.wiktku-zarava-row:last-child")); if (isLast) { var newRow = steps.zarava.buildRow(group); list.append(newRow); } steps.zarava.syncDisabledKeys(group); }, /** Disables already-selected dialects in all other dropdowns within one group. */ syncDisabledKeys: function (group) { var taken = $.extend({}, steps.zarava.disabledKeys); group.find("li.wiktku-zarava-row select").each(function () { var v = $(this).val(); if (v) taken[v] = true; }); group.find("li.wiktku-zarava-row select").each(function () { var self = $(this); var own = self.val(); self.find("option").each(function () { var code = $(this).val(); if (!code) return; $(this).prop("disabled", taken[code] && code !== own); }); }); }, /** Builds (or fetches) the .wiktku-zarava-group for one gloss. */ buildGroup: function (stepDiv, gi) { var group = $("<div class='wiktku-zarava-group'></div>").attr("data-gloss-pos", gi); var list = $("<ul class='wiktku-zarava-list wiktku-lang-row-list'></ul>"); list.append(steps.zarava.buildRow(group)); group.append(list); stepDiv.append(group); return group; }, /** Syncs one .wiktku-zarava-group per current gloss (same logic as steps.trans.build). */ build: function (stepDiv) { var glosses = steps.trans.glossList(); if (!glosses.length) { stepDiv.find(".wiktku-zarava-group").remove(); return null; } var existingGroups = stepDiv.find(".wiktku-zarava-group"); if (existingGroups.length > glosses.length) { existingGroups.slice(glosses.length).remove(); } $.each(glosses, function (gi, gloss) { var group = stepDiv.find(".wiktku-zarava-group[data-gloss-pos='" + gi + "']"); if (!group.length) group = steps.zarava.buildGroup(stepDiv, gi); var label = group.find(".wiktku-zarava-group-label"); if (glosses.length > 1) { if (!label.length) { label = $("<div class='wiktku-zarava-group-label'></div>"); group.prepend(label); } label.text(gloss.index + " " + gloss.text); } else if (label.length) { label.remove(); } }); return null; }, /** Reads the dialect rows for a single gloss group. */ getGroupTranslations: function (group) { var result = []; group.find("li.wiktku-zarava-row").each(function () { var lang = $(this).find("select").val(); if (!lang) return; var words = []; $(this).find("ul.wiktku-zarava-words textarea").each(function () { var v = $.trim($(this).val()); if (v) words.push(v); }); if (words.length) result.push([lang, words]); }); return result; }, /** Reads all rows from the DOM, grouped by gloss position. */ getTranslations: function (stepDiv) { var result = []; stepDiv.find(".wiktku-zarava-group").each(function () { result.push(steps.zarava.getGroupTranslations($(this))); }); return result; }, output: function (values) { if (values.lang !== "ku") return ""; var stepDiv = $("#wiktku-start-zarava"); var glosses = steps.trans.glossList(); if (!glosses.length) return ""; var blocks = $.map(glosses, function (gloss, gi) { var group = stepDiv.find(".wiktku-zarava-group[data-gloss-pos='" + gi + "']"); var rows = group.length ? steps.zarava.getGroupTranslations(group) : []; if (!gloss.text && !rows.length) return undefined; if (rows.length) { rows.sort(function (a, b) { var aLang = langsByCode[a[0]] || []; var bLang = langsByCode[b[0]] || []; return (aLang[2] || "").localeCompare(bLang[2] || "", "ku"); }); } var wordLines = $.map(rows, function (row) { var lang = row[0]; var words = row[1]; var wikiWords = words.map(function (w) { return "{{W|" + lang + "|" + w + "}}"; }).join(", "); return "* {{Z|" + lang + "}}: " + wikiWords; }).join("\n"); if (!wordLines) return undefined; var block = "{{werger-ser|" + (gloss.text || "?") + "|" + gloss.index + "}}"; block += "\n" + wordLines; block += "\n{{werger-bin}}"; return block; }); if (!blocks.length) return ""; return "\n==== Bi zaravayên din ====\n" + blocks.join("\n") + "\n"; } }, trans: { id: "trans", name: "werger", visible: function (values) { if (!(values.lang === "ku" && values.pos)) return false; // Hide Werger only when EVERY sense is a template sense (Guharto etc.) // with a title filled in — i.e. there is real content but no plain // gloss to attach a translation table to. A mix of real + template // senses still shows Werger; the template senses are simply skipped // in output(). // // "Real" here means a non-şablon sense with either mane text or // other filled-in fields (etîket/hevmane/nimûne/jêder…), since // dfn.getOutput() renders the latter too, as {{mane?|lang}} plus // whatever else was filled in. // // When nothing has been filled in at all, output() will emit // {{mane?|lang}} instead of a gloss — but Werger should still show, // since the user may want to add translations before they've // settled on a gloss. var dfnSenses = steps.dfn.getSenses($("#wiktku-start-dfn")); var hasRealSense = dfnSenses.some(function (s) { return !s.tpl && (s.mane !== "" || senseHasExtraContent(s)); }); var hasFilledTplSense = dfnSenses.some(function (s) { return s.tpl && s.tplTitle; }); return hasRealSense || !hasFilledTplSense; }, disabledKeys: { "navz": true, "ku": true, "ckb": true, "sdh": true, "lki": true, "hac": true, "zza": true }, /** * Builds one translation row: a language dropdown + a growing list * of word inputs. When the dropdown gets a value the next empty row * is appended automatically. * * @param group the specific .wiktku-trans-group this row belongs to * (each gloss has its own group and its own list of rows, so the * lookups below must stay scoped to that group rather than the * whole step — the step now holds one list per gloss). */ buildRow: function (group) { var row = $("<li class='wiktku-trans-row wiktku-lang-row'></li>"); // Language selector — chosen is applied after insertion into DOM. var langSel = $(mw.html.element("select", { "class": "wiktku-start-step-keyfield wiktku-start-narrow" })); langSel.attr("data-placeholder", "Zimanekî lê bigere"); populateMenus(langSel, steps.trans.keys || [], steps.trans.disabledKeys); // When a language is chosen, ensure a next empty row exists. langSel.on("change", function () { steps.trans.onLangChange(group, row); }); // Word list for this language. var wordList = $("<ul class='wiktku-trans-words wiktku-lang-row-words'></ul>"); var firstWord = steps.trans.makeWordInput(); wordList.append($("<li></li>").append(firstWord)); if (isMobile) { row.append(wrapNativeSelect(langSel)).append(wordList); } else { row.append(langSel).append(wordList); } return row; }, makeWordInput: function () { var input = $("<textarea></textarea>") .attr("name", "wiktku-trans-word-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 1) .attr("class", "wiktku-dfn-subfield wiktku-start-narrow") .attr("placeholder", "Tercime…"); input.on("input", function () { var list = $(this).closest("ul.wiktku-trans-words"); var item = $(this).parent(); var val = $.trim($(this).val()); if (val && item.is(list.children("li:last-child"))) { var next = steps.trans.makeWordInput(); list.append($("<li></li>").append(next)); } }); return input; }, onLangChange: function (group, row) { var list = group.find("ul.wiktku-trans-list"); var isLast = row.is(list.children("li.wiktku-trans-row:last-child")); if (isLast) { var newRow = steps.trans.buildRow(group); list.append(newRow); // Init chosen after the new row is in the DOM (desktop only). if (!isMobile) newRow.find("select").chosen(chosenOptions); } // Keep disabled keys in sync across this gloss's lang selectors // only — the same language can be used for different senses. steps.trans.syncDisabledKeys(group); }, /** Disables already-selected languages in all other dropdowns within one group. */ syncDisabledKeys: function (group) { var taken = $.extend({}, steps.trans.disabledKeys); group.find("li.wiktku-trans-row select").each(function () { var v = $(this).val(); if (v) taken[v] = true; }); group.find("li.wiktku-trans-row select").each(function () { var self = $(this); var own = self.val(); self.find("option").each(function () { var code = $(this).val(); if (!code) return; $(this).prop("disabled", taken[code] && code !== own); }); self.trigger("chosen:updated"); }); }, /** * Builds (or fetches) the .wiktku-trans-group for one gloss, with * its own label and its own list of translation rows. */ buildGroup: function (stepDiv, gi) { var group = $("<div class='wiktku-trans-group'></div>").attr("data-gloss-pos", gi); var list = $("<ul class='wiktku-trans-list wiktku-lang-row-list'></ul>"); list.append(steps.trans.buildRow(group)); group.append(list); stepDiv.append(group); // Init chosen after the select is in the DOM (desktop only). if (!isMobile) list.find("select").chosen(chosenOptions); return group; }, /** * Syncs one .wiktku-trans-group per current gloss, adding new * groups and removing stale ones as senses are added or removed, * while leaving existing groups (and whatever translations the * user has already typed into them) untouched. Groups are keyed * to their gloss's position in glossList() via data-gloss-pos, so * a group always matches the same sense across rebuilds as long * as senses aren't reordered relative to each other. */ build: function (stepDiv) { var glosses = steps.trans.glossList(); if (!glosses.length) { stepDiv.find(".wiktku-trans-group").remove(); return null; } // Drop groups for glosses that no longer exist (always from the // tail — groups are only ever appended in gloss order below). var existingGroups = stepDiv.find(".wiktku-trans-group"); if (existingGroups.length > glosses.length) { existingGroups.slice(glosses.length).remove(); } $.each(glosses, function (gi, gloss) { var group = stepDiv.find(".wiktku-trans-group[data-gloss-pos='" + gi + "']"); if (!group.length) group = steps.trans.buildGroup(stepDiv, gi); // Only label groups when there's more than one gloss to // distinguish between — a single gloss needs no caption. var label = group.find(".wiktku-trans-group-label"); if (glosses.length > 1) { if (!label.length) { label = $("<div class='wiktku-trans-group-label'></div>"); group.prepend(label); } label.text(gloss.index + " " + gloss.text); } else if (label.length) { label.remove(); } }); return null; }, /** Reads the translation rows for a single gloss group. */ getGroupTranslations: function (group) { var result = []; group.find("li.wiktku-trans-row").each(function () { var lang = $(this).find("select").val(); if (!lang) return; var words = []; $(this).find("ul.wiktku-trans-words textarea").each(function () { var v = $.trim($(this).val()); if (v) words.push(v); }); if (words.length) result.push([lang, words]); }); return result; }, /** * Reads all translation rows from the DOM, grouped by gloss * position — one array of [lang, words] rows per gloss group, in * the same order as the .wiktku-trans-group elements. */ getTranslations: function (stepDiv) { var result = []; stepDiv.find(".wiktku-trans-group").each(function () { result.push(steps.trans.getGroupTranslations($(this))); }); return result; }, /** * Builds the numbered "{ index, gloss }" list — one entry per dfn * sense that has a real mane (skips template senses like Guharto, * which have nothing to caption a translation table with). The * index matches the sense's actual position in the numbered "#" * definition list (1-based), including template senses in the count, * so the number printed next to {{werger-ser}} lines up with the * gloss the reader sees in the entry. * * When nothing has been filled in at all (dfn.getOutput() will emit * {{mane?|lang}} as sense 1), this returns a single placeholder * entry with empty text instead of an empty array, so Werger still * has one group to attach translations to before a gloss exists. * When every filled sense is a template sense instead, this stays * empty — that mirrors trans.visible()'s hidden case, where there's * no group in the DOM for a placeholder to attach to anyway. */ glossList: function () { var dfnSenses = steps.dfn.getSenses($("#wiktku-start-dfn")); var glosses = []; var hasFilledTplSense = false; $.each(dfnSenses, function (i, s) { if (s.tpl) { if (s.tplTitle) hasFilledTplSense = true; return; // template sense — no gloss to caption with } var dfn = s.mane; if (!dfn) { // No mane text, but other fields (etîket/hevmane/nimûne/ // jêder…) are filled — dfn.getOutput() still emits this // sense as a numbered line using {{mane?|lang}}, so it // needs its own gloss group too, just with no caption text. if (senseHasExtraContent(s)) glosses.push({ index: i + 1, text: "" }); return; } if (dfn[0] !== dfn[0].toLowerCase()) dfn = decapitalize(dfn); dfn = stripWikilinks(dfn).replace(/[.…?!)\]،؟]+$/, ""); glosses.push({ index: i + 1, text: dfn }); }); if (!glosses.length && !hasFilledTplSense) { glosses.push({ index: 1, text: "" }); } return glosses; }, output: function (values) { if (values.lang !== "ku") return ""; var stepDiv = $("#wiktku-start-trans"); var glosses = steps.trans.glossList(); // Every sense is a template sense — there's no real gloss // anywhere and no group in the DOM either (glossList() only // returns empty in that case), so skip the section entirely. if (!glosses.length) return ""; // Each gloss now has its own group of translation rows — // attach every gloss's own words under its own werger-ser/-bin // pair instead of dumping everything under the first one. var blocks = $.map(glosses, function (gloss, gi) { var group = stepDiv.find(".wiktku-trans-group[data-gloss-pos='" + gi + "']"); var rows = group.length ? steps.trans.getGroupTranslations(group) : []; // Placeholder gloss (no real mane entered yet) with nothing // translated into it — nothing to output, and gloss.text is // empty so there's no caption to give {{werger-ser}} anyway. if (!gloss.text && !rows.length) return undefined; if (rows.length) { // Sort by Kurdish sort key. rows.sort(function (a, b) { var aLang = langsByCode[a[0]] || []; var bLang = langsByCode[b[0]] || []; return (aLang[2] || "").localeCompare(bLang[2] || "", "ku"); }); } var wordLines = $.map(rows, function (row) { var lang = row[0]; var words = row[1]; var wikiWords = words.map(function (w) { return "{{W|" + lang + "|" + w + "}}"; }).join(", "); return "* {{Z|" + lang + "}}: " + wikiWords; }).join("\n"); var block = "{{werger-ser|" + (gloss.text || "?") + "|" + gloss.index + "}}"; if (wordLines) block += "\n" + wordLines; block += "\n{{werger-bin}}"; return block; }); if (!blocks.length) return ""; return "\n==== Werger ====\n" + blocks.join("\n") + "\n"; } }, }; steps.trans.keys = steps.lang.choices; steps.dunde.keys = steps.lang.choices; steps.zarava.keys = getZaravaKeys(steps.lang.choices); var ordered_steps = [ steps.lang, steps.pron, steps.pos, steps.cinsiyet, steps.lektur, steps.tr, steps.dfn, steps.je, steps.tekildar, steps.etym, steps.dunde, steps.binereherwiha, steps.zarava, steps.trans]; // Step ids that belong to each section (not shared across sections). var PER_SECTION_STEP_IDS = [ "pos", "cinsiyet", "lektur", "tr", "dfn", "je", "tekildar", "etym", "dunde", "binereherwiha", "zarava", "trans" ]; // ── Multi-section state ────────────────────────────────────────────────── // Each entry is a plain snapshot: { pos, cinsiyet, lektur, tr, dfn (senses[]), // je, tekildar, binereherwiha, trans (rows[]) }. var sections = [{}]; // section 0 starts empty (DOM is the truth) var activeSection = 0; function snapshotDfn() { return steps.dfn.getSenses($("#wiktku-start-dfn")); } /** * Rebuild the dfn DOM from a previously snapshotted senses array. */ function restoreDfn(senses) { var stepDiv = $("#wiktku-start-dfn"); // Tear down the existing list so build() recreates it cleanly. stepDiv.find("ol.wiktku-dfn-list").remove(); steps.dfn.build(stepDiv); var list = stepDiv.find("ol.wiktku-dfn-list"); $.each(senses, function (i, sense) { // Ensure enough blocks exist (build() seeds one). var blocks = list.find("li.wiktku-dfn-sense"); var block = blocks.eq(i); if (!block.length) { var nb = steps.dfn.buildSenseBlock(stepDiv); list.append(nb); block = list.find("li.wiktku-dfn-sense").last(); } // Template selector. block.find("select.wiktku-dfn-tpl-select").val(sense.tpl || ""); if (sense.tpl) { block.find("textarea.wiktku-dfn-mane").hide(); block.find("input.wiktku-dfn-tpl-title").val(sense.tplTitle || "").show(); } else { block.find("textarea.wiktku-dfn-mane").val(sense.mane || "").show(); block.find("input.wiktku-dfn-tpl-title").hide().val(""); } // Re-sync the formên alternatîv/hevmane/… hide state now that // tplSelect's value was set programmatically (its own "change" // handler doesn't fire from .val(), so this doesn't happen otherwise). var updateVis = block.data("updateFieldVisibility"); if (updateVis) updateVis(); // Restore a sub-list (etiket, formên alternatîv, hevmane …) from a values array. function restoreSubList(cls, values) { if (!values || !values.length) return; var groupDiv = block.find("." + cls + "-group"); var subList = groupDiv.find("ol, ul").first(); if (!subList.length) return; // group not found // Fill existing items, append new ones as needed. $.each(values, function (j, val) { var items = subList.find("li"); if (j < items.length) { items.eq(j).find("textarea").val(val); } else { var ta = $("<textarea></textarea>") .attr("name", "wiktku-dfn-restore-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 1) .attr("class", "wiktku-dfn-subfield wiktku-start-narrow") .val(val); ta.on("input", function () { steps.dfn.onSubInput(subList, this, 1, true); }); subList.append($("<li></li>").append(ta)); } }); } // Reveal and populate lazy groups that have data. var lazyMap = { "wiktku-dfn-etiket": sense.etiket, "wiktku-dfn-alternativ": sense.alternativ, "wiktku-dfn-hevmane": sense.hevmane, "wiktku-dfn-dijmane": sense.dijmane, "wiktku-dfn-koordine": sense.koordine, "wiktku-dfn-jornav": sense.jornav, "wiktku-dfn-jernav": sense.jernav }; $.each(lazyMap, function (cls, vals) { if (vals && vals.length) restoreSubList(cls, vals); }); // Nimûne items are objects { text, tr?, t? } — restore using the builder. if (sense.nimune && sense.nimune.length) { var nimuneGroupDiv = block.find(".wiktku-dfn-nimune-group"); var nimuneList = nimuneGroupDiv.find("ol.wiktku-dfn-nimune-list"); var buildFn = nimuneGroupDiv.data("buildNimuneLi"); nimuneList.empty(); $.each(sense.nimune, function (_, n) { var text = typeof n === "object" ? (n.text || "") : n; if (!text) return; var li = buildFn ? buildFn() : $("<li class='wiktku-dfn-nimune-li'></li>"); li.find(".wiktku-dfn-nimune-text").val(text); if (n.tr) li.find(".wiktku-dfn-nimune-tr").val(n.tr); if (n.t) li.find(".wiktku-dfn-nimune-t").val(n.t); nimuneList.append(li); }); // Always leave a blank trailing item. if (buildFn) nimuneList.append(buildFn()); } // Restore jêder (quote/citation) entries — a growing list, restored using the // builder just like Nimûne. Accepts either the current array shape or a // single legacy object (from older saved sections) for backwards compatibility. var jederArr = $.isArray(sense.jeder) ? sense.jeder : (sense.jeder ? [sense.jeder] : []); if (jederArr.length) { var jederGroupDiv = block.find(".wiktku-dfn-jeder-group"); var jederList = jederGroupDiv.find("ol.wiktku-dfn-jeder-list"); var buildJederFn = jederGroupDiv.data("buildJederLi"); jederList.empty(); $.each(jederArr, function (_, j) { if (!j || !j.quote) return; var li = buildJederFn ? buildJederFn() : $("<li class='wiktku-dfn-jeder-li'></li>"); li.find(".wiktku-dfn-nimune-quote").val(j.quote); if (j.quoteTr) li.find(".wiktku-dfn-nimune-quote-tr").val(j.quoteTr); if (j.quoteT) li.find(".wiktku-dfn-nimune-quote-t").val(j.quoteT); if (j.jederManual) { var manualSel = li.find(".wiktku-dfn-quote-src-sel"); manualSel.val("__manual__").trigger("change"); li.find(".wiktku-dfn-quote-src-manual").val(j.jederManual); } else if (j.jederTpl) { var srcSel = li.find(".wiktku-dfn-quote-src-sel"); srcSel.val(j.jederTpl).trigger("change"); if (j.jêderFields) { $.each(j.jêderFields, function (key, val) { li.find(".wiktku-dfn-quote-src-input[data-field-key='" + key + "']").val(val); }); } } jederList.append(li); }); // Always leave a blank trailing item, same as Nimûne. if (buildJederFn) jederList.append(buildJederFn()); } }); } /** * Snapshot simple (non-dfn) per-section steps from current DOM into obj. */ function saveCurrentSection() { var snap = {}; $.each(PER_SECTION_STEP_IDS, function (_, id) { if (id === "dfn") { snap.dfn = snapshotDfn(); return; } if (id === "etym") { snap.etym = $.trim($("#wiktku-start-etym .wiktku-etym-text").val()); return; } var step = steps[id]; if (!step) return; var stepDiv = $("#wiktku-start-" + id); if (id === "trans") { snap.trans = steps.trans.getTranslations(stepDiv); return; } if (id === "zarava") { snap.zarava = steps.zarava.getTranslations(stepDiv); return; } if (id === "dunde") { snap.dunde = steps.dunde.getRows(stepDiv); return; } // Generic: read all step fields. var fields = stepDiv.find(".wiktku-start-step-field"); if (step.multiple) { snap[id] = fields.map(function () { return $(this).val(); }).get(); } else { snap[id] = fields.val(); } }); sections[activeSection] = snap; } /** * Restore a previously saved snapshot into the form DOM. */ function restoreSection(snap) { $.each(PER_SECTION_STEP_IDS, function (_, id) { if (id === "dfn") { restoreDfn(snap.dfn || []); return; } if (id === "etym") { $("#wiktku-start-etym .wiktku-etym-wrap").remove(); steps.etym.build($("#wiktku-start-etym")); $("#wiktku-start-etym .wiktku-etym-text").val(snap.etym || ""); return; } if (id === "trans") { // Rebuild trans groups (dfn must already be restored by this // point in the $.each loop, so glossList() reflects it). var transDiv = $("#wiktku-start-trans"); transDiv.find(".wiktku-trans-group").remove(); steps.trans.build(transDiv); var groupsSnap = snap.trans || []; $.each(groupsSnap, function (gi, rows) { var group = transDiv.find(".wiktku-trans-group[data-gloss-pos='" + gi + "']"); if (!group.length) return; // gloss no longer exists — drop its rows var list = group.find("ul.wiktku-trans-list"); $.each(rows, function (j, row) { var lang = row[0], words = row[1]; var lastRow = list.find("li.wiktku-trans-row").last(); lastRow.find("select").val(lang).trigger("change"); var wordList = lastRow.find("ul.wiktku-trans-words"); $.each(words, function (k, word) { var wordItems = wordList.find("li"); if (k < wordItems.length) { wordItems.eq(k).find("textarea").val(word); } else { // .val() below doesn't fire "input", so the normal // auto-grow never runs — append a matching item // ourselves instead of silently dropping the word. var extraInput = steps.trans.makeWordInput(); wordList.append($("<li></li>").append(extraInput)); extraInput.val(word); } }); // Leave one trailing empty field so the row can still grow // when the user types, matching a freshly-built row. if ($.trim(wordList.children("li").last().find("textarea").val())) { wordList.append($("<li></li>").append(steps.trans.makeWordInput())); } }); }); return; } if (id === "zarava") { // Rebuild zarava groups (dfn must already be restored by this // point in the $.each loop, so glossList() reflects it). var zaravaDiv = $("#wiktku-start-zarava"); zaravaDiv.find(".wiktku-zarava-group").remove(); steps.zarava.build(zaravaDiv); var zaravaGroupsSnap = snap.zarava || []; $.each(zaravaGroupsSnap, function (gi, rows) { var group = zaravaDiv.find(".wiktku-zarava-group[data-gloss-pos='" + gi + "']"); if (!group.length) return; // gloss no longer exists — drop its rows var list = group.find("ul.wiktku-zarava-list"); $.each(rows, function (j, row) { var lang = row[0], words = row[1]; var lastRow = list.find("li.wiktku-zarava-row").last(); lastRow.find("select").val(lang).trigger("change"); var wordList = lastRow.find("ul.wiktku-zarava-words"); $.each(words, function (k, word) { var wordItems = wordList.find("li"); if (k < wordItems.length) { wordItems.eq(k).find("textarea").val(word); } else { var extraInput = steps.zarava.makeWordInput(); wordList.append($("<li></li>").append(extraInput)); extraInput.val(word); } }); if ($.trim(wordList.children("li").last().find("textarea").val())) { wordList.append($("<li></li>").append(steps.zarava.makeWordInput())); } }); }); return; } if (id === "dunde") { // Rebuild dunde rows. var dundeDiv = $("#wiktku-start-dunde"); dundeDiv.find("ul.wiktku-dunde-list").remove(); steps.dunde.build(dundeDiv); var dundeRows = snap.dunde || []; $.each(dundeRows, function (i, row) { var lang = row[0], words = row[1]; var list = dundeDiv.find("ul.wiktku-dunde-list"); var lastRow = list.find("li.wiktku-dunde-row").last(); lastRow.find("select").val(lang).trigger("change"); var wordList = lastRow.find("ul.wiktku-dunde-words"); $.each(words, function (j, word) { var wordItems = wordList.find("li"); if (j < wordItems.length) { wordItems.eq(j).find("textarea").val(word); } else { // .val() below doesn't fire "input", so the normal // auto-grow never runs — append a matching item // ourselves instead of silently dropping the word. var extraInput = steps.dunde.makeWordInput(); wordList.append($("<li></li>").append(extraInput)); extraInput.val(word); } }); // Leave one trailing empty field so the row can still grow // when the user types, matching a freshly-built row. if ($.trim(wordList.children("li").last().find("textarea").val())) { wordList.append($("<li></li>").append(steps.dunde.makeWordInput())); } }); return; } var step = steps[id]; if (!step) return; var stepDiv = $("#wiktku-start-" + id); var fields = stepDiv.find(".wiktku-start-step-field"); var val = snap[id]; if (val === undefined || val === null) return; if (step.multiple) { var arr = val; fields.each(function (i) { if (i < arr.length) $(this).val(arr[i]); }); } else { fields.val(val); } // Notify chosen widgets of the programmatic value change. if (!isMobile) fields.filter("select").trigger("chosen:updated"); }); } function getWikitextForCurrentSection(callback) { var values = getValues(); var entry = steps.pos.output(values); steps.dfn.getOutput(values, function (output) { entry += output; entry += steps.je.output(values); entry += steps.tekildar.output(values); entry += steps.etym.output(values); entry += steps.dunde.output(values); entry += steps.binereherwiha.output(values); entry += steps.zarava.output(values); entry += steps.trans.output(values); callback(entry, values); }); } function getWikitextAllSections(callback) { saveCurrentSection(); var results = new Array(sections.length); var sharedValues = getValues(); // lang/pron are shared function processSection(i) { if (i >= sections.length) { // All done — restore original active section. restoreSection(sections[activeSection]); refresh(); callback(results, sharedValues); return; } restoreSection(sections[i]); refresh(); getWikitextForCurrentSection(function (sectionText) { results[i] = sectionText; processSection(i + 1); }); } processSection(0); } /** * Assembles wikitext for all sections plus the shared lang/pron header. */ function getWikitext(callback) { getWikitextAllSections(function (sectionTexts, sharedValues) { var entry = steps.lang.output(sharedValues); entry += steps.pron.output(sharedValues); entry += sectionTexts.join("\n"); // Edit summary uses section 0's values. Read from the saved snapshot // (not the live DOM) so it doesn't mix section 0's pos with whichever // section happens to be active/restored at this point. var dfnSenses = (sections[0] && sections[0].dfn) || []; var dfnSummary = dfnSenses.map(function (s) { return s.mane; }).filter(Boolean).join("; "); var summaryLabel = addLangMode ? "WF:Ziman lê zêde" : "WF:Nû"; var summary = "([[Mediawiki:Gadget-start.js|" + summaryLabel + "]] v.2.0) +" + sharedValues.lang + ":" + sections[0].pos + ":" + dfnSummary; var summaryField = document.getElementById("wpSummary"); if (addLangMode && summaryField.value) { summary = summaryField.value + " " + summary; } summaryField.value = summary; callback(entry); }); } var continueBtn; function getValuesForStep(stepId) { var fields = $("#wiktku-start-" + stepId + " .wiktku-start-step-field"); var step = steps[stepId]; if (step.keys) { var values = {}; fields.each(function (i, field) { var key = $(field).prevAll(".wiktku-start-step-keyfield").val(); if (key) values[key] = $(field).val(); }); return values; } else if (step.multiple) { return fields.map(function () { return $(this).val(); }).get(); } return fields.val(); } function getValues() { var values = {}; $.each(steps, function (stepId) { values[stepId] = getValuesForStep(stepId); }); return values; } function populateMenus(inputs, choices, disabledValues) { if (!disabledValues) disabledValues = {}; var vals = inputs.map(function (i, input) { return $(input).val(); }); inputs.empty(); inputs.append($("<option></option>")); $.each(choices, function (j, choice) { // Append the language code in parentheses so that typing a code // (e.g. "ku") in the search box still finds the language name. var displayText = capitalize(choice[1]); if (choice[2] !== undefined) { // This is a language choice [code, name, sortKey] — show code. displayText = capitalize(choice[1]) + " (" + choice[0] + ")"; } var option = $(mw.html.element("option", { value: choice[0] }, displayText)); if (disabledValues[choice[0]]) option.prop("disabled", true); inputs.append(option); }); inputs.val(function (i) { return vals[i]; }); } /** * Returns a bitmap containing the keys that should be disabled for a key * menu in the given step because they are disabled or already taken by * another key menu. */ function getDisabledKeys(step) { var occupiedKeys = {}; $("#wiktku-start-" + step.id + " .wiktku-start-step-keyfield").each(function () { occupiedKeys[$(this).val()] = true; }); if (step.disabledKeys) $.extend(occupiedKeys, step.disabledKeys); return occupiedKeys; } function buildKeyInput(step) { if (!step.keys) return undefined; var input = $(mw.html.element("select", { "class": "wiktku-start-step-keyfield wiktku-start-narrow" })); input.attr("data-placeholder", "Hilbijêre " + step.keyName); if (isMobile) { populateMenus(input, step.keys, getDisabledKeys(step)); // On mobile return the wrapper; the select is inside it. // Change events still fire on the inner select. return wrapNativeSelect(input); } input.on("chosen:showing_dropdown", function () { $(this).data("wiktku-defaultValue", $(this).val()); }); input.change(function (_, context) { var inputs = $("#wiktku-start-" + step.id + " .wiktku-start-step-keyfield").not(this); var oldValue = $(this).data("wiktku-defaultValue"); var newValue = context.selected; inputs.find("option[value='" + oldValue + "']").prop('disabled', false); inputs.find("option[value='" + newValue + "']").prop('disabled', true); inputs.trigger("chosen:updated"); }); populateMenus(input, step.keys, getDisabledKeys(step)); return input; } /** * If the current text field has text and there are no more text fields after * the current text field in the list, add another text field to the list. */ function refreshForTextField(currentInput, step) { currentInput = $(currentInput); var value = currentInput.val(); var item = currentInput.parent(); if (value && !item.next("li").length) { var nextInput = $("<textarea></textarea>") .attr("name", "wiktku-field-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("class", currentInput.attr("class")) .attr("rows", currentInput.attr("rows") || 1); nextInput.on("input", function (evt) { refreshForTextField(evt.target, step); }); var nextKeyInput = buildKeyInput(step); var nextItem = $("<li></li>").append(nextKeyInput).append(nextInput); item.parent().append(nextItem); if (nextKeyInput) nextKeyInput.chosen(chosenOptions); } var canContinue = !continueBtn.isDisabled(); if ((value && !canContinue) || (!value && canContinue)) { refresh(step); } } function prepareInput(input, step) { if (!input) return; if (step.required) input.prop('required', true); input.change(step, refresh); } /** * Shows and hides all the steps based on whether their prerequisites are met, * and updates placeholders where applicable. */ function refresh(evt) { var values = getValues(); var changedStep = evt && evt.data; var didFocus = false; var canContinue = true; // Re-filter template options in every sense block whenever lang changes. $("#wiktku-start-dfn .wiktku-dfn-tpl-select").each(function () { var fn = $(this).data("updateOptions"); if (typeof fn === "function") fn(); }); // Re-filter pronunciation and etymology template dropdowns when language changes. steps.pron.refreshTplSelect(); steps.etym.refreshTplSelect(); // Sync tr/t sub-fields in every nimûne item to the current language. // tr shown when language needs transliteration; t shown when lang !== "ku". (function () { var lang = values.lang || ""; var showTr = needsTransliteration(lang); var showT = lang && lang !== "ku"; $("#wiktku-start-dfn .wiktku-dfn-nimune-list li.wiktku-dfn-nimune-li").each(function () { var li = $(this); // Ensure the sub-wrapper exists when we need it. var subWrap = li.find(".wiktku-dfn-nimune-sub"); // tr field var trTa = li.find(".wiktku-dfn-nimune-tr"); if (showTr && !trTa.length) { if (!subWrap.length) { subWrap = $("<div></div>").addClass("wiktku-dfn-nimune-sub"); li.append(subWrap); } trTa = $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-tr-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 5) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-tr") .attr("placeholder", "Transkrîpsiyon…"); subWrap.prepend(trTa); } else if (!showTr && trTa.length) { trTa.remove(); } // t field var tTa = li.find(".wiktku-dfn-nimune-t"); if (showT && !tTa.length) { if (!subWrap.length) { subWrap = $("<div></div>").addClass("wiktku-dfn-nimune-sub"); li.append(subWrap); } tTa = $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-t-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 5) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-t") .attr("placeholder", "Tercimeya nimûneyê kurmancî…"); subWrap.append(tTa); } else if (!showT && tTa.length) { tTa.remove(); } // Remove the wrapper if it ended up empty. subWrap = li.find(".wiktku-dfn-nimune-sub"); if (subWrap.length && !subWrap.children().length) subWrap.remove(); }); }()); // Sync tr/t sub-fields in every jêder citation to the current language. // tr shown when language needs transliteration; t shown when lang !== "ku". (function () { var lang = values.lang || ""; var showTr = needsTransliteration(lang); var showT = lang && lang !== "ku"; $("#wiktku-start-dfn .wiktku-dfn-jeder-list li.wiktku-dfn-jeder-li").each(function () { var li = $(this); // Ensure the sub-wrapper exists when we need it. It must sit right // after the quote textarea and before the source selector. var subWrap = li.find(".wiktku-dfn-quote-sub"); // tr field var trTa = li.find(".wiktku-dfn-nimune-quote-tr"); if (showTr && !trTa.length) { if (!subWrap.length) { subWrap = $("<div></div>").addClass("wiktku-dfn-quote-sub"); li.find(".wiktku-dfn-nimune-quote").after(subWrap); } trTa = $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-quote-tr-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 2) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-quote-tr") .attr("placeholder", "Transkrîpsiyona jêgirtinê…"); subWrap.prepend(trTa); } else if (!showTr && trTa.length) { trTa.remove(); } // t field var tTa = li.find(".wiktku-dfn-nimune-quote-t"); if (showT && !tTa.length) { if (!subWrap.length) { subWrap = $("<div></div>").addClass("wiktku-dfn-quote-sub"); li.find(".wiktku-dfn-nimune-quote").after(subWrap); } tTa = $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-quote-t-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 2) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-quote-t") .attr("placeholder", "Tercimeya jêgirtinê ya kurmancî…"); subWrap.append(tTa); } else if (!showT && tTa.length) { tTa.remove(); } // Remove the wrapper if it ended up empty. subWrap = li.find(".wiktku-dfn-quote-sub"); if (subWrap.length && !subWrap.children().length) subWrap.remove(); }); }()); $.each(steps, function (stepId, step) { if (typeof(step.visible) === "function" && !step.visible(values)) { $("#wiktku-start-" + stepId).slideUp(); } else { var stepDiv = $("#wiktku-start-" + stepId); if (changedStep !== step && typeof(step.build) === "function") { prepareInput(step.build(stepDiv, values), step); } var input = stepDiv.find(".wiktku-start-step-field"); if (typeof(step.example) === "function") { // .find() above already reaches nested fields (e.g. the dfn // step's mane textareas inside each sense block), so one // assignment covers every step; dfn keeps its own fallback. var exampleText = step.example(values) || (step.id === "dfn" ? "Mane…" : ""); input.attr("placeholder", exampleText); } var didSlideDown; if (!didFocus && stepDiv.css("display") === "none" && step.required) { didSlideDown = function (evt) { input.focus(); }; didFocus = true; } stepDiv.slideDown(didSlideDown); } if (step.required && (values[stepId] === "" || (step.multiple && values[stepId].join("") === ""))) { canContinue = false; } }); continueBtn.setDisabled(!canContinue); } function destroy() { $("#wiktku-start-form, .noafterwizard").slideUp(function () { $(this).remove(); }); $(".noarticletext .nowizard, #editform").slideDown(); $("#ca-edit").removeClass("selected"); $("#ca-wiktku-nowizard").addClass("selected"); } // Priority order for Kurdish dialects and the navz pseudo-code. // Codes listed here come before all other languages; unlisted codes // are sorted alphabetically by their display name via localeCompare. var LANG_PRIORITY = ["navz", "ku", "hac", "sdh", "lki", "ckb", "zza"]; /** * Inserts a new == {{ziman|code}} == section into existing page wikitext * at the correct sorted position: * 1. Any content before the first language section is preserved at the top. * 2. navz is always first, then ku/hac/sdh/lki/ckb/zza in that order, * then all other languages sorted by display name (localeCompare). */ function insertNewLangSection(existing, wikitext) { var newCodeMatch = wikitext.match(/^== \{\{ziman\|([^}]+)\}\} ==/); var newCode = newCodeMatch ? newCodeMatch[1] : ""; var sections = []; var preamble = ""; var firstMatch = existing.match(/(?:^|\n)== \{\{ziman\|/); if (!firstMatch) { // No existing lang sections at all — just append. var sep = existing && !/\n\s*$/.test(existing) ? "\n\n" : ""; return existing + sep + wikitext; } // Everything before the first == {{ziman|...}} == is the preamble. var firstSectionStart = existing.indexOf("== {{ziman|"); // Walk back to the start of that line. var lineStart = existing.lastIndexOf("\n", firstSectionStart - 1); var preambleEnd = lineStart !== -1 ? lineStart + 1 : 0; preamble = existing.slice(0, preambleEnd); // Parse each language section: header line + everything until the next header. var body = existing.slice(preambleEnd); // NOTE: with the /m flag, a bare "$" matches end-of-*line*, not just // end-of-string — that previously made the non-greedy content group // stop at the section's first line break instead of running to the // next language header (or the real end of the text), silently // dropping the rest of that section's wikitext. (?![\s\S]) matches // only the true end of the string, /m flag or not. var langSectionRe = /^(== \{\{ziman\|([^}]+)\}\} ==\n?)([\s\S]*?)(?=\n== \{\{ziman\||(?![\s\S]))/gm; var m; while ((m = langSectionRe.exec(body)) !== null) { sections.push({ code: m[2], content: m[0] // full text of this section including header }); } // Determine sort rank: priority list first (by index), then alphabetical. function getLangName(code) { var entry = langsByCode[code]; return entry ? entry[1] : code; } function sortRank(code) { var idx = LANG_PRIORITY.indexOf(code); return idx !== -1 ? idx : LANG_PRIORITY.length; } function compareLangs(a, b) { var ra = sortRank(a), rb = sortRank(b); if (ra !== rb) return ra - rb; // Both are outside priority list — sort by display name. return getLangName(a).localeCompare(getLangName(b), userLang); } // Insert the new section into the sorted list. var newSection = { code: newCode, content: wikitext }; var inserted = false; for (var i = 0; i < sections.length; i++) { if (compareLangs(newCode, sections[i].code) < 0) { sections.splice(i, 0, newSection); inserted = true; break; } } if (!inserted) sections.push(newSection); // Re-join: preamble + sections separated by newlines. var joined = sections.map(function (s) { // Ensure each section ends with exactly one newline before the next. return s.content.replace(/\n+$/, ""); }).join("\n"); return preamble + joined + "\n"; } function build() { $(".nowizard, .nowizard .noafterwizard").hide(); // Dismiss the startup notice now that the form is ready. if (!isMobile) mw.notify("", { tag: "wiktku-start-notice" }); var callToAction = $("#wiktku-calltoaction"); var origCallToActionText = callToAction.text(); $(mw.util.addPortletLink("p-views", "#", "Edîtora çavkaniyê veke", "ca-wiktku-nowizard", "Vê rûpelê bi edîtora çavkaniyê çêke", undefined, "#ca-watch")).click(function (evt) { evt.preventDefault(); callToAction.text(origCallToActionText); destroy(); }); if (callToAction.length) { callToAction.text(origCallToActionText + " Forma li jêr ji bo çêkirina madeyeke nû bi kar bîne."); } var startForm = $("<form id='wiktku-start-form'></form>"); if (addLangMode) { startForm.append($("<p class='wiktku-addlang-notice'></p>").text( "Bi vê formê tu yê beşeke nû li rûpelê îlaw bikî. Eger ev zimanê ku tu îlawe dikî jixwe di rûpelê de hebe, beşa nû li dawiya vî zimanî dê were îlawekirin. " + "Ji kerema xwe netîceya dawî kontrol bikin, eger problemek derkeve, li [[Mediawiki talk:Gadget-start.js|nîqaşa vê amûrê]] problemê ragihîne.")); } var spinner; // Tab bar for switching between POS sections. var sectionTabsDiv = $("<div id='wiktku-section-tabs'></div>"); startForm.submit(function (evt) { evt.preventDefault(); continueBtn.setDisabled(true); spinner.show(); getWikitext(function (wikitext) { if (addLangMode) { var textbox = $("#wpTextbox1"); var existing = textbox.val() || ""; // Check whether the generated lang header already exists in the page. // wikitext always starts with "== {{ziman|CODE}} ==\n" (from steps.lang.output). // If that exact section heading is already present in the existing content, // strip it from the new output and insert the remaining content at the end // of that lang section (just before the next == level-2 heading, or at the // very end of the page if there is no following section). var langHeaderMatch = wikitext.match(/^(== \{\{ziman\|[^}]+\}\} ==\n)/); if (langHeaderMatch) { var langHeader = langHeaderMatch[1]; // e.g. "== {{ziman|ku}} ==\n" // Escape for use in RegExp. var escapedHeader = langHeader.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); if (new RegExp(escapedHeader).test(existing)) { // Strip the header from the new output. var newContent = wikitext.slice(langHeader.length); // Find the insertion point: end of the existing lang section. // A new L2 heading marks the start of the next language block. var afterHeader = existing.indexOf(langHeader); var searchFrom = afterHeader + langHeader.length; // Find the next == … == heading after this section's start. var nextL2 = existing.indexOf("\n== ", searchFrom); var insertAt = nextL2 !== -1 ? nextL2 : existing.length; // Ensure there's a blank line before the inserted block. var before = existing.slice(0, insertAt); var after = existing.slice(insertAt); var sep = /\n\s*$/.test(before) ? "" : "\n"; textbox.val(before + sep + newContent + after); } else { // New language — insert at the correct sorted position. textbox.val(insertNewLangSection(existing, wikitext)); } } else { // Unexpected format — insert at sorted position anyway. textbox.val(insertNewLangSection(existing, wikitext)); } } else { $("#wpTextbox1").val(wikitext); } $("html, body").animate({scrollTop: 0}); callToAction.text("Hindik ma!"); $("#wiktku-preview-container").remove(); destroy(); }); }); $.each(ordered_steps, function (i, step) { var stepDiv = $(mw.html.element("div", { "class": "wiktku-start-step", id: "wiktku-start-" + step.id })); var name = capitalize(step.name); stepDiv.append($(mw.html.element("h3", { "class": "wiktku-start-step-name" }, new mw.html.Raw(mw.html.element("label", { "for": "wiktku-start-" + step.id + "-field" }, name))))); if (step.question_fmt) { stepDiv.append($(mw.html.element("label", { "class": "wiktku-start-step-question", "for": "wiktku-start-" + step.id + "-field" }, step.question_fmt))); if (step.question_br) stepDiv.append($("<br>")); } var input; if (step.choices) { input = $(mw.html.element("select", { "class": "wiktku-start-step-field", id: "wiktku-start-" + step.id + "-field" })); input.attr("data-placeholder", capitalize(step.name) + " hilbijêre "); populateMenus(input, step.choices); if (step.multiple) input.attr("multiple", true); if (isMobile) { stepDiv.append(wrapNativeSelect(input)); } else { stepDiv.append(input); } } else if (typeof(step.build) === "function") { input = step.build(stepDiv); } else { input = $("<textarea></textarea>") .attr("class", "wiktku-start-step-field") .attr("id", "wiktku-start-" + step.id + "-field") .attr("rows", step.rows || 2); if (step.narrow) input.addClass("wiktku-start-narrow"); if (step.multiple) { input.on("input", function (evt) { refreshForTextField(evt.target, step); }); var keyInput = buildKeyInput(step); var list = $(step.ordered ? "<ol></ol>" : "<ul></ul>") .append($("<li></li>").append(keyInput).append(input)); stepDiv.append(list); } else stepDiv.append(input); } prepareInput(input, step); stepDiv.hide(); // Insert tab bar just before the first per-section step. if (step.id === "pos") startForm.append(sectionTabsDiv); startForm.append(stepDiv); }); // ── Section tab helpers ────────────────────────────────────────────── // ── Add-section button — lives in the tab bar, disabled until pos chosen ── var addSectionBtn = new OO.ui.ButtonWidget({ label: "+ Beş zêde bike", disabled: true }); addSectionBtn.on("click", function () { saveCurrentSection(); sections.push({}); activeSection = sections.length - 1; $.each(PER_SECTION_STEP_IDS, function (_, id) { if (id === "dfn") { var stepDiv = $("#wiktku-start-dfn"); stepDiv.find("ol.wiktku-dfn-list").remove(); steps.dfn.build(stepDiv); return; } if (id === "etym") { $("#wiktku-start-etym .wiktku-etym-wrap").remove(); steps.etym.build($("#wiktku-start-etym")); return; } if (id === "trans") { var transDiv = $("#wiktku-start-trans"); transDiv.find(".wiktku-trans-group").remove(); return; } if (id === "zarava") { var zaravaDiv = $("#wiktku-start-zarava"); zaravaDiv.find(".wiktku-zarava-group").remove(); return; } if (id === "dunde") { var dundeDiv = $("#wiktku-start-dunde"); dundeDiv.find("ul.wiktku-dunde-list").remove(); return; } var stepDiv = $("#wiktku-start-" + id); stepDiv.find(".wiktku-start-step-field").val(""); if (!isMobile) stepDiv.find("select.wiktku-start-step-field").trigger("chosen:updated"); }); renderSectionTabs(); refresh(); $("html, body").animate({ scrollTop: sectionTabsDiv.offset().top - 20 }, 300); }); /** Re-render the tab bar to reflect current sections[] and activeSection. */ function renderSectionTabs() { // Detach (not remove) the button first: .empty() strips bound // event data from any children left inside it, which would // silently kill addSectionBtn's click handler on every re-render. addSectionBtn.$element.detach(); sectionTabsDiv.empty(); var lang = getValues().lang || ""; if (!lang) { sectionTabsDiv.hide(); return; } sectionTabsDiv.show(); $.each(sections, function (i) { var posVal = sections[i].pos || ""; var tabLabel = posVal ? capitalize(posVal) : ("Beş " + (i + 1)); var tab = $("<span></span>") .addClass("wiktku-section-tab") .text(tabLabel) .toggleClass("wiktku-tab-active", i === activeSection); (function (idx) { tab.on("click", function () { if (idx === activeSection) return; saveCurrentSection(); activeSection = idx; restoreSection(sections[activeSection]); refresh(); renderSectionTabs(); }); }(i)); sectionTabsDiv.append(tab); }); // Enable "Beş zêde bike" only when the active section has a pos chosen. var activePos = sections[activeSection] && sections[activeSection].pos ? sections[activeSection].pos : getValues().pos; addSectionBtn.setDisabled(!activePos); sectionTabsDiv.append(addSectionBtn.$element); } renderSectionTabs(); // Update the active tab's label whenever pos changes. startForm.on("change", "#wiktku-start-pos-field", function () { renderSectionTabs(); }); // Show the tab bar as soon as a language is selected. startForm.on("change", "#wiktku-start-lang-field", function () { renderSectionTabs(); }); var footer = $("<div id='wiktku-start-footer'></div>"); spinner = $(mw.html.element("img", { id: "wiktku-start-spinner", src: "//upload.wikimedia.org/wikipedia/commons/d/de/Ajax-loader.gif", alt: "Tê barkirin…", title: "Tê barkirin…" })); footer.append(spinner.hide()); continueBtn = new OO.ui.ButtonWidget({ id: "wiktku-unhide-editform", label: "Bişîne", flags: [ "primary", "progressive" ] }); continueBtn.on("click", function () { mw.notify("Tê şandin…", { type: "info", tag: "wiktku-submit" }); startForm.trigger("submit"); }); footer.append(continueBtn.$element); // "Edîtora çavkaniyê veke" button — inline fallback for the portlet link // which is invisible on mobile and easy to miss on desktop. var sourceEditorBtn = new OO.ui.ButtonWidget({ label: "Edîtora çavkaniyê veke", framed: false }); sourceEditorBtn.on("click", function () { destroy(); }); footer.append(sourceEditorBtn.$element); // ── Preview checkboxes ─────────────────────────────────────────────── // Wikitext preview (raw text panel) var previewCheck = $("<input type='checkbox' id='wiktku-preview-toggle'>"); var previewLabel = $("<label for='wiktku-preview-toggle'></label>") .text(" Pêşdîtina wîkîtekstê"); var previewPanel = $("<pre id='wiktku-preview-panel'></pre>").hide(); // Live rendered preview (parsed HTML panel, same logic as AjaxEdit). // Not available on mobile — API polling causes too many problems on small screens. var livePreviewCheck = null; var livePreviewPanel = null; if (!isMobile) { livePreviewCheck = $("<input type='checkbox' id='wiktku-live-preview-toggle'>"); livePreviewPanel = $("<div id='wiktku-live-preview-panel'></div>").hide(); } // Container that holds both panels and switches between stacked / side-by-side. var previewContainer = $("<div id='wiktku-preview-container'></div>"); previewContainer.append(previewPanel); if (!isMobile) previewContainer.append(livePreviewPanel); var previewTimer = null; var livePreviewIntervalId = -1; var livePreviewActive = false; // guards in-flight fetches after uncheck /** Rebuilds wikitext preview if its checkbox is checked. */ function schedulePreview() { if (!previewCheck.prop("checked")) return; clearTimeout(previewTimer); // Debounce: wait 400 ms after the last keystroke before rebuilding. previewTimer = setTimeout(function () { getWikitext(function (wikitext) { previewPanel.text(wikitext).show(); updatePanelLayout(); }); }, 400); } /** Fetches parsed HTML and populates the live preview panel. */ function loadLivePreview() { getWikitext(function (wikitext) { new mw.Api().parse(wikitext, { title: mw.config.get("wgPageName") }).done(function (html) { // Discard result if the user unchecked while the fetch was in flight. if (!livePreviewActive) return; livePreviewPanel.html(html).show(); updatePanelLayout(); }); }); } /** Adjusts panel widths depending on which previews are visible. */ function updatePanelLayout() { var wikitextVisible = previewCheck.prop("checked"); var liveVisible = livePreviewCheck && livePreviewCheck.prop("checked"); if (wikitextVisible && liveVisible) { // Side by side — each panel takes roughly half the available width. previewPanel.css({ "flex": "1 1 45%", "min-width": "280px" }); livePreviewPanel.css({ "flex": "1 1 45%", "min-width": "280px" }); } else { // Full width for whichever is visible — only touch panels that are // actually shown so that setting flex doesn't override display:none. if (wikitextVisible) previewPanel.css({ "flex": "1 1 100%", "min-width": "" }); if (liveVisible && livePreviewPanel) livePreviewPanel.css({ "flex": "1 1 100%", "min-width": "" }); } } previewCheck.on("change", function () { if ($(this).prop("checked")) { schedulePreview(); } else { clearTimeout(previewTimer); previewPanel.hide(); updatePanelLayout(); } }); if (!isMobile) { livePreviewCheck.on("change", function () { if ($(this).prop("checked")) { livePreviewActive = true; livePreviewPanel.show(); loadLivePreview(); livePreviewIntervalId = setInterval(loadLivePreview, 500); } else { livePreviewActive = false; clearInterval(livePreviewIntervalId); livePreviewIntervalId = -1; livePreviewPanel.hide().empty(); updatePanelLayout(); } }); } // Listen on all input/change events on the form and update both previews. startForm.on("input change", function () { schedulePreview(); }); footer.append($("<span style='margin-left:1em'></span>") .append(previewCheck).append(previewLabel)); if (!isMobile) { var livePreviewLabel = $("<label for='wiktku-live-preview-toggle'></label>") .text(" Pêşdîtina zindî"); footer.append($("<span style='margin-left:1em'></span>") .append(livePreviewCheck).append(livePreviewLabel)); } startForm.append(footer); $("#editform").hide().before(startForm); // Insert preview container (holds both panels) after the form. startForm.after(previewContainer); if (!isMobile) startForm.find("select").chosen(chosenOptions); refresh(); // Zimanan ji MediaWiki:Gadget-translation_editor.js/ziman.json bar bike. // Kodên ku bi "-pro" diqedin û navên ku "zimanê destan" tê de heye // tên derxistin. Zimanên xardkirî li serî dimînin, yên din // bi alfabeyê li dû wan tên. // Pinned choices come from MediaWiki:Gadget-start.js/data.json (langChoices), // already loaded into steps.lang.choices before build() runs. var pinnedChoices = steps.lang.choices.slice(); var pinnedCodes = $.map(pinnedChoices, function (choice) { return choice[0]; }); new mw.Api().get({ action: "query", prop: "revisions", titles: "MediaWiki:Gadget-translation_editor.js/ziman.json", rvprop: "content", rvslots: "main", formatversion: 2 }).then(function (data) { var page = data.query.pages[0]; var content = page && page.revisions && page.revisions[0].slots.main.content; var zimanData; try { zimanData = JSON.parse(content); } catch (e) { zimanData = {}; } var extraChoices = []; $.each(zimanData, function (code, name) { // Filter: skip proto-language codes and legendary/reconstructed langs. if (/-pro$/i.test(code)) return; if (/ziman[eê]\s+destan/i.test(name)) return; // Skip codes already in the pinned list (they are handled above). if (pinnedCodes.indexOf(code) !== -1) return; // sortKey: bare name without leading "zimanê " for sorting. var sortKey = name.replace(/^ziman[eê]\s+/i, ""); var choice = [code, name, sortKey]; extraChoices.push(choice); langsByCode[code] = choice; }); // Populate langsByCode for pinned choices too. $.each(pinnedChoices, function (i, choice) { // Ensure pinned choices have a sortKey (index 2). if (choice.length < 3) choice[2] = choice[1]; langsByCode[choice[0]] = choice; }); // Sort the extra choices alphabetically by sort key. extraChoices.sort(function (a, b) { return a[2].localeCompare(b[2], userLang); }); // Final list: pinned first, then the rest. var allChoices = pinnedChoices.concat(extraChoices); steps.lang.choices = allChoices; steps.trans.keys = allChoices; steps.dunde.keys = allChoices; steps.zarava.keys = getZaravaKeys(allChoices); var langMenu = $("#wiktku-start-lang-field"); populateMenus(langMenu, steps.lang.choices); langMenu.trigger("chosen:updated"); var transMenus = $("#wiktku-start-trans .wiktku-start-step-keyfield"); populateMenus(transMenus, steps.trans.keys, getDisabledKeys(steps.trans)); transMenus.trigger("chosen:updated"); var dundeMenus = $("#wiktku-start-dunde .wiktku-start-step-keyfield"); populateMenus(dundeMenus, steps.dunde.keys, getDisabledKeys(steps.dunde)); dundeMenus.trigger("chosen:updated"); var zaravaMenus = $("#wiktku-start-zarava .wiktku-start-step-keyfield"); populateMenus(zaravaMenus, steps.zarava.keys, getDisabledKeys(steps.zarava)); }); } mw.loader.using(["jquery.chosen", "mediawiki.api", "oojs-ui-core"], function () { if (!isMobile) { mw.notify( "Amûr dest pê dike, hinek bisekinin. Not: jkx Sentaks (sentaks highlighter) neaktîv bikin", { type: "info", tag: "wiktku-start-notice", autoHide: false } ); } // Load metadata, langChoices, posChoices and tplDefs from the companion // data page so they can be updated without touching this script. new mw.Api().get({ action: "query", prop: "revisions", titles: "MediaWiki:Gadget-start.js/data.json", rvprop: "content", rvslots: "main", formatversion: 2 }).then(function (data) { var page = data.query.pages[0]; var content = page && page.revisions && page.revisions[0].slots.main.content; var d; try { d = JSON.parse(content); } catch (e) { d = {}; } // Populate metadata. if (d.metadata) $.extend(metadata, d.metadata); // Populate gender labels. if (d.genderLabels) $.extend(GENDER_BASE_LABELS, d.genderLabels); // Populate lang choices (pinned list used by build() → ziman.json loader). if (d.langChoices) steps.lang.choices = d.langChoices; // Populate POS choices. if (d.posChoices) steps.pos.choices = d.posChoices; // Populate template definitions for the dfn sense-block builder. if (d.tplDefs) steps.dfn.tplDefs = d.tplDefs; // Populate pos placeholder examples. if (d.posExamples) steps.dfn.posExamples = d.posExamples; // Populate citation template definitions for the quote widget. if (d.jederDefs) steps.dfn.jederDefs = d.jederDefs; // Populate pronunciation and etymology template insert lists. if (d.pronTpls) { steps.pron.pronTpls = d.pronTpls; steps.pron.refreshTplSelect(); } if (d.etymTpls) { steps.etym.etymTpls = d.etymTpls; steps.etym.refreshTplSelect(); } // Sync trans/dunde/zarava keys with the (now populated) lang choices. steps.trans.keys = steps.lang.choices; steps.dunde.keys = steps.lang.choices; steps.zarava.keys = getZaravaKeys(steps.lang.choices); }).always(build); }); }); //</nowiki> moie9e3a1lmcq961x8bqy56vniv1uz3 6265565 6265564 2026-07-19T13:42:13Z Wikihez 7344 6265565 javascript text/javascript // Li ser [[vi:MediaWiki:Gadget-start.js]] hatiye refaktorkirin. //<nowiki> $(function () { var ns = mw.config.get("wgNamespaceNumber"); if (ns && !(ns === 2 && mw.config.get("wgPageName").match(/\/ceribandin$|\/test$/))) { return; } var action = mw.config.get("wgAction"); var pageExists = !!mw.config.get("wgArticleId"); // "Zimanek lê zêde bike" mode: triggered from the portlet link below. // Runs the same wizard on an EXISTING page's edit form, but appends the // generated section instead of replacing the textarea's content. var addLangMode = pageExists && mw.util.getParamValue("wiktkuaddlang") === "1"; // On a normal page view of an existing page, just add the portlet link // that takes the user into addLangMode; don't build anything else here. if (action === "view" && pageExists) { mw.util.addPortletLink("p-views", mw.util.getUrl(mw.config.get("wgPageName"), { action: "submit", wiktkuaddlang: "1" }), "+Ziman/beşeke din", "ca-wiktku-addlang", "Ji vê rûpelê re zimanekî nû zêde bike"); return; } if (!(action === "edit" || action === "submit")) { return; } if (!addLangMode && !$(".mw-newarticletext, .mw-newarticletextanon").length) { return; } if (window.location.href.includes("editintro=User:Wikihez/creation/intro")) { return; // Do not run the script wextê WF:Bilez dişuxile } function capitalize(str) { if (!str) return str; return str[0].toUpperCase() + str.substr(1); } function decapitalize(str) { if (!str) return str; return str[0].toLowerCase() + str.substr(1); } function escapeRegExp(str) { return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); } function stripWikilinks(str) { return str.replace(/\[\[([^\]|]+)(?:\|([^\]]+))?\]\]/g, function (m, target, display) { return display || target; }); } function insertAtCursor(el, text) { var start = el.selectionStart; var end = el.selectionEnd; var val = el.value; el.value = val.slice(0, start) + text + val.slice(end); var pos = start + text.length; el.selectionStart = el.selectionEnd = pos; } var pageName = mw.config.get("wgPageName").replaceAll(/_/g, " "); if (ns) pageName = pageName.replace(/.*\//, ""); var pageNameRe = escapeRegExp(pageName); var userLang = mw.config.get("wgUserLanguage"); // Mobile detection: MobileFrontend sets wgMFMode, or fall back to touch check. var isMobile = !!mw.config.get("wgMFMode") || window.matchMedia("(pointer: coarse)").matches; var chosenOptions = { width: "20em", disable_search_threshold: 0, placeholder_text_single: "Yekî hilbijêre", placeholder_text_multiple: "Hilbijêre", no_results_text: "Nehat dîtin", enable_split_word_search: true, search_contains: true }; function wrapNativeSelect(select) { var placeholder = select.attr("data-placeholder") || "Lê bigere…"; // Hide the native select — we drive it programmatically. select.hide(); var wrapper = $("<span class='wiktku-native-select-wrap'></span>"); var textInput = $("<input type='search' autocomplete='off'>") .attr("placeholder", placeholder) .addClass("wiktku-start-narrow wiktku-ac-input"); var resultsList = $("<ul class='wiktku-ac-results'></ul>").hide(); // Full option cache — rebuilt when chosen:updated fires. var allOptions = []; function cacheOptions() { allOptions = []; select.find("option").each(function () { var v = $(this).val(); if (!v) return; // skip the empty placeholder option allOptions.push({ value: v, text: $(this).text(), disabled: $(this).prop("disabled") }); }); } cacheOptions(); function showResults(query) { var q = query.trim().toLowerCase(); resultsList.empty(); var matched; if (q) { matched = []; $.each(allOptions, function (_, o) { if (o.disabled) return; var codeMatch = o.value.toLowerCase().indexOf(q) !== -1; var nameMatch = o.text.toLowerCase().indexOf(q) !== -1; if (codeMatch || nameMatch) { matched.push({ opt: o, codeMatch: codeMatch }); } }); // Code matches (especially prefix matches) come first. matched.sort(function (a, b) { var aCode = a.opt.value.toLowerCase(); var bCode = b.opt.value.toLowerCase(); var aPrefix = aCode.indexOf(q) === 0; var bPrefix = bCode.indexOf(q) === 0; if (aPrefix !== bPrefix) return aPrefix ? -1 : 1; if (a.codeMatch !== b.codeMatch) return a.codeMatch ? -1 : 1; return 0; }); matched = matched.map(function (item) { return item.opt; }); } else { matched = allOptions.filter(function (o) { return !o.disabled; }); } if (!matched.length) { resultsList.hide(); return; } $.each(matched.slice(0, 50), function (_, opt) { var li = $("<li></li>").text(opt.text).attr("data-value", opt.value); // Use touchend instead of touchstart so that a scroll gesture does // not accidentally select an item. We track whether the finger moved // between touchstart and touchend — if it did, it was a scroll. var touchMoved = false; li.on("touchstart", function () { touchMoved = false; }); li.on("touchmove", function () { touchMoved = true; }); li.on("touchend", function (e) { if (touchMoved) return; // was a scroll, not a tap e.preventDefault(); selectOption(opt.value, opt.text); }); // Keep mousedown for desktop fallback. li.on("mousedown", function (e) { e.preventDefault(); selectOption(opt.value, opt.text); }); resultsList.append(li); }); // Position the list above or below depending on available viewport space. var inputRect = textInput[0].getBoundingClientRect(); var viewportH = window.innerHeight; var spaceBelow = viewportH - inputRect.bottom - 8; var spaceAbove = inputRect.top - 8; var maxH = Math.min(224, Math.max(spaceBelow, spaceAbove)); // 224px ≈ 14em resultsList.css({ "max-height": maxH + "px", "top": spaceBelow >= spaceAbove ? "100%" : "auto", "bottom": spaceBelow >= spaceAbove ? "auto" : "100%" }); resultsList.show(); } function selectOption(value, text) { textInput.val(text); select.val(value); resultsList.hide(); select.trigger("change"); } textInput.on("input focus", function () { showResults($(this).val()); }); textInput.on("blur", function () { // Short delay so a touchstart on a result item fires first. setTimeout(function () { resultsList.hide(); }, 200); }); // chosen:updated → re-cache (called after ziman.json loads). select.on("chosen:updated", function () { cacheOptions(); // If a value is already selected, keep the display text in sync. var cur = select.val(); if (cur) { var match = $.grep(allOptions, function (o) { return o.value === cur; })[0]; if (match) textInput.val(match.text); } }); // No-op .chosen() so desktop call-sites don't need guarding. select.chosen = function () { return select; }; wrapper.append(textInput).append(resultsList).append(select); return wrapper; } var langsByCode = {}; // Populated from [[MediaWiki:Gadget-start.js/data.json]] at runtime. var metadata = {}; // Zaravayên kurdî yên ku di beşa "Bi zaravayên din" de tên pêşkêşkirin — // ev kod ji beşa Werger têne derxistin daku heman zimên du caran neyê xwendin. var ZARAVA_LANG_CODES = ["ckb", "sdh", "lki", "hac", "zza"]; function getZaravaKeys(choices) { var byCode = {}; $.each(choices || [], function (_, c) { byCode[c[0]] = c; }); var result = []; $.each(ZARAVA_LANG_CODES, function (_, code) { if (byCode[code]) result.push(byCode[code]); }); return result; } function needsTransliteration(langCode) { var meta = metadata[langCode]; if (!meta || !meta.sc) return false; var scripts = Array.isArray(meta.sc) ? meta.sc : [meta.sc]; return scripts.length > 0 && scripts[0] !== "Latn"; } // Kodên cinsiyetê yên di metadata.g de — ji data.json tê dagirtin var GENDER_BASE_LABELS = {}; // Sub-lists that only make sense for a plain (non-şablon) sense — hidden // when a şablon (e.g. {{guharto|…}}) is chosen for that sense, since a // template-based sense has no "own" gloss for alternate forms, synonyms, // antonyms, coordinate terms, hypernyms or hyponyms to attach to. Etîket, // Nimûne and Jêgirtin stay visible either way. var HIDDEN_ON_TPL_GROUPS = [ "wiktku-dfn-alternativ", "wiktku-dfn-hevmane", "wiktku-dfn-dijmane", "wiktku-dfn-koordine", "wiktku-dfn-jornav", "wiktku-dfn-jernav" ]; function genderLabel(code) { if (code === "p") return "Pirjimar"; var pluralMatch = code.match(/^(.+)-p$/); if (pluralMatch && GENDER_BASE_LABELS[pluralMatch[1]]) { return GENDER_BASE_LABELS[pluralMatch[1]] + " (pirjimar)"; } return GENDER_BASE_LABELS[code] || code; } /** * True if a sense has any content worth keeping besides its mane text — * etîket, hevmane/dijmane/koordîne/etc. word lists, nimûne, or jêder * (quote). Used so a sense with an empty mane but filled-in extra * fields still gets emitted (with {{mane?}} standing in for the gloss) * instead of being silently dropped. */ function senseHasExtraContent(s) { if (s.etiket && $.grep(s.etiket, function (e) { return $.trim(e) !== ""; }).length) return true; if (s.alternativ.length || s.hevmane.length || s.dijmane.length || s.koordine.length || s.jornav.length || s.jernav.length) return true; if (s.nimune && $.grep(s.nimune, function (n) { return (typeof n === "object" ? n.text : n) !== ""; }).length > 0) return true; if (s.jeder && $.grep(s.jeder, function (j) { return j && j.quote; }).length > 0) return true; return false; } /** * formatNimune: each nimûne item can be { text, tr, t }: * text — example text * tr — transliteration (only when the language needs it) * t — Kurdish translation (third positional param, no key) */ function formatNimune(nimunes, lang, hasJeder) { var hasNimune = nimunes && $.grep(nimunes, function (n) { return (typeof n === "object" ? n.text : n) !== ""; }).length > 0; if (!hasNimune) { return hasJeder ? "" : "\n#* {{bênimûne|" + lang + "}}"; } return $.map(nimunes, function (n) { var text = typeof n === "object" ? n.text : n; if (!text) return undefined; var bolded = text.replace( new RegExp("(" + pageNameRe + "([^( |,|;|\\?|\\.|\\!)]+)?)", "ig"), "'''$1'''"); var tpl = "\n#: {{nm|" + lang + "|" + bolded; if (typeof n === "object") { if (n.tr) tpl += "|tr=" + n.tr; // Translation as third positional param (no key needed). if (n.t) tpl += "|" + n.t; } // Short examples fit on one line together with their translation. // rêz=1 is not used for ku — definitions are shown on separate lines there. if (text.length < 200 && lang !== "ku") tpl += "|rêz=1"; tpl += "}}"; return tpl; }).join(""); } /** * Formats a list of jêder (quote/citation) objects into wikitext lines. * Each entry that has no quote text is skipped. Returns "" when the list * is empty or every entry is blank. * * #* {{jêder-…|lang|jêgirtin=…|tr=…|tercime=…|…fields…}} * * When no template is chosen, the generic {{jêder|…}} template is used * instead. Its 2nd positional param is the user's freeform "bi destê xwe * binivîsim" source text when supplied, or the çavkanî? placeholder otherwise. * If that text contains "=" it is passed as |2=… instead of a bare * positional param, since MediaWiki would otherwise misparse it as its * own key=value pair and break the template: * #* {{jêder|lang|jêgirtin=…|tr=…|tercime=…|<manual source or çavkanî?>}} */ function formatJeder(jederList, lang) { if (!jederList || !jederList.length) return ""; return $.map(jederList, function (jeder) { if (!jeder || !jeder.quote) return undefined; if (jeder.jederTpl) { var cite = "\n#* {{" + jeder.jederTpl + "|" + lang; cite += "|jêgirtin=" + jeder.quote; if (jeder.quoteTr) cite += "|tr=" + jeder.quoteTr; if (jeder.quoteT) cite += "|tercime=" + jeder.quoteT; $.each(jeder.jêderFields || {}, function (key, val) { if (val) cite += "|" + key + "=" + val; }); cite += "}}"; return cite; } var out = "\n#* {{jêder|" + lang + "|jêgirtin=" + jeder.quote; if (jeder.quoteTr) out += "|tr=" + jeder.quoteTr; if (jeder.quoteT) out += "|tercime=" + jeder.quoteT; var srcParam = jeder.jederManual ? jeder.jederManual : "çavkanî?"; // A positional param containing "=" gets parsed as its own key=value // pair by MediaWiki and breaks the template, so force it to be // explicitly named (|2=) whenever that's the case. out += (srcParam.indexOf("=") !== -1 ? "|2=" : "|") + srcParam; out += "}}"; return out; }).join(""); } function makeWordListStep(id, name, question_fmt, header, templateName) { return { id: id, name: name, question_fmt: question_fmt, multiple: true, narrow: true, visible: function (values) { return values.lang && values.pos; }, output: function (values) { var words = $.grep(values[id] || [], function (w) { return !!w; }); if (!words.length) return ""; var lang = values.lang; var section = "\n==== " + header + " ====\n"; if (words.length === 1) { // Single word — keep the simple inline template. return section + "* {{" + templateName + "|" + lang + "|" + words[0] + "}}\n"; } // Multiple words — use {{kol3}} with one positional param per word. var params = "cure=" + header + "\n" + $.map(words, function (w) { return "|" + w; }).join("\n"); return section + "{{kol3|" + lang + "|" + params + "\n}}\n"; } }; } var steps = { lang: { id: "lang", required: true, name: "ziman", question_fmt: '"' + pageName + '" bi çi zimanî ye?', question_br: true, // Populated from [[MediaWiki:Gadget-start.js/data.json]] (langChoices). choices: [], output: function (values) { return "== {{ziman|" + values.lang + "}} ==\n"; } }, pron: { id: "pron", name: "bilêvkirin", question_fmt: '"' + pageName + '" çawa tê telafûzkirin?', // pronTpls populated from data.json pronTpls: [], visible: function (values) { if (!values.lang) return false; // In addLangMode, only skip pron when this langcode's section // already exists in the page — if it's a new language, show it. if (addLangMode) { var existing = $("#wpTextbox1").val() || ""; var header = "== {{ziman|" + values.lang + "}} =="; return existing.indexOf(header) === -1; } return true; }, /** Fills (or refills) the insert-dropdown from the current pronTpls array, filtering by language. */ refreshTplSelect: function () { var sel = $("#wiktku-start-pron .wiktku-tpl-insert-select"); if (!sel.length) return; var lang = getValues().lang || ""; sel.find("option[value!='']").remove(); $.each(steps.pron.pronTpls, function (_, tpl) { // Filter: if tpl.langs exists, only show if lang is in that list; otherwise show always var allowed = !tpl.langs || tpl.langs.indexOf(lang) !== -1; if (allowed) { sel.append($("<option></option>") .val(tpl.snippet) .text(tpl.name + " — " + tpl.desc) .attr("data-nolang", tpl.noLang ? "1" : "")); } }); // Notify Chosen that the option list has changed (no-op on mobile). if (!isMobile) sel.trigger("chosen:updated"); }, build: function (stepDiv) { if (stepDiv.find(".wiktku-pron-wrap").length) return null; var wrap = $("<div class='wiktku-pron-wrap'></div>"); var ta = $("<textarea></textarea>") .attr("name", "wiktku-pron-" + $.now()) .attr("class", "wiktku-start-step-field wiktku-pron-text") .attr("rows", 4) .attr("placeholder", "Nimûne: {{IPA|ku|/pɛɪ̯n/}} yan {{kîte|ku|he|ce|ki|rin}}"); // Template insert dropdown — filtered by language. var sel = $("<select class='wiktku-tpl-insert-select'></select>"); sel.append($("<option value=''>— şablonek lê zêde bike —</option>")); var lang = getValues().lang || ""; $.each(steps.pron.pronTpls, function (_, tpl) { // Filter: if tpl.langs exists, only show if lang is in that list; otherwise show always var allowed = !tpl.langs || tpl.langs.indexOf(lang) !== -1; if (allowed) { sel.append($("<option></option>") .val(tpl.snippet) .text(tpl.name + " — " + tpl.desc) .attr("data-nolang", tpl.noLang ? "1" : "")); } }); sel.on("change", function () { var snippet = $(this).val(); if (!snippet) return; var lang = getValues().lang || ""; // Check if the selected option has noLang flag var selectedOption = sel.find("option:selected"); var hasNoLang = selectedOption.attr("data-nolang") === "1"; if (!hasNoLang) { snippet = snippet.replace(/CODE/g, lang).replace(/SOURCELANG/g, "?"); } insertAtCursor(ta[0], snippet); $(this).val(""); ta.focus(); }); wrap.append(sel).append($("<br>")).append(ta); stepDiv.append(wrap); return ta; }, output: function () { var text = $.trim($("#wiktku-start-pron .wiktku-pron-text").val()); if (!text) return ""; var lines = text.split("\n"); var out = $.map(lines, function (line) { line = $.trim(line); if (!line) return undefined; return line.charAt(0) === "*" ? line : "* " + line; }).join("\n"); return "\n=== Bilêvkirin ===\n" + out + "\n"; } }, pos: { id: "pos", required: true, name: "Cureyê rêzimanî", question_fmt: 'Cureyê rêzimanî yê "' + pageName + '" çi ye?', visible: function (values) { return values.lang; }, question_br: true, // Populated from [[MediaWiki:Gadget-start.js/data.json]] (posChoices). choices: [], output: function (values) { var pos = values.pos || ""; var cinsiyet = values.cinsiyet || ""; // from the cinsiyet step var lekTur = values.lektur || ""; // from the lêker transitivity step var capitalizedPos = capitalize(pos); var outputString = "\n=== " + capitalizedPos + " ===\n"; // Add ku-tewîn-nav for single-word navdêr/serenav with known gender. if (!pageName.includes(" ") && cinsiyet && GENDER_BASE_LABELS[cinsiyet] && (pos === "navdêr" || pos === "serenav") && values.lang === "ku") { outputString += "{{ku-tewîn-nav|" + pageName + "|" + GENDER_BASE_LABELS[cinsiyet]; if (pos === "serenav") outputString += "|y"; outputString += "}}\n"; } outputString += "{{" + pos + "|" + values.lang; if (pos === "navdêr" || pos === "serenav") { if (cinsiyet) { outputString += "|c=" + cinsiyet; } else if (values.lang === "ku") { // Unknown gender — prompt editor to fill it in. outputString += "|c=?"; } } else if (/^lêker/.test(pos) && lekTur) { outputString += "|c=" + lekTur; } if (values.tr) { outputString += "|tr=" + values.tr; } outputString += "}}\n"; return outputString; } }, /** * cinsiyet (grammatical gender) — only shown for navdêr/serenav, û * tenê ger metadata ji bo zimanê hilbijartî lîsteyeke "g" (cinsiyet) * were dayîn. Opsiyonên vê gavê ne sabît in — ji metadata[values.lang].g * têne çêkirin, ji ber ku di hemû zimanan de cinsiyet tine. */ cinsiyet: { id: "cinsiyet", name: "cinsiyet", question_fmt: 'Cinsiyeta "' + pageName + '" çi ye?', question_br: true, visible: function (values) { var meta = metadata[values.lang]; return !!(values.lang && (values.pos === "navdêr" || values.pos === "serenav") && meta && meta.g && meta.g.length); }, build: function (stepDiv, values) { var select = stepDiv.find("select.wiktku-start-step-field"); if (!select.length) { select = $(mw.html.element("select", { "class": "wiktku-start-step-field", id: "wiktku-start-cinsiyet-field" })); stepDiv.append(select); } if (!values) return select; var meta = metadata[values.lang]; var codes = (meta && meta.g) || []; var prevVal = select.val(); var choices = $.map(codes, function (code) { return [[code, genderLabel(code)]]; }); populateMenus(select, choices); if ($.grep(choices, function (c) { return c[0] === prevVal; }).length) { select.val(prevVal); } if (!isMobile) select.trigger("chosen:updated"); return select; }, output: function () { return ""; } // consumed by pos.output }, /** * Lêker transitivity — only shown for any lêker variant. */ lektur: { id: "lektur", name: "Cureyê lêkerê (fiîlê)", question_fmt: "Cureyê lêkerê (fiîlê) çi ye?", question_br: true, visible: function (values) { return values.lang && values.pos && /^lêker/.test(values.pos); }, // Dictionary: value → display label. Add new types here. choices: [ ["gh", "gerguhêz"], ['x-gh', 'xwerû-gerguhêz'], ['p-gh', 'pêkhatî-gerguhêz'], ['h-gh', 'hevedudanî-gerguhêz'], ['b-gh', 'biwêjî-gerguhêz'], ["ngh", "negerguhêz"], ['x-ngh', 'xwerû-negerguhêz'], ['p-ngh', 'pêkhatî-negerguhêz'], ['h-ngh', 'hevedudanî-negerguhêz'], ['b-ngh', 'biwêjî-negerguhêz'] ], output: function () { return ""; } // consumed by pos.output }, tr: { id: "tr", name: "transkrîpsiyon", question_fmt: "Transkrîpsiyona kelîmeyê", multiple: false, narrow: true, visible: function (values) { return values.lang && values.pos && needsTransliteration(values.lang); } }, dfn: { id: "dfn", // required: true, ger mane tinebe [[Şablon:mane?]] bi kar bîne name: "Mane", question_fmt: "Maneya kelîmeyê binivîse. Mane otomatîk tê lînkkirin! Ji bo tercimeyan beşa 'Werger' bi kar bîne!", multiple: true, ordered: true, rows: 3, visible: function (values) { return values.lang && values.pos; }, example: function (values) { // posExamples loaded from [[MediaWiki:Gadget-start.js/data.json]]. var examples = steps.dfn.posExamples || {}; var full = values.pos || ""; return examples[full] || ""; }, /** * Builds one sense block (<li>) inside the ordered list. * Each block contains: * - a textarea for the definition * - an expandable nimûne list * - single-row sub-lists for formên alternatîv, hevmane, dijmane */ buildSenseBlock: function (stepDiv) { var block = $("<li class='wiktku-dfn-sense'></li>"); // — Mane textarea (declared first so the template handler can reference it) — var dfnArea = $("<textarea></textarea>") .attr("name", "wiktku-dfn-mane-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("class", "wiktku-start-step-field wiktku-dfn-mane") .attr("rows", 6) .attr("placeholder", "Mane…"); dfnArea.on("input", function () { steps.dfn.onDfnInput(stepDiv, block, this); }); // — Template selector (optional — replaces mane when chosen) — // Template definitions loaded from [[MediaWiki:Gadget-start.js/data.json]]. var tplDefs = steps.dfn.tplDefs || []; // Cache of all non-placeholder option elements — used by updateTplOptions // to remove/re-add options (the only approach compatible with Chosen.js). var _allTplOptions = []; var tplSelect = $(mw.html.element("select", { "class": "wiktku-dfn-tpl-select" })); tplSelect.append($("<option value=''>— yan jî şablonek hilbijêre —</option>")); $.each(tplDefs, function (_, tpl) { var opt = $("<option></option>") .val(tpl.name) .text(tpl.name) .attr("data-langs", tpl.langs ? tpl.langs.join(",") : "") .attr("data-nolang", tpl.noLang ? "1" : ""); tplSelect.append(opt); _allTplOptions.push(opt[0]); }); function updateTplOptions() { var lang = getValues().lang || ""; var currentVal = tplSelect.val(); var currentStillValid = false; // Detach all non-placeholder options, then re-attach only the visible ones. // This is the only approach that works correctly with both native <select> // and Chosen.js on desktop. tplSelect.find("option[value!='']").detach(); $.each(_allTplOptions, function (_, opt) { var allowed = $(opt).attr("data-langs"); var visible = !allowed || allowed.split(",").indexOf(lang) !== -1; if (visible) { tplSelect.append(opt); if ($(opt).val() === currentVal) currentStillValid = true; } }); if (!isMobile) tplSelect.trigger("chosen:updated"); if (currentVal && !currentStillValid) { tplSelect.val(""); dfnArea.show(); tplTitleInput.hide().val(""); } } // Store updater on the element so refresh() can call it for all blocks. tplSelect.data("updateOptions", updateTplOptions); var tplTitleInput = $("<input type='text'>") .addClass("wiktku-dfn-tpl-title wiktku-start-narrow") .attr("placeholder", "Navê rûpelê…") .hide(); // Grow the sense list when the title field of the last block gets content, // mirroring what onDfnInput does for the plain mane textarea. tplTitleInput.on("input", function () { steps.dfn.onDfnInput(stepDiv, block, this); }); /** * When a şablon sense is chosen, formên alternatîv/hevmane/dijmane/ * termên koordîne/jornav/jêrnav don't apply (there's no plain gloss * to hang them off), so hide those subgroups. Etîket, Nimûne and * Jêgirtin stay visible and still usable for a şablon sense. */ function updateFieldVisibility() { var isTpl = !!tplSelect.val(); $.each(HIDDEN_ON_TPL_GROUPS, function (_, cls) { block.find("." + cls + "-group").toggle(!isTpl); }); } // Store on the block so restoreDfn() can re-sync visibility // after programmatically setting tplSelect's value. block.data("updateFieldVisibility", updateFieldVisibility); tplSelect.on("change", function () { var chosen = $(this).val(); if (chosen) { dfnArea.hide(); tplTitleInput.show().focus(); } else { dfnArea.show(); tplTitleInput.hide().val(""); } updateFieldVisibility(); // Re-run refresh so the Werger step visibility updates. refresh(); }); var tplRow = $("<div></div>").addClass("wiktku-dfn-tpl-row") .append(tplSelect).append(" ").append(tplTitleInput); block.append(tplRow); block.append(dfnArea); // Apply lang filter on initial build. updateTplOptions(); // — Sub-field groups — // All groups are always visible with a placeholder textarea. // Nimûne is last in the DOM and last in the output. var allGroups = [ { cls: "wiktku-dfn-etiket", label: "Etîket", rows: 1, narrow: true, izah: "xisûsen, Mêrdîn, anatomî, Badînî" }, { cls: "wiktku-dfn-alternativ", label: "Formên alternatîv", rows: 1, narrow: true, izah: "Varyantên vê kelîmeyê" }, { cls: "wiktku-dfn-hevmane", label: "Hevmane", rows: 1, narrow: true, izah: "Spehî hevmaneya Bedew e." }, { cls: "wiktku-dfn-dijmane", label: "Dijmane", rows: 1, narrow: true, izah: "Zengîn dijmaneya feqîr e." }, { cls: "wiktku-dfn-koordine", label: "Termên koordîne", rows: 1, narrow: true, izah: "Pisîk û kûçik termên koordîne ne çunkî Jornavên wan gelek in" }, { cls: "wiktku-dfn-jornav", label: "Jornav", rows: 1, narrow: true, izah: "Heywan jornavê guhandar e" }, { cls: "wiktku-dfn-jernav", label: "Jêrnav", rows: 1, narrow: true, izah: "Guhandar jêrnavê heywan e" }, { cls: "wiktku-dfn-nimune", label: "Nimûne", rows: 2, narrow: false } ]; $.each(allGroups, function (_, g) { var groupDiv = $("<div></div>").addClass("wiktku-dfn-subgroup " + g.cls + "-group"); function buildNimuneLi() { var lang = getValues().lang || ""; var li = $("<li></li>").addClass("wiktku-dfn-nimune-li"); var mainTa = $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-text-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", g.rows) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-text") .attr("placeholder", "Nimûneya emilandina kelîmeyê tu bi xwe binivîse…"); mainTa.on("input", function () { var val = $.trim($(this).val()); var isLast = li.is(list.children("li:last-child")); if (val && isLast) { list.append(buildNimuneLi()); } }); li.append(mainTa); var subWrap = $("<div></div>").addClass("wiktku-dfn-nimune-sub"); if (needsTransliteration(lang)) { subWrap.append( $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-tr-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 5) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-tr") .attr("placeholder", "Transkrîpsiyona bi alfabeya latînî") ); } if (lang && lang !== "ku") { subWrap.append( $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-t-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 5) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-t") .attr("placeholder", "Tercimeya kurmancî") ); } if (subWrap.children().length) li.append(subWrap); return li; } if (g.cls === "wiktku-dfn-nimune") { // Nimûne — compound widget with tr/t sub-fields. var lbl = $("<span></span>").addClass("wiktku-dfn-sublabel").text(g.label + ": "); var list = $("<ol></ol>").addClass("wiktku-dfn-sublist " + g.cls + "-list"); groupDiv.data("buildNimuneLi", buildNimuneLi); list.append(buildNimuneLi()); groupDiv.append(lbl).append(list); block.append(groupDiv); } else { // Regular always-visible group — label + growing textarea list. var lbl = $("<span></span>").addClass("wiktku-dfn-sublabel").text(g.label + ": " + g.izah); var list = $("<ol></ol>").addClass("wiktku-dfn-sublist " + g.cls + "-list"); var firstInput = $("<textarea></textarea>") .attr("name", g.cls + "-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", g.rows) .attr("class", "wiktku-dfn-subfield" + (g.narrow ? " wiktku-start-narrow" : "")) .attr("placeholder", g.label + "…"); firstInput.on("input", function () { steps.dfn.onSubInput(list, this, g.rows, g.narrow); }); list.append($("<li></li>").append(firstInput)); groupDiv.append(lbl).append(list); block.append(groupDiv); } }); // — Jêder (quote / citation) group — a growing list, sibling to Nimûne — // Structured the same way as Nimûne (ol.wiktku-dfn-sublist > li) so it // lines up at the same indentation, and so that typing into the last // citation's Jêgirtin box automatically opens a fresh empty one below it. (function () { var jederGroupDiv = $("<div></div>").addClass("wiktku-dfn-subgroup wiktku-dfn-jeder-group"); var jederLbl = $("<span></span>").addClass("wiktku-dfn-sublabel").text("Jêgirtin: "); var jederList = $("<ol></ol>").addClass("wiktku-dfn-sublist wiktku-dfn-jeder-list"); function buildJederLi() { var lang = getValues().lang || ""; var li = $("<li></li>").addClass("wiktku-dfn-jeder-li"); var dragHandle = $("<span></span>") .addClass("wiktku-jeder-drag-handle") .attr("title", "Bişkûne û bikişîne da ku rêzê biguhezîne"); // Quote text textarea var quoteTa = $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-quote-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 2) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-quote") .attr("placeholder", "Nimûneya emilandinê ji kitêb an çavkaniyeke din binivîse"); quoteTa.on("input", function () { var val = $.trim($(this).val()); var isLast = li.is(jederList.children("li:last-child")); if (val && isLast) { jederList.append(buildJederLi()); } }); li.append(dragHandle).append(quoteTa); // tr/t sub-fields for the quote — shown as needed for the language. var quoteSubWrap = $("<div></div>").addClass("wiktku-dfn-quote-sub"); if (needsTransliteration(lang)) { quoteSubWrap.append( $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-quote-tr-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 2) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-quote-tr") .attr("placeholder", "Transkrîpsiyona jêgirtinê…") ); } if (lang && lang !== "ku") { quoteSubWrap.append( $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-quote-t-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 2) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-quote-t") .attr("placeholder", "Tercimeya jêgirtinê bi kurmancî") ); } if (quoteSubWrap.children().length) li.append(quoteSubWrap); // Citoid auto-fill: fetch citation data from a URL, DOI or ISBN and // prefill the source şablon + fields below (see Gadget-citoid-helper.js). var citoidWrap = $("<div></div>").addClass("wiktku-dfn-quote-citoid"); var citoidInput = $("<input type='text'>") .addClass("wiktku-dfn-quote-citoid-input wiktku-start-narrow") .attr("placeholder", "URL, DOI an ISBN binivîse ku otomatîk were tijekirin…"); var citoidBtn = new OO.ui.ButtonWidget({ label: "Bi Citoid bîne", classes: [ "wiktku-dfn-quote-citoid-btn" ] }); var citoidStatus = $("<span></span>").addClass("wiktku-dfn-quote-citoid-status"); /** * Fetches citation data from Citoid and applies it to this * citation's şablon selector + fields. Mirrors the logic in * Form.prototype._fillFromCitoid (Gadget-wikt.add-examples.js): * - only (re)selects the şablon when it actually differs from * what's already chosen, so a repeat fetch doesn't wipe out * a template the user already picked; * - only fills fields that are currently empty, so it never * overwrites something the user typed by hand; * - falls back to the freeform "bi destê xwe binivîsim" source * only when nothing was typed there yet. */ function runCitoidFetch() { var query = $.trim(citoidInput.val()); if (!query) { mw.notify("Ji kerema xwe re pêşî URL, DOI an ISBNyekê binivîse."); return; } citoidBtn.setDisabled(true); citoidStatus.text("Tê anîn…"); wikt.citoidHelper.ensure().then(function () { return wikt.citoid.fetchJederFields(query); }).then(function (result) { var jederKey = result.jederKey; var hasTpl = !!jederKey && srcSel.find("option[value='" + jederKey + "']").length > 0; var targetVal = hasTpl ? jederKey : "__manual__"; // Only (re)select — and thus rebuild — the field rows if // we're switching to a different şablon than what's // already chosen, so a second fetch doesn't clear fields // the user already filled in by hand. if (srcSel.val() !== targetVal) { srcSel.val(targetVal).trigger("change"); srcSel.trigger("chosen:updated"); } if (hasTpl) { // Tenê qadên vala tijî bike. $.each(result.fields, function (key, val) { var input = srcFields.find("[data-field-key='" + key + "']"); if (input.length && !$.trim(input.val())) { input.val(val); } }); } else { // Şablonek nehat naskirin ji bo vê itemType — rêzikeke // çavkaniyê ya bi destan a ji qadên Citoid tê çêkirin, // lê tenê ger qada destan vala be. var manualField = srcFields.find(".wiktku-dfn-quote-src-manual"); if (!$.trim(manualField.val())) { var parts = []; $.each(["nivîskar", "sernav", "websîte", "kovar", "weşanxane", "sal", "url"], function (_, k) { if (result.fields[k]) parts.push(result.fields[k]); }); manualField.val(parts.join(", ")); } } citoidStatus.text(""); }, function (errorMsg) { citoidStatus.text(typeof errorMsg === "string" ? errorMsg : "Nehat dîtin. Kontrol bike ka URL/DOI/ISBN rast e."); }).always(function () { citoidBtn.setDisabled(false); }); } citoidBtn.on("click", runCitoidFetch); citoidInput.on("keydown", function (e) { if (e.which === 13) { // Enter e.preventDefault(); runCitoidFetch(); } }); citoidWrap.append(citoidInput).append(citoidBtn.$element).append(citoidStatus); // Source template selector, specific to this citation. var srcSel = $("<select></select>").addClass("wiktku-dfn-quote-src-sel"); srcSel.append($("<option value=''>— Çavkaniyê hilbijêre —</option>")); srcSel.append($("<option></option>").val("__manual__").text("Bi destê xwe binivîsim")); var jederDefs = steps.dfn.jederDefs || {}; $.each(jederDefs, function (tplName, def) { srcSel.append($("<option></option>").val(tplName).text(def.label)); }); // Dynamic source fields container. var srcFields = $("<div></div>").addClass("wiktku-dfn-quote-src-fields"); srcSel.on("change", function () { srcFields.empty(); var chosen = $(this).val(); if (!chosen) return; if (chosen === "__manual__") { // Freeform source, written by the user — becomes the 2nd // positional param of {{jêder|lang|…}} instead of çavkanî?. srcFields.append( $("<textarea></textarea>") .attr("rows", 4) .addClass("wiktku-dfn-subfield wiktku-dfn-quote-src-manual") .attr("placeholder", "Çavkaniyê bi destê xwe binivîse…") ); return; } var def = (steps.dfn.jederDefs || {})[chosen]; if (!def) return; $.each(def.fields, function (_, f) { var row = $("<div></div>").addClass("wiktku-dfn-quote-src-row"); var fieldLbl = $("<label></label>").text(f.label + ": "); var inp = $("<textarea></textarea>") .attr("rows", 2) .addClass("wiktku-dfn-quote-src-input wiktku-start-narrow") .attr("data-field-key", f.key) .attr("placeholder", f.label + "…"); row.append(fieldLbl).append(inp); srcFields.append(row); }); }); li.append(citoidWrap).append(srcSel).append(srcFields); return li; } jederGroupDiv.data("buildJederLi", buildJederLi); jederList.append(buildJederLi()); // Make citation rows sortable (drag to reorder). // The last row is always the empty trailing row — cancel its drag. mw.loader.using("jquery.ui.sortable", function () { jederList.sortable({ handle: ".wiktku-jeder-drag-handle", axis: "y", items: "li:not(:last-child)", tolerance: "pointer" }); }); jederGroupDiv.append(jederLbl).append(jederList); block.append(jederGroupDiv); }()); // Apply the initial hide/show state for the sub-groups (matches // tplSelect's starting value, which is normally empty). updateFieldVisibility(); return block; }, /** Grows the sense list when the last mane textarea gets content. */ onDfnInput: function (stepDiv, block, textarea) { var val = $.trim($(textarea).val()); var list = stepDiv.find("ol.wiktku-dfn-list"); var isLast = block.is(list.children("li:last-child")); if (val && isLast) { var newBlock = steps.dfn.buildSenseBlock(stepDiv); list.append(newBlock); // Apply Chosen to the new block's template selector on desktop. if (!isMobile) newBlock.find("select.wiktku-dfn-tpl-select").chosen(chosenOptions); } refresh(); }, /** Grows a sub-list (nimûne/formên alternatîv/hevmane/dijmane/termên koordîne) on input. */ onSubInput: function (list, input, rows, narrow) { var val = $.trim($(input).val()); var item = $(input).parent(); var isLast = item.is(list.children("li:last-child")); if (val && isLast) { var next = $("<textarea></textarea>") .attr("name", "wiktku-dfn-sub-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", rows) .attr("class", "wiktku-dfn-subfield" + (narrow ? " wiktku-start-narrow" : "")); next.on("input", function () { steps.dfn.onSubInput(list, this, rows, narrow); }); list.append($("<li></li>").append(next)); } }, // Populated from [[MediaWiki:Gadget-start.js/data.json]] (tplDefs, posExamples, jederDefs). tplDefs: [], posExamples: {}, jederDefs: {}, build: function (stepDiv) { if (stepDiv.find("ol.wiktku-dfn-list").length) return null; var list = $("<ol class='wiktku-dfn-list'></ol>"); list.append(steps.dfn.buildSenseBlock(stepDiv)); stepDiv.append(list); return null; }, /** Reads all sense blocks from the DOM and returns an array of sense objects. */ getSenses: function (stepDiv) { var senses = []; stepDiv.find("li.wiktku-dfn-sense").each(function () { var block = $(this); var tplSel = block.find("select.wiktku-dfn-tpl-select"); var tpl = tplSel.val() || ""; // noLang: template already encodes the language — don't add |lang| param. var tplNoLang = tpl ? tplSel.find("option[value='" + tpl + "']").attr("data-nolang") === "1" : false; var tplTitle = $.trim(block.find("input.wiktku-dfn-tpl-title").val()); var mane = $.trim(block.find("textarea.wiktku-dfn-mane").val()); var etiket = (function () { var vals = []; block.find(".wiktku-dfn-etiket-list textarea").each(function () { var v = $.trim($(this).val()); if (v) vals.push(v); }); return vals; }()); function readList(cls) { var vals = []; block.find("." + cls + "-list textarea").each(function () { var v = $.trim($(this).val()); if (v) vals.push(v); }); return vals; } // Nimûne items are compound: { text, tr?, t? } function readNimuneList() { var items = []; block.find(".wiktku-dfn-nimune-list li.wiktku-dfn-nimune-li").each(function () { var text = $.trim($(this).find(".wiktku-dfn-nimune-text").val()); if (!text) return; var obj = { text: text }; var tr = $.trim($(this).find(".wiktku-dfn-nimune-tr").val()); var t = $.trim($(this).find(".wiktku-dfn-nimune-t").val()); if (tr) obj.tr = tr; if (t) obj.t = t; items.push(obj); }); return items; } // Jêder is a growing list of citations, one per li — mirrors readNimuneList(). function readJederList() { var items = []; block.find(".wiktku-dfn-jeder-list li.wiktku-dfn-jeder-li").each(function () { var li = $(this); var quote = $.trim(li.find(".wiktku-dfn-nimune-quote").val()); if (!quote) return; var obj = { quote: quote }; var qtr = $.trim(li.find(".wiktku-dfn-nimune-quote-tr").val()); var qt = $.trim(li.find(".wiktku-dfn-nimune-quote-t").val()); if (qtr) obj.quoteTr = qtr; if (qt) obj.quoteT = qt; var tplName = li.find(".wiktku-dfn-quote-src-sel").val(); if (tplName === "__manual__") { var manual = $.trim(li.find(".wiktku-dfn-quote-src-manual").val()); if (manual) obj.jederManual = manual; } else if (tplName) { obj.jederTpl = tplName; var fields = {}; li.find(".wiktku-dfn-quote-src-input").each(function () { var k = $(this).attr("data-field-key"); var v = $.trim($(this).val()); if (k && v) fields[k] = v; }); obj.jêderFields = fields; } items.push(obj); }); return items; } senses.push({ tpl: tpl, tplNoLang: tplNoLang, tplTitle: tplTitle, mane: mane, etiket: etiket, nimune: readNimuneList(), jeder: readJederList(), alternativ: readList("wiktku-dfn-alternativ"), hevmane: readList("wiktku-dfn-hevmane"), dijmane: readList("wiktku-dfn-dijmane"), koordine: readList("wiktku-dfn-koordine"), jornav: readList("wiktku-dfn-jornav"), jernav: readList("wiktku-dfn-jernav") }); }); return senses; }, getOutput: function (values, callback) { var stepDiv = $("#wiktku-start-dfn"); var senses = steps.dfn.getSenses(stepDiv); var lang = values.lang; // A sense counts as "filled" if it has a mane, a chosen template + title, // or any other content (etîket/hevmane/nimûne/jêder…) worth keeping. var hasMane = senses.some(function (s) { return s.mane !== "" || (s.tpl && s.tplTitle) || senseHasExtraContent(s); }); // True only when at least one sense has a regular mane (needs linkify). var hasRegularMane = senses.some(function (s) { return !s.tpl && s.mane !== ""; }); // nimûne and jêder lines must never pass through linkify — only // the plain mane text should be linkified. We build two parallel // arrays: defLines (sent to linkify) and citeLines (kept aside). // Each entry in citeLines corresponds 1-to-1 with a defLines entry; // a template token {{wiktku-cite-N}} is embedded in defLines so // that after linkify runs we know exactly where to splice them back. // Template-call syntax is guaranteed safe: linkifiers leave {{ }} // tokens completely untouched. var defLines = []; // one entry per kept sense (goes to linkify) var citeLines = []; // parallel — nimûne+jêder for that same sense $.each(senses, function (_, sense) { // — Template sense (e.g. {{guharto|ku|somepage}}) — if (sense.tpl) { if (!sense.tplTitle) return; // skip empty template senses var tplLabelTpl = ""; if (sense.etiket && sense.etiket.length) { var tplLabelParts = sense.etiket.map(function (part) { return $.trim(part); }).filter(function (part) { return part !== ""; }); if (tplLabelParts.length) { tplLabelTpl = " {{e|" + lang + "|" + tplLabelParts.join("|") + "}} "; } } var tplCall = sense.tplNoLang ? "{{" + sense.tpl + "|" + sense.tplTitle + "}}" : "{{" + sense.tpl + "|" + lang + "|" + sense.tplTitle + "}}"; var tplHasJeder = sense.jeder && $.grep(sense.jeder, function (j) { return j && j.quote; }).length > 0; var idx = defLines.length; var cite = formatNimune(sense.nimune, lang, tplHasJeder) + formatJeder(sense.jeder, lang); defLines.push("#" + (tplLabelTpl ? tplLabelTpl : " ") + tplCall + (cite ? "{{wiktku-cite-" + idx + "}}" : "")); citeLines.push(cite); return; } // — Normal mane sense — var dfn = sense.mane; if (!dfn && !senseHasExtraContent(sense)) return; // truly empty if (dfn) { dfn = stripWikilinks(dfn); if (dfn[0] !== dfn[0].toUpperCase()) dfn = capitalize(dfn); if (!dfn.match(/[.…?!)\]]$/)) dfn += "."; } else { dfn = "{{mane?|" + lang + "}}"; } var labelTpl = ""; if (sense.etiket && sense.etiket.length) { var labelParts = sense.etiket.map(function (part) { return $.trim(part); }).filter(function (part) { return part !== ""; }); if (labelParts.length) { labelTpl = " {{e|" + lang + "|" + labelParts.join("|") + "}} "; } } var out = "#" + (labelTpl ? labelTpl : " ") + dfn; function wordLine(tpl, words) { if (!words.length) return ""; return "\n#: {{" + tpl + "|" + lang + "|" + words.join("|") + "}}"; } out += wordLine("alt-r", sense.alternativ); out += wordLine("hevmane", sense.hevmane); out += wordLine("dijmane", sense.dijmane); out += wordLine("koordîne", sense.koordine); out += wordLine("jornav", sense.jornav); out += wordLine("jêrnav", sense.jernav); var hasJeder = sense.jeder && $.grep(sense.jeder, function (j) { return j && j.quote; }).length > 0; var cite = formatNimune(sense.nimune, lang, hasJeder) + formatJeder(sense.jeder, lang); var idx = defLines.length; defLines.push(out + (cite ? "{{wiktku-cite-" + idx + "}}" : "")); citeLines.push(cite); }); // Splice citeLines back into a linkified string, replacing each // {{wiktku-cite-N}} token with its stored nimûne/jêder block. function restoreCites(t) { return t.replace(/\{\{wiktku-cite-(\d+)\}\}/g, function (_, n) { return citeLines[parseInt(n, 10)] || ""; }); } var text = defLines.join("\n") + "\n"; if (!hasMane) { // No definitions entered — emit {{mane?}} with bênimûne. text = "# {{mane?|" + lang + "}}\n#* {{bênimûne|" + lang + "}}\n"; callback(text); return; } if (!hasRegularMane) { // All filled senses are template senses — no linkify needed. callback(restoreCites(text)); return; } var didTryToLoad = function () { if (typeof $.wiktviLinkify === "function") { $.wiktviLinkify(text, function (linked) { callback(restoreCites(linked)); }); } else { callback(restoreCites(text)); } }; mw.loader.using("ext.gadget.linkify", didTryToLoad, didTryToLoad); } }, je: makeWordListStep("je", "jê", "Kelîmeyên jê çêbûyî binivîse", "Jê", "g"), tekildar: makeWordListStep("tekildar", "têkildar", "Kelîmeyên ji aliyê etîmolojiyê ve têkildarî vê kelîmeyê binivîse", "Têkildar", "g"), binereherwiha: makeWordListStep("binereherwiha", "binêre herwiha", "Kelîmeyên din ên eleqedar binivîse", "Binêre herwiha", "g"), etym: { id: "etym", name: "etîmolojî", question_fmt: "Etîmolojiya kelîmeyê binivîse", // etymTpls populated from data.json etymTpls: [], visible: function (values) { return values.lang && values.pos; }, /** Fills (or refills) the insert-dropdown from the current etymTpls array. */ refreshTplSelect: function () { var sel = $("#wiktku-start-etym .wiktku-tpl-insert-select"); if (!sel.length) return; sel.find("option[value!='']").remove(); $.each(steps.etym.etymTpls, function (_, tpl) { sel.append($("<option></option>").val(tpl.snippet).text(tpl.name + " — " + tpl.desc)); }); // Notify Chosen that the option list has changed (no-op on mobile). if (!isMobile) sel.trigger("chosen:updated"); }, build: function (stepDiv) { if (stepDiv.find(".wiktku-etym-wrap").length) return null; var wrap = $("<div class='wiktku-etym-wrap'></div>"); var ta = $("<textarea></textarea>") .attr("name", "wiktku-etym-" + $.now()) .attr("class", "wiktku-start-step-field wiktku-etym-text") .attr("rows", 4) .attr("placeholder", "Nimûne: Ji {{ji|en|ku|apple}}. yan rasterast binivîse…"); // Template insert dropdown — options also refreshed after data.json loads. var sel = $("<select class='wiktku-tpl-insert-select'></select>"); sel.append($("<option value=''>— şablonek lê zêde bike —</option>")); $.each(steps.etym.etymTpls, function (_, tpl) { sel.append($("<option></option>").val(tpl.snippet).text(tpl.name + " — " + tpl.desc)); }); sel.on("change", function () { var snippet = $(this).val(); if (!snippet) return; var lang = getValues().lang || ""; snippet = snippet.replace(/CODE/g, lang).replace(/SOURCELANG/g, "?"); insertAtCursor(ta[0], snippet); $(this).val(""); ta.focus(); }); wrap.append(sel).append($("<br>")).append(ta); stepDiv.append(wrap); return ta; }, output: function (values) { var text = $.trim($("#wiktku-start-etym .wiktku-etym-text").val()); if (text) { return "\n==== Etîmolojî ====\n" + text + "\n"; } // No etymology entered — emit {{ji?|lang}} as a placeholder, // but only when the entry has at least one regular (non-şablon) // sense with content — either real mane text, or an empty mane // with other fields filled in (which dfn.getOutput() renders as // {{mane?|lang}} with those fields attached). A şablon sense // like {{guharto|…}} never counts, filled in or not. var dfnSenses = steps.dfn.getSenses($("#wiktku-start-dfn")); var hasRegularMane = dfnSenses.some(function (s) { return !s.tpl && (s.mane !== "" || senseHasExtraContent(s)); }); if (!hasRegularMane) return ""; return "\n==== Etîmolojî ====\n{{ji?|" + values.lang + "}}\n"; } }, dunde: { id: "dunde", name: "dûnde", question_fmt: "Eger ev kelîme ji vî zimanî ketibe zimanekî din, vî zimanî û kelîmeya wî binivîse", visible: function (values) { return !!values.pos; }, disabledKeys: { "navz": true}, /** * Builds one row: a language dropdown + a growing list of word * inputs. When the dropdown gets a value the next empty row is * appended automatically. Mirrors steps.trans's row widget, but * flat (one shared list — dûnde isn't tied to individual senses). */ buildRow: function (stepDiv) { var row = $("<li class='wiktku-dunde-row wiktku-lang-row'></li>"); // Language selector — chosen is applied after insertion into DOM. var langSel = $(mw.html.element("select", { "class": "wiktku-start-step-keyfield wiktku-start-narrow" })); langSel.attr("data-placeholder", "Zimanekî lê bigere"); populateMenus(langSel, steps.dunde.keys || [], steps.dunde.disabledKeys); // When a language is chosen, ensure a next empty row exists. langSel.on("change", function () { steps.dunde.onLangChange(stepDiv, row); }); // Word list for this language. var wordList = $("<ul class='wiktku-dunde-words wiktku-lang-row-words'></ul>"); var firstWord = steps.dunde.makeWordInput(); wordList.append($("<li></li>").append(firstWord)); if (isMobile) { row.append(wrapNativeSelect(langSel)).append(wordList); } else { row.append(langSel).append(wordList); } return row; }, makeWordInput: function () { var input = $("<textarea></textarea>") .attr("name", "wiktku-dunde-word-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 1) .attr("class", "wiktku-dfn-subfield wiktku-start-narrow") .attr("placeholder", "Kelîme…"); input.on("input", function () { var list = $(this).closest("ul.wiktku-dunde-words"); var item = $(this).parent(); var val = $.trim($(this).val()); if (val && item.is(list.children("li:last-child"))) { var next = steps.dunde.makeWordInput(); list.append($("<li></li>").append(next)); } }); return input; }, onLangChange: function (stepDiv, row) { var list = stepDiv.find("ul.wiktku-dunde-list"); var isLast = row.is(list.children("li.wiktku-dunde-row:last-child")); if (isLast) { var newRow = steps.dunde.buildRow(stepDiv); list.append(newRow); // Init chosen after the new row is in the DOM (desktop only). if (!isMobile) newRow.find("select").chosen(chosenOptions); } // Keep disabled keys in sync across all lang selectors. steps.dunde.syncDisabledKeys(stepDiv); }, /** Disables already-selected languages in all other dropdowns. */ syncDisabledKeys: function (stepDiv) { var taken = $.extend({}, steps.dunde.disabledKeys); stepDiv.find("li.wiktku-dunde-row select").each(function () { var v = $(this).val(); if (v) taken[v] = true; }); stepDiv.find("li.wiktku-dunde-row select").each(function () { var self = $(this); var own = self.val(); self.find("option").each(function () { var code = $(this).val(); if (!code) return; $(this).prop("disabled", taken[code] && code !== own); }); self.trigger("chosen:updated"); }); }, build: function (stepDiv) { if (stepDiv.find("ul.wiktku-dunde-list").length) return null; var list = $("<ul class='wiktku-dunde-list wiktku-lang-row-list'></ul>"); list.append(steps.dunde.buildRow(stepDiv)); stepDiv.append(list); // Init chosen after the select is in the DOM (desktop only). if (!isMobile) list.find("select").chosen(chosenOptions); return null; }, /** Reads all [langcode, words[]] rows from the DOM. */ getRows: function (stepDiv) { var result = []; stepDiv.find("li.wiktku-dunde-row").each(function () { var lang = $(this).find("select").val(); if (!lang) return; var words = []; $(this).find("ul.wiktku-dunde-words textarea").each(function () { var v = $.trim($(this).val()); if (v) words.push(v); }); if (words.length) result.push([lang, words]); }); return result; }, output: function () { var stepDiv = $("#wiktku-start-dunde"); var rows = steps.dunde.getRows(stepDiv); if (!rows.length) return ""; var lines = $.map(rows, function (row) { var lang = row[0], words = row[1]; return "* {{dû|" + lang + "|" + words.join("|") + "}}"; }); return "\n==== Dûnde ====\n" + lines.join("\n") + "\n"; } }, zarava: { id: "zarava", name: "bi zaravayên din", visible: function (values) { return steps.trans.visible(values); }, disabledKeys: { "navz": true }, buildRow: function (group) { var row = $("<li class='wiktku-zarava-row wiktku-lang-row'></li>"); var langSel = $(mw.html.element("select", { "class": "wiktku-start-step-keyfield wiktku-start-narrow" })); populateMenus(langSel, steps.zarava.keys || [], steps.zarava.disabledKeys); langSel.on("change", function () { steps.zarava.onLangChange(group, row); }); var wordList = $("<ul class='wiktku-zarava-words wiktku-lang-row-words'></ul>"); var firstWord = steps.zarava.makeWordInput(); wordList.append($("<li></li>").append(firstWord)); row.append(langSel).append(wordList); return row; }, makeWordInput: function () { var input = $("<textarea></textarea>") .attr("name", "wiktku-zarava-word-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 1) .attr("class", "wiktku-dfn-subfield wiktku-start-narrow") .attr("placeholder", "Tercime…"); input.on("input", function () { var list = $(this).closest("ul.wiktku-zarava-words"); var item = $(this).parent(); var val = $.trim($(this).val()); if (val && item.is(list.children("li:last-child"))) { var next = steps.zarava.makeWordInput(); list.append($("<li></li>").append(next)); } }); return input; }, onLangChange: function (group, row) { var list = group.find("ul.wiktku-zarava-list"); var isLast = row.is(list.children("li.wiktku-zarava-row:last-child")); if (isLast) { var newRow = steps.zarava.buildRow(group); list.append(newRow); } steps.zarava.syncDisabledKeys(group); }, /** Disables already-selected dialects in all other dropdowns within one group. */ syncDisabledKeys: function (group) { var taken = $.extend({}, steps.zarava.disabledKeys); group.find("li.wiktku-zarava-row select").each(function () { var v = $(this).val(); if (v) taken[v] = true; }); group.find("li.wiktku-zarava-row select").each(function () { var self = $(this); var own = self.val(); self.find("option").each(function () { var code = $(this).val(); if (!code) return; $(this).prop("disabled", taken[code] && code !== own); }); }); }, /** Builds (or fetches) the .wiktku-zarava-group for one gloss. */ buildGroup: function (stepDiv, gi) { var group = $("<div class='wiktku-zarava-group'></div>").attr("data-gloss-pos", gi); var list = $("<ul class='wiktku-zarava-list wiktku-lang-row-list'></ul>"); list.append(steps.zarava.buildRow(group)); group.append(list); stepDiv.append(group); return group; }, /** Syncs one .wiktku-zarava-group per current gloss (same logic as steps.trans.build). */ build: function (stepDiv) { var glosses = steps.trans.glossList(); if (!glosses.length) { stepDiv.find(".wiktku-zarava-group").remove(); return null; } var existingGroups = stepDiv.find(".wiktku-zarava-group"); if (existingGroups.length > glosses.length) { existingGroups.slice(glosses.length).remove(); } $.each(glosses, function (gi, gloss) { var group = stepDiv.find(".wiktku-zarava-group[data-gloss-pos='" + gi + "']"); if (!group.length) group = steps.zarava.buildGroup(stepDiv, gi); var label = group.find(".wiktku-zarava-group-label"); if (glosses.length > 1) { if (!label.length) { label = $("<div class='wiktku-zarava-group-label'></div>"); group.prepend(label); } label.text(gloss.index + " " + gloss.text); } else if (label.length) { label.remove(); } }); return null; }, /** Reads the dialect rows for a single gloss group. */ getGroupTranslations: function (group) { var result = []; group.find("li.wiktku-zarava-row").each(function () { var lang = $(this).find("select").val(); if (!lang) return; var words = []; $(this).find("ul.wiktku-zarava-words textarea").each(function () { var v = $.trim($(this).val()); if (v) words.push(v); }); if (words.length) result.push([lang, words]); }); return result; }, /** Reads all rows from the DOM, grouped by gloss position. */ getTranslations: function (stepDiv) { var result = []; stepDiv.find(".wiktku-zarava-group").each(function () { result.push(steps.zarava.getGroupTranslations($(this))); }); return result; }, output: function (values) { if (values.lang !== "ku") return ""; var stepDiv = $("#wiktku-start-zarava"); var glosses = steps.trans.glossList(); if (!glosses.length) return ""; var blocks = $.map(glosses, function (gloss, gi) { var group = stepDiv.find(".wiktku-zarava-group[data-gloss-pos='" + gi + "']"); var rows = group.length ? steps.zarava.getGroupTranslations(group) : []; if (!gloss.text && !rows.length) return undefined; if (rows.length) { rows.sort(function (a, b) { var aLang = langsByCode[a[0]] || []; var bLang = langsByCode[b[0]] || []; return (aLang[2] || "").localeCompare(bLang[2] || "", "ku"); }); } var wordLines = $.map(rows, function (row) { var lang = row[0]; var words = row[1]; var wikiWords = words.map(function (w) { return "{{W|" + lang + "|" + w + "}}"; }).join(", "); return "* {{Z|" + lang + "}}: " + wikiWords; }).join("\n"); if (!wordLines) return undefined; var block = "{{werger-ser|" + (gloss.text || "?") + "|" + gloss.index + "}}"; block += "\n" + wordLines; block += "\n{{werger-bin}}"; return block; }); if (!blocks.length) return ""; return "\n==== Bi zaravayên din ====\n" + blocks.join("\n") + "\n"; } }, trans: { id: "trans", name: "werger", visible: function (values) { if (!(values.lang === "ku" && values.pos)) return false; // Hide Werger only when EVERY sense is a template sense (Guharto etc.) // with a title filled in — i.e. there is real content but no plain // gloss to attach a translation table to. A mix of real + template // senses still shows Werger; the template senses are simply skipped // in output(). // // "Real" here means a non-şablon sense with either mane text or // other filled-in fields (etîket/hevmane/nimûne/jêder…), since // dfn.getOutput() renders the latter too, as {{mane?|lang}} plus // whatever else was filled in. // // When nothing has been filled in at all, output() will emit // {{mane?|lang}} instead of a gloss — but Werger should still show, // since the user may want to add translations before they've // settled on a gloss. var dfnSenses = steps.dfn.getSenses($("#wiktku-start-dfn")); var hasRealSense = dfnSenses.some(function (s) { return !s.tpl && (s.mane !== "" || senseHasExtraContent(s)); }); var hasFilledTplSense = dfnSenses.some(function (s) { return s.tpl && s.tplTitle; }); return hasRealSense || !hasFilledTplSense; }, disabledKeys: { "navz": true, "ku": true, "ckb": true, "sdh": true, "lki": true, "hac": true, "zza": true }, /** * Builds one translation row: a language dropdown + a growing list * of word inputs. When the dropdown gets a value the next empty row * is appended automatically. * * @param group the specific .wiktku-trans-group this row belongs to * (each gloss has its own group and its own list of rows, so the * lookups below must stay scoped to that group rather than the * whole step — the step now holds one list per gloss). */ buildRow: function (group) { var row = $("<li class='wiktku-trans-row wiktku-lang-row'></li>"); // Language selector — chosen is applied after insertion into DOM. var langSel = $(mw.html.element("select", { "class": "wiktku-start-step-keyfield wiktku-start-narrow" })); langSel.attr("data-placeholder", "Zimanekî lê bigere"); populateMenus(langSel, steps.trans.keys || [], steps.trans.disabledKeys); // When a language is chosen, ensure a next empty row exists. langSel.on("change", function () { steps.trans.onLangChange(group, row); }); // Word list for this language. var wordList = $("<ul class='wiktku-trans-words wiktku-lang-row-words'></ul>"); var firstWord = steps.trans.makeWordInput(); wordList.append($("<li></li>").append(firstWord)); if (isMobile) { row.append(wrapNativeSelect(langSel)).append(wordList); } else { row.append(langSel).append(wordList); } return row; }, makeWordInput: function () { var input = $("<textarea></textarea>") .attr("name", "wiktku-trans-word-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 1) .attr("class", "wiktku-dfn-subfield wiktku-start-narrow") .attr("placeholder", "Tercime…"); input.on("input", function () { var list = $(this).closest("ul.wiktku-trans-words"); var item = $(this).parent(); var val = $.trim($(this).val()); if (val && item.is(list.children("li:last-child"))) { var next = steps.trans.makeWordInput(); list.append($("<li></li>").append(next)); } }); return input; }, onLangChange: function (group, row) { var list = group.find("ul.wiktku-trans-list"); var isLast = row.is(list.children("li.wiktku-trans-row:last-child")); if (isLast) { var newRow = steps.trans.buildRow(group); list.append(newRow); // Init chosen after the new row is in the DOM (desktop only). if (!isMobile) newRow.find("select").chosen(chosenOptions); } // Keep disabled keys in sync across this gloss's lang selectors // only — the same language can be used for different senses. steps.trans.syncDisabledKeys(group); }, /** Disables already-selected languages in all other dropdowns within one group. */ syncDisabledKeys: function (group) { var taken = $.extend({}, steps.trans.disabledKeys); group.find("li.wiktku-trans-row select").each(function () { var v = $(this).val(); if (v) taken[v] = true; }); group.find("li.wiktku-trans-row select").each(function () { var self = $(this); var own = self.val(); self.find("option").each(function () { var code = $(this).val(); if (!code) return; $(this).prop("disabled", taken[code] && code !== own); }); self.trigger("chosen:updated"); }); }, /** * Builds (or fetches) the .wiktku-trans-group for one gloss, with * its own label and its own list of translation rows. */ buildGroup: function (stepDiv, gi) { var group = $("<div class='wiktku-trans-group'></div>").attr("data-gloss-pos", gi); var list = $("<ul class='wiktku-trans-list wiktku-lang-row-list'></ul>"); list.append(steps.trans.buildRow(group)); group.append(list); stepDiv.append(group); // Init chosen after the select is in the DOM (desktop only). if (!isMobile) list.find("select").chosen(chosenOptions); return group; }, /** * Syncs one .wiktku-trans-group per current gloss, adding new * groups and removing stale ones as senses are added or removed, * while leaving existing groups (and whatever translations the * user has already typed into them) untouched. Groups are keyed * to their gloss's position in glossList() via data-gloss-pos, so * a group always matches the same sense across rebuilds as long * as senses aren't reordered relative to each other. */ build: function (stepDiv) { var glosses = steps.trans.glossList(); if (!glosses.length) { stepDiv.find(".wiktku-trans-group").remove(); return null; } // Drop groups for glosses that no longer exist (always from the // tail — groups are only ever appended in gloss order below). var existingGroups = stepDiv.find(".wiktku-trans-group"); if (existingGroups.length > glosses.length) { existingGroups.slice(glosses.length).remove(); } $.each(glosses, function (gi, gloss) { var group = stepDiv.find(".wiktku-trans-group[data-gloss-pos='" + gi + "']"); if (!group.length) group = steps.trans.buildGroup(stepDiv, gi); // Only label groups when there's more than one gloss to // distinguish between — a single gloss needs no caption. var label = group.find(".wiktku-trans-group-label"); if (glosses.length > 1) { if (!label.length) { label = $("<div class='wiktku-trans-group-label'></div>"); group.prepend(label); } label.text(gloss.index + " " + gloss.text); } else if (label.length) { label.remove(); } }); return null; }, /** Reads the translation rows for a single gloss group. */ getGroupTranslations: function (group) { var result = []; group.find("li.wiktku-trans-row").each(function () { var lang = $(this).find("select").val(); if (!lang) return; var words = []; $(this).find("ul.wiktku-trans-words textarea").each(function () { var v = $.trim($(this).val()); if (v) words.push(v); }); if (words.length) result.push([lang, words]); }); return result; }, /** * Reads all translation rows from the DOM, grouped by gloss * position — one array of [lang, words] rows per gloss group, in * the same order as the .wiktku-trans-group elements. */ getTranslations: function (stepDiv) { var result = []; stepDiv.find(".wiktku-trans-group").each(function () { result.push(steps.trans.getGroupTranslations($(this))); }); return result; }, /** * Builds the numbered "{ index, gloss }" list — one entry per dfn * sense that has a real mane (skips template senses like Guharto, * which have nothing to caption a translation table with). The * index matches the sense's actual position in the numbered "#" * definition list (1-based), including template senses in the count, * so the number printed next to {{werger-ser}} lines up with the * gloss the reader sees in the entry. * * When nothing has been filled in at all (dfn.getOutput() will emit * {{mane?|lang}} as sense 1), this returns a single placeholder * entry with empty text instead of an empty array, so Werger still * has one group to attach translations to before a gloss exists. * When every filled sense is a template sense instead, this stays * empty — that mirrors trans.visible()'s hidden case, where there's * no group in the DOM for a placeholder to attach to anyway. */ glossList: function () { var dfnSenses = steps.dfn.getSenses($("#wiktku-start-dfn")); var glosses = []; var hasFilledTplSense = false; $.each(dfnSenses, function (i, s) { if (s.tpl) { if (s.tplTitle) hasFilledTplSense = true; return; // template sense — no gloss to caption with } var dfn = s.mane; if (!dfn) { // No mane text, but other fields (etîket/hevmane/nimûne/ // jêder…) are filled — dfn.getOutput() still emits this // sense as a numbered line using {{mane?|lang}}, so it // needs its own gloss group too, just with no caption text. if (senseHasExtraContent(s)) glosses.push({ index: i + 1, text: "" }); return; } if (dfn[0] !== dfn[0].toLowerCase()) dfn = decapitalize(dfn); dfn = stripWikilinks(dfn).replace(/[.…?!)\]،؟]+$/, ""); glosses.push({ index: i + 1, text: dfn }); }); if (!glosses.length && !hasFilledTplSense) { glosses.push({ index: 1, text: "" }); } return glosses; }, output: function (values) { if (values.lang !== "ku") return ""; var stepDiv = $("#wiktku-start-trans"); var glosses = steps.trans.glossList(); // Every sense is a template sense — there's no real gloss // anywhere and no group in the DOM either (glossList() only // returns empty in that case), so skip the section entirely. if (!glosses.length) return ""; // Each gloss now has its own group of translation rows — // attach every gloss's own words under its own werger-ser/-bin // pair instead of dumping everything under the first one. var blocks = $.map(glosses, function (gloss, gi) { var group = stepDiv.find(".wiktku-trans-group[data-gloss-pos='" + gi + "']"); var rows = group.length ? steps.trans.getGroupTranslations(group) : []; // Placeholder gloss (no real mane entered yet) with nothing // translated into it — nothing to output, and gloss.text is // empty so there's no caption to give {{werger-ser}} anyway. if (!gloss.text && !rows.length) return undefined; if (rows.length) { // Sort by Kurdish sort key. rows.sort(function (a, b) { var aLang = langsByCode[a[0]] || []; var bLang = langsByCode[b[0]] || []; return (aLang[2] || "").localeCompare(bLang[2] || "", "ku"); }); } var wordLines = $.map(rows, function (row) { var lang = row[0]; var words = row[1]; var wikiWords = words.map(function (w) { return "{{W|" + lang + "|" + w + "}}"; }).join(", "); return "* {{Z|" + lang + "}}: " + wikiWords; }).join("\n"); var block = "{{werger-ser|" + (gloss.text || "?") + "|" + gloss.index + "}}"; if (wordLines) block += "\n" + wordLines; block += "\n{{werger-bin}}"; return block; }); if (!blocks.length) return ""; return "\n==== Werger ====\n" + blocks.join("\n") + "\n"; } }, }; steps.trans.keys = steps.lang.choices; steps.dunde.keys = steps.lang.choices; steps.zarava.keys = getZaravaKeys(steps.lang.choices); var ordered_steps = [ steps.lang, steps.pron, steps.pos, steps.cinsiyet, steps.lektur, steps.tr, steps.dfn, steps.je, steps.tekildar, steps.etym, steps.dunde, steps.binereherwiha, steps.zarava, steps.trans]; // Step ids that belong to each section (not shared across sections). var PER_SECTION_STEP_IDS = [ "pos", "cinsiyet", "lektur", "tr", "dfn", "je", "tekildar", "etym", "dunde", "binereherwiha", "zarava", "trans" ]; // ── Multi-section state ────────────────────────────────────────────────── // Each entry is a plain snapshot: { pos, cinsiyet, lektur, tr, dfn (senses[]), // je, tekildar, binereherwiha, trans (rows[]) }. var sections = [{}]; // section 0 starts empty (DOM is the truth) var activeSection = 0; function snapshotDfn() { return steps.dfn.getSenses($("#wiktku-start-dfn")); } /** * Rebuild the dfn DOM from a previously snapshotted senses array. */ function restoreDfn(senses) { var stepDiv = $("#wiktku-start-dfn"); // Tear down the existing list so build() recreates it cleanly. stepDiv.find("ol.wiktku-dfn-list").remove(); steps.dfn.build(stepDiv); var list = stepDiv.find("ol.wiktku-dfn-list"); $.each(senses, function (i, sense) { // Ensure enough blocks exist (build() seeds one). var blocks = list.find("li.wiktku-dfn-sense"); var block = blocks.eq(i); if (!block.length) { var nb = steps.dfn.buildSenseBlock(stepDiv); list.append(nb); block = list.find("li.wiktku-dfn-sense").last(); } // Template selector. block.find("select.wiktku-dfn-tpl-select").val(sense.tpl || ""); if (sense.tpl) { block.find("textarea.wiktku-dfn-mane").hide(); block.find("input.wiktku-dfn-tpl-title").val(sense.tplTitle || "").show(); } else { block.find("textarea.wiktku-dfn-mane").val(sense.mane || "").show(); block.find("input.wiktku-dfn-tpl-title").hide().val(""); } // Re-sync the formên alternatîv/hevmane/… hide state now that // tplSelect's value was set programmatically (its own "change" // handler doesn't fire from .val(), so this doesn't happen otherwise). var updateVis = block.data("updateFieldVisibility"); if (updateVis) updateVis(); // Restore a sub-list (etiket, formên alternatîv, hevmane …) from a values array. function restoreSubList(cls, values) { if (!values || !values.length) return; var groupDiv = block.find("." + cls + "-group"); var subList = groupDiv.find("ol, ul").first(); if (!subList.length) return; // group not found // Fill existing items, append new ones as needed. $.each(values, function (j, val) { var items = subList.find("li"); if (j < items.length) { items.eq(j).find("textarea").val(val); } else { var ta = $("<textarea></textarea>") .attr("name", "wiktku-dfn-restore-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 1) .attr("class", "wiktku-dfn-subfield wiktku-start-narrow") .val(val); ta.on("input", function () { steps.dfn.onSubInput(subList, this, 1, true); }); subList.append($("<li></li>").append(ta)); } }); } // Reveal and populate lazy groups that have data. var lazyMap = { "wiktku-dfn-etiket": sense.etiket, "wiktku-dfn-alternativ": sense.alternativ, "wiktku-dfn-hevmane": sense.hevmane, "wiktku-dfn-dijmane": sense.dijmane, "wiktku-dfn-koordine": sense.koordine, "wiktku-dfn-jornav": sense.jornav, "wiktku-dfn-jernav": sense.jernav }; $.each(lazyMap, function (cls, vals) { if (vals && vals.length) restoreSubList(cls, vals); }); // Nimûne items are objects { text, tr?, t? } — restore using the builder. if (sense.nimune && sense.nimune.length) { var nimuneGroupDiv = block.find(".wiktku-dfn-nimune-group"); var nimuneList = nimuneGroupDiv.find("ol.wiktku-dfn-nimune-list"); var buildFn = nimuneGroupDiv.data("buildNimuneLi"); nimuneList.empty(); $.each(sense.nimune, function (_, n) { var text = typeof n === "object" ? (n.text || "") : n; if (!text) return; var li = buildFn ? buildFn() : $("<li class='wiktku-dfn-nimune-li'></li>"); li.find(".wiktku-dfn-nimune-text").val(text); if (n.tr) li.find(".wiktku-dfn-nimune-tr").val(n.tr); if (n.t) li.find(".wiktku-dfn-nimune-t").val(n.t); nimuneList.append(li); }); // Always leave a blank trailing item. if (buildFn) nimuneList.append(buildFn()); } // Restore jêder (quote/citation) entries — a growing list, restored using the // builder just like Nimûne. Accepts either the current array shape or a // single legacy object (from older saved sections) for backwards compatibility. var jederArr = $.isArray(sense.jeder) ? sense.jeder : (sense.jeder ? [sense.jeder] : []); if (jederArr.length) { var jederGroupDiv = block.find(".wiktku-dfn-jeder-group"); var jederList = jederGroupDiv.find("ol.wiktku-dfn-jeder-list"); var buildJederFn = jederGroupDiv.data("buildJederLi"); jederList.empty(); $.each(jederArr, function (_, j) { if (!j || !j.quote) return; var li = buildJederFn ? buildJederFn() : $("<li class='wiktku-dfn-jeder-li'></li>"); li.find(".wiktku-dfn-nimune-quote").val(j.quote); if (j.quoteTr) li.find(".wiktku-dfn-nimune-quote-tr").val(j.quoteTr); if (j.quoteT) li.find(".wiktku-dfn-nimune-quote-t").val(j.quoteT); if (j.jederManual) { var manualSel = li.find(".wiktku-dfn-quote-src-sel"); manualSel.val("__manual__").trigger("change"); li.find(".wiktku-dfn-quote-src-manual").val(j.jederManual); } else if (j.jederTpl) { var srcSel = li.find(".wiktku-dfn-quote-src-sel"); srcSel.val(j.jederTpl).trigger("change"); if (j.jêderFields) { $.each(j.jêderFields, function (key, val) { li.find(".wiktku-dfn-quote-src-input[data-field-key='" + key + "']").val(val); }); } } jederList.append(li); }); // Always leave a blank trailing item, same as Nimûne. if (buildJederFn) jederList.append(buildJederFn()); } }); } /** * Snapshot simple (non-dfn) per-section steps from current DOM into obj. */ function saveCurrentSection() { var snap = {}; $.each(PER_SECTION_STEP_IDS, function (_, id) { if (id === "dfn") { snap.dfn = snapshotDfn(); return; } if (id === "etym") { snap.etym = $.trim($("#wiktku-start-etym .wiktku-etym-text").val()); return; } var step = steps[id]; if (!step) return; var stepDiv = $("#wiktku-start-" + id); if (id === "trans") { snap.trans = steps.trans.getTranslations(stepDiv); return; } if (id === "zarava") { snap.zarava = steps.zarava.getTranslations(stepDiv); return; } if (id === "dunde") { snap.dunde = steps.dunde.getRows(stepDiv); return; } // Generic: read all step fields. var fields = stepDiv.find(".wiktku-start-step-field"); if (step.multiple) { snap[id] = fields.map(function () { return $(this).val(); }).get(); } else { snap[id] = fields.val(); } }); sections[activeSection] = snap; } /** * Restore a previously saved snapshot into the form DOM. */ function restoreSection(snap) { $.each(PER_SECTION_STEP_IDS, function (_, id) { if (id === "dfn") { restoreDfn(snap.dfn || []); return; } if (id === "etym") { $("#wiktku-start-etym .wiktku-etym-wrap").remove(); steps.etym.build($("#wiktku-start-etym")); $("#wiktku-start-etym .wiktku-etym-text").val(snap.etym || ""); return; } if (id === "trans") { // Rebuild trans groups (dfn must already be restored by this // point in the $.each loop, so glossList() reflects it). var transDiv = $("#wiktku-start-trans"); transDiv.find(".wiktku-trans-group").remove(); steps.trans.build(transDiv); var groupsSnap = snap.trans || []; $.each(groupsSnap, function (gi, rows) { var group = transDiv.find(".wiktku-trans-group[data-gloss-pos='" + gi + "']"); if (!group.length) return; // gloss no longer exists — drop its rows var list = group.find("ul.wiktku-trans-list"); $.each(rows, function (j, row) { var lang = row[0], words = row[1]; var lastRow = list.find("li.wiktku-trans-row").last(); lastRow.find("select").val(lang).trigger("change"); var wordList = lastRow.find("ul.wiktku-trans-words"); $.each(words, function (k, word) { var wordItems = wordList.find("li"); if (k < wordItems.length) { wordItems.eq(k).find("textarea").val(word); } else { // .val() below doesn't fire "input", so the normal // auto-grow never runs — append a matching item // ourselves instead of silently dropping the word. var extraInput = steps.trans.makeWordInput(); wordList.append($("<li></li>").append(extraInput)); extraInput.val(word); } }); // Leave one trailing empty field so the row can still grow // when the user types, matching a freshly-built row. if ($.trim(wordList.children("li").last().find("textarea").val())) { wordList.append($("<li></li>").append(steps.trans.makeWordInput())); } }); }); return; } if (id === "zarava") { // Rebuild zarava groups (dfn must already be restored by this // point in the $.each loop, so glossList() reflects it). var zaravaDiv = $("#wiktku-start-zarava"); zaravaDiv.find(".wiktku-zarava-group").remove(); steps.zarava.build(zaravaDiv); var zaravaGroupsSnap = snap.zarava || []; $.each(zaravaGroupsSnap, function (gi, rows) { var group = zaravaDiv.find(".wiktku-zarava-group[data-gloss-pos='" + gi + "']"); if (!group.length) return; // gloss no longer exists — drop its rows var list = group.find("ul.wiktku-zarava-list"); $.each(rows, function (j, row) { var lang = row[0], words = row[1]; var lastRow = list.find("li.wiktku-zarava-row").last(); lastRow.find("select").val(lang).trigger("change"); var wordList = lastRow.find("ul.wiktku-zarava-words"); $.each(words, function (k, word) { var wordItems = wordList.find("li"); if (k < wordItems.length) { wordItems.eq(k).find("textarea").val(word); } else { var extraInput = steps.zarava.makeWordInput(); wordList.append($("<li></li>").append(extraInput)); extraInput.val(word); } }); if ($.trim(wordList.children("li").last().find("textarea").val())) { wordList.append($("<li></li>").append(steps.zarava.makeWordInput())); } }); }); return; } if (id === "dunde") { // Rebuild dunde rows. var dundeDiv = $("#wiktku-start-dunde"); dundeDiv.find("ul.wiktku-dunde-list").remove(); steps.dunde.build(dundeDiv); var dundeRows = snap.dunde || []; $.each(dundeRows, function (i, row) { var lang = row[0], words = row[1]; var list = dundeDiv.find("ul.wiktku-dunde-list"); var lastRow = list.find("li.wiktku-dunde-row").last(); lastRow.find("select").val(lang).trigger("change"); var wordList = lastRow.find("ul.wiktku-dunde-words"); $.each(words, function (j, word) { var wordItems = wordList.find("li"); if (j < wordItems.length) { wordItems.eq(j).find("textarea").val(word); } else { // .val() below doesn't fire "input", so the normal // auto-grow never runs — append a matching item // ourselves instead of silently dropping the word. var extraInput = steps.dunde.makeWordInput(); wordList.append($("<li></li>").append(extraInput)); extraInput.val(word); } }); // Leave one trailing empty field so the row can still grow // when the user types, matching a freshly-built row. if ($.trim(wordList.children("li").last().find("textarea").val())) { wordList.append($("<li></li>").append(steps.dunde.makeWordInput())); } }); return; } var step = steps[id]; if (!step) return; var stepDiv = $("#wiktku-start-" + id); var fields = stepDiv.find(".wiktku-start-step-field"); var val = snap[id]; if (val === undefined || val === null) return; if (step.multiple) { var arr = val; fields.each(function (i) { if (i < arr.length) $(this).val(arr[i]); }); } else { fields.val(val); } // Notify chosen widgets of the programmatic value change. if (!isMobile) fields.filter("select").trigger("chosen:updated"); }); } function getWikitextForCurrentSection(callback) { var values = getValues(); var entry = steps.pos.output(values); steps.dfn.getOutput(values, function (output) { entry += output; entry += steps.je.output(values); entry += steps.tekildar.output(values); entry += steps.etym.output(values); entry += steps.dunde.output(values); entry += steps.binereherwiha.output(values); entry += steps.zarava.output(values); entry += steps.trans.output(values); callback(entry, values); }); } function getWikitextAllSections(callback) { saveCurrentSection(); var results = new Array(sections.length); var sharedValues = getValues(); // lang/pron are shared function processSection(i) { if (i >= sections.length) { // All done — restore original active section. restoreSection(sections[activeSection]); refresh(); callback(results, sharedValues); return; } restoreSection(sections[i]); refresh(); getWikitextForCurrentSection(function (sectionText) { results[i] = sectionText; processSection(i + 1); }); } processSection(0); } /** * Assembles wikitext for all sections plus the shared lang/pron header. */ function getWikitext(callback) { getWikitextAllSections(function (sectionTexts, sharedValues) { var entry = steps.lang.output(sharedValues); entry += steps.pron.output(sharedValues); entry += sectionTexts.join("\n"); // Edit summary uses section 0's values. Read from the saved snapshot // (not the live DOM) so it doesn't mix section 0's pos with whichever // section happens to be active/restored at this point. var dfnSenses = (sections[0] && sections[0].dfn) || []; var dfnSummary = dfnSenses.map(function (s) { return s.mane; }).filter(Boolean).join("; "); var summaryLabel = addLangMode ? "WF:Ziman lê zêde" : "WF:Nû"; var summary = "([[Mediawiki:Gadget-start.js|" + summaryLabel + "]] v.2.0) +" + sharedValues.lang + ":" + sections[0].pos + ":" + dfnSummary; var summaryField = document.getElementById("wpSummary"); if (addLangMode && summaryField.value) { summary = summaryField.value + " " + summary; } summaryField.value = summary; callback(entry); }); } var continueBtn; function getValuesForStep(stepId) { var fields = $("#wiktku-start-" + stepId + " .wiktku-start-step-field"); var step = steps[stepId]; if (step.keys) { var values = {}; fields.each(function (i, field) { var key = $(field).prevAll(".wiktku-start-step-keyfield").val(); if (key) values[key] = $(field).val(); }); return values; } else if (step.multiple) { return fields.map(function () { return $(this).val(); }).get(); } return fields.val(); } function getValues() { var values = {}; $.each(steps, function (stepId) { values[stepId] = getValuesForStep(stepId); }); return values; } function populateMenus(inputs, choices, disabledValues) { if (!disabledValues) disabledValues = {}; var vals = inputs.map(function (i, input) { return $(input).val(); }); inputs.empty(); inputs.append($("<option></option>")); $.each(choices, function (j, choice) { // Append the language code in parentheses so that typing a code // (e.g. "ku") in the search box still finds the language name. var displayText = capitalize(choice[1]); if (choice[2] !== undefined) { // This is a language choice [code, name, sortKey] — show code. displayText = capitalize(choice[1]) + " (" + choice[0] + ")"; } var option = $(mw.html.element("option", { value: choice[0] }, displayText)); if (disabledValues[choice[0]]) option.prop("disabled", true); inputs.append(option); }); inputs.val(function (i) { return vals[i]; }); } /** * Returns a bitmap containing the keys that should be disabled for a key * menu in the given step because they are disabled or already taken by * another key menu. */ function getDisabledKeys(step) { var occupiedKeys = {}; $("#wiktku-start-" + step.id + " .wiktku-start-step-keyfield").each(function () { occupiedKeys[$(this).val()] = true; }); if (step.disabledKeys) $.extend(occupiedKeys, step.disabledKeys); return occupiedKeys; } function buildKeyInput(step) { if (!step.keys) return undefined; var input = $(mw.html.element("select", { "class": "wiktku-start-step-keyfield wiktku-start-narrow" })); input.attr("data-placeholder", "Hilbijêre " + step.keyName); if (isMobile) { populateMenus(input, step.keys, getDisabledKeys(step)); // On mobile return the wrapper; the select is inside it. // Change events still fire on the inner select. return wrapNativeSelect(input); } input.on("chosen:showing_dropdown", function () { $(this).data("wiktku-defaultValue", $(this).val()); }); input.change(function (_, context) { var inputs = $("#wiktku-start-" + step.id + " .wiktku-start-step-keyfield").not(this); var oldValue = $(this).data("wiktku-defaultValue"); var newValue = context.selected; inputs.find("option[value='" + oldValue + "']").prop('disabled', false); inputs.find("option[value='" + newValue + "']").prop('disabled', true); inputs.trigger("chosen:updated"); }); populateMenus(input, step.keys, getDisabledKeys(step)); return input; } /** * If the current text field has text and there are no more text fields after * the current text field in the list, add another text field to the list. */ function refreshForTextField(currentInput, step) { currentInput = $(currentInput); var value = currentInput.val(); var item = currentInput.parent(); if (value && !item.next("li").length) { var nextInput = $("<textarea></textarea>") .attr("name", "wiktku-field-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("class", currentInput.attr("class")) .attr("rows", currentInput.attr("rows") || 1); nextInput.on("input", function (evt) { refreshForTextField(evt.target, step); }); var nextKeyInput = buildKeyInput(step); var nextItem = $("<li></li>").append(nextKeyInput).append(nextInput); item.parent().append(nextItem); if (nextKeyInput) nextKeyInput.chosen(chosenOptions); } var canContinue = !continueBtn.isDisabled(); if ((value && !canContinue) || (!value && canContinue)) { refresh(step); } } function prepareInput(input, step) { if (!input) return; if (step.required) input.prop('required', true); input.change(step, refresh); } /** * Shows and hides all the steps based on whether their prerequisites are met, * and updates placeholders where applicable. */ function refresh(evt) { var values = getValues(); var changedStep = evt && evt.data; var didFocus = false; var canContinue = true; // Re-filter template options in every sense block whenever lang changes. $("#wiktku-start-dfn .wiktku-dfn-tpl-select").each(function () { var fn = $(this).data("updateOptions"); if (typeof fn === "function") fn(); }); // Re-filter pronunciation and etymology template dropdowns when language changes. steps.pron.refreshTplSelect(); steps.etym.refreshTplSelect(); // Sync tr/t sub-fields in every nimûne item to the current language. // tr shown when language needs transliteration; t shown when lang !== "ku". (function () { var lang = values.lang || ""; var showTr = needsTransliteration(lang); var showT = lang && lang !== "ku"; $("#wiktku-start-dfn .wiktku-dfn-nimune-list li.wiktku-dfn-nimune-li").each(function () { var li = $(this); // Ensure the sub-wrapper exists when we need it. var subWrap = li.find(".wiktku-dfn-nimune-sub"); // tr field var trTa = li.find(".wiktku-dfn-nimune-tr"); if (showTr && !trTa.length) { if (!subWrap.length) { subWrap = $("<div></div>").addClass("wiktku-dfn-nimune-sub"); li.append(subWrap); } trTa = $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-tr-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 5) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-tr") .attr("placeholder", "Transkrîpsiyon…"); subWrap.prepend(trTa); } else if (!showTr && trTa.length) { trTa.remove(); } // t field var tTa = li.find(".wiktku-dfn-nimune-t"); if (showT && !tTa.length) { if (!subWrap.length) { subWrap = $("<div></div>").addClass("wiktku-dfn-nimune-sub"); li.append(subWrap); } tTa = $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-t-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 5) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-t") .attr("placeholder", "Tercimeya nimûneyê kurmancî…"); subWrap.append(tTa); } else if (!showT && tTa.length) { tTa.remove(); } // Remove the wrapper if it ended up empty. subWrap = li.find(".wiktku-dfn-nimune-sub"); if (subWrap.length && !subWrap.children().length) subWrap.remove(); }); }()); // Sync tr/t sub-fields in every jêder citation to the current language. // tr shown when language needs transliteration; t shown when lang !== "ku". (function () { var lang = values.lang || ""; var showTr = needsTransliteration(lang); var showT = lang && lang !== "ku"; $("#wiktku-start-dfn .wiktku-dfn-jeder-list li.wiktku-dfn-jeder-li").each(function () { var li = $(this); // Ensure the sub-wrapper exists when we need it. It must sit right // after the quote textarea and before the source selector. var subWrap = li.find(".wiktku-dfn-quote-sub"); // tr field var trTa = li.find(".wiktku-dfn-nimune-quote-tr"); if (showTr && !trTa.length) { if (!subWrap.length) { subWrap = $("<div></div>").addClass("wiktku-dfn-quote-sub"); li.find(".wiktku-dfn-nimune-quote").after(subWrap); } trTa = $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-quote-tr-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 2) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-quote-tr") .attr("placeholder", "Transkrîpsiyona jêgirtinê…"); subWrap.prepend(trTa); } else if (!showTr && trTa.length) { trTa.remove(); } // t field var tTa = li.find(".wiktku-dfn-nimune-quote-t"); if (showT && !tTa.length) { if (!subWrap.length) { subWrap = $("<div></div>").addClass("wiktku-dfn-quote-sub"); li.find(".wiktku-dfn-nimune-quote").after(subWrap); } tTa = $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-quote-t-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 2) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-quote-t") .attr("placeholder", "Tercimeya jêgirtinê ya kurmancî…"); subWrap.append(tTa); } else if (!showT && tTa.length) { tTa.remove(); } // Remove the wrapper if it ended up empty. subWrap = li.find(".wiktku-dfn-quote-sub"); if (subWrap.length && !subWrap.children().length) subWrap.remove(); }); }()); $.each(steps, function (stepId, step) { if (typeof(step.visible) === "function" && !step.visible(values)) { $("#wiktku-start-" + stepId).slideUp(); } else { var stepDiv = $("#wiktku-start-" + stepId); if (changedStep !== step && typeof(step.build) === "function") { prepareInput(step.build(stepDiv, values), step); } var input = stepDiv.find(".wiktku-start-step-field"); if (typeof(step.example) === "function") { // .find() above already reaches nested fields (e.g. the dfn // step's mane textareas inside each sense block), so one // assignment covers every step; dfn keeps its own fallback. var exampleText = step.example(values) || (step.id === "dfn" ? "Mane…" : ""); input.attr("placeholder", exampleText); } var didSlideDown; if (!didFocus && stepDiv.css("display") === "none" && step.required) { didSlideDown = function (evt) { input.focus(); }; didFocus = true; } stepDiv.slideDown(didSlideDown); } if (step.required && (values[stepId] === "" || (step.multiple && values[stepId].join("") === ""))) { canContinue = false; } }); continueBtn.setDisabled(!canContinue); } function destroy() { $("#wiktku-start-form, .noafterwizard").slideUp(function () { $(this).remove(); }); $(".noarticletext .nowizard, #editform").slideDown(); $("#ca-edit").removeClass("selected"); $("#ca-wiktku-nowizard").addClass("selected"); } // Priority order for Kurdish dialects and the navz pseudo-code. // Codes listed here come before all other languages; unlisted codes // are sorted alphabetically by their display name via localeCompare. var LANG_PRIORITY = ["navz", "ku", "hac", "sdh", "lki", "ckb", "zza"]; /** * Inserts a new == {{ziman|code}} == section into existing page wikitext * at the correct sorted position: * 1. Any content before the first language section is preserved at the top. * 2. navz is always first, then ku/hac/sdh/lki/ckb/zza in that order, * then all other languages sorted by display name (localeCompare). */ function insertNewLangSection(existing, wikitext) { var newCodeMatch = wikitext.match(/^== \{\{ziman\|([^}]+)\}\} ==/); var newCode = newCodeMatch ? newCodeMatch[1] : ""; var sections = []; var preamble = ""; var firstMatch = existing.match(/(?:^|\n)== \{\{ziman\|/); if (!firstMatch) { // No existing lang sections at all — just append. var sep = existing && !/\n\s*$/.test(existing) ? "\n\n" : ""; return existing + sep + wikitext; } // Everything before the first == {{ziman|...}} == is the preamble. var firstSectionStart = existing.indexOf("== {{ziman|"); // Walk back to the start of that line. var lineStart = existing.lastIndexOf("\n", firstSectionStart - 1); var preambleEnd = lineStart !== -1 ? lineStart + 1 : 0; preamble = existing.slice(0, preambleEnd); // Parse each language section: header line + everything until the next header. var body = existing.slice(preambleEnd); // NOTE: with the /m flag, a bare "$" matches end-of-*line*, not just // end-of-string — that previously made the non-greedy content group // stop at the section's first line break instead of running to the // next language header (or the real end of the text), silently // dropping the rest of that section's wikitext. (?![\s\S]) matches // only the true end of the string, /m flag or not. var langSectionRe = /^(== \{\{ziman\|([^}]+)\}\} ==\n?)([\s\S]*?)(?=\n== \{\{ziman\||(?![\s\S]))/gm; var m; while ((m = langSectionRe.exec(body)) !== null) { sections.push({ code: m[2], content: m[0] // full text of this section including header }); } // Determine sort rank: priority list first (by index), then alphabetical. function getLangName(code) { var entry = langsByCode[code]; return entry ? entry[1] : code; } function sortRank(code) { var idx = LANG_PRIORITY.indexOf(code); return idx !== -1 ? idx : LANG_PRIORITY.length; } function compareLangs(a, b) { var ra = sortRank(a), rb = sortRank(b); if (ra !== rb) return ra - rb; // Both are outside priority list — sort by display name. return getLangName(a).localeCompare(getLangName(b), userLang); } // Insert the new section into the sorted list. var newSection = { code: newCode, content: wikitext }; var inserted = false; for (var i = 0; i < sections.length; i++) { if (compareLangs(newCode, sections[i].code) < 0) { sections.splice(i, 0, newSection); inserted = true; break; } } if (!inserted) sections.push(newSection); // Re-join: preamble + sections separated by newlines. var joined = sections.map(function (s) { // Ensure each section ends with exactly one newline before the next. return s.content.replace(/\n+$/, ""); }).join("\n"); return preamble + joined + "\n"; } function build() { $(".nowizard, .nowizard .noafterwizard").hide(); var callToAction = $("#wiktku-calltoaction"); var origCallToActionText = callToAction.text(); $(mw.util.addPortletLink("p-views", "#", "Edîtora çavkaniyê veke", "ca-wiktku-nowizard", "Vê rûpelê bi edîtora çavkaniyê çêke", undefined, "#ca-watch")).click(function (evt) { evt.preventDefault(); callToAction.text(origCallToActionText); destroy(); }); if (callToAction.length) { callToAction.text(origCallToActionText + " Forma li jêr ji bo çêkirina madeyeke nû bi kar bîne."); } var startForm = $("<form id='wiktku-start-form'></form>"); if (addLangMode) { startForm.append($("<p class='wiktku-addlang-notice'></p>").text( "Bi vê formê tu yê beşeke nû li rûpelê îlaw bikî. Eger ev zimanê ku tu îlawe dikî jixwe di rûpelê de hebe, beşa nû li dawiya vî zimanî dê were îlawekirin. " + "Ji kerema xwe netîceya dawî kontrol bikin, eger problemek derkeve, li [[Mediawiki talk:Gadget-start.js|nîqaşa vê amûrê]] problemê ragihîne.")); } var spinner; // Tab bar for switching between POS sections. var sectionTabsDiv = $("<div id='wiktku-section-tabs'></div>"); startForm.submit(function (evt) { evt.preventDefault(); continueBtn.setDisabled(true); spinner.show(); getWikitext(function (wikitext) { if (addLangMode) { var textbox = $("#wpTextbox1"); var existing = textbox.val() || ""; // Check whether the generated lang header already exists in the page. // wikitext always starts with "== {{ziman|CODE}} ==\n" (from steps.lang.output). // If that exact section heading is already present in the existing content, // strip it from the new output and insert the remaining content at the end // of that lang section (just before the next == level-2 heading, or at the // very end of the page if there is no following section). var langHeaderMatch = wikitext.match(/^(== \{\{ziman\|[^}]+\}\} ==\n)/); if (langHeaderMatch) { var langHeader = langHeaderMatch[1]; // e.g. "== {{ziman|ku}} ==\n" // Escape for use in RegExp. var escapedHeader = langHeader.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); if (new RegExp(escapedHeader).test(existing)) { // Strip the header from the new output. var newContent = wikitext.slice(langHeader.length); // Find the insertion point: end of the existing lang section. // A new L2 heading marks the start of the next language block. var afterHeader = existing.indexOf(langHeader); var searchFrom = afterHeader + langHeader.length; // Find the next == … == heading after this section's start. var nextL2 = existing.indexOf("\n== ", searchFrom); var insertAt = nextL2 !== -1 ? nextL2 : existing.length; // Ensure there's a blank line before the inserted block. var before = existing.slice(0, insertAt); var after = existing.slice(insertAt); var sep = /\n\s*$/.test(before) ? "" : "\n"; textbox.val(before + sep + newContent + after); } else { // New language — insert at the correct sorted position. textbox.val(insertNewLangSection(existing, wikitext)); } } else { // Unexpected format — insert at sorted position anyway. textbox.val(insertNewLangSection(existing, wikitext)); } } else { $("#wpTextbox1").val(wikitext); } $("html, body").animate({scrollTop: 0}); callToAction.text("Hindik ma!"); $("#wiktku-preview-container").remove(); destroy(); }); }); $.each(ordered_steps, function (i, step) { var stepDiv = $(mw.html.element("div", { "class": "wiktku-start-step", id: "wiktku-start-" + step.id })); var name = capitalize(step.name); stepDiv.append($(mw.html.element("h3", { "class": "wiktku-start-step-name" }, new mw.html.Raw(mw.html.element("label", { "for": "wiktku-start-" + step.id + "-field" }, name))))); if (step.question_fmt) { stepDiv.append($(mw.html.element("label", { "class": "wiktku-start-step-question", "for": "wiktku-start-" + step.id + "-field" }, step.question_fmt))); if (step.question_br) stepDiv.append($("<br>")); } var input; if (step.choices) { input = $(mw.html.element("select", { "class": "wiktku-start-step-field", id: "wiktku-start-" + step.id + "-field" })); input.attr("data-placeholder", capitalize(step.name) + " hilbijêre "); populateMenus(input, step.choices); if (step.multiple) input.attr("multiple", true); if (isMobile) { stepDiv.append(wrapNativeSelect(input)); } else { stepDiv.append(input); } } else if (typeof(step.build) === "function") { input = step.build(stepDiv); } else { input = $("<textarea></textarea>") .attr("class", "wiktku-start-step-field") .attr("id", "wiktku-start-" + step.id + "-field") .attr("rows", step.rows || 2); if (step.narrow) input.addClass("wiktku-start-narrow"); if (step.multiple) { input.on("input", function (evt) { refreshForTextField(evt.target, step); }); var keyInput = buildKeyInput(step); var list = $(step.ordered ? "<ol></ol>" : "<ul></ul>") .append($("<li></li>").append(keyInput).append(input)); stepDiv.append(list); } else stepDiv.append(input); } prepareInput(input, step); stepDiv.hide(); // Insert tab bar just before the first per-section step. if (step.id === "pos") startForm.append(sectionTabsDiv); startForm.append(stepDiv); }); // ── Section tab helpers ────────────────────────────────────────────── // ── Add-section button — lives in the tab bar, disabled until pos chosen ── var addSectionBtn = new OO.ui.ButtonWidget({ label: "+ Beş zêde bike", disabled: true }); addSectionBtn.on("click", function () { saveCurrentSection(); sections.push({}); activeSection = sections.length - 1; $.each(PER_SECTION_STEP_IDS, function (_, id) { if (id === "dfn") { var stepDiv = $("#wiktku-start-dfn"); stepDiv.find("ol.wiktku-dfn-list").remove(); steps.dfn.build(stepDiv); return; } if (id === "etym") { $("#wiktku-start-etym .wiktku-etym-wrap").remove(); steps.etym.build($("#wiktku-start-etym")); return; } if (id === "trans") { var transDiv = $("#wiktku-start-trans"); transDiv.find(".wiktku-trans-group").remove(); return; } if (id === "zarava") { var zaravaDiv = $("#wiktku-start-zarava"); zaravaDiv.find(".wiktku-zarava-group").remove(); return; } if (id === "dunde") { var dundeDiv = $("#wiktku-start-dunde"); dundeDiv.find("ul.wiktku-dunde-list").remove(); return; } var stepDiv = $("#wiktku-start-" + id); stepDiv.find(".wiktku-start-step-field").val(""); if (!isMobile) stepDiv.find("select.wiktku-start-step-field").trigger("chosen:updated"); }); renderSectionTabs(); refresh(); $("html, body").animate({ scrollTop: sectionTabsDiv.offset().top - 20 }, 300); }); /** Re-render the tab bar to reflect current sections[] and activeSection. */ function renderSectionTabs() { // Detach (not remove) the button first: .empty() strips bound // event data from any children left inside it, which would // silently kill addSectionBtn's click handler on every re-render. addSectionBtn.$element.detach(); sectionTabsDiv.empty(); var lang = getValues().lang || ""; if (!lang) { sectionTabsDiv.hide(); return; } sectionTabsDiv.show(); $.each(sections, function (i) { var posVal = sections[i].pos || ""; var tabLabel = posVal ? capitalize(posVal) : ("Beş " + (i + 1)); var tab = $("<span></span>") .addClass("wiktku-section-tab") .text(tabLabel) .toggleClass("wiktku-tab-active", i === activeSection); (function (idx) { tab.on("click", function () { if (idx === activeSection) return; saveCurrentSection(); activeSection = idx; restoreSection(sections[activeSection]); refresh(); renderSectionTabs(); }); }(i)); sectionTabsDiv.append(tab); }); // Enable "Beş zêde bike" only when the active section has a pos chosen. var activePos = sections[activeSection] && sections[activeSection].pos ? sections[activeSection].pos : getValues().pos; addSectionBtn.setDisabled(!activePos); sectionTabsDiv.append(addSectionBtn.$element); } renderSectionTabs(); // Update the active tab's label whenever pos changes. startForm.on("change", "#wiktku-start-pos-field", function () { renderSectionTabs(); }); // Show the tab bar as soon as a language is selected. startForm.on("change", "#wiktku-start-lang-field", function () { renderSectionTabs(); }); var footer = $("<div id='wiktku-start-footer'></div>"); spinner = $(mw.html.element("img", { id: "wiktku-start-spinner", src: "//upload.wikimedia.org/wikipedia/commons/d/de/Ajax-loader.gif", alt: "Tê barkirin…", title: "Tê barkirin…" })); footer.append(spinner.hide()); continueBtn = new OO.ui.ButtonWidget({ id: "wiktku-unhide-editform", label: "Bişîne", flags: [ "primary", "progressive" ] }); continueBtn.on("click", function () { mw.notify("Tê şandin…", { type: "info", tag: "wiktku-submit" }); startForm.trigger("submit"); }); footer.append(continueBtn.$element); // "Edîtora çavkaniyê veke" button — inline fallback for the portlet link // which is invisible on mobile and easy to miss on desktop. var sourceEditorBtn = new OO.ui.ButtonWidget({ label: "Edîtora çavkaniyê veke", framed: false }); sourceEditorBtn.on("click", function () { destroy(); }); footer.append(sourceEditorBtn.$element); // ── Preview checkboxes ─────────────────────────────────────────────── // Wikitext preview (raw text panel) var previewCheck = $("<input type='checkbox' id='wiktku-preview-toggle'>"); var previewLabel = $("<label for='wiktku-preview-toggle'></label>") .text(" Pêşdîtina wîkîtekstê"); var previewPanel = $("<pre id='wiktku-preview-panel'></pre>").hide(); // Live rendered preview (parsed HTML panel, same logic as AjaxEdit). // Not available on mobile — API polling causes too many problems on small screens. var livePreviewCheck = null; var livePreviewPanel = null; if (!isMobile) { livePreviewCheck = $("<input type='checkbox' id='wiktku-live-preview-toggle'>"); livePreviewPanel = $("<div id='wiktku-live-preview-panel'></div>").hide(); } // Container that holds both panels and switches between stacked / side-by-side. var previewContainer = $("<div id='wiktku-preview-container'></div>"); previewContainer.append(previewPanel); if (!isMobile) previewContainer.append(livePreviewPanel); var previewTimer = null; var livePreviewIntervalId = -1; var livePreviewActive = false; // guards in-flight fetches after uncheck /** Rebuilds wikitext preview if its checkbox is checked. */ function schedulePreview() { if (!previewCheck.prop("checked")) return; clearTimeout(previewTimer); // Debounce: wait 400 ms after the last keystroke before rebuilding. previewTimer = setTimeout(function () { getWikitext(function (wikitext) { previewPanel.text(wikitext).show(); updatePanelLayout(); }); }, 400); } /** Fetches parsed HTML and populates the live preview panel. */ function loadLivePreview() { getWikitext(function (wikitext) { new mw.Api().parse(wikitext, { title: mw.config.get("wgPageName") }).done(function (html) { // Discard result if the user unchecked while the fetch was in flight. if (!livePreviewActive) return; livePreviewPanel.html(html).show(); updatePanelLayout(); }); }); } /** Adjusts panel widths depending on which previews are visible. */ function updatePanelLayout() { var wikitextVisible = previewCheck.prop("checked"); var liveVisible = livePreviewCheck && livePreviewCheck.prop("checked"); if (wikitextVisible && liveVisible) { // Side by side — each panel takes roughly half the available width. previewPanel.css({ "flex": "1 1 45%", "min-width": "280px" }); livePreviewPanel.css({ "flex": "1 1 45%", "min-width": "280px" }); } else { // Full width for whichever is visible — only touch panels that are // actually shown so that setting flex doesn't override display:none. if (wikitextVisible) previewPanel.css({ "flex": "1 1 100%", "min-width": "" }); if (liveVisible && livePreviewPanel) livePreviewPanel.css({ "flex": "1 1 100%", "min-width": "" }); } } previewCheck.on("change", function () { if ($(this).prop("checked")) { schedulePreview(); } else { clearTimeout(previewTimer); previewPanel.hide(); updatePanelLayout(); } }); if (!isMobile) { livePreviewCheck.on("change", function () { if ($(this).prop("checked")) { livePreviewActive = true; livePreviewPanel.show(); loadLivePreview(); livePreviewIntervalId = setInterval(loadLivePreview, 500); } else { livePreviewActive = false; clearInterval(livePreviewIntervalId); livePreviewIntervalId = -1; livePreviewPanel.hide().empty(); updatePanelLayout(); } }); } // Listen on all input/change events on the form and update both previews. startForm.on("input change", function () { schedulePreview(); }); footer.append($("<span style='margin-left:1em'></span>") .append(previewCheck).append(previewLabel)); if (!isMobile) { var livePreviewLabel = $("<label for='wiktku-live-preview-toggle'></label>") .text(" Pêşdîtina zindî"); footer.append($("<span style='margin-left:1em'></span>") .append(livePreviewCheck).append(livePreviewLabel)); } startForm.append(footer); $("#editform").hide().before(startForm); // Insert preview container (holds both panels) after the form. startForm.after(previewContainer); if (!isMobile) startForm.find("select").chosen(chosenOptions); refresh(); // Zimanan ji MediaWiki:Gadget-translation_editor.js/ziman.json bar bike. // Kodên ku bi "-pro" diqedin û navên ku "zimanê destan" tê de heye // tên derxistin. Zimanên xardkirî li serî dimînin, yên din // bi alfabeyê li dû wan tên. // Pinned choices come from MediaWiki:Gadget-start.js/data.json (langChoices), // already loaded into steps.lang.choices before build() runs. var pinnedChoices = steps.lang.choices.slice(); var pinnedCodes = $.map(pinnedChoices, function (choice) { return choice[0]; }); new mw.Api().get({ action: "query", prop: "revisions", titles: "MediaWiki:Gadget-translation_editor.js/ziman.json", rvprop: "content", rvslots: "main", formatversion: 2 }).then(function (data) { var page = data.query.pages[0]; var content = page && page.revisions && page.revisions[0].slots.main.content; var zimanData; try { zimanData = JSON.parse(content); } catch (e) { zimanData = {}; } var extraChoices = []; $.each(zimanData, function (code, name) { // Filter: skip proto-language codes and legendary/reconstructed langs. if (/-pro$/i.test(code)) return; if (/ziman[eê]\s+destan/i.test(name)) return; // Skip codes already in the pinned list (they are handled above). if (pinnedCodes.indexOf(code) !== -1) return; // sortKey: bare name without leading "zimanê " for sorting. var sortKey = name.replace(/^ziman[eê]\s+/i, ""); var choice = [code, name, sortKey]; extraChoices.push(choice); langsByCode[code] = choice; }); // Populate langsByCode for pinned choices too. $.each(pinnedChoices, function (i, choice) { // Ensure pinned choices have a sortKey (index 2). if (choice.length < 3) choice[2] = choice[1]; langsByCode[choice[0]] = choice; }); // Sort the extra choices alphabetically by sort key. extraChoices.sort(function (a, b) { return a[2].localeCompare(b[2], userLang); }); // Final list: pinned first, then the rest. var allChoices = pinnedChoices.concat(extraChoices); steps.lang.choices = allChoices; steps.trans.keys = allChoices; steps.dunde.keys = allChoices; steps.zarava.keys = getZaravaKeys(allChoices); var langMenu = $("#wiktku-start-lang-field"); populateMenus(langMenu, steps.lang.choices); langMenu.trigger("chosen:updated"); var transMenus = $("#wiktku-start-trans .wiktku-start-step-keyfield"); populateMenus(transMenus, steps.trans.keys, getDisabledKeys(steps.trans)); transMenus.trigger("chosen:updated"); var dundeMenus = $("#wiktku-start-dunde .wiktku-start-step-keyfield"); populateMenus(dundeMenus, steps.dunde.keys, getDisabledKeys(steps.dunde)); dundeMenus.trigger("chosen:updated"); var zaravaMenus = $("#wiktku-start-zarava .wiktku-start-step-keyfield"); populateMenus(zaravaMenus, steps.zarava.keys, getDisabledKeys(steps.zarava)); }); } mw.loader.using(["jquery.chosen", "mediawiki.api", "oojs-ui-core"], function () { if (!isMobile) { mw.notify( "Amûr dest pê dike, hinek bisekinin. Not: jkx Sentaks (sentaks highlighter) neaktîv bikin", { type: "info", tag: "wiktku-start-notice", autoHide: false } ); } // Load metadata, langChoices, posChoices and tplDefs from the companion // data page so they can be updated without touching this script. new mw.Api().get({ action: "query", prop: "revisions", titles: "MediaWiki:Gadget-start.js/data.json", rvprop: "content", rvslots: "main", formatversion: 2 }).then(function (data) { var page = data.query.pages[0]; var content = page && page.revisions && page.revisions[0].slots.main.content; var d; try { d = JSON.parse(content); } catch (e) { d = {}; } // Populate metadata. if (d.metadata) $.extend(metadata, d.metadata); // Populate gender labels. if (d.genderLabels) $.extend(GENDER_BASE_LABELS, d.genderLabels); // Populate lang choices (pinned list used by build() → ziman.json loader). if (d.langChoices) steps.lang.choices = d.langChoices; // Populate POS choices. if (d.posChoices) steps.pos.choices = d.posChoices; // Populate template definitions for the dfn sense-block builder. if (d.tplDefs) steps.dfn.tplDefs = d.tplDefs; // Populate pos placeholder examples. if (d.posExamples) steps.dfn.posExamples = d.posExamples; // Populate citation template definitions for the quote widget. if (d.jederDefs) steps.dfn.jederDefs = d.jederDefs; // Populate pronunciation and etymology template insert lists. if (d.pronTpls) { steps.pron.pronTpls = d.pronTpls; steps.pron.refreshTplSelect(); } if (d.etymTpls) { steps.etym.etymTpls = d.etymTpls; steps.etym.refreshTplSelect(); } // Sync trans/dunde/zarava keys with the (now populated) lang choices. steps.trans.keys = steps.lang.choices; steps.dunde.keys = steps.lang.choices; steps.zarava.keys = getZaravaKeys(steps.lang.choices); }).always(build); }); }); //</nowiki> ghmiujnsdm86mj9kaczl4d7gu4juw88 6265567 6265565 2026-07-19T13:50:35Z Wikihez 7344 6265567 javascript text/javascript // Li ser [[vi:MediaWiki:Gadget-start.js]] hatiye refaktorkirin. //<nowiki> $(function () { var ns = mw.config.get("wgNamespaceNumber"); if (ns && !(ns === 2 && mw.config.get("wgPageName").match(/\/ceribandin$|\/test$/))) { return; } var action = mw.config.get("wgAction"); var pageExists = !!mw.config.get("wgArticleId"); // "Zimanek lê zêde bike" mode: triggered from the portlet link below. // Runs the same wizard on an EXISTING page's edit form, but appends the // generated section instead of replacing the textarea's content. var addLangMode = pageExists && mw.util.getParamValue("wiktkuaddlang") === "1"; // On a normal page view of an existing page, just add the portlet link // that takes the user into addLangMode; don't build anything else here. if (action === "view" && pageExists) { mw.util.addPortletLink("p-views", mw.util.getUrl(mw.config.get("wgPageName"), { action: "submit", wiktkuaddlang: "1" }), "+Ziman/beşeke din", "ca-wiktku-addlang", "Ji vê rûpelê re zimanekî nû zêde bike"); return; } if (!(action === "edit" || action === "submit")) { return; } if (!addLangMode && !$(".mw-newarticletext, .mw-newarticletextanon").length) { return; } if (window.location.href.includes("editintro=User:Wikihez/creation/intro")) { return; // Do not run the script wextê WF:Bilez dişuxile } function capitalize(str) { if (!str) return str; return str[0].toUpperCase() + str.substr(1); } function decapitalize(str) { if (!str) return str; return str[0].toLowerCase() + str.substr(1); } function escapeRegExp(str) { return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); } function stripWikilinks(str) { return str.replace(/\[\[([^\]|]+)(?:\|([^\]]+))?\]\]/g, function (m, target, display) { return display || target; }); } function insertAtCursor(el, text) { var start = el.selectionStart; var end = el.selectionEnd; var val = el.value; el.value = val.slice(0, start) + text + val.slice(end); var pos = start + text.length; el.selectionStart = el.selectionEnd = pos; } var pageName = mw.config.get("wgPageName").replaceAll(/_/g, " "); if (ns) pageName = pageName.replace(/.*\//, ""); var pageNameRe = escapeRegExp(pageName); var userLang = mw.config.get("wgUserLanguage"); // Mobile detection: MobileFrontend sets wgMFMode, or fall back to touch check. var isMobile = !!mw.config.get("wgMFMode") || window.matchMedia("(pointer: coarse)").matches; var chosenOptions = { width: "20em", disable_search_threshold: 0, placeholder_text_single: "Yekî hilbijêre", placeholder_text_multiple: "Hilbijêre", no_results_text: "Nehat dîtin", enable_split_word_search: true, search_contains: true }; function wrapNativeSelect(select) { var placeholder = select.attr("data-placeholder") || "Lê bigere…"; // Hide the native select — we drive it programmatically. select.hide(); var wrapper = $("<span class='wiktku-native-select-wrap'></span>"); var textInput = $("<input type='search' autocomplete='off'>") .attr("placeholder", placeholder) .addClass("wiktku-start-narrow wiktku-ac-input"); var resultsList = $("<ul class='wiktku-ac-results'></ul>").hide(); // Full option cache — rebuilt when chosen:updated fires. var allOptions = []; function cacheOptions() { allOptions = []; select.find("option").each(function () { var v = $(this).val(); if (!v) return; // skip the empty placeholder option allOptions.push({ value: v, text: $(this).text(), disabled: $(this).prop("disabled") }); }); } cacheOptions(); function showResults(query) { var q = query.trim().toLowerCase(); resultsList.empty(); var matched; if (q) { matched = []; $.each(allOptions, function (_, o) { if (o.disabled) return; var codeMatch = o.value.toLowerCase().indexOf(q) !== -1; var nameMatch = o.text.toLowerCase().indexOf(q) !== -1; if (codeMatch || nameMatch) { matched.push({ opt: o, codeMatch: codeMatch }); } }); // Code matches (especially prefix matches) come first. matched.sort(function (a, b) { var aCode = a.opt.value.toLowerCase(); var bCode = b.opt.value.toLowerCase(); var aPrefix = aCode.indexOf(q) === 0; var bPrefix = bCode.indexOf(q) === 0; if (aPrefix !== bPrefix) return aPrefix ? -1 : 1; if (a.codeMatch !== b.codeMatch) return a.codeMatch ? -1 : 1; return 0; }); matched = matched.map(function (item) { return item.opt; }); } else { matched = allOptions.filter(function (o) { return !o.disabled; }); } if (!matched.length) { resultsList.hide(); return; } $.each(matched.slice(0, 50), function (_, opt) { var li = $("<li></li>").text(opt.text).attr("data-value", opt.value); // Use touchend instead of touchstart so that a scroll gesture does // not accidentally select an item. We track whether the finger moved // between touchstart and touchend — if it did, it was a scroll. var touchMoved = false; li.on("touchstart", function () { touchMoved = false; }); li.on("touchmove", function () { touchMoved = true; }); li.on("touchend", function (e) { if (touchMoved) return; // was a scroll, not a tap e.preventDefault(); selectOption(opt.value, opt.text); }); // Keep mousedown for desktop fallback. li.on("mousedown", function (e) { e.preventDefault(); selectOption(opt.value, opt.text); }); resultsList.append(li); }); // Position the list above or below depending on available viewport space. var inputRect = textInput[0].getBoundingClientRect(); var viewportH = window.innerHeight; var spaceBelow = viewportH - inputRect.bottom - 8; var spaceAbove = inputRect.top - 8; var maxH = Math.min(224, Math.max(spaceBelow, spaceAbove)); // 224px ≈ 14em resultsList.css({ "max-height": maxH + "px", "top": spaceBelow >= spaceAbove ? "100%" : "auto", "bottom": spaceBelow >= spaceAbove ? "auto" : "100%" }); resultsList.show(); } function selectOption(value, text) { textInput.val(text); select.val(value); resultsList.hide(); select.trigger("change"); } textInput.on("input focus", function () { showResults($(this).val()); }); textInput.on("blur", function () { // Short delay so a touchstart on a result item fires first. setTimeout(function () { resultsList.hide(); }, 200); }); // chosen:updated → re-cache (called after ziman.json loads). select.on("chosen:updated", function () { cacheOptions(); // If a value is already selected, keep the display text in sync. var cur = select.val(); if (cur) { var match = $.grep(allOptions, function (o) { return o.value === cur; })[0]; if (match) textInput.val(match.text); } }); // No-op .chosen() so desktop call-sites don't need guarding. select.chosen = function () { return select; }; wrapper.append(textInput).append(resultsList).append(select); return wrapper; } var langsByCode = {}; // Populated from [[MediaWiki:Gadget-start.js/data.json]] at runtime. var metadata = {}; // Zaravayên kurdî yên ku di beşa "Bi zaravayên din" de tên pêşkêşkirin — // ev kod ji beşa Werger têne derxistin daku heman zimên du caran neyê xwendin. var ZARAVA_LANG_CODES = ["ckb", "sdh", "lki", "hac", "zza"]; function getZaravaKeys(choices) { var byCode = {}; $.each(choices || [], function (_, c) { byCode[c[0]] = c; }); var result = []; $.each(ZARAVA_LANG_CODES, function (_, code) { if (byCode[code]) result.push(byCode[code]); }); return result; } function needsTransliteration(langCode) { var meta = metadata[langCode]; if (!meta || !meta.sc) return false; var scripts = Array.isArray(meta.sc) ? meta.sc : [meta.sc]; return scripts.length > 0 && scripts[0] !== "Latn"; } // Kodên cinsiyetê yên di metadata.g de — ji data.json tê dagirtin var GENDER_BASE_LABELS = {}; // Sub-lists that only make sense for a plain (non-şablon) sense — hidden // when a şablon (e.g. {{guharto|…}}) is chosen for that sense, since a // template-based sense has no "own" gloss for alternate forms, synonyms, // antonyms, coordinate terms, hypernyms or hyponyms to attach to. Etîket, // Nimûne and Jêgirtin stay visible either way. var HIDDEN_ON_TPL_GROUPS = [ "wiktku-dfn-alternativ", "wiktku-dfn-hevmane", "wiktku-dfn-dijmane", "wiktku-dfn-koordine", "wiktku-dfn-jornav", "wiktku-dfn-jernav" ]; function genderLabel(code) { if (code === "p") return "Pirjimar"; var pluralMatch = code.match(/^(.+)-p$/); if (pluralMatch && GENDER_BASE_LABELS[pluralMatch[1]]) { return GENDER_BASE_LABELS[pluralMatch[1]] + " (pirjimar)"; } return GENDER_BASE_LABELS[code] || code; } /** * True if a sense has any content worth keeping besides its mane text — * etîket, hevmane/dijmane/koordîne/etc. word lists, nimûne, or jêder * (quote). Used so a sense with an empty mane but filled-in extra * fields still gets emitted (with {{mane?}} standing in for the gloss) * instead of being silently dropped. */ function senseHasExtraContent(s) { if (s.etiket && $.grep(s.etiket, function (e) { return $.trim(e) !== ""; }).length) return true; if (s.alternativ.length || s.hevmane.length || s.dijmane.length || s.koordine.length || s.jornav.length || s.jernav.length) return true; if (s.nimune && $.grep(s.nimune, function (n) { return (typeof n === "object" ? n.text : n) !== ""; }).length > 0) return true; if (s.jeder && $.grep(s.jeder, function (j) { return j && j.quote; }).length > 0) return true; return false; } /** * formatNimune: each nimûne item can be { text, tr, t }: * text — example text * tr — transliteration (only when the language needs it) * t — Kurdish translation (third positional param, no key) */ function formatNimune(nimunes, lang, hasJeder) { var hasNimune = nimunes && $.grep(nimunes, function (n) { return (typeof n === "object" ? n.text : n) !== ""; }).length > 0; if (!hasNimune) { return hasJeder ? "" : "\n#* {{bênimûne|" + lang + "}}"; } return $.map(nimunes, function (n) { var text = typeof n === "object" ? n.text : n; if (!text) return undefined; var bolded = text.replace( new RegExp("(" + pageNameRe + "([^( |,|;|\\?|\\.|\\!)]+)?)", "ig"), "'''$1'''"); var tpl = "\n#: {{nm|" + lang + "|" + bolded; if (typeof n === "object") { if (n.tr) tpl += "|tr=" + n.tr; // Translation as third positional param (no key needed). if (n.t) tpl += "|" + n.t; } // Short examples fit on one line together with their translation. // rêz=1 is not used for ku — definitions are shown on separate lines there. if (text.length < 200 && lang !== "ku") tpl += "|rêz=1"; tpl += "}}"; return tpl; }).join(""); } /** * Formats a list of jêder (quote/citation) objects into wikitext lines. * Each entry that has no quote text is skipped. Returns "" when the list * is empty or every entry is blank. * * #* {{jêder-…|lang|jêgirtin=…|tr=…|tercime=…|…fields…}} * * When no template is chosen, the generic {{jêder|…}} template is used * instead. Its 2nd positional param is the user's freeform "bi destê xwe * binivîsim" source text when supplied, or the çavkanî? placeholder otherwise. * If that text contains "=" it is passed as |2=… instead of a bare * positional param, since MediaWiki would otherwise misparse it as its * own key=value pair and break the template: * #* {{jêder|lang|jêgirtin=…|tr=…|tercime=…|<manual source or çavkanî?>}} */ function formatJeder(jederList, lang) { if (!jederList || !jederList.length) return ""; return $.map(jederList, function (jeder) { if (!jeder || !jeder.quote) return undefined; if (jeder.jederTpl) { var cite = "\n#* {{" + jeder.jederTpl + "|" + lang; cite += "|jêgirtin=" + jeder.quote; if (jeder.quoteTr) cite += "|tr=" + jeder.quoteTr; if (jeder.quoteT) cite += "|tercime=" + jeder.quoteT; $.each(jeder.jêderFields || {}, function (key, val) { if (val) cite += "|" + key + "=" + val; }); cite += "}}"; return cite; } var out = "\n#* {{jêder|" + lang + "|jêgirtin=" + jeder.quote; if (jeder.quoteTr) out += "|tr=" + jeder.quoteTr; if (jeder.quoteT) out += "|tercime=" + jeder.quoteT; var srcParam = jeder.jederManual ? jeder.jederManual : "çavkanî?"; // A positional param containing "=" gets parsed as its own key=value // pair by MediaWiki and breaks the template, so force it to be // explicitly named (|2=) whenever that's the case. out += (srcParam.indexOf("=") !== -1 ? "|2=" : "|") + srcParam; out += "}}"; return out; }).join(""); } function makeWordListStep(id, name, question_fmt, header, templateName) { return { id: id, name: name, question_fmt: question_fmt, multiple: true, narrow: true, visible: function (values) { return values.lang && values.pos; }, output: function (values) { var words = $.grep(values[id] || [], function (w) { return !!w; }); if (!words.length) return ""; var lang = values.lang; var section = "\n==== " + header + " ====\n"; if (words.length === 1) { // Single word — keep the simple inline template. return section + "* {{" + templateName + "|" + lang + "|" + words[0] + "}}\n"; } // Multiple words — use {{kol3}} with one positional param per word. var params = "cure=" + header + "\n" + $.map(words, function (w) { return "|" + w; }).join("\n"); return section + "{{kol3|" + lang + "|" + params + "\n}}\n"; } }; } var steps = { lang: { id: "lang", required: true, name: "ziman", question_fmt: '"' + pageName + '" bi çi zimanî ye?', question_br: true, // Populated from [[MediaWiki:Gadget-start.js/data.json]] (langChoices). choices: [], output: function (values) { return "== {{ziman|" + values.lang + "}} ==\n"; } }, pron: { id: "pron", name: "bilêvkirin", question_fmt: '"' + pageName + '" çawa tê telafûzkirin?', // pronTpls populated from data.json pronTpls: [], visible: function (values) { if (!values.lang) return false; // In addLangMode, only skip pron when this langcode's section // already exists in the page — if it's a new language, show it. if (addLangMode) { var existing = $("#wpTextbox1").val() || ""; var header = "== {{ziman|" + values.lang + "}} =="; return existing.indexOf(header) === -1; } return true; }, /** Fills (or refills) the insert-dropdown from the current pronTpls array, filtering by language. */ refreshTplSelect: function () { var sel = $("#wiktku-start-pron .wiktku-tpl-insert-select"); if (!sel.length) return; var lang = getValues().lang || ""; sel.find("option[value!='']").remove(); $.each(steps.pron.pronTpls, function (_, tpl) { // Filter: if tpl.langs exists, only show if lang is in that list; otherwise show always var allowed = !tpl.langs || tpl.langs.indexOf(lang) !== -1; if (allowed) { sel.append($("<option></option>") .val(tpl.snippet) .text(tpl.name + " — " + tpl.desc) .attr("data-nolang", tpl.noLang ? "1" : "")); } }); // Notify Chosen that the option list has changed (no-op on mobile). if (!isMobile) sel.trigger("chosen:updated"); }, build: function (stepDiv) { if (stepDiv.find(".wiktku-pron-wrap").length) return null; var wrap = $("<div class='wiktku-pron-wrap'></div>"); var ta = $("<textarea></textarea>") .attr("name", "wiktku-pron-" + $.now()) .attr("class", "wiktku-start-step-field wiktku-pron-text") .attr("rows", 4) .attr("placeholder", "Nimûne: {{IPA|ku|/pɛɪ̯n/}} yan {{kîte|ku|he|ce|ki|rin}}"); // Template insert dropdown — filtered by language. var sel = $("<select class='wiktku-tpl-insert-select'></select>"); sel.append($("<option value=''>— şablonek lê zêde bike —</option>")); var lang = getValues().lang || ""; $.each(steps.pron.pronTpls, function (_, tpl) { // Filter: if tpl.langs exists, only show if lang is in that list; otherwise show always var allowed = !tpl.langs || tpl.langs.indexOf(lang) !== -1; if (allowed) { sel.append($("<option></option>") .val(tpl.snippet) .text(tpl.name + " — " + tpl.desc) .attr("data-nolang", tpl.noLang ? "1" : "")); } }); sel.on("change", function () { var snippet = $(this).val(); if (!snippet) return; var lang = getValues().lang || ""; // Check if the selected option has noLang flag var selectedOption = sel.find("option:selected"); var hasNoLang = selectedOption.attr("data-nolang") === "1"; if (!hasNoLang) { snippet = snippet.replace(/CODE/g, lang).replace(/SOURCELANG/g, "?"); } insertAtCursor(ta[0], snippet); $(this).val(""); ta.focus(); }); wrap.append(sel).append($("<br>")).append(ta); stepDiv.append(wrap); return ta; }, output: function () { var text = $.trim($("#wiktku-start-pron .wiktku-pron-text").val()); if (!text) return ""; var lines = text.split("\n"); var out = $.map(lines, function (line) { line = $.trim(line); if (!line) return undefined; return line.charAt(0) === "*" ? line : "* " + line; }).join("\n"); return "\n=== Bilêvkirin ===\n" + out + "\n"; } }, pos: { id: "pos", required: true, name: "Cureyê rêzimanî", question_fmt: 'Cureyê rêzimanî yê "' + pageName + '" çi ye?', visible: function (values) { return values.lang; }, question_br: true, // Populated from [[MediaWiki:Gadget-start.js/data.json]] (posChoices). choices: [], output: function (values) { var pos = values.pos || ""; var cinsiyet = values.cinsiyet || ""; // from the cinsiyet step var lekTur = values.lektur || ""; // from the lêker transitivity step var capitalizedPos = capitalize(pos); var outputString = "\n=== " + capitalizedPos + " ===\n"; // Add ku-tewîn-nav for single-word navdêr/serenav with known gender. if (!pageName.includes(" ") && cinsiyet && GENDER_BASE_LABELS[cinsiyet] && (pos === "navdêr" || pos === "serenav") && values.lang === "ku") { outputString += "{{ku-tewîn-nav|" + pageName + "|" + GENDER_BASE_LABELS[cinsiyet]; if (pos === "serenav") outputString += "|y"; outputString += "}}\n"; } outputString += "{{" + pos + "|" + values.lang; if (pos === "navdêr" || pos === "serenav") { if (cinsiyet) { outputString += "|c=" + cinsiyet; } else if (values.lang === "ku") { // Unknown gender — prompt editor to fill it in. outputString += "|c=?"; } } else if (/^lêker/.test(pos) && lekTur) { outputString += "|c=" + lekTur; } if (values.tr) { outputString += "|tr=" + values.tr; } outputString += "}}\n"; return outputString; } }, /** * cinsiyet (grammatical gender) — only shown for navdêr/serenav, û * tenê ger metadata ji bo zimanê hilbijartî lîsteyeke "g" (cinsiyet) * were dayîn. Opsiyonên vê gavê ne sabît in — ji metadata[values.lang].g * têne çêkirin, ji ber ku di hemû zimanan de cinsiyet tine. */ cinsiyet: { id: "cinsiyet", name: "cinsiyet", question_fmt: 'Cinsiyeta "' + pageName + '" çi ye?', question_br: true, visible: function (values) { var meta = metadata[values.lang]; return !!(values.lang && (values.pos === "navdêr" || values.pos === "serenav") && meta && meta.g && meta.g.length); }, build: function (stepDiv, values) { var select = stepDiv.find("select.wiktku-start-step-field"); if (!select.length) { select = $(mw.html.element("select", { "class": "wiktku-start-step-field", id: "wiktku-start-cinsiyet-field" })); stepDiv.append(select); } if (!values) return select; var meta = metadata[values.lang]; var codes = (meta && meta.g) || []; var prevVal = select.val(); var choices = $.map(codes, function (code) { return [[code, genderLabel(code)]]; }); populateMenus(select, choices); if ($.grep(choices, function (c) { return c[0] === prevVal; }).length) { select.val(prevVal); } if (!isMobile) select.trigger("chosen:updated"); return select; }, output: function () { return ""; } // consumed by pos.output }, /** * Lêker transitivity — only shown for any lêker variant. */ lektur: { id: "lektur", name: "Cureyê lêkerê (fiîlê)", question_fmt: "Cureyê lêkerê (fiîlê) çi ye?", question_br: true, visible: function (values) { return values.lang && values.pos && /^lêker/.test(values.pos); }, // Dictionary: value → display label. Add new types here. choices: [ ["gh", "gerguhêz"], ['x-gh', 'xwerû-gerguhêz'], ['p-gh', 'pêkhatî-gerguhêz'], ['h-gh', 'hevedudanî-gerguhêz'], ['b-gh', 'biwêjî-gerguhêz'], ["ngh", "negerguhêz"], ['x-ngh', 'xwerû-negerguhêz'], ['p-ngh', 'pêkhatî-negerguhêz'], ['h-ngh', 'hevedudanî-negerguhêz'], ['b-ngh', 'biwêjî-negerguhêz'] ], output: function () { return ""; } // consumed by pos.output }, tr: { id: "tr", name: "transkrîpsiyon", question_fmt: "Transkrîpsiyona kelîmeyê", multiple: false, narrow: true, visible: function (values) { return values.lang && values.pos && needsTransliteration(values.lang); } }, dfn: { id: "dfn", // required: true, ger mane tinebe [[Şablon:mane?]] bi kar bîne name: "Mane", question_fmt: "Maneya kelîmeyê binivîse. Mane otomatîk tê lînkkirin! Ji bo tercimeyan beşa 'Werger' bi kar bîne!", multiple: true, ordered: true, rows: 3, visible: function (values) { return values.lang && values.pos; }, example: function (values) { // posExamples loaded from [[MediaWiki:Gadget-start.js/data.json]]. var examples = steps.dfn.posExamples || {}; var full = values.pos || ""; return examples[full] || ""; }, /** * Builds one sense block (<li>) inside the ordered list. * Each block contains: * - a textarea for the definition * - an expandable nimûne list * - single-row sub-lists for formên alternatîv, hevmane, dijmane */ buildSenseBlock: function (stepDiv) { var block = $("<li class='wiktku-dfn-sense'></li>"); // — Mane textarea (declared first so the template handler can reference it) — var dfnArea = $("<textarea></textarea>") .attr("name", "wiktku-dfn-mane-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("class", "wiktku-start-step-field wiktku-dfn-mane") .attr("rows", 6) .attr("placeholder", "Mane…"); dfnArea.on("input", function () { steps.dfn.onDfnInput(stepDiv, block, this); }); // — Template selector (optional — replaces mane when chosen) — // Template definitions loaded from [[MediaWiki:Gadget-start.js/data.json]]. var tplDefs = steps.dfn.tplDefs || []; // Cache of all non-placeholder option elements — used by updateTplOptions // to remove/re-add options (the only approach compatible with Chosen.js). var _allTplOptions = []; var tplSelect = $(mw.html.element("select", { "class": "wiktku-dfn-tpl-select" })); tplSelect.append($("<option value=''>— yan jî şablonek hilbijêre —</option>")); $.each(tplDefs, function (_, tpl) { var opt = $("<option></option>") .val(tpl.name) .text(tpl.name) .attr("data-langs", tpl.langs ? tpl.langs.join(",") : "") .attr("data-nolang", tpl.noLang ? "1" : ""); tplSelect.append(opt); _allTplOptions.push(opt[0]); }); function updateTplOptions() { var lang = getValues().lang || ""; var currentVal = tplSelect.val(); var currentStillValid = false; // Detach all non-placeholder options, then re-attach only the visible ones. // This is the only approach that works correctly with both native <select> // and Chosen.js on desktop. tplSelect.find("option[value!='']").detach(); $.each(_allTplOptions, function (_, opt) { var allowed = $(opt).attr("data-langs"); var visible = !allowed || allowed.split(",").indexOf(lang) !== -1; if (visible) { tplSelect.append(opt); if ($(opt).val() === currentVal) currentStillValid = true; } }); if (!isMobile) tplSelect.trigger("chosen:updated"); if (currentVal && !currentStillValid) { tplSelect.val(""); dfnArea.show(); tplTitleInput.hide().val(""); } } // Store updater on the element so refresh() can call it for all blocks. tplSelect.data("updateOptions", updateTplOptions); var tplTitleInput = $("<input type='text'>") .addClass("wiktku-dfn-tpl-title wiktku-start-narrow") .attr("placeholder", "Navê rûpelê…") .hide(); // Grow the sense list when the title field of the last block gets content, // mirroring what onDfnInput does for the plain mane textarea. tplTitleInput.on("input", function () { steps.dfn.onDfnInput(stepDiv, block, this); }); /** * When a şablon sense is chosen, formên alternatîv/hevmane/dijmane/ * termên koordîne/jornav/jêrnav don't apply (there's no plain gloss * to hang them off), so hide those subgroups. Etîket, Nimûne and * Jêgirtin stay visible and still usable for a şablon sense. */ function updateFieldVisibility() { var isTpl = !!tplSelect.val(); $.each(HIDDEN_ON_TPL_GROUPS, function (_, cls) { block.find("." + cls + "-group").toggle(!isTpl); }); } // Store on the block so restoreDfn() can re-sync visibility // after programmatically setting tplSelect's value. block.data("updateFieldVisibility", updateFieldVisibility); tplSelect.on("change", function () { var chosen = $(this).val(); if (chosen) { dfnArea.hide(); tplTitleInput.show().focus(); } else { dfnArea.show(); tplTitleInput.hide().val(""); } updateFieldVisibility(); // Re-run refresh so the Werger step visibility updates. refresh(); }); var tplRow = $("<div></div>").addClass("wiktku-dfn-tpl-row") .append(tplSelect).append(" ").append(tplTitleInput); block.append(tplRow); block.append(dfnArea); // Apply lang filter on initial build. updateTplOptions(); // — Sub-field groups — // All groups are always visible with a placeholder textarea. // Nimûne is last in the DOM and last in the output. var allGroups = [ { cls: "wiktku-dfn-etiket", label: "Etîket", rows: 1, narrow: true, izah: "xisûsen, Mêrdîn, anatomî, Badînî" }, { cls: "wiktku-dfn-alternativ", label: "Formên alternatîv", rows: 1, narrow: true, izah: "Varyantên vê kelîmeyê" }, { cls: "wiktku-dfn-hevmane", label: "Hevmane", rows: 1, narrow: true, izah: "Spehî hevmaneya Bedew e." }, { cls: "wiktku-dfn-dijmane", label: "Dijmane", rows: 1, narrow: true, izah: "Zengîn dijmaneya feqîr e." }, { cls: "wiktku-dfn-koordine", label: "Termên koordîne", rows: 1, narrow: true, izah: "Pisîk û kûçik termên koordîne ne çunkî Jornavên wan gelek in" }, { cls: "wiktku-dfn-jornav", label: "Jornav", rows: 1, narrow: true, izah: "Heywan jornavê guhandar e" }, { cls: "wiktku-dfn-jernav", label: "Jêrnav", rows: 1, narrow: true, izah: "Guhandar jêrnavê heywan e" }, { cls: "wiktku-dfn-nimune", label: "Nimûne", rows: 2, narrow: false } ]; $.each(allGroups, function (_, g) { var groupDiv = $("<div></div>").addClass("wiktku-dfn-subgroup " + g.cls + "-group"); function buildNimuneLi() { var lang = getValues().lang || ""; var li = $("<li></li>").addClass("wiktku-dfn-nimune-li"); var mainTa = $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-text-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", g.rows) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-text") .attr("placeholder", "Nimûneya emilandina kelîmeyê tu bi xwe binivîse…"); mainTa.on("input", function () { var val = $.trim($(this).val()); var isLast = li.is(list.children("li:last-child")); if (val && isLast) { list.append(buildNimuneLi()); } }); li.append(mainTa); var subWrap = $("<div></div>").addClass("wiktku-dfn-nimune-sub"); if (needsTransliteration(lang)) { subWrap.append( $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-tr-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 5) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-tr") .attr("placeholder", "Transkrîpsiyona bi alfabeya latînî") ); } if (lang && lang !== "ku") { subWrap.append( $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-t-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 5) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-t") .attr("placeholder", "Tercimeya kurmancî") ); } if (subWrap.children().length) li.append(subWrap); return li; } if (g.cls === "wiktku-dfn-nimune") { // Nimûne — compound widget with tr/t sub-fields. var lbl = $("<span></span>").addClass("wiktku-dfn-sublabel").text(g.label + ": "); var list = $("<ol></ol>").addClass("wiktku-dfn-sublist " + g.cls + "-list"); groupDiv.data("buildNimuneLi", buildNimuneLi); list.append(buildNimuneLi()); groupDiv.append(lbl).append(list); block.append(groupDiv); } else { // Regular always-visible group — label + growing textarea list. var lbl = $("<span></span>").addClass("wiktku-dfn-sublabel").text(g.label + ": " + g.izah); var list = $("<ol></ol>").addClass("wiktku-dfn-sublist " + g.cls + "-list"); var firstInput = $("<textarea></textarea>") .attr("name", g.cls + "-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", g.rows) .attr("class", "wiktku-dfn-subfield" + (g.narrow ? " wiktku-start-narrow" : "")) .attr("placeholder", g.label + "…"); firstInput.on("input", function () { steps.dfn.onSubInput(list, this, g.rows, g.narrow); }); list.append($("<li></li>").append(firstInput)); groupDiv.append(lbl).append(list); block.append(groupDiv); } }); // — Jêder (quote / citation) group — a growing list, sibling to Nimûne — // Structured the same way as Nimûne (ol.wiktku-dfn-sublist > li) so it // lines up at the same indentation, and so that typing into the last // citation's Jêgirtin box automatically opens a fresh empty one below it. (function () { var jederGroupDiv = $("<div></div>").addClass("wiktku-dfn-subgroup wiktku-dfn-jeder-group"); var jederLbl = $("<span></span>").addClass("wiktku-dfn-sublabel").text("Jêgirtin: "); var jederList = $("<ol></ol>").addClass("wiktku-dfn-sublist wiktku-dfn-jeder-list"); function buildJederLi() { var lang = getValues().lang || ""; var li = $("<li></li>").addClass("wiktku-dfn-jeder-li"); var dragHandle = $("<span></span>") .addClass("wiktku-jeder-drag-handle") .attr("title", "Bişkûne û bikişîne da ku rêzê biguhezîne"); // Quote text textarea var quoteTa = $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-quote-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 2) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-quote") .attr("placeholder", "Nimûneya emilandinê ji kitêb an çavkaniyeke din binivîse"); quoteTa.on("input", function () { var val = $.trim($(this).val()); var isLast = li.is(jederList.children("li:last-child")); if (val && isLast) { jederList.append(buildJederLi()); } }); li.append(dragHandle).append(quoteTa); // tr/t sub-fields for the quote — shown as needed for the language. var quoteSubWrap = $("<div></div>").addClass("wiktku-dfn-quote-sub"); if (needsTransliteration(lang)) { quoteSubWrap.append( $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-quote-tr-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 2) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-quote-tr") .attr("placeholder", "Transkrîpsiyona jêgirtinê…") ); } if (lang && lang !== "ku") { quoteSubWrap.append( $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-quote-t-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 2) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-quote-t") .attr("placeholder", "Tercimeya jêgirtinê bi kurmancî") ); } if (quoteSubWrap.children().length) li.append(quoteSubWrap); // Citoid auto-fill: fetch citation data from a URL, DOI or ISBN and // prefill the source şablon + fields below (see Gadget-citoid-helper.js). var citoidWrap = $("<div></div>").addClass("wiktku-dfn-quote-citoid"); var citoidInput = $("<input type='text'>") .addClass("wiktku-dfn-quote-citoid-input wiktku-start-narrow") .attr("placeholder", "URL, DOI an ISBN binivîse ku otomatîk were tijekirin…"); var citoidBtn = new OO.ui.ButtonWidget({ label: "Bi Citoid bîne", classes: [ "wiktku-dfn-quote-citoid-btn" ] }); var citoidStatus = $("<span></span>").addClass("wiktku-dfn-quote-citoid-status"); /** * Fetches citation data from Citoid and applies it to this * citation's şablon selector + fields. Mirrors the logic in * Form.prototype._fillFromCitoid (Gadget-wikt.add-examples.js): * - only (re)selects the şablon when it actually differs from * what's already chosen, so a repeat fetch doesn't wipe out * a template the user already picked; * - only fills fields that are currently empty, so it never * overwrites something the user typed by hand; * - falls back to the freeform "bi destê xwe binivîsim" source * only when nothing was typed there yet. */ function runCitoidFetch() { var query = $.trim(citoidInput.val()); if (!query) { mw.notify("Ji kerema xwe re pêşî URL, DOI an ISBNyekê binivîse."); return; } citoidBtn.setDisabled(true); citoidStatus.text("Tê anîn…"); wikt.citoidHelper.ensure().then(function () { return wikt.citoid.fetchJederFields(query); }).then(function (result) { var jederKey = result.jederKey; var hasTpl = !!jederKey && srcSel.find("option[value='" + jederKey + "']").length > 0; var targetVal = hasTpl ? jederKey : "__manual__"; // Only (re)select — and thus rebuild — the field rows if // we're switching to a different şablon than what's // already chosen, so a second fetch doesn't clear fields // the user already filled in by hand. if (srcSel.val() !== targetVal) { srcSel.val(targetVal).trigger("change"); srcSel.trigger("chosen:updated"); } if (hasTpl) { // Tenê qadên vala tijî bike. $.each(result.fields, function (key, val) { var input = srcFields.find("[data-field-key='" + key + "']"); if (input.length && !$.trim(input.val())) { input.val(val); } }); } else { // Şablonek nehat naskirin ji bo vê itemType — rêzikeke // çavkaniyê ya bi destan a ji qadên Citoid tê çêkirin, // lê tenê ger qada destan vala be. var manualField = srcFields.find(".wiktku-dfn-quote-src-manual"); if (!$.trim(manualField.val())) { var parts = []; $.each(["nivîskar", "sernav", "websîte", "kovar", "weşanxane", "sal", "url"], function (_, k) { if (result.fields[k]) parts.push(result.fields[k]); }); manualField.val(parts.join(", ")); } } citoidStatus.text(""); }, function (errorMsg) { citoidStatus.text(typeof errorMsg === "string" ? errorMsg : "Nehat dîtin. Kontrol bike ka URL/DOI/ISBN rast e."); }).always(function () { citoidBtn.setDisabled(false); }); } citoidBtn.on("click", runCitoidFetch); citoidInput.on("keydown", function (e) { if (e.which === 13) { // Enter e.preventDefault(); runCitoidFetch(); } }); citoidWrap.append(citoidInput).append(citoidBtn.$element).append(citoidStatus); // Source template selector, specific to this citation. var srcSel = $("<select></select>").addClass("wiktku-dfn-quote-src-sel"); srcSel.append($("<option value=''>— Çavkaniyê hilbijêre —</option>")); srcSel.append($("<option></option>").val("__manual__").text("Bi destê xwe binivîsim")); var jederDefs = steps.dfn.jederDefs || {}; $.each(jederDefs, function (tplName, def) { srcSel.append($("<option></option>").val(tplName).text(def.label)); }); // Dynamic source fields container. var srcFields = $("<div></div>").addClass("wiktku-dfn-quote-src-fields"); srcSel.on("change", function () { srcFields.empty(); var chosen = $(this).val(); if (!chosen) return; if (chosen === "__manual__") { // Freeform source, written by the user — becomes the 2nd // positional param of {{jêder|lang|…}} instead of çavkanî?. srcFields.append( $("<textarea></textarea>") .attr("rows", 4) .addClass("wiktku-dfn-subfield wiktku-dfn-quote-src-manual") .attr("placeholder", "Çavkaniyê bi destê xwe binivîse…") ); return; } var def = (steps.dfn.jederDefs || {})[chosen]; if (!def) return; $.each(def.fields, function (_, f) { var row = $("<div></div>").addClass("wiktku-dfn-quote-src-row"); var fieldLbl = $("<label></label>").text(f.label + ": "); var inp = $("<textarea></textarea>") .attr("rows", 2) .addClass("wiktku-dfn-quote-src-input wiktku-start-narrow") .attr("data-field-key", f.key) .attr("placeholder", f.label + "…"); row.append(fieldLbl).append(inp); srcFields.append(row); }); }); li.append(citoidWrap).append(srcSel).append(srcFields); return li; } jederGroupDiv.data("buildJederLi", buildJederLi); jederList.append(buildJederLi()); // Make citation rows sortable (drag to reorder). // The last row is always the empty trailing row — cancel its drag. mw.loader.using("jquery.ui.sortable", function () { jederList.sortable({ handle: ".wiktku-jeder-drag-handle", axis: "y", items: "li:not(:last-child)", tolerance: "pointer" }); }); jederGroupDiv.append(jederLbl).append(jederList); block.append(jederGroupDiv); }()); // Apply the initial hide/show state for the sub-groups (matches // tplSelect's starting value, which is normally empty). updateFieldVisibility(); return block; }, /** Grows the sense list when the last mane textarea gets content. */ onDfnInput: function (stepDiv, block, textarea) { var val = $.trim($(textarea).val()); var list = stepDiv.find("ol.wiktku-dfn-list"); var isLast = block.is(list.children("li:last-child")); if (val && isLast) { var newBlock = steps.dfn.buildSenseBlock(stepDiv); list.append(newBlock); // Apply Chosen to the new block's template selector on desktop. if (!isMobile) newBlock.find("select.wiktku-dfn-tpl-select").chosen(chosenOptions); } refresh(); }, /** Grows a sub-list (nimûne/formên alternatîv/hevmane/dijmane/termên koordîne) on input. */ onSubInput: function (list, input, rows, narrow) { var val = $.trim($(input).val()); var item = $(input).parent(); var isLast = item.is(list.children("li:last-child")); if (val && isLast) { var next = $("<textarea></textarea>") .attr("name", "wiktku-dfn-sub-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", rows) .attr("class", "wiktku-dfn-subfield" + (narrow ? " wiktku-start-narrow" : "")); next.on("input", function () { steps.dfn.onSubInput(list, this, rows, narrow); }); list.append($("<li></li>").append(next)); } }, // Populated from [[MediaWiki:Gadget-start.js/data.json]] (tplDefs, posExamples, jederDefs). tplDefs: [], posExamples: {}, jederDefs: {}, build: function (stepDiv) { if (stepDiv.find("ol.wiktku-dfn-list").length) return null; var list = $("<ol class='wiktku-dfn-list'></ol>"); list.append(steps.dfn.buildSenseBlock(stepDiv)); stepDiv.append(list); return null; }, /** Reads all sense blocks from the DOM and returns an array of sense objects. */ getSenses: function (stepDiv) { var senses = []; stepDiv.find("li.wiktku-dfn-sense").each(function () { var block = $(this); var tplSel = block.find("select.wiktku-dfn-tpl-select"); var tpl = tplSel.val() || ""; // noLang: template already encodes the language — don't add |lang| param. var tplNoLang = tpl ? tplSel.find("option[value='" + tpl + "']").attr("data-nolang") === "1" : false; var tplTitle = $.trim(block.find("input.wiktku-dfn-tpl-title").val()); var mane = $.trim(block.find("textarea.wiktku-dfn-mane").val()); var etiket = (function () { var vals = []; block.find(".wiktku-dfn-etiket-list textarea").each(function () { var v = $.trim($(this).val()); if (v) vals.push(v); }); return vals; }()); function readList(cls) { var vals = []; block.find("." + cls + "-list textarea").each(function () { var v = $.trim($(this).val()); if (v) vals.push(v); }); return vals; } // Nimûne items are compound: { text, tr?, t? } function readNimuneList() { var items = []; block.find(".wiktku-dfn-nimune-list li.wiktku-dfn-nimune-li").each(function () { var text = $.trim($(this).find(".wiktku-dfn-nimune-text").val()); if (!text) return; var obj = { text: text }; var tr = $.trim($(this).find(".wiktku-dfn-nimune-tr").val()); var t = $.trim($(this).find(".wiktku-dfn-nimune-t").val()); if (tr) obj.tr = tr; if (t) obj.t = t; items.push(obj); }); return items; } // Jêder is a growing list of citations, one per li — mirrors readNimuneList(). function readJederList() { var items = []; block.find(".wiktku-dfn-jeder-list li.wiktku-dfn-jeder-li").each(function () { var li = $(this); var quote = $.trim(li.find(".wiktku-dfn-nimune-quote").val()); if (!quote) return; var obj = { quote: quote }; var qtr = $.trim(li.find(".wiktku-dfn-nimune-quote-tr").val()); var qt = $.trim(li.find(".wiktku-dfn-nimune-quote-t").val()); if (qtr) obj.quoteTr = qtr; if (qt) obj.quoteT = qt; var tplName = li.find(".wiktku-dfn-quote-src-sel").val(); if (tplName === "__manual__") { var manual = $.trim(li.find(".wiktku-dfn-quote-src-manual").val()); if (manual) obj.jederManual = manual; } else if (tplName) { obj.jederTpl = tplName; var fields = {}; li.find(".wiktku-dfn-quote-src-input").each(function () { var k = $(this).attr("data-field-key"); var v = $.trim($(this).val()); if (k && v) fields[k] = v; }); obj.jêderFields = fields; } items.push(obj); }); return items; } senses.push({ tpl: tpl, tplNoLang: tplNoLang, tplTitle: tplTitle, mane: mane, etiket: etiket, nimune: readNimuneList(), jeder: readJederList(), alternativ: readList("wiktku-dfn-alternativ"), hevmane: readList("wiktku-dfn-hevmane"), dijmane: readList("wiktku-dfn-dijmane"), koordine: readList("wiktku-dfn-koordine"), jornav: readList("wiktku-dfn-jornav"), jernav: readList("wiktku-dfn-jernav") }); }); return senses; }, getOutput: function (values, callback) { var stepDiv = $("#wiktku-start-dfn"); var senses = steps.dfn.getSenses(stepDiv); var lang = values.lang; // A sense counts as "filled" if it has a mane, a chosen template + title, // or any other content (etîket/hevmane/nimûne/jêder…) worth keeping. var hasMane = senses.some(function (s) { return s.mane !== "" || (s.tpl && s.tplTitle) || senseHasExtraContent(s); }); // True only when at least one sense has a regular mane (needs linkify). var hasRegularMane = senses.some(function (s) { return !s.tpl && s.mane !== ""; }); // nimûne and jêder lines must never pass through linkify — only // the plain mane text should be linkified. We build two parallel // arrays: defLines (sent to linkify) and citeLines (kept aside). // Each entry in citeLines corresponds 1-to-1 with a defLines entry; // a template token {{wiktku-cite-N}} is embedded in defLines so // that after linkify runs we know exactly where to splice them back. // Template-call syntax is guaranteed safe: linkifiers leave {{ }} // tokens completely untouched. var defLines = []; // one entry per kept sense (goes to linkify) var citeLines = []; // parallel — nimûne+jêder for that same sense $.each(senses, function (_, sense) { // — Template sense (e.g. {{guharto|ku|somepage}}) — if (sense.tpl) { if (!sense.tplTitle) return; // skip empty template senses var tplLabelTpl = ""; if (sense.etiket && sense.etiket.length) { var tplLabelParts = sense.etiket.map(function (part) { return $.trim(part); }).filter(function (part) { return part !== ""; }); if (tplLabelParts.length) { tplLabelTpl = " {{e|" + lang + "|" + tplLabelParts.join("|") + "}} "; } } var tplCall = sense.tplNoLang ? "{{" + sense.tpl + "|" + sense.tplTitle + "}}" : "{{" + sense.tpl + "|" + lang + "|" + sense.tplTitle + "}}"; var tplHasJeder = sense.jeder && $.grep(sense.jeder, function (j) { return j && j.quote; }).length > 0; var idx = defLines.length; var cite = formatNimune(sense.nimune, lang, tplHasJeder) + formatJeder(sense.jeder, lang); defLines.push("#" + (tplLabelTpl ? tplLabelTpl : " ") + tplCall + (cite ? "{{wiktku-cite-" + idx + "}}" : "")); citeLines.push(cite); return; } // — Normal mane sense — var dfn = sense.mane; if (!dfn && !senseHasExtraContent(sense)) return; // truly empty if (dfn) { dfn = stripWikilinks(dfn); if (dfn[0] !== dfn[0].toUpperCase()) dfn = capitalize(dfn); if (!dfn.match(/[.…?!)\]]$/)) dfn += "."; } else { dfn = "{{mane?|" + lang + "}}"; } var labelTpl = ""; if (sense.etiket && sense.etiket.length) { var labelParts = sense.etiket.map(function (part) { return $.trim(part); }).filter(function (part) { return part !== ""; }); if (labelParts.length) { labelTpl = " {{e|" + lang + "|" + labelParts.join("|") + "}} "; } } var out = "#" + (labelTpl ? labelTpl : " ") + dfn; function wordLine(tpl, words) { if (!words.length) return ""; return "\n#: {{" + tpl + "|" + lang + "|" + words.join("|") + "}}"; } out += wordLine("alt-r", sense.alternativ); out += wordLine("hevmane", sense.hevmane); out += wordLine("dijmane", sense.dijmane); out += wordLine("koordîne", sense.koordine); out += wordLine("jornav", sense.jornav); out += wordLine("jêrnav", sense.jernav); var hasJeder = sense.jeder && $.grep(sense.jeder, function (j) { return j && j.quote; }).length > 0; var cite = formatNimune(sense.nimune, lang, hasJeder) + formatJeder(sense.jeder, lang); var idx = defLines.length; defLines.push(out + (cite ? "{{wiktku-cite-" + idx + "}}" : "")); citeLines.push(cite); }); // Splice citeLines back into a linkified string, replacing each // {{wiktku-cite-N}} token with its stored nimûne/jêder block. function restoreCites(t) { return t.replace(/\{\{wiktku-cite-(\d+)\}\}/g, function (_, n) { return citeLines[parseInt(n, 10)] || ""; }); } var text = defLines.join("\n") + "\n"; if (!hasMane) { // No definitions entered — emit {{mane?}} with bênimûne. text = "# {{mane?|" + lang + "}}\n#* {{bênimûne|" + lang + "}}\n"; callback(text); return; } if (!hasRegularMane) { // All filled senses are template senses — no linkify needed. callback(restoreCites(text)); return; } var didTryToLoad = function () { if (typeof $.wiktviLinkify === "function") { $.wiktviLinkify(text, function (linked) { callback(restoreCites(linked)); }); } else { callback(restoreCites(text)); } }; mw.loader.using("ext.gadget.linkify", didTryToLoad, didTryToLoad); } }, je: makeWordListStep("je", "jê", "Kelîmeyên jê çêbûyî binivîse", "Jê", "g"), tekildar: makeWordListStep("tekildar", "têkildar", "Kelîmeyên ji aliyê etîmolojiyê ve têkildarî vê kelîmeyê binivîse", "Têkildar", "g"), binereherwiha: makeWordListStep("binereherwiha", "binêre herwiha", "Kelîmeyên din ên eleqedar binivîse", "Binêre herwiha", "g"), etym: { id: "etym", name: "etîmolojî", question_fmt: "Etîmolojiya kelîmeyê binivîse", // etymTpls populated from data.json etymTpls: [], visible: function (values) { return values.lang && values.pos; }, /** Fills (or refills) the insert-dropdown from the current etymTpls array. */ refreshTplSelect: function () { var sel = $("#wiktku-start-etym .wiktku-tpl-insert-select"); if (!sel.length) return; sel.find("option[value!='']").remove(); $.each(steps.etym.etymTpls, function (_, tpl) { sel.append($("<option></option>").val(tpl.snippet).text(tpl.name + " — " + tpl.desc)); }); // Notify Chosen that the option list has changed (no-op on mobile). if (!isMobile) sel.trigger("chosen:updated"); }, build: function (stepDiv) { if (stepDiv.find(".wiktku-etym-wrap").length) return null; var wrap = $("<div class='wiktku-etym-wrap'></div>"); var ta = $("<textarea></textarea>") .attr("name", "wiktku-etym-" + $.now()) .attr("class", "wiktku-start-step-field wiktku-etym-text") .attr("rows", 4) .attr("placeholder", "Nimûne: Ji {{ji|en|ku|apple}}. yan rasterast binivîse…"); // Template insert dropdown — options also refreshed after data.json loads. var sel = $("<select class='wiktku-tpl-insert-select'></select>"); sel.append($("<option value=''>— şablonek lê zêde bike —</option>")); $.each(steps.etym.etymTpls, function (_, tpl) { sel.append($("<option></option>").val(tpl.snippet).text(tpl.name + " — " + tpl.desc)); }); sel.on("change", function () { var snippet = $(this).val(); if (!snippet) return; var lang = getValues().lang || ""; snippet = snippet.replace(/CODE/g, lang).replace(/SOURCELANG/g, "?"); insertAtCursor(ta[0], snippet); $(this).val(""); ta.focus(); }); wrap.append(sel).append($("<br>")).append(ta); stepDiv.append(wrap); return ta; }, output: function (values) { var text = $.trim($("#wiktku-start-etym .wiktku-etym-text").val()); if (text) { return "\n==== Etîmolojî ====\n" + text + "\n"; } // No etymology entered — emit {{ji?|lang}} as a placeholder, // but only when the entry has at least one regular (non-şablon) // sense with content — either real mane text, or an empty mane // with other fields filled in (which dfn.getOutput() renders as // {{mane?|lang}} with those fields attached). A şablon sense // like {{guharto|…}} never counts, filled in or not. var dfnSenses = steps.dfn.getSenses($("#wiktku-start-dfn")); var hasRegularMane = dfnSenses.some(function (s) { return !s.tpl && (s.mane !== "" || senseHasExtraContent(s)); }); if (!hasRegularMane) return ""; return "\n==== Etîmolojî ====\n{{ji?|" + values.lang + "}}\n"; } }, dunde: { id: "dunde", name: "dûnde", question_fmt: "Eger ev kelîme ji vî zimanî ketibe zimanekî din, vî zimanî û kelîmeya wî binivîse", visible: function (values) { return !!values.pos; }, disabledKeys: { "navz": true}, /** * Builds one row: a language dropdown + a growing list of word * inputs. When the dropdown gets a value the next empty row is * appended automatically. Mirrors steps.trans's row widget, but * flat (one shared list — dûnde isn't tied to individual senses). */ buildRow: function (stepDiv) { var row = $("<li class='wiktku-dunde-row wiktku-lang-row'></li>"); // Language selector — chosen is applied after insertion into DOM. var langSel = $(mw.html.element("select", { "class": "wiktku-start-step-keyfield wiktku-start-narrow" })); langSel.attr("data-placeholder", "Zimanekî lê bigere"); populateMenus(langSel, steps.dunde.keys || [], steps.dunde.disabledKeys); // When a language is chosen, ensure a next empty row exists. langSel.on("change", function () { steps.dunde.onLangChange(stepDiv, row); }); // Word list for this language. var wordList = $("<ul class='wiktku-dunde-words wiktku-lang-row-words'></ul>"); var firstWord = steps.dunde.makeWordInput(); wordList.append($("<li></li>").append(firstWord)); if (isMobile) { row.append(wrapNativeSelect(langSel)).append(wordList); } else { row.append(langSel).append(wordList); } return row; }, makeWordInput: function () { var input = $("<textarea></textarea>") .attr("name", "wiktku-dunde-word-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 1) .attr("class", "wiktku-dfn-subfield wiktku-start-narrow") .attr("placeholder", "Kelîme…"); input.on("input", function () { var list = $(this).closest("ul.wiktku-dunde-words"); var item = $(this).parent(); var val = $.trim($(this).val()); if (val && item.is(list.children("li:last-child"))) { var next = steps.dunde.makeWordInput(); list.append($("<li></li>").append(next)); } }); return input; }, onLangChange: function (stepDiv, row) { var list = stepDiv.find("ul.wiktku-dunde-list"); var isLast = row.is(list.children("li.wiktku-dunde-row:last-child")); if (isLast) { var newRow = steps.dunde.buildRow(stepDiv); list.append(newRow); // Init chosen after the new row is in the DOM (desktop only). if (!isMobile) newRow.find("select").chosen(chosenOptions); } // Keep disabled keys in sync across all lang selectors. steps.dunde.syncDisabledKeys(stepDiv); }, /** Disables already-selected languages in all other dropdowns. */ syncDisabledKeys: function (stepDiv) { var taken = $.extend({}, steps.dunde.disabledKeys); stepDiv.find("li.wiktku-dunde-row select").each(function () { var v = $(this).val(); if (v) taken[v] = true; }); stepDiv.find("li.wiktku-dunde-row select").each(function () { var self = $(this); var own = self.val(); self.find("option").each(function () { var code = $(this).val(); if (!code) return; $(this).prop("disabled", taken[code] && code !== own); }); self.trigger("chosen:updated"); }); }, build: function (stepDiv) { if (stepDiv.find("ul.wiktku-dunde-list").length) return null; var list = $("<ul class='wiktku-dunde-list wiktku-lang-row-list'></ul>"); list.append(steps.dunde.buildRow(stepDiv)); stepDiv.append(list); // Init chosen after the select is in the DOM (desktop only). if (!isMobile) list.find("select").chosen(chosenOptions); return null; }, /** Reads all [langcode, words[]] rows from the DOM. */ getRows: function (stepDiv) { var result = []; stepDiv.find("li.wiktku-dunde-row").each(function () { var lang = $(this).find("select").val(); if (!lang) return; var words = []; $(this).find("ul.wiktku-dunde-words textarea").each(function () { var v = $.trim($(this).val()); if (v) words.push(v); }); if (words.length) result.push([lang, words]); }); return result; }, output: function () { var stepDiv = $("#wiktku-start-dunde"); var rows = steps.dunde.getRows(stepDiv); if (!rows.length) return ""; var lines = $.map(rows, function (row) { var lang = row[0], words = row[1]; return "* {{dû|" + lang + "|" + words.join("|") + "}}"; }); return "\n==== Dûnde ====\n" + lines.join("\n") + "\n"; } }, zarava: { id: "zarava", name: "bi zaravayên din", visible: function (values) { return steps.trans.visible(values); }, disabledKeys: { "navz": true }, buildRow: function (group) { var row = $("<li class='wiktku-zarava-row wiktku-lang-row'></li>"); var langSel = $(mw.html.element("select", { "class": "wiktku-start-step-keyfield wiktku-start-narrow" })); populateMenus(langSel, steps.zarava.keys || [], steps.zarava.disabledKeys); langSel.on("change", function () { steps.zarava.onLangChange(group, row); }); var wordList = $("<ul class='wiktku-zarava-words wiktku-lang-row-words'></ul>"); var firstWord = steps.zarava.makeWordInput(); wordList.append($("<li></li>").append(firstWord)); row.append(langSel).append(wordList); return row; }, makeWordInput: function () { var input = $("<textarea></textarea>") .attr("name", "wiktku-zarava-word-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 1) .attr("class", "wiktku-dfn-subfield wiktku-start-narrow") .attr("placeholder", "Tercime…"); input.on("input", function () { var list = $(this).closest("ul.wiktku-zarava-words"); var item = $(this).parent(); var val = $.trim($(this).val()); if (val && item.is(list.children("li:last-child"))) { var next = steps.zarava.makeWordInput(); list.append($("<li></li>").append(next)); } }); return input; }, onLangChange: function (group, row) { var list = group.find("ul.wiktku-zarava-list"); var isLast = row.is(list.children("li.wiktku-zarava-row:last-child")); if (isLast) { var newRow = steps.zarava.buildRow(group); list.append(newRow); } steps.zarava.syncDisabledKeys(group); }, /** Disables already-selected dialects in all other dropdowns within one group. */ syncDisabledKeys: function (group) { var taken = $.extend({}, steps.zarava.disabledKeys); group.find("li.wiktku-zarava-row select").each(function () { var v = $(this).val(); if (v) taken[v] = true; }); group.find("li.wiktku-zarava-row select").each(function () { var self = $(this); var own = self.val(); self.find("option").each(function () { var code = $(this).val(); if (!code) return; $(this).prop("disabled", taken[code] && code !== own); }); }); }, /** Builds (or fetches) the .wiktku-zarava-group for one gloss. */ buildGroup: function (stepDiv, gi) { var group = $("<div class='wiktku-zarava-group'></div>").attr("data-gloss-pos", gi); var list = $("<ul class='wiktku-zarava-list wiktku-lang-row-list'></ul>"); list.append(steps.zarava.buildRow(group)); group.append(list); stepDiv.append(group); return group; }, /** Syncs one .wiktku-zarava-group per current gloss (same logic as steps.trans.build). */ build: function (stepDiv) { var glosses = steps.trans.glossList(); if (!glosses.length) { stepDiv.find(".wiktku-zarava-group").remove(); return null; } var existingGroups = stepDiv.find(".wiktku-zarava-group"); if (existingGroups.length > glosses.length) { existingGroups.slice(glosses.length).remove(); } $.each(glosses, function (gi, gloss) { var group = stepDiv.find(".wiktku-zarava-group[data-gloss-pos='" + gi + "']"); if (!group.length) group = steps.zarava.buildGroup(stepDiv, gi); var label = group.find(".wiktku-zarava-group-label"); if (glosses.length > 1) { if (!label.length) { label = $("<div class='wiktku-zarava-group-label'></div>"); group.prepend(label); } label.text(gloss.index + " " + gloss.text); } else if (label.length) { label.remove(); } }); return null; }, /** Reads the dialect rows for a single gloss group. */ getGroupTranslations: function (group) { var result = []; group.find("li.wiktku-zarava-row").each(function () { var lang = $(this).find("select").val(); if (!lang) return; var words = []; $(this).find("ul.wiktku-zarava-words textarea").each(function () { var v = $.trim($(this).val()); if (v) words.push(v); }); if (words.length) result.push([lang, words]); }); return result; }, /** Reads all rows from the DOM, grouped by gloss position. */ getTranslations: function (stepDiv) { var result = []; stepDiv.find(".wiktku-zarava-group").each(function () { result.push(steps.zarava.getGroupTranslations($(this))); }); return result; }, output: function (values) { if (values.lang !== "ku") return ""; var stepDiv = $("#wiktku-start-zarava"); var glosses = steps.trans.glossList(); if (!glosses.length) return ""; var blocks = $.map(glosses, function (gloss, gi) { var group = stepDiv.find(".wiktku-zarava-group[data-gloss-pos='" + gi + "']"); var rows = group.length ? steps.zarava.getGroupTranslations(group) : []; if (!gloss.text && !rows.length) return undefined; if (rows.length) { rows.sort(function (a, b) { var aLang = langsByCode[a[0]] || []; var bLang = langsByCode[b[0]] || []; return (aLang[2] || "").localeCompare(bLang[2] || "", "ku"); }); } var wordLines = $.map(rows, function (row) { var lang = row[0]; var words = row[1]; var wikiWords = words.map(function (w) { return "{{W|" + lang + "|" + w + "}}"; }).join(", "); return "* {{Z|" + lang + "}}: " + wikiWords; }).join("\n"); if (!wordLines) return undefined; var block = "{{werger-ser|" + (gloss.text || "?") + "|" + gloss.index + "}}"; block += "\n" + wordLines; block += "\n{{werger-bin}}"; return block; }); if (!blocks.length) return ""; return "\n==== Bi zaravayên din ====\n" + blocks.join("\n") + "\n"; } }, trans: { id: "trans", name: "werger", visible: function (values) { if (!(values.lang === "ku" && values.pos)) return false; // Hide Werger only when EVERY sense is a template sense (Guharto etc.) // with a title filled in — i.e. there is real content but no plain // gloss to attach a translation table to. A mix of real + template // senses still shows Werger; the template senses are simply skipped // in output(). // // "Real" here means a non-şablon sense with either mane text or // other filled-in fields (etîket/hevmane/nimûne/jêder…), since // dfn.getOutput() renders the latter too, as {{mane?|lang}} plus // whatever else was filled in. // // When nothing has been filled in at all, output() will emit // {{mane?|lang}} instead of a gloss — but Werger should still show, // since the user may want to add translations before they've // settled on a gloss. var dfnSenses = steps.dfn.getSenses($("#wiktku-start-dfn")); var hasRealSense = dfnSenses.some(function (s) { return !s.tpl && (s.mane !== "" || senseHasExtraContent(s)); }); var hasFilledTplSense = dfnSenses.some(function (s) { return s.tpl && s.tplTitle; }); return hasRealSense || !hasFilledTplSense; }, disabledKeys: { "navz": true, "ku": true, "ckb": true, "sdh": true, "lki": true, "hac": true, "zza": true }, /** * Builds one translation row: a language dropdown + a growing list * of word inputs. When the dropdown gets a value the next empty row * is appended automatically. * * @param group the specific .wiktku-trans-group this row belongs to * (each gloss has its own group and its own list of rows, so the * lookups below must stay scoped to that group rather than the * whole step — the step now holds one list per gloss). */ buildRow: function (group) { var row = $("<li class='wiktku-trans-row wiktku-lang-row'></li>"); // Language selector — chosen is applied after insertion into DOM. var langSel = $(mw.html.element("select", { "class": "wiktku-start-step-keyfield wiktku-start-narrow" })); langSel.attr("data-placeholder", "Zimanekî lê bigere"); populateMenus(langSel, steps.trans.keys || [], steps.trans.disabledKeys); // When a language is chosen, ensure a next empty row exists. langSel.on("change", function () { steps.trans.onLangChange(group, row); }); // Word list for this language. var wordList = $("<ul class='wiktku-trans-words wiktku-lang-row-words'></ul>"); var firstWord = steps.trans.makeWordInput(); wordList.append($("<li></li>").append(firstWord)); if (isMobile) { row.append(wrapNativeSelect(langSel)).append(wordList); } else { row.append(langSel).append(wordList); } return row; }, makeWordInput: function () { var input = $("<textarea></textarea>") .attr("name", "wiktku-trans-word-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 1) .attr("class", "wiktku-dfn-subfield wiktku-start-narrow") .attr("placeholder", "Tercime…"); input.on("input", function () { var list = $(this).closest("ul.wiktku-trans-words"); var item = $(this).parent(); var val = $.trim($(this).val()); if (val && item.is(list.children("li:last-child"))) { var next = steps.trans.makeWordInput(); list.append($("<li></li>").append(next)); } }); return input; }, onLangChange: function (group, row) { var list = group.find("ul.wiktku-trans-list"); var isLast = row.is(list.children("li.wiktku-trans-row:last-child")); if (isLast) { var newRow = steps.trans.buildRow(group); list.append(newRow); // Init chosen after the new row is in the DOM (desktop only). if (!isMobile) newRow.find("select").chosen(chosenOptions); } // Keep disabled keys in sync across this gloss's lang selectors // only — the same language can be used for different senses. steps.trans.syncDisabledKeys(group); }, /** Disables already-selected languages in all other dropdowns within one group. */ syncDisabledKeys: function (group) { var taken = $.extend({}, steps.trans.disabledKeys); group.find("li.wiktku-trans-row select").each(function () { var v = $(this).val(); if (v) taken[v] = true; }); group.find("li.wiktku-trans-row select").each(function () { var self = $(this); var own = self.val(); self.find("option").each(function () { var code = $(this).val(); if (!code) return; $(this).prop("disabled", taken[code] && code !== own); }); self.trigger("chosen:updated"); }); }, /** * Builds (or fetches) the .wiktku-trans-group for one gloss, with * its own label and its own list of translation rows. */ buildGroup: function (stepDiv, gi) { var group = $("<div class='wiktku-trans-group'></div>").attr("data-gloss-pos", gi); var list = $("<ul class='wiktku-trans-list wiktku-lang-row-list'></ul>"); list.append(steps.trans.buildRow(group)); group.append(list); stepDiv.append(group); // Init chosen after the select is in the DOM (desktop only). if (!isMobile) list.find("select").chosen(chosenOptions); return group; }, /** * Syncs one .wiktku-trans-group per current gloss, adding new * groups and removing stale ones as senses are added or removed, * while leaving existing groups (and whatever translations the * user has already typed into them) untouched. Groups are keyed * to their gloss's position in glossList() via data-gloss-pos, so * a group always matches the same sense across rebuilds as long * as senses aren't reordered relative to each other. */ build: function (stepDiv) { var glosses = steps.trans.glossList(); if (!glosses.length) { stepDiv.find(".wiktku-trans-group").remove(); return null; } // Drop groups for glosses that no longer exist (always from the // tail — groups are only ever appended in gloss order below). var existingGroups = stepDiv.find(".wiktku-trans-group"); if (existingGroups.length > glosses.length) { existingGroups.slice(glosses.length).remove(); } $.each(glosses, function (gi, gloss) { var group = stepDiv.find(".wiktku-trans-group[data-gloss-pos='" + gi + "']"); if (!group.length) group = steps.trans.buildGroup(stepDiv, gi); // Only label groups when there's more than one gloss to // distinguish between — a single gloss needs no caption. var label = group.find(".wiktku-trans-group-label"); if (glosses.length > 1) { if (!label.length) { label = $("<div class='wiktku-trans-group-label'></div>"); group.prepend(label); } label.text(gloss.index + " " + gloss.text); } else if (label.length) { label.remove(); } }); return null; }, /** Reads the translation rows for a single gloss group. */ getGroupTranslations: function (group) { var result = []; group.find("li.wiktku-trans-row").each(function () { var lang = $(this).find("select").val(); if (!lang) return; var words = []; $(this).find("ul.wiktku-trans-words textarea").each(function () { var v = $.trim($(this).val()); if (v) words.push(v); }); if (words.length) result.push([lang, words]); }); return result; }, /** * Reads all translation rows from the DOM, grouped by gloss * position — one array of [lang, words] rows per gloss group, in * the same order as the .wiktku-trans-group elements. */ getTranslations: function (stepDiv) { var result = []; stepDiv.find(".wiktku-trans-group").each(function () { result.push(steps.trans.getGroupTranslations($(this))); }); return result; }, /** * Builds the numbered "{ index, gloss }" list — one entry per dfn * sense that has a real mane (skips template senses like Guharto, * which have nothing to caption a translation table with). The * index matches the sense's actual position in the numbered "#" * definition list (1-based), including template senses in the count, * so the number printed next to {{werger-ser}} lines up with the * gloss the reader sees in the entry. * * When nothing has been filled in at all (dfn.getOutput() will emit * {{mane?|lang}} as sense 1), this returns a single placeholder * entry with empty text instead of an empty array, so Werger still * has one group to attach translations to before a gloss exists. * When every filled sense is a template sense instead, this stays * empty — that mirrors trans.visible()'s hidden case, where there's * no group in the DOM for a placeholder to attach to anyway. */ glossList: function () { var dfnSenses = steps.dfn.getSenses($("#wiktku-start-dfn")); var glosses = []; var hasFilledTplSense = false; $.each(dfnSenses, function (i, s) { if (s.tpl) { if (s.tplTitle) hasFilledTplSense = true; return; // template sense — no gloss to caption with } var dfn = s.mane; if (!dfn) { // No mane text, but other fields (etîket/hevmane/nimûne/ // jêder…) are filled — dfn.getOutput() still emits this // sense as a numbered line using {{mane?|lang}}, so it // needs its own gloss group too, just with no caption text. if (senseHasExtraContent(s)) glosses.push({ index: i + 1, text: "" }); return; } if (dfn[0] !== dfn[0].toLowerCase()) dfn = decapitalize(dfn); dfn = stripWikilinks(dfn).replace(/[.…?!)\]،؟]+$/, ""); glosses.push({ index: i + 1, text: dfn }); }); if (!glosses.length && !hasFilledTplSense) { glosses.push({ index: 1, text: "" }); } return glosses; }, output: function (values) { if (values.lang !== "ku") return ""; var stepDiv = $("#wiktku-start-trans"); var glosses = steps.trans.glossList(); // Every sense is a template sense — there's no real gloss // anywhere and no group in the DOM either (glossList() only // returns empty in that case), so skip the section entirely. if (!glosses.length) return ""; // Each gloss now has its own group of translation rows — // attach every gloss's own words under its own werger-ser/-bin // pair instead of dumping everything under the first one. var blocks = $.map(glosses, function (gloss, gi) { var group = stepDiv.find(".wiktku-trans-group[data-gloss-pos='" + gi + "']"); var rows = group.length ? steps.trans.getGroupTranslations(group) : []; // Placeholder gloss (no real mane entered yet) with nothing // translated into it — nothing to output, and gloss.text is // empty so there's no caption to give {{werger-ser}} anyway. if (!gloss.text && !rows.length) return undefined; if (rows.length) { // Sort by Kurdish sort key. rows.sort(function (a, b) { var aLang = langsByCode[a[0]] || []; var bLang = langsByCode[b[0]] || []; return (aLang[2] || "").localeCompare(bLang[2] || "", "ku"); }); } var wordLines = $.map(rows, function (row) { var lang = row[0]; var words = row[1]; var wikiWords = words.map(function (w) { return "{{W|" + lang + "|" + w + "}}"; }).join(", "); return "* {{Z|" + lang + "}}: " + wikiWords; }).join("\n"); var block = "{{werger-ser|" + (gloss.text || "?") + "|" + gloss.index + "}}"; if (wordLines) block += "\n" + wordLines; block += "\n{{werger-bin}}"; return block; }); if (!blocks.length) return ""; return "\n==== Werger ====\n" + blocks.join("\n") + "\n"; } }, }; steps.trans.keys = steps.lang.choices; steps.dunde.keys = steps.lang.choices; steps.zarava.keys = getZaravaKeys(steps.lang.choices); var ordered_steps = [ steps.lang, steps.pron, steps.pos, steps.cinsiyet, steps.lektur, steps.tr, steps.dfn, steps.je, steps.tekildar, steps.etym, steps.dunde, steps.binereherwiha, steps.zarava, steps.trans]; // Step ids that belong to each section (not shared across sections). var PER_SECTION_STEP_IDS = [ "pos", "cinsiyet", "lektur", "tr", "dfn", "je", "tekildar", "etym", "dunde", "binereherwiha", "zarava", "trans" ]; // ── Multi-section state ────────────────────────────────────────────────── // Each entry is a plain snapshot: { pos, cinsiyet, lektur, tr, dfn (senses[]), // je, tekildar, binereherwiha, trans (rows[]) }. var sections = [{}]; // section 0 starts empty (DOM is the truth) var activeSection = 0; function snapshotDfn() { return steps.dfn.getSenses($("#wiktku-start-dfn")); } /** * Rebuild the dfn DOM from a previously snapshotted senses array. */ function restoreDfn(senses) { var stepDiv = $("#wiktku-start-dfn"); // Tear down the existing list so build() recreates it cleanly. stepDiv.find("ol.wiktku-dfn-list").remove(); steps.dfn.build(stepDiv); var list = stepDiv.find("ol.wiktku-dfn-list"); $.each(senses, function (i, sense) { // Ensure enough blocks exist (build() seeds one). var blocks = list.find("li.wiktku-dfn-sense"); var block = blocks.eq(i); if (!block.length) { var nb = steps.dfn.buildSenseBlock(stepDiv); list.append(nb); block = list.find("li.wiktku-dfn-sense").last(); } // Template selector. block.find("select.wiktku-dfn-tpl-select").val(sense.tpl || ""); if (sense.tpl) { block.find("textarea.wiktku-dfn-mane").hide(); block.find("input.wiktku-dfn-tpl-title").val(sense.tplTitle || "").show(); } else { block.find("textarea.wiktku-dfn-mane").val(sense.mane || "").show(); block.find("input.wiktku-dfn-tpl-title").hide().val(""); } // Re-sync the formên alternatîv/hevmane/… hide state now that // tplSelect's value was set programmatically (its own "change" // handler doesn't fire from .val(), so this doesn't happen otherwise). var updateVis = block.data("updateFieldVisibility"); if (updateVis) updateVis(); // Restore a sub-list (etiket, formên alternatîv, hevmane …) from a values array. function restoreSubList(cls, values) { if (!values || !values.length) return; var groupDiv = block.find("." + cls + "-group"); var subList = groupDiv.find("ol, ul").first(); if (!subList.length) return; // group not found // Fill existing items, append new ones as needed. $.each(values, function (j, val) { var items = subList.find("li"); if (j < items.length) { items.eq(j).find("textarea").val(val); } else { var ta = $("<textarea></textarea>") .attr("name", "wiktku-dfn-restore-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 1) .attr("class", "wiktku-dfn-subfield wiktku-start-narrow") .val(val); ta.on("input", function () { steps.dfn.onSubInput(subList, this, 1, true); }); subList.append($("<li></li>").append(ta)); } }); } // Reveal and populate lazy groups that have data. var lazyMap = { "wiktku-dfn-etiket": sense.etiket, "wiktku-dfn-alternativ": sense.alternativ, "wiktku-dfn-hevmane": sense.hevmane, "wiktku-dfn-dijmane": sense.dijmane, "wiktku-dfn-koordine": sense.koordine, "wiktku-dfn-jornav": sense.jornav, "wiktku-dfn-jernav": sense.jernav }; $.each(lazyMap, function (cls, vals) { if (vals && vals.length) restoreSubList(cls, vals); }); // Nimûne items are objects { text, tr?, t? } — restore using the builder. if (sense.nimune && sense.nimune.length) { var nimuneGroupDiv = block.find(".wiktku-dfn-nimune-group"); var nimuneList = nimuneGroupDiv.find("ol.wiktku-dfn-nimune-list"); var buildFn = nimuneGroupDiv.data("buildNimuneLi"); nimuneList.empty(); $.each(sense.nimune, function (_, n) { var text = typeof n === "object" ? (n.text || "") : n; if (!text) return; var li = buildFn ? buildFn() : $("<li class='wiktku-dfn-nimune-li'></li>"); li.find(".wiktku-dfn-nimune-text").val(text); if (n.tr) li.find(".wiktku-dfn-nimune-tr").val(n.tr); if (n.t) li.find(".wiktku-dfn-nimune-t").val(n.t); nimuneList.append(li); }); // Always leave a blank trailing item. if (buildFn) nimuneList.append(buildFn()); } // Restore jêder (quote/citation) entries — a growing list, restored using the // builder just like Nimûne. Accepts either the current array shape or a // single legacy object (from older saved sections) for backwards compatibility. var jederArr = $.isArray(sense.jeder) ? sense.jeder : (sense.jeder ? [sense.jeder] : []); if (jederArr.length) { var jederGroupDiv = block.find(".wiktku-dfn-jeder-group"); var jederList = jederGroupDiv.find("ol.wiktku-dfn-jeder-list"); var buildJederFn = jederGroupDiv.data("buildJederLi"); jederList.empty(); $.each(jederArr, function (_, j) { if (!j || !j.quote) return; var li = buildJederFn ? buildJederFn() : $("<li class='wiktku-dfn-jeder-li'></li>"); li.find(".wiktku-dfn-nimune-quote").val(j.quote); if (j.quoteTr) li.find(".wiktku-dfn-nimune-quote-tr").val(j.quoteTr); if (j.quoteT) li.find(".wiktku-dfn-nimune-quote-t").val(j.quoteT); if (j.jederManual) { var manualSel = li.find(".wiktku-dfn-quote-src-sel"); manualSel.val("__manual__").trigger("change"); li.find(".wiktku-dfn-quote-src-manual").val(j.jederManual); } else if (j.jederTpl) { var srcSel = li.find(".wiktku-dfn-quote-src-sel"); srcSel.val(j.jederTpl).trigger("change"); if (j.jêderFields) { $.each(j.jêderFields, function (key, val) { li.find(".wiktku-dfn-quote-src-input[data-field-key='" + key + "']").val(val); }); } } jederList.append(li); }); // Always leave a blank trailing item, same as Nimûne. if (buildJederFn) jederList.append(buildJederFn()); } }); } /** * Snapshot simple (non-dfn) per-section steps from current DOM into obj. */ function saveCurrentSection() { var snap = {}; $.each(PER_SECTION_STEP_IDS, function (_, id) { if (id === "dfn") { snap.dfn = snapshotDfn(); return; } if (id === "etym") { snap.etym = $.trim($("#wiktku-start-etym .wiktku-etym-text").val()); return; } var step = steps[id]; if (!step) return; var stepDiv = $("#wiktku-start-" + id); if (id === "trans") { snap.trans = steps.trans.getTranslations(stepDiv); return; } if (id === "zarava") { snap.zarava = steps.zarava.getTranslations(stepDiv); return; } if (id === "dunde") { snap.dunde = steps.dunde.getRows(stepDiv); return; } // Generic: read all step fields. var fields = stepDiv.find(".wiktku-start-step-field"); if (step.multiple) { snap[id] = fields.map(function () { return $(this).val(); }).get(); } else { snap[id] = fields.val(); } }); sections[activeSection] = snap; } /** * Restore a previously saved snapshot into the form DOM. */ function restoreSection(snap) { $.each(PER_SECTION_STEP_IDS, function (_, id) { if (id === "dfn") { restoreDfn(snap.dfn || []); return; } if (id === "etym") { $("#wiktku-start-etym .wiktku-etym-wrap").remove(); steps.etym.build($("#wiktku-start-etym")); $("#wiktku-start-etym .wiktku-etym-text").val(snap.etym || ""); return; } if (id === "trans") { // Rebuild trans groups (dfn must already be restored by this // point in the $.each loop, so glossList() reflects it). var transDiv = $("#wiktku-start-trans"); transDiv.find(".wiktku-trans-group").remove(); steps.trans.build(transDiv); var groupsSnap = snap.trans || []; $.each(groupsSnap, function (gi, rows) { var group = transDiv.find(".wiktku-trans-group[data-gloss-pos='" + gi + "']"); if (!group.length) return; // gloss no longer exists — drop its rows var list = group.find("ul.wiktku-trans-list"); $.each(rows, function (j, row) { var lang = row[0], words = row[1]; var lastRow = list.find("li.wiktku-trans-row").last(); lastRow.find("select").val(lang).trigger("change"); var wordList = lastRow.find("ul.wiktku-trans-words"); $.each(words, function (k, word) { var wordItems = wordList.find("li"); if (k < wordItems.length) { wordItems.eq(k).find("textarea").val(word); } else { // .val() below doesn't fire "input", so the normal // auto-grow never runs — append a matching item // ourselves instead of silently dropping the word. var extraInput = steps.trans.makeWordInput(); wordList.append($("<li></li>").append(extraInput)); extraInput.val(word); } }); // Leave one trailing empty field so the row can still grow // when the user types, matching a freshly-built row. if ($.trim(wordList.children("li").last().find("textarea").val())) { wordList.append($("<li></li>").append(steps.trans.makeWordInput())); } }); }); return; } if (id === "zarava") { // Rebuild zarava groups (dfn must already be restored by this // point in the $.each loop, so glossList() reflects it). var zaravaDiv = $("#wiktku-start-zarava"); zaravaDiv.find(".wiktku-zarava-group").remove(); steps.zarava.build(zaravaDiv); var zaravaGroupsSnap = snap.zarava || []; $.each(zaravaGroupsSnap, function (gi, rows) { var group = zaravaDiv.find(".wiktku-zarava-group[data-gloss-pos='" + gi + "']"); if (!group.length) return; // gloss no longer exists — drop its rows var list = group.find("ul.wiktku-zarava-list"); $.each(rows, function (j, row) { var lang = row[0], words = row[1]; var lastRow = list.find("li.wiktku-zarava-row").last(); lastRow.find("select").val(lang).trigger("change"); var wordList = lastRow.find("ul.wiktku-zarava-words"); $.each(words, function (k, word) { var wordItems = wordList.find("li"); if (k < wordItems.length) { wordItems.eq(k).find("textarea").val(word); } else { var extraInput = steps.zarava.makeWordInput(); wordList.append($("<li></li>").append(extraInput)); extraInput.val(word); } }); if ($.trim(wordList.children("li").last().find("textarea").val())) { wordList.append($("<li></li>").append(steps.zarava.makeWordInput())); } }); }); return; } if (id === "dunde") { // Rebuild dunde rows. var dundeDiv = $("#wiktku-start-dunde"); dundeDiv.find("ul.wiktku-dunde-list").remove(); steps.dunde.build(dundeDiv); var dundeRows = snap.dunde || []; $.each(dundeRows, function (i, row) { var lang = row[0], words = row[1]; var list = dundeDiv.find("ul.wiktku-dunde-list"); var lastRow = list.find("li.wiktku-dunde-row").last(); lastRow.find("select").val(lang).trigger("change"); var wordList = lastRow.find("ul.wiktku-dunde-words"); $.each(words, function (j, word) { var wordItems = wordList.find("li"); if (j < wordItems.length) { wordItems.eq(j).find("textarea").val(word); } else { // .val() below doesn't fire "input", so the normal // auto-grow never runs — append a matching item // ourselves instead of silently dropping the word. var extraInput = steps.dunde.makeWordInput(); wordList.append($("<li></li>").append(extraInput)); extraInput.val(word); } }); // Leave one trailing empty field so the row can still grow // when the user types, matching a freshly-built row. if ($.trim(wordList.children("li").last().find("textarea").val())) { wordList.append($("<li></li>").append(steps.dunde.makeWordInput())); } }); return; } var step = steps[id]; if (!step) return; var stepDiv = $("#wiktku-start-" + id); var fields = stepDiv.find(".wiktku-start-step-field"); var val = snap[id]; if (val === undefined || val === null) return; if (step.multiple) { var arr = val; fields.each(function (i) { if (i < arr.length) $(this).val(arr[i]); }); } else { fields.val(val); } // Notify chosen widgets of the programmatic value change. if (!isMobile) fields.filter("select").trigger("chosen:updated"); }); } function getWikitextForCurrentSection(callback) { var values = getValues(); var entry = steps.pos.output(values); steps.dfn.getOutput(values, function (output) { entry += output; entry += steps.je.output(values); entry += steps.tekildar.output(values); entry += steps.etym.output(values); entry += steps.dunde.output(values); entry += steps.binereherwiha.output(values); entry += steps.zarava.output(values); entry += steps.trans.output(values); callback(entry, values); }); } function getWikitextAllSections(callback) { saveCurrentSection(); var results = new Array(sections.length); var sharedValues = getValues(); // lang/pron are shared function processSection(i) { if (i >= sections.length) { // All done — restore original active section. restoreSection(sections[activeSection]); refresh(); callback(results, sharedValues); return; } restoreSection(sections[i]); refresh(); getWikitextForCurrentSection(function (sectionText) { results[i] = sectionText; processSection(i + 1); }); } processSection(0); } /** * Assembles wikitext for all sections plus the shared lang/pron header. */ function getWikitext(callback) { getWikitextAllSections(function (sectionTexts, sharedValues) { var entry = steps.lang.output(sharedValues); entry += steps.pron.output(sharedValues); entry += sectionTexts.join("\n"); // Edit summary uses section 0's values. Read from the saved snapshot // (not the live DOM) so it doesn't mix section 0's pos with whichever // section happens to be active/restored at this point. var dfnSenses = (sections[0] && sections[0].dfn) || []; var dfnSummary = dfnSenses.map(function (s) { return s.mane; }).filter(Boolean).join("; "); var summaryLabel = addLangMode ? "WF:Ziman lê zêde" : "WF:Nû"; var summary = "([[Mediawiki:Gadget-start.js|" + summaryLabel + "]] v.2.0) +" + sharedValues.lang + ":" + sections[0].pos + ":" + dfnSummary; var summaryField = document.getElementById("wpSummary"); if (addLangMode && summaryField.value) { summary = summaryField.value + " " + summary; } summaryField.value = summary; callback(entry); }); } var continueBtn; function getValuesForStep(stepId) { var fields = $("#wiktku-start-" + stepId + " .wiktku-start-step-field"); var step = steps[stepId]; if (step.keys) { var values = {}; fields.each(function (i, field) { var key = $(field).prevAll(".wiktku-start-step-keyfield").val(); if (key) values[key] = $(field).val(); }); return values; } else if (step.multiple) { return fields.map(function () { return $(this).val(); }).get(); } return fields.val(); } function getValues() { var values = {}; $.each(steps, function (stepId) { values[stepId] = getValuesForStep(stepId); }); return values; } function populateMenus(inputs, choices, disabledValues) { if (!disabledValues) disabledValues = {}; var vals = inputs.map(function (i, input) { return $(input).val(); }); inputs.empty(); inputs.append($("<option></option>")); $.each(choices, function (j, choice) { // Append the language code in parentheses so that typing a code // (e.g. "ku") in the search box still finds the language name. var displayText = capitalize(choice[1]); if (choice[2] !== undefined) { // This is a language choice [code, name, sortKey] — show code. displayText = capitalize(choice[1]) + " (" + choice[0] + ")"; } var option = $(mw.html.element("option", { value: choice[0] }, displayText)); if (disabledValues[choice[0]]) option.prop("disabled", true); inputs.append(option); }); inputs.val(function (i) { return vals[i]; }); } /** * Returns a bitmap containing the keys that should be disabled for a key * menu in the given step because they are disabled or already taken by * another key menu. */ function getDisabledKeys(step) { var occupiedKeys = {}; $("#wiktku-start-" + step.id + " .wiktku-start-step-keyfield").each(function () { occupiedKeys[$(this).val()] = true; }); if (step.disabledKeys) $.extend(occupiedKeys, step.disabledKeys); return occupiedKeys; } function buildKeyInput(step) { if (!step.keys) return undefined; var input = $(mw.html.element("select", { "class": "wiktku-start-step-keyfield wiktku-start-narrow" })); input.attr("data-placeholder", "Hilbijêre " + step.keyName); if (isMobile) { populateMenus(input, step.keys, getDisabledKeys(step)); // On mobile return the wrapper; the select is inside it. // Change events still fire on the inner select. return wrapNativeSelect(input); } input.on("chosen:showing_dropdown", function () { $(this).data("wiktku-defaultValue", $(this).val()); }); input.change(function (_, context) { var inputs = $("#wiktku-start-" + step.id + " .wiktku-start-step-keyfield").not(this); var oldValue = $(this).data("wiktku-defaultValue"); var newValue = context.selected; inputs.find("option[value='" + oldValue + "']").prop('disabled', false); inputs.find("option[value='" + newValue + "']").prop('disabled', true); inputs.trigger("chosen:updated"); }); populateMenus(input, step.keys, getDisabledKeys(step)); return input; } /** * If the current text field has text and there are no more text fields after * the current text field in the list, add another text field to the list. */ function refreshForTextField(currentInput, step) { currentInput = $(currentInput); var value = currentInput.val(); var item = currentInput.parent(); if (value && !item.next("li").length) { var nextInput = $("<textarea></textarea>") .attr("name", "wiktku-field-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("class", currentInput.attr("class")) .attr("rows", currentInput.attr("rows") || 1); nextInput.on("input", function (evt) { refreshForTextField(evt.target, step); }); var nextKeyInput = buildKeyInput(step); var nextItem = $("<li></li>").append(nextKeyInput).append(nextInput); item.parent().append(nextItem); if (nextKeyInput) nextKeyInput.chosen(chosenOptions); } var canContinue = !continueBtn.isDisabled(); if ((value && !canContinue) || (!value && canContinue)) { refresh(step); } } function prepareInput(input, step) { if (!input) return; if (step.required) input.prop('required', true); input.change(step, refresh); } /** * Shows and hides all the steps based on whether their prerequisites are met, * and updates placeholders where applicable. */ function refresh(evt) { var values = getValues(); var changedStep = evt && evt.data; var didFocus = false; var canContinue = true; // Re-filter template options in every sense block whenever lang changes. $("#wiktku-start-dfn .wiktku-dfn-tpl-select").each(function () { var fn = $(this).data("updateOptions"); if (typeof fn === "function") fn(); }); // Re-filter pronunciation and etymology template dropdowns when language changes. steps.pron.refreshTplSelect(); steps.etym.refreshTplSelect(); // Sync tr/t sub-fields in every nimûne item to the current language. // tr shown when language needs transliteration; t shown when lang !== "ku". (function () { var lang = values.lang || ""; var showTr = needsTransliteration(lang); var showT = lang && lang !== "ku"; $("#wiktku-start-dfn .wiktku-dfn-nimune-list li.wiktku-dfn-nimune-li").each(function () { var li = $(this); // Ensure the sub-wrapper exists when we need it. var subWrap = li.find(".wiktku-dfn-nimune-sub"); // tr field var trTa = li.find(".wiktku-dfn-nimune-tr"); if (showTr && !trTa.length) { if (!subWrap.length) { subWrap = $("<div></div>").addClass("wiktku-dfn-nimune-sub"); li.append(subWrap); } trTa = $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-tr-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 5) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-tr") .attr("placeholder", "Transkrîpsiyon…"); subWrap.prepend(trTa); } else if (!showTr && trTa.length) { trTa.remove(); } // t field var tTa = li.find(".wiktku-dfn-nimune-t"); if (showT && !tTa.length) { if (!subWrap.length) { subWrap = $("<div></div>").addClass("wiktku-dfn-nimune-sub"); li.append(subWrap); } tTa = $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-t-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 5) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-t") .attr("placeholder", "Tercimeya nimûneyê kurmancî…"); subWrap.append(tTa); } else if (!showT && tTa.length) { tTa.remove(); } // Remove the wrapper if it ended up empty. subWrap = li.find(".wiktku-dfn-nimune-sub"); if (subWrap.length && !subWrap.children().length) subWrap.remove(); }); }()); // Sync tr/t sub-fields in every jêder citation to the current language. // tr shown when language needs transliteration; t shown when lang !== "ku". (function () { var lang = values.lang || ""; var showTr = needsTransliteration(lang); var showT = lang && lang !== "ku"; $("#wiktku-start-dfn .wiktku-dfn-jeder-list li.wiktku-dfn-jeder-li").each(function () { var li = $(this); // Ensure the sub-wrapper exists when we need it. It must sit right // after the quote textarea and before the source selector. var subWrap = li.find(".wiktku-dfn-quote-sub"); // tr field var trTa = li.find(".wiktku-dfn-nimune-quote-tr"); if (showTr && !trTa.length) { if (!subWrap.length) { subWrap = $("<div></div>").addClass("wiktku-dfn-quote-sub"); li.find(".wiktku-dfn-nimune-quote").after(subWrap); } trTa = $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-quote-tr-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 2) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-quote-tr") .attr("placeholder", "Transkrîpsiyona jêgirtinê…"); subWrap.prepend(trTa); } else if (!showTr && trTa.length) { trTa.remove(); } // t field var tTa = li.find(".wiktku-dfn-nimune-quote-t"); if (showT && !tTa.length) { if (!subWrap.length) { subWrap = $("<div></div>").addClass("wiktku-dfn-quote-sub"); li.find(".wiktku-dfn-nimune-quote").after(subWrap); } tTa = $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-quote-t-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 2) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-quote-t") .attr("placeholder", "Tercimeya jêgirtinê ya kurmancî…"); subWrap.append(tTa); } else if (!showT && tTa.length) { tTa.remove(); } // Remove the wrapper if it ended up empty. subWrap = li.find(".wiktku-dfn-quote-sub"); if (subWrap.length && !subWrap.children().length) subWrap.remove(); }); }()); $.each(steps, function (stepId, step) { if (typeof(step.visible) === "function" && !step.visible(values)) { $("#wiktku-start-" + stepId).slideUp(); } else { var stepDiv = $("#wiktku-start-" + stepId); if (changedStep !== step && typeof(step.build) === "function") { prepareInput(step.build(stepDiv, values), step); } var input = stepDiv.find(".wiktku-start-step-field"); if (typeof(step.example) === "function") { // .find() above already reaches nested fields (e.g. the dfn // step's mane textareas inside each sense block), so one // assignment covers every step; dfn keeps its own fallback. var exampleText = step.example(values) || (step.id === "dfn" ? "Mane…" : ""); input.attr("placeholder", exampleText); } var didSlideDown; if (!didFocus && stepDiv.css("display") === "none" && step.required) { didSlideDown = function (evt) { input.focus(); }; didFocus = true; } stepDiv.slideDown(didSlideDown); } if (step.required && (values[stepId] === "" || (step.multiple && values[stepId].join("") === ""))) { canContinue = false; } }); continueBtn.setDisabled(!canContinue); } function destroy() { $("#wiktku-start-form, .noafterwizard").slideUp(function () { $(this).remove(); }); $(".noarticletext .nowizard, #editform").slideDown(); $("#ca-edit").removeClass("selected"); $("#ca-wiktku-nowizard").addClass("selected"); } // Priority order for Kurdish dialects and the navz pseudo-code. // Codes listed here come before all other languages; unlisted codes // are sorted alphabetically by their display name via localeCompare. var LANG_PRIORITY = ["navz", "ku", "hac", "sdh", "lki", "ckb", "zza"]; /** * Inserts a new == {{ziman|code}} == section into existing page wikitext * at the correct sorted position: * 1. Any content before the first language section is preserved at the top. * 2. navz is always first, then ku/hac/sdh/lki/ckb/zza in that order, * then all other languages sorted by display name (localeCompare). */ function insertNewLangSection(existing, wikitext) { var newCodeMatch = wikitext.match(/^== \{\{ziman\|([^}]+)\}\} ==/); var newCode = newCodeMatch ? newCodeMatch[1] : ""; var sections = []; var preamble = ""; var firstMatch = existing.match(/(?:^|\n)== \{\{ziman\|/); if (!firstMatch) { // No existing lang sections at all — just append. var sep = existing && !/\n\s*$/.test(existing) ? "\n\n" : ""; return existing + sep + wikitext; } // Everything before the first == {{ziman|...}} == is the preamble. var firstSectionStart = existing.indexOf("== {{ziman|"); // Walk back to the start of that line. var lineStart = existing.lastIndexOf("\n", firstSectionStart - 1); var preambleEnd = lineStart !== -1 ? lineStart + 1 : 0; preamble = existing.slice(0, preambleEnd); // Parse each language section: header line + everything until the next header. var body = existing.slice(preambleEnd); // NOTE: with the /m flag, a bare "$" matches end-of-*line*, not just // end-of-string — that previously made the non-greedy content group // stop at the section's first line break instead of running to the // next language header (or the real end of the text), silently // dropping the rest of that section's wikitext. (?![\s\S]) matches // only the true end of the string, /m flag or not. var langSectionRe = /^(== \{\{ziman\|([^}]+)\}\} ==\n?)([\s\S]*?)(?=\n== \{\{ziman\||(?![\s\S]))/gm; var m; while ((m = langSectionRe.exec(body)) !== null) { sections.push({ code: m[2], content: m[0] // full text of this section including header }); } // Determine sort rank: priority list first (by index), then alphabetical. function getLangName(code) { var entry = langsByCode[code]; return entry ? entry[1] : code; } function sortRank(code) { var idx = LANG_PRIORITY.indexOf(code); return idx !== -1 ? idx : LANG_PRIORITY.length; } function compareLangs(a, b) { var ra = sortRank(a), rb = sortRank(b); if (ra !== rb) return ra - rb; // Both are outside priority list — sort by display name. return getLangName(a).localeCompare(getLangName(b), userLang); } // Insert the new section into the sorted list. var newSection = { code: newCode, content: wikitext }; var inserted = false; for (var i = 0; i < sections.length; i++) { if (compareLangs(newCode, sections[i].code) < 0) { sections.splice(i, 0, newSection); inserted = true; break; } } if (!inserted) sections.push(newSection); // Re-join: preamble + sections separated by newlines. var joined = sections.map(function (s) { // Ensure each section ends with exactly one newline before the next. return s.content.replace(/\n+$/, ""); }).join("\n"); return preamble + joined + "\n"; } function build() { $(".nowizard, .nowizard .noafterwizard").hide(); var callToAction = $("#wiktku-calltoaction"); var origCallToActionText = callToAction.text(); $(mw.util.addPortletLink("p-views", "#", "Edîtora çavkaniyê veke", "ca-wiktku-nowizard", "Vê rûpelê bi edîtora çavkaniyê çêke", undefined, "#ca-watch")).click(function (evt) { evt.preventDefault(); callToAction.text(origCallToActionText); destroy(); }); if (callToAction.length) { callToAction.text(origCallToActionText + " Forma li jêr ji bo çêkirina madeyeke nû bi kar bîne."); } var startForm = $("<form id='wiktku-start-form'></form>"); if (addLangMode) { startForm.append($("<p class='wiktku-addlang-notice'></p>").text( "Bi vê formê tu yê beşeke nû li rûpelê îlaw bikî. Eger ev zimanê ku tu îlawe dikî jixwe di rûpelê de hebe, beşa nû li dawiya vî zimanî dê were îlawekirin. " + "Ji kerema xwe netîceya dawî kontrol bikin, eger problemek derkeve, li [[Mediawiki talk:Gadget-start.js|nîqaşa vê amûrê]] problemê ragihîne.")); } var spinner; // Tab bar for switching between POS sections. var sectionTabsDiv = $("<div id='wiktku-section-tabs'></div>"); startForm.submit(function (evt) { evt.preventDefault(); continueBtn.setDisabled(true); spinner.show(); getWikitext(function (wikitext) { if (addLangMode) { var textbox = $("#wpTextbox1"); var existing = textbox.val() || ""; // Check whether the generated lang header already exists in the page. // wikitext always starts with "== {{ziman|CODE}} ==\n" (from steps.lang.output). // If that exact section heading is already present in the existing content, // strip it from the new output and insert the remaining content at the end // of that lang section (just before the next == level-2 heading, or at the // very end of the page if there is no following section). var langHeaderMatch = wikitext.match(/^(== \{\{ziman\|[^}]+\}\} ==\n)/); if (langHeaderMatch) { var langHeader = langHeaderMatch[1]; // e.g. "== {{ziman|ku}} ==\n" // Escape for use in RegExp. var escapedHeader = langHeader.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); if (new RegExp(escapedHeader).test(existing)) { // Strip the header from the new output. var newContent = wikitext.slice(langHeader.length); // Find the insertion point: end of the existing lang section. // A new L2 heading marks the start of the next language block. var afterHeader = existing.indexOf(langHeader); var searchFrom = afterHeader + langHeader.length; // Find the next == … == heading after this section's start. var nextL2 = existing.indexOf("\n== ", searchFrom); var insertAt = nextL2 !== -1 ? nextL2 : existing.length; // Ensure there's a blank line before the inserted block. var before = existing.slice(0, insertAt); var after = existing.slice(insertAt); var sep = /\n\s*$/.test(before) ? "" : "\n"; textbox.val(before + sep + newContent + after); } else { // New language — insert at the correct sorted position. textbox.val(insertNewLangSection(existing, wikitext)); } } else { // Unexpected format — insert at sorted position anyway. textbox.val(insertNewLangSection(existing, wikitext)); } } else { $("#wpTextbox1").val(wikitext); } $("html, body").animate({scrollTop: 0}); callToAction.text("Hindik ma!"); $("#wiktku-preview-container").remove(); destroy(); }); }); $.each(ordered_steps, function (i, step) { var stepDiv = $(mw.html.element("div", { "class": "wiktku-start-step", id: "wiktku-start-" + step.id })); var name = capitalize(step.name); stepDiv.append($(mw.html.element("h3", { "class": "wiktku-start-step-name" }, new mw.html.Raw(mw.html.element("label", { "for": "wiktku-start-" + step.id + "-field" }, name))))); if (step.question_fmt) { stepDiv.append($(mw.html.element("label", { "class": "wiktku-start-step-question", "for": "wiktku-start-" + step.id + "-field" }, step.question_fmt))); if (step.question_br) stepDiv.append($("<br>")); } var input; if (step.choices) { input = $(mw.html.element("select", { "class": "wiktku-start-step-field", id: "wiktku-start-" + step.id + "-field" })); input.attr("data-placeholder", capitalize(step.name) + " hilbijêre "); populateMenus(input, step.choices); if (step.multiple) input.attr("multiple", true); if (isMobile) { stepDiv.append(wrapNativeSelect(input)); } else { stepDiv.append(input); } } else if (typeof(step.build) === "function") { input = step.build(stepDiv); } else { input = $("<textarea></textarea>") .attr("class", "wiktku-start-step-field") .attr("id", "wiktku-start-" + step.id + "-field") .attr("rows", step.rows || 2); if (step.narrow) input.addClass("wiktku-start-narrow"); if (step.multiple) { input.on("input", function (evt) { refreshForTextField(evt.target, step); }); var keyInput = buildKeyInput(step); var list = $(step.ordered ? "<ol></ol>" : "<ul></ul>") .append($("<li></li>").append(keyInput).append(input)); stepDiv.append(list); } else stepDiv.append(input); } prepareInput(input, step); stepDiv.hide(); // Insert tab bar just before the first per-section step. if (step.id === "pos") startForm.append(sectionTabsDiv); startForm.append(stepDiv); }); // ── Section tab helpers ────────────────────────────────────────────── // ── Add-section button — lives in the tab bar, disabled until pos chosen ── var addSectionBtn = new OO.ui.ButtonWidget({ label: "+ Beş zêde bike", disabled: true }); addSectionBtn.on("click", function () { saveCurrentSection(); sections.push({}); activeSection = sections.length - 1; $.each(PER_SECTION_STEP_IDS, function (_, id) { if (id === "dfn") { var stepDiv = $("#wiktku-start-dfn"); stepDiv.find("ol.wiktku-dfn-list").remove(); steps.dfn.build(stepDiv); return; } if (id === "etym") { $("#wiktku-start-etym .wiktku-etym-wrap").remove(); steps.etym.build($("#wiktku-start-etym")); return; } if (id === "trans") { var transDiv = $("#wiktku-start-trans"); transDiv.find(".wiktku-trans-group").remove(); return; } if (id === "zarava") { var zaravaDiv = $("#wiktku-start-zarava"); zaravaDiv.find(".wiktku-zarava-group").remove(); return; } if (id === "dunde") { var dundeDiv = $("#wiktku-start-dunde"); dundeDiv.find("ul.wiktku-dunde-list").remove(); return; } var stepDiv = $("#wiktku-start-" + id); stepDiv.find(".wiktku-start-step-field").val(""); if (!isMobile) stepDiv.find("select.wiktku-start-step-field").trigger("chosen:updated"); }); renderSectionTabs(); refresh(); $("html, body").animate({ scrollTop: sectionTabsDiv.offset().top - 20 }, 300); }); /** Re-render the tab bar to reflect current sections[] and activeSection. */ function renderSectionTabs() { // Detach (not remove) the button first: .empty() strips bound // event data from any children left inside it, which would // silently kill addSectionBtn's click handler on every re-render. addSectionBtn.$element.detach(); sectionTabsDiv.empty(); var lang = getValues().lang || ""; if (!lang) { sectionTabsDiv.hide(); return; } sectionTabsDiv.show(); $.each(sections, function (i) { var posVal = sections[i].pos || ""; var tabLabel = posVal ? capitalize(posVal) : ("Beş " + (i + 1)); var tab = $("<span></span>") .addClass("wiktku-section-tab") .text(tabLabel) .toggleClass("wiktku-tab-active", i === activeSection); (function (idx) { tab.on("click", function () { if (idx === activeSection) return; saveCurrentSection(); activeSection = idx; restoreSection(sections[activeSection]); refresh(); renderSectionTabs(); }); }(i)); sectionTabsDiv.append(tab); }); // Enable "Beş zêde bike" only when the active section has a pos chosen. var activePos = sections[activeSection] && sections[activeSection].pos ? sections[activeSection].pos : getValues().pos; addSectionBtn.setDisabled(!activePos); sectionTabsDiv.append(addSectionBtn.$element); } renderSectionTabs(); // Update the active tab's label whenever pos changes. startForm.on("change", "#wiktku-start-pos-field", function () { renderSectionTabs(); }); // Show the tab bar as soon as a language is selected. startForm.on("change", "#wiktku-start-lang-field", function () { renderSectionTabs(); }); var footer = $("<div id='wiktku-start-footer'></div>"); spinner = $(mw.html.element("img", { id: "wiktku-start-spinner", src: "//upload.wikimedia.org/wikipedia/commons/d/de/Ajax-loader.gif", alt: "Tê barkirin…", title: "Tê barkirin…" })); footer.append(spinner.hide()); continueBtn = new OO.ui.ButtonWidget({ id: "wiktku-unhide-editform", label: "Bişîne", flags: [ "primary", "progressive" ] }); continueBtn.on("click", function () { mw.notify("Tê şandin…", { type: "info", tag: "wiktku-submit" }); startForm.trigger("submit"); }); footer.append(continueBtn.$element); // "Edîtora çavkaniyê veke" button — inline fallback for the portlet link // which is invisible on mobile and easy to miss on desktop. var sourceEditorBtn = new OO.ui.ButtonWidget({ label: "Edîtora çavkaniyê veke", framed: false }); sourceEditorBtn.on("click", function () { destroy(); }); footer.append(sourceEditorBtn.$element); // ── Preview checkboxes ─────────────────────────────────────────────── // Wikitext preview (raw text panel) var previewCheck = $("<input type='checkbox' id='wiktku-preview-toggle'>"); var previewLabel = $("<label for='wiktku-preview-toggle'></label>") .text(" Pêşdîtina wîkîtekstê"); var previewPanel = $("<pre id='wiktku-preview-panel'></pre>").hide(); // Live rendered preview (parsed HTML panel, same logic as AjaxEdit). // Not available on mobile — API polling causes too many problems on small screens. var livePreviewCheck = null; var livePreviewPanel = null; if (!isMobile) { livePreviewCheck = $("<input type='checkbox' id='wiktku-live-preview-toggle'>"); livePreviewPanel = $("<div id='wiktku-live-preview-panel'></div>").hide(); } // Container that holds both panels and switches between stacked / side-by-side. var previewContainer = $("<div id='wiktku-preview-container'></div>"); previewContainer.append(previewPanel); if (!isMobile) previewContainer.append(livePreviewPanel); var previewTimer = null; var livePreviewIntervalId = -1; var livePreviewActive = false; // guards in-flight fetches after uncheck /** Rebuilds wikitext preview if its checkbox is checked. */ function schedulePreview() { if (!previewCheck.prop("checked")) return; clearTimeout(previewTimer); // Debounce: wait 400 ms after the last keystroke before rebuilding. previewTimer = setTimeout(function () { getWikitext(function (wikitext) { previewPanel.text(wikitext).show(); updatePanelLayout(); }); }, 400); } /** Fetches parsed HTML and populates the live preview panel. */ function loadLivePreview() { getWikitext(function (wikitext) { new mw.Api().parse(wikitext, { title: mw.config.get("wgPageName") }).done(function (html) { // Discard result if the user unchecked while the fetch was in flight. if (!livePreviewActive) return; livePreviewPanel.html(html).show(); updatePanelLayout(); }); }); } /** Adjusts panel widths depending on which previews are visible. */ function updatePanelLayout() { var wikitextVisible = previewCheck.prop("checked"); var liveVisible = livePreviewCheck && livePreviewCheck.prop("checked"); if (wikitextVisible && liveVisible) { // Side by side — each panel takes roughly half the available width. previewPanel.css({ "flex": "1 1 45%", "min-width": "280px" }); livePreviewPanel.css({ "flex": "1 1 45%", "min-width": "280px" }); } else { // Full width for whichever is visible — only touch panels that are // actually shown so that setting flex doesn't override display:none. if (wikitextVisible) previewPanel.css({ "flex": "1 1 100%", "min-width": "" }); if (liveVisible && livePreviewPanel) livePreviewPanel.css({ "flex": "1 1 100%", "min-width": "" }); } } previewCheck.on("change", function () { if ($(this).prop("checked")) { schedulePreview(); } else { clearTimeout(previewTimer); previewPanel.hide(); updatePanelLayout(); } }); if (!isMobile) { livePreviewCheck.on("change", function () { if ($(this).prop("checked")) { livePreviewActive = true; livePreviewPanel.show(); loadLivePreview(); livePreviewIntervalId = setInterval(loadLivePreview, 500); } else { livePreviewActive = false; clearInterval(livePreviewIntervalId); livePreviewIntervalId = -1; livePreviewPanel.hide().empty(); updatePanelLayout(); } }); } // Listen on all input/change events on the form and update both previews. startForm.on("input change", function () { schedulePreview(); }); footer.append($("<span style='margin-left:1em'></span>") .append(previewCheck).append(previewLabel)); if (!isMobile) { var livePreviewLabel = $("<label for='wiktku-live-preview-toggle'></label>") .text(" Pêşdîtina zindî"); footer.append($("<span style='margin-left:1em'></span>") .append(livePreviewCheck).append(livePreviewLabel)); } startForm.append(footer); $("#editform").hide().before(startForm); // Insert preview container (holds both panels) after the form. startForm.after(previewContainer); if (!isMobile) startForm.find("select").chosen(chosenOptions); refresh(); // Zimanan ji MediaWiki:Gadget-translation_editor.js/ziman.json bar bike. // Kodên ku bi "-pro" diqedin û navên ku "zimanê destan" tê de heye // tên derxistin. Zimanên xardkirî li serî dimînin, yên din // bi alfabeyê li dû wan tên. // Pinned choices come from MediaWiki:Gadget-start.js/data.json (langChoices), // already loaded into steps.lang.choices before build() runs. var pinnedChoices = steps.lang.choices.slice(); var pinnedCodes = $.map(pinnedChoices, function (choice) { return choice[0]; }); new mw.Api().get({ action: "query", prop: "revisions", titles: "MediaWiki:Gadget-translation_editor.js/ziman.json", rvprop: "content", rvslots: "main", formatversion: 2 }).then(function (data) { var page = data.query.pages[0]; var content = page && page.revisions && page.revisions[0].slots.main.content; var zimanData; try { zimanData = JSON.parse(content); } catch (e) { zimanData = {}; } var extraChoices = []; $.each(zimanData, function (code, name) { // Filter: skip proto-language codes and legendary/reconstructed langs. if (/-pro$/i.test(code)) return; if (/ziman[eê]\s+destan/i.test(name)) return; // Skip codes already in the pinned list (they are handled above). if (pinnedCodes.indexOf(code) !== -1) return; // sortKey: bare name without leading "zimanê " for sorting. var sortKey = name.replace(/^ziman[eê]\s+/i, ""); var choice = [code, name, sortKey]; extraChoices.push(choice); langsByCode[code] = choice; }); // Populate langsByCode for pinned choices too. $.each(pinnedChoices, function (i, choice) { // Ensure pinned choices have a sortKey (index 2). if (choice.length < 3) choice[2] = choice[1]; langsByCode[choice[0]] = choice; }); // Sort the extra choices alphabetically by sort key. extraChoices.sort(function (a, b) { return a[2].localeCompare(b[2], userLang); }); // Final list: pinned first, then the rest. var allChoices = pinnedChoices.concat(extraChoices); steps.lang.choices = allChoices; steps.trans.keys = allChoices; steps.dunde.keys = allChoices; steps.zarava.keys = getZaravaKeys(allChoices); var langMenu = $("#wiktku-start-lang-field"); populateMenus(langMenu, steps.lang.choices); langMenu.trigger("chosen:updated"); var transMenus = $("#wiktku-start-trans .wiktku-start-step-keyfield"); populateMenus(transMenus, steps.trans.keys, getDisabledKeys(steps.trans)); transMenus.trigger("chosen:updated"); var dundeMenus = $("#wiktku-start-dunde .wiktku-start-step-keyfield"); populateMenus(dundeMenus, steps.dunde.keys, getDisabledKeys(steps.dunde)); dundeMenus.trigger("chosen:updated"); var zaravaMenus = $("#wiktku-start-zarava .wiktku-start-step-keyfield"); populateMenus(zaravaMenus, steps.zarava.keys, getDisabledKeys(steps.zarava)); }); } mw.loader.using(["jquery.chosen", "mediawiki.api", "oojs-ui-core"], function () { if (!isMobile) { var startNotice = mw.notify( "Amûr dest pê dike, hinek bisekinin. Not: jkx Sentaks (sentaks highlighter) neaktîv bikin", { type: "info", tag: "wiktku-start-notice", autoHide: false } ); // Keep the notice visible for at least 5 seconds regardless of // how quickly the form loads. setTimeout(function () { if (startNotice && startNotice.close) startNotice.close(); }, 5000); } // Load metadata, langChoices, posChoices and tplDefs from the companion // data page so they can be updated without touching this script. new mw.Api().get({ action: "query", prop: "revisions", titles: "MediaWiki:Gadget-start.js/data.json", rvprop: "content", rvslots: "main", formatversion: 2 }).then(function (data) { var page = data.query.pages[0]; var content = page && page.revisions && page.revisions[0].slots.main.content; var d; try { d = JSON.parse(content); } catch (e) { d = {}; } // Populate metadata. if (d.metadata) $.extend(metadata, d.metadata); // Populate gender labels. if (d.genderLabels) $.extend(GENDER_BASE_LABELS, d.genderLabels); // Populate lang choices (pinned list used by build() → ziman.json loader). if (d.langChoices) steps.lang.choices = d.langChoices; // Populate POS choices. if (d.posChoices) steps.pos.choices = d.posChoices; // Populate template definitions for the dfn sense-block builder. if (d.tplDefs) steps.dfn.tplDefs = d.tplDefs; // Populate pos placeholder examples. if (d.posExamples) steps.dfn.posExamples = d.posExamples; // Populate citation template definitions for the quote widget. if (d.jederDefs) steps.dfn.jederDefs = d.jederDefs; // Populate pronunciation and etymology template insert lists. if (d.pronTpls) { steps.pron.pronTpls = d.pronTpls; steps.pron.refreshTplSelect(); } if (d.etymTpls) { steps.etym.etymTpls = d.etymTpls; steps.etym.refreshTplSelect(); } // Sync trans/dunde/zarava keys with the (now populated) lang choices. steps.trans.keys = steps.lang.choices; steps.dunde.keys = steps.lang.choices; steps.zarava.keys = getZaravaKeys(steps.lang.choices); }).always(build); }); }); //</nowiki> e24hkyfputvjhgbytyx04mjv0emjus2 6265568 6265567 2026-07-19T13:52:45Z Wikihez 7344 6265568 javascript text/javascript // Li ser [[vi:MediaWiki:Gadget-start.js]] hatiye refaktorkirin. //<nowiki> $(function () { var ns = mw.config.get("wgNamespaceNumber"); if (ns && !(ns === 2 && mw.config.get("wgPageName").match(/\/ceribandin$|\/test$/))) { return; } var action = mw.config.get("wgAction"); var pageExists = !!mw.config.get("wgArticleId"); // "Zimanek lê zêde bike" mode: triggered from the portlet link below. // Runs the same wizard on an EXISTING page's edit form, but appends the // generated section instead of replacing the textarea's content. var addLangMode = pageExists && mw.util.getParamValue("wiktkuaddlang") === "1"; // On a normal page view of an existing page, just add the portlet link // that takes the user into addLangMode; don't build anything else here. if (action === "view" && pageExists) { mw.util.addPortletLink("p-views", mw.util.getUrl(mw.config.get("wgPageName"), { action: "submit", wiktkuaddlang: "1" }), "+Ziman/beşeke din", "ca-wiktku-addlang", "Ji vê rûpelê re zimanekî nû zêde bike"); return; } if (!(action === "edit" || action === "submit")) { return; } if (!addLangMode && !$(".mw-newarticletext, .mw-newarticletextanon").length) { return; } if (window.location.href.includes("editintro=User:Wikihez/creation/intro")) { return; // Do not run the script wextê WF:Bilez dişuxile } function capitalize(str) { if (!str) return str; return str[0].toUpperCase() + str.substr(1); } function decapitalize(str) { if (!str) return str; return str[0].toLowerCase() + str.substr(1); } function escapeRegExp(str) { return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); } function stripWikilinks(str) { return str.replace(/\[\[([^\]|]+)(?:\|([^\]]+))?\]\]/g, function (m, target, display) { return display || target; }); } function insertAtCursor(el, text) { var start = el.selectionStart; var end = el.selectionEnd; var val = el.value; el.value = val.slice(0, start) + text + val.slice(end); var pos = start + text.length; el.selectionStart = el.selectionEnd = pos; } var pageName = mw.config.get("wgPageName").replaceAll(/_/g, " "); if (ns) pageName = pageName.replace(/.*\//, ""); var pageNameRe = escapeRegExp(pageName); var userLang = mw.config.get("wgUserLanguage"); // Mobile detection: MobileFrontend sets wgMFMode, or fall back to touch check. var isMobile = !!mw.config.get("wgMFMode") || window.matchMedia("(pointer: coarse)").matches; var chosenOptions = { width: "20em", disable_search_threshold: 0, placeholder_text_single: "Yekî hilbijêre", placeholder_text_multiple: "Hilbijêre", no_results_text: "Nehat dîtin", enable_split_word_search: true, search_contains: true }; function wrapNativeSelect(select) { var placeholder = select.attr("data-placeholder") || "Lê bigere…"; // Hide the native select — we drive it programmatically. select.hide(); var wrapper = $("<span class='wiktku-native-select-wrap'></span>"); var textInput = $("<input type='search' autocomplete='off'>") .attr("placeholder", placeholder) .addClass("wiktku-start-narrow wiktku-ac-input"); var resultsList = $("<ul class='wiktku-ac-results'></ul>").hide(); // Full option cache — rebuilt when chosen:updated fires. var allOptions = []; function cacheOptions() { allOptions = []; select.find("option").each(function () { var v = $(this).val(); if (!v) return; // skip the empty placeholder option allOptions.push({ value: v, text: $(this).text(), disabled: $(this).prop("disabled") }); }); } cacheOptions(); function showResults(query) { var q = query.trim().toLowerCase(); resultsList.empty(); var matched; if (q) { matched = []; $.each(allOptions, function (_, o) { if (o.disabled) return; var codeMatch = o.value.toLowerCase().indexOf(q) !== -1; var nameMatch = o.text.toLowerCase().indexOf(q) !== -1; if (codeMatch || nameMatch) { matched.push({ opt: o, codeMatch: codeMatch }); } }); // Code matches (especially prefix matches) come first. matched.sort(function (a, b) { var aCode = a.opt.value.toLowerCase(); var bCode = b.opt.value.toLowerCase(); var aPrefix = aCode.indexOf(q) === 0; var bPrefix = bCode.indexOf(q) === 0; if (aPrefix !== bPrefix) return aPrefix ? -1 : 1; if (a.codeMatch !== b.codeMatch) return a.codeMatch ? -1 : 1; return 0; }); matched = matched.map(function (item) { return item.opt; }); } else { matched = allOptions.filter(function (o) { return !o.disabled; }); } if (!matched.length) { resultsList.hide(); return; } $.each(matched.slice(0, 50), function (_, opt) { var li = $("<li></li>").text(opt.text).attr("data-value", opt.value); // Use touchend instead of touchstart so that a scroll gesture does // not accidentally select an item. We track whether the finger moved // between touchstart and touchend — if it did, it was a scroll. var touchMoved = false; li.on("touchstart", function () { touchMoved = false; }); li.on("touchmove", function () { touchMoved = true; }); li.on("touchend", function (e) { if (touchMoved) return; // was a scroll, not a tap e.preventDefault(); selectOption(opt.value, opt.text); }); // Keep mousedown for desktop fallback. li.on("mousedown", function (e) { e.preventDefault(); selectOption(opt.value, opt.text); }); resultsList.append(li); }); // Position the list above or below depending on available viewport space. var inputRect = textInput[0].getBoundingClientRect(); var viewportH = window.innerHeight; var spaceBelow = viewportH - inputRect.bottom - 8; var spaceAbove = inputRect.top - 8; var maxH = Math.min(224, Math.max(spaceBelow, spaceAbove)); // 224px ≈ 14em resultsList.css({ "max-height": maxH + "px", "top": spaceBelow >= spaceAbove ? "100%" : "auto", "bottom": spaceBelow >= spaceAbove ? "auto" : "100%" }); resultsList.show(); } function selectOption(value, text) { textInput.val(text); select.val(value); resultsList.hide(); select.trigger("change"); } textInput.on("input focus", function () { showResults($(this).val()); }); textInput.on("blur", function () { // Short delay so a touchstart on a result item fires first. setTimeout(function () { resultsList.hide(); }, 200); }); // chosen:updated → re-cache (called after ziman.json loads). select.on("chosen:updated", function () { cacheOptions(); // If a value is already selected, keep the display text in sync. var cur = select.val(); if (cur) { var match = $.grep(allOptions, function (o) { return o.value === cur; })[0]; if (match) textInput.val(match.text); } }); // No-op .chosen() so desktop call-sites don't need guarding. select.chosen = function () { return select; }; wrapper.append(textInput).append(resultsList).append(select); return wrapper; } var langsByCode = {}; // Populated from [[MediaWiki:Gadget-start.js/data.json]] at runtime. var metadata = {}; // Zaravayên kurdî yên ku di beşa "Bi zaravayên din" de tên pêşkêşkirin — // ev kod ji beşa Werger têne derxistin daku heman zimên du caran neyê xwendin. var ZARAVA_LANG_CODES = ["ckb", "sdh", "lki", "hac", "zza"]; function getZaravaKeys(choices) { var byCode = {}; $.each(choices || [], function (_, c) { byCode[c[0]] = c; }); var result = []; $.each(ZARAVA_LANG_CODES, function (_, code) { if (byCode[code]) result.push(byCode[code]); }); return result; } function needsTransliteration(langCode) { var meta = metadata[langCode]; if (!meta || !meta.sc) return false; var scripts = Array.isArray(meta.sc) ? meta.sc : [meta.sc]; return scripts.length > 0 && scripts[0] !== "Latn"; } // Kodên cinsiyetê yên di metadata.g de — ji data.json tê dagirtin var GENDER_BASE_LABELS = {}; // Sub-lists that only make sense for a plain (non-şablon) sense — hidden // when a şablon (e.g. {{guharto|…}}) is chosen for that sense, since a // template-based sense has no "own" gloss for alternate forms, synonyms, // antonyms, coordinate terms, hypernyms or hyponyms to attach to. Etîket, // Nimûne and Jêgirtin stay visible either way. var HIDDEN_ON_TPL_GROUPS = [ "wiktku-dfn-alternativ", "wiktku-dfn-hevmane", "wiktku-dfn-dijmane", "wiktku-dfn-koordine", "wiktku-dfn-jornav", "wiktku-dfn-jernav" ]; function genderLabel(code) { if (code === "p") return "Pirjimar"; var pluralMatch = code.match(/^(.+)-p$/); if (pluralMatch && GENDER_BASE_LABELS[pluralMatch[1]]) { return GENDER_BASE_LABELS[pluralMatch[1]] + " (pirjimar)"; } return GENDER_BASE_LABELS[code] || code; } /** * True if a sense has any content worth keeping besides its mane text — * etîket, hevmane/dijmane/koordîne/etc. word lists, nimûne, or jêder * (quote). Used so a sense with an empty mane but filled-in extra * fields still gets emitted (with {{mane?}} standing in for the gloss) * instead of being silently dropped. */ function senseHasExtraContent(s) { if (s.etiket && $.grep(s.etiket, function (e) { return $.trim(e) !== ""; }).length) return true; if (s.alternativ.length || s.hevmane.length || s.dijmane.length || s.koordine.length || s.jornav.length || s.jernav.length) return true; if (s.nimune && $.grep(s.nimune, function (n) { return (typeof n === "object" ? n.text : n) !== ""; }).length > 0) return true; if (s.jeder && $.grep(s.jeder, function (j) { return j && j.quote; }).length > 0) return true; return false; } /** * formatNimune: each nimûne item can be { text, tr, t }: * text — example text * tr — transliteration (only when the language needs it) * t — Kurdish translation (third positional param, no key) */ function formatNimune(nimunes, lang, hasJeder) { var hasNimune = nimunes && $.grep(nimunes, function (n) { return (typeof n === "object" ? n.text : n) !== ""; }).length > 0; if (!hasNimune) { return hasJeder ? "" : "\n#* {{bênimûne|" + lang + "}}"; } return $.map(nimunes, function (n) { var text = typeof n === "object" ? n.text : n; if (!text) return undefined; var bolded = text.replace( new RegExp("(" + pageNameRe + "([^( |,|;|\\?|\\.|\\!)]+)?)", "ig"), "'''$1'''"); var tpl = "\n#: {{nm|" + lang + "|" + bolded; if (typeof n === "object") { if (n.tr) tpl += "|tr=" + n.tr; // Translation as third positional param (no key needed). if (n.t) tpl += "|" + n.t; } // Short examples fit on one line together with their translation. // rêz=1 is not used for ku — definitions are shown on separate lines there. if (text.length < 200 && lang !== "ku") tpl += "|rêz=1"; tpl += "}}"; return tpl; }).join(""); } /** * Formats a list of jêder (quote/citation) objects into wikitext lines. * Each entry that has no quote text is skipped. Returns "" when the list * is empty or every entry is blank. * * #* {{jêder-…|lang|jêgirtin=…|tr=…|tercime=…|…fields…}} * * When no template is chosen, the generic {{jêder|…}} template is used * instead. Its 2nd positional param is the user's freeform "bi destê xwe * binivîsim" source text when supplied, or the çavkanî? placeholder otherwise. * If that text contains "=" it is passed as |2=… instead of a bare * positional param, since MediaWiki would otherwise misparse it as its * own key=value pair and break the template: * #* {{jêder|lang|jêgirtin=…|tr=…|tercime=…|<manual source or çavkanî?>}} */ function formatJeder(jederList, lang) { if (!jederList || !jederList.length) return ""; return $.map(jederList, function (jeder) { if (!jeder || !jeder.quote) return undefined; if (jeder.jederTpl) { var cite = "\n#* {{" + jeder.jederTpl + "|" + lang; cite += "|jêgirtin=" + jeder.quote; if (jeder.quoteTr) cite += "|tr=" + jeder.quoteTr; if (jeder.quoteT) cite += "|tercime=" + jeder.quoteT; $.each(jeder.jêderFields || {}, function (key, val) { if (val) cite += "|" + key + "=" + val; }); cite += "}}"; return cite; } var out = "\n#* {{jêder|" + lang + "|jêgirtin=" + jeder.quote; if (jeder.quoteTr) out += "|tr=" + jeder.quoteTr; if (jeder.quoteT) out += "|tercime=" + jeder.quoteT; var srcParam = jeder.jederManual ? jeder.jederManual : "çavkanî?"; // A positional param containing "=" gets parsed as its own key=value // pair by MediaWiki and breaks the template, so force it to be // explicitly named (|2=) whenever that's the case. out += (srcParam.indexOf("=") !== -1 ? "|2=" : "|") + srcParam; out += "}}"; return out; }).join(""); } function makeWordListStep(id, name, question_fmt, header, templateName) { return { id: id, name: name, question_fmt: question_fmt, multiple: true, narrow: true, visible: function (values) { return values.lang && values.pos; }, output: function (values) { var words = $.grep(values[id] || [], function (w) { return !!w; }); if (!words.length) return ""; var lang = values.lang; var section = "\n==== " + header + " ====\n"; if (words.length === 1) { // Single word — keep the simple inline template. return section + "* {{" + templateName + "|" + lang + "|" + words[0] + "}}\n"; } // Multiple words — use {{kol3}} with one positional param per word. var params = "cure=" + header + "\n" + $.map(words, function (w) { return "|" + w; }).join("\n"); return section + "{{kol3|" + lang + "|" + params + "\n}}\n"; } }; } var steps = { lang: { id: "lang", required: true, name: "ziman", question_fmt: '"' + pageName + '" bi çi zimanî ye?', question_br: true, // Populated from [[MediaWiki:Gadget-start.js/data.json]] (langChoices). choices: [], output: function (values) { return "== {{ziman|" + values.lang + "}} ==\n"; } }, pron: { id: "pron", name: "bilêvkirin", question_fmt: '"' + pageName + '" çawa tê telafûzkirin?', // pronTpls populated from data.json pronTpls: [], visible: function (values) { if (!values.lang) return false; // In addLangMode, only skip pron when this langcode's section // already exists in the page — if it's a new language, show it. if (addLangMode) { var existing = $("#wpTextbox1").val() || ""; var header = "== {{ziman|" + values.lang + "}} =="; return existing.indexOf(header) === -1; } return true; }, /** Fills (or refills) the insert-dropdown from the current pronTpls array, filtering by language. */ refreshTplSelect: function () { var sel = $("#wiktku-start-pron .wiktku-tpl-insert-select"); if (!sel.length) return; var lang = getValues().lang || ""; sel.find("option[value!='']").remove(); $.each(steps.pron.pronTpls, function (_, tpl) { // Filter: if tpl.langs exists, only show if lang is in that list; otherwise show always var allowed = !tpl.langs || tpl.langs.indexOf(lang) !== -1; if (allowed) { sel.append($("<option></option>") .val(tpl.snippet) .text(tpl.name + " — " + tpl.desc) .attr("data-nolang", tpl.noLang ? "1" : "")); } }); // Notify Chosen that the option list has changed (no-op on mobile). if (!isMobile) sel.trigger("chosen:updated"); }, build: function (stepDiv) { if (stepDiv.find(".wiktku-pron-wrap").length) return null; var wrap = $("<div class='wiktku-pron-wrap'></div>"); var ta = $("<textarea></textarea>") .attr("name", "wiktku-pron-" + $.now()) .attr("class", "wiktku-start-step-field wiktku-pron-text") .attr("rows", 4) .attr("placeholder", "Nimûne: {{IPA|ku|/pɛɪ̯n/}} yan {{kîte|ku|he|ce|ki|rin}}"); // Template insert dropdown — filtered by language. var sel = $("<select class='wiktku-tpl-insert-select'></select>"); sel.append($("<option value=''>— şablonek lê zêde bike —</option>")); var lang = getValues().lang || ""; $.each(steps.pron.pronTpls, function (_, tpl) { // Filter: if tpl.langs exists, only show if lang is in that list; otherwise show always var allowed = !tpl.langs || tpl.langs.indexOf(lang) !== -1; if (allowed) { sel.append($("<option></option>") .val(tpl.snippet) .text(tpl.name + " — " + tpl.desc) .attr("data-nolang", tpl.noLang ? "1" : "")); } }); sel.on("change", function () { var snippet = $(this).val(); if (!snippet) return; var lang = getValues().lang || ""; // Check if the selected option has noLang flag var selectedOption = sel.find("option:selected"); var hasNoLang = selectedOption.attr("data-nolang") === "1"; if (!hasNoLang) { snippet = snippet.replace(/CODE/g, lang).replace(/SOURCELANG/g, "?"); } insertAtCursor(ta[0], snippet); $(this).val(""); ta.focus(); }); wrap.append(sel).append($("<br>")).append(ta); stepDiv.append(wrap); return ta; }, output: function () { var text = $.trim($("#wiktku-start-pron .wiktku-pron-text").val()); if (!text) return ""; var lines = text.split("\n"); var out = $.map(lines, function (line) { line = $.trim(line); if (!line) return undefined; return line.charAt(0) === "*" ? line : "* " + line; }).join("\n"); return "\n=== Bilêvkirin ===\n" + out + "\n"; } }, pos: { id: "pos", required: true, name: "Cureyê rêzimanî", question_fmt: 'Cureyê rêzimanî yê "' + pageName + '" çi ye?', visible: function (values) { return values.lang; }, question_br: true, // Populated from [[MediaWiki:Gadget-start.js/data.json]] (posChoices). choices: [], output: function (values) { var pos = values.pos || ""; var cinsiyet = values.cinsiyet || ""; // from the cinsiyet step var lekTur = values.lektur || ""; // from the lêker transitivity step var capitalizedPos = capitalize(pos); var outputString = "\n=== " + capitalizedPos + " ===\n"; // Add ku-tewîn-nav for single-word navdêr/serenav with known gender. if (!pageName.includes(" ") && cinsiyet && GENDER_BASE_LABELS[cinsiyet] && (pos === "navdêr" || pos === "serenav") && values.lang === "ku") { outputString += "{{ku-tewîn-nav|" + pageName + "|" + GENDER_BASE_LABELS[cinsiyet]; if (pos === "serenav") outputString += "|y"; outputString += "}}\n"; } outputString += "{{" + pos + "|" + values.lang; if (pos === "navdêr" || pos === "serenav") { if (cinsiyet) { outputString += "|c=" + cinsiyet; } else if (values.lang === "ku") { // Unknown gender — prompt editor to fill it in. outputString += "|c=?"; } } else if (/^lêker/.test(pos) && lekTur) { outputString += "|c=" + lekTur; } if (values.tr) { outputString += "|tr=" + values.tr; } outputString += "}}\n"; return outputString; } }, /** * cinsiyet (grammatical gender) — only shown for navdêr/serenav, û * tenê ger metadata ji bo zimanê hilbijartî lîsteyeke "g" (cinsiyet) * were dayîn. Opsiyonên vê gavê ne sabît in — ji metadata[values.lang].g * têne çêkirin, ji ber ku di hemû zimanan de cinsiyet tine. */ cinsiyet: { id: "cinsiyet", name: "cinsiyet", question_fmt: 'Cinsiyeta "' + pageName + '" çi ye?', question_br: true, visible: function (values) { var meta = metadata[values.lang]; return !!(values.lang && (values.pos === "navdêr" || values.pos === "serenav") && meta && meta.g && meta.g.length); }, build: function (stepDiv, values) { var select = stepDiv.find("select.wiktku-start-step-field"); if (!select.length) { select = $(mw.html.element("select", { "class": "wiktku-start-step-field", id: "wiktku-start-cinsiyet-field" })); stepDiv.append(select); } if (!values) return select; var meta = metadata[values.lang]; var codes = (meta && meta.g) || []; var prevVal = select.val(); var choices = $.map(codes, function (code) { return [[code, genderLabel(code)]]; }); populateMenus(select, choices); if ($.grep(choices, function (c) { return c[0] === prevVal; }).length) { select.val(prevVal); } if (!isMobile) select.trigger("chosen:updated"); return select; }, output: function () { return ""; } // consumed by pos.output }, /** * Lêker transitivity — only shown for any lêker variant. */ lektur: { id: "lektur", name: "Cureyê lêkerê (fiîlê)", question_fmt: "Cureyê lêkerê (fiîlê) çi ye?", question_br: true, visible: function (values) { return values.lang && values.pos && /^lêker/.test(values.pos); }, // Dictionary: value → display label. Add new types here. choices: [ ["gh", "gerguhêz"], ['x-gh', 'xwerû-gerguhêz'], ['p-gh', 'pêkhatî-gerguhêz'], ['h-gh', 'hevedudanî-gerguhêz'], ['b-gh', 'biwêjî-gerguhêz'], ["ngh", "negerguhêz"], ['x-ngh', 'xwerû-negerguhêz'], ['p-ngh', 'pêkhatî-negerguhêz'], ['h-ngh', 'hevedudanî-negerguhêz'], ['b-ngh', 'biwêjî-negerguhêz'] ], output: function () { return ""; } // consumed by pos.output }, tr: { id: "tr", name: "transkrîpsiyon", question_fmt: "Transkrîpsiyona kelîmeyê", multiple: false, narrow: true, visible: function (values) { return values.lang && values.pos && needsTransliteration(values.lang); } }, dfn: { id: "dfn", // required: true, ger mane tinebe [[Şablon:mane?]] bi kar bîne name: "Mane", question_fmt: "Maneya kelîmeyê binivîse. Mane otomatîk tê lînkkirin! Ji bo tercimeyan beşa 'Werger' bi kar bîne!", multiple: true, ordered: true, rows: 3, visible: function (values) { return values.lang && values.pos; }, example: function (values) { // posExamples loaded from [[MediaWiki:Gadget-start.js/data.json]]. var examples = steps.dfn.posExamples || {}; var full = values.pos || ""; return examples[full] || ""; }, /** * Builds one sense block (<li>) inside the ordered list. * Each block contains: * - a textarea for the definition * - an expandable nimûne list * - single-row sub-lists for formên alternatîv, hevmane, dijmane */ buildSenseBlock: function (stepDiv) { var block = $("<li class='wiktku-dfn-sense'></li>"); // — Mane textarea (declared first so the template handler can reference it) — var dfnArea = $("<textarea></textarea>") .attr("name", "wiktku-dfn-mane-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("class", "wiktku-start-step-field wiktku-dfn-mane") .attr("rows", 6) .attr("placeholder", "Mane…"); dfnArea.on("input", function () { steps.dfn.onDfnInput(stepDiv, block, this); }); // — Template selector (optional — replaces mane when chosen) — // Template definitions loaded from [[MediaWiki:Gadget-start.js/data.json]]. var tplDefs = steps.dfn.tplDefs || []; // Cache of all non-placeholder option elements — used by updateTplOptions // to remove/re-add options (the only approach compatible with Chosen.js). var _allTplOptions = []; var tplSelect = $(mw.html.element("select", { "class": "wiktku-dfn-tpl-select" })); tplSelect.append($("<option value=''>— yan jî şablonek hilbijêre —</option>")); $.each(tplDefs, function (_, tpl) { var opt = $("<option></option>") .val(tpl.name) .text(tpl.name) .attr("data-langs", tpl.langs ? tpl.langs.join(",") : "") .attr("data-nolang", tpl.noLang ? "1" : ""); tplSelect.append(opt); _allTplOptions.push(opt[0]); }); function updateTplOptions() { var lang = getValues().lang || ""; var currentVal = tplSelect.val(); var currentStillValid = false; // Detach all non-placeholder options, then re-attach only the visible ones. // This is the only approach that works correctly with both native <select> // and Chosen.js on desktop. tplSelect.find("option[value!='']").detach(); $.each(_allTplOptions, function (_, opt) { var allowed = $(opt).attr("data-langs"); var visible = !allowed || allowed.split(",").indexOf(lang) !== -1; if (visible) { tplSelect.append(opt); if ($(opt).val() === currentVal) currentStillValid = true; } }); if (!isMobile) tplSelect.trigger("chosen:updated"); if (currentVal && !currentStillValid) { tplSelect.val(""); dfnArea.show(); tplTitleInput.hide().val(""); } } // Store updater on the element so refresh() can call it for all blocks. tplSelect.data("updateOptions", updateTplOptions); var tplTitleInput = $("<input type='text'>") .addClass("wiktku-dfn-tpl-title wiktku-start-narrow") .attr("placeholder", "Navê rûpelê…") .hide(); // Grow the sense list when the title field of the last block gets content, // mirroring what onDfnInput does for the plain mane textarea. tplTitleInput.on("input", function () { steps.dfn.onDfnInput(stepDiv, block, this); }); /** * When a şablon sense is chosen, formên alternatîv/hevmane/dijmane/ * termên koordîne/jornav/jêrnav don't apply (there's no plain gloss * to hang them off), so hide those subgroups. Etîket, Nimûne and * Jêgirtin stay visible and still usable for a şablon sense. */ function updateFieldVisibility() { var isTpl = !!tplSelect.val(); $.each(HIDDEN_ON_TPL_GROUPS, function (_, cls) { block.find("." + cls + "-group").toggle(!isTpl); }); } // Store on the block so restoreDfn() can re-sync visibility // after programmatically setting tplSelect's value. block.data("updateFieldVisibility", updateFieldVisibility); tplSelect.on("change", function () { var chosen = $(this).val(); if (chosen) { dfnArea.hide(); tplTitleInput.show().focus(); } else { dfnArea.show(); tplTitleInput.hide().val(""); } updateFieldVisibility(); // Re-run refresh so the Werger step visibility updates. refresh(); }); var tplRow = $("<div></div>").addClass("wiktku-dfn-tpl-row") .append(tplSelect).append(" ").append(tplTitleInput); block.append(tplRow); block.append(dfnArea); // Apply lang filter on initial build. updateTplOptions(); // — Sub-field groups — // All groups are always visible with a placeholder textarea. // Nimûne is last in the DOM and last in the output. var allGroups = [ { cls: "wiktku-dfn-etiket", label: "Etîket", rows: 1, narrow: true, izah: "xisûsen, Mêrdîn, anatomî, Badînî" }, { cls: "wiktku-dfn-alternativ", label: "Formên alternatîv", rows: 1, narrow: true, izah: "Varyantên vê kelîmeyê" }, { cls: "wiktku-dfn-hevmane", label: "Hevmane", rows: 1, narrow: true, izah: "Spehî hevmaneya Bedew e." }, { cls: "wiktku-dfn-dijmane", label: "Dijmane", rows: 1, narrow: true, izah: "Zengîn dijmaneya feqîr e." }, { cls: "wiktku-dfn-koordine", label: "Termên koordîne", rows: 1, narrow: true, izah: "Pisîk û kûçik termên koordîne ne çunkî Jornavên wan gelek in" }, { cls: "wiktku-dfn-jornav", label: "Jornav", rows: 1, narrow: true, izah: "Heywan jornavê guhandar e" }, { cls: "wiktku-dfn-jernav", label: "Jêrnav", rows: 1, narrow: true, izah: "Guhandar jêrnavê heywan e" }, { cls: "wiktku-dfn-nimune", label: "Nimûne", rows: 2, narrow: false } ]; $.each(allGroups, function (_, g) { var groupDiv = $("<div></div>").addClass("wiktku-dfn-subgroup " + g.cls + "-group"); function buildNimuneLi() { var lang = getValues().lang || ""; var li = $("<li></li>").addClass("wiktku-dfn-nimune-li"); var mainTa = $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-text-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", g.rows) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-text") .attr("placeholder", "Nimûneya emilandina kelîmeyê tu bi xwe binivîse…"); mainTa.on("input", function () { var val = $.trim($(this).val()); var isLast = li.is(list.children("li:last-child")); if (val && isLast) { list.append(buildNimuneLi()); } }); li.append(mainTa); var subWrap = $("<div></div>").addClass("wiktku-dfn-nimune-sub"); if (needsTransliteration(lang)) { subWrap.append( $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-tr-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 5) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-tr") .attr("placeholder", "Transkrîpsiyona bi alfabeya latînî") ); } if (lang && lang !== "ku") { subWrap.append( $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-t-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 5) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-t") .attr("placeholder", "Tercimeya kurmancî") ); } if (subWrap.children().length) li.append(subWrap); return li; } if (g.cls === "wiktku-dfn-nimune") { // Nimûne — compound widget with tr/t sub-fields. var lbl = $("<span></span>").addClass("wiktku-dfn-sublabel").text(g.label + ": "); var list = $("<ol></ol>").addClass("wiktku-dfn-sublist " + g.cls + "-list"); groupDiv.data("buildNimuneLi", buildNimuneLi); list.append(buildNimuneLi()); groupDiv.append(lbl).append(list); block.append(groupDiv); } else { // Regular always-visible group — label + growing textarea list. var lbl = $("<span></span>").addClass("wiktku-dfn-sublabel").text(g.label + ": " + g.izah); var list = $("<ol></ol>").addClass("wiktku-dfn-sublist " + g.cls + "-list"); var firstInput = $("<textarea></textarea>") .attr("name", g.cls + "-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", g.rows) .attr("class", "wiktku-dfn-subfield" + (g.narrow ? " wiktku-start-narrow" : "")) .attr("placeholder", g.label + "…"); firstInput.on("input", function () { steps.dfn.onSubInput(list, this, g.rows, g.narrow); }); list.append($("<li></li>").append(firstInput)); groupDiv.append(lbl).append(list); block.append(groupDiv); } }); // — Jêder (quote / citation) group — a growing list, sibling to Nimûne — // Structured the same way as Nimûne (ol.wiktku-dfn-sublist > li) so it // lines up at the same indentation, and so that typing into the last // citation's Jêgirtin box automatically opens a fresh empty one below it. (function () { var jederGroupDiv = $("<div></div>").addClass("wiktku-dfn-subgroup wiktku-dfn-jeder-group"); var jederLbl = $("<span></span>").addClass("wiktku-dfn-sublabel").text("Jêgirtin: "); var jederList = $("<ol></ol>").addClass("wiktku-dfn-sublist wiktku-dfn-jeder-list"); function buildJederLi() { var lang = getValues().lang || ""; var li = $("<li></li>").addClass("wiktku-dfn-jeder-li"); var dragHandle = $("<span></span>") .addClass("wiktku-jeder-drag-handle") .attr("title", "Bişkûne û bikişîne da ku rêzê biguhezîne"); // Quote text textarea var quoteTa = $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-quote-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 2) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-quote") .attr("placeholder", "Nimûneya emilandinê ji kitêb an çavkaniyeke din binivîse"); quoteTa.on("input", function () { var val = $.trim($(this).val()); var isLast = li.is(jederList.children("li:last-child")); if (val && isLast) { jederList.append(buildJederLi()); } }); li.append(dragHandle).append(quoteTa); // tr/t sub-fields for the quote — shown as needed for the language. var quoteSubWrap = $("<div></div>").addClass("wiktku-dfn-quote-sub"); if (needsTransliteration(lang)) { quoteSubWrap.append( $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-quote-tr-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 2) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-quote-tr") .attr("placeholder", "Transkrîpsiyona jêgirtinê…") ); } if (lang && lang !== "ku") { quoteSubWrap.append( $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-quote-t-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 2) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-quote-t") .attr("placeholder", "Tercimeya jêgirtinê bi kurmancî") ); } if (quoteSubWrap.children().length) li.append(quoteSubWrap); // Citoid auto-fill: fetch citation data from a URL, DOI or ISBN and // prefill the source şablon + fields below (see Gadget-citoid-helper.js). var citoidWrap = $("<div></div>").addClass("wiktku-dfn-quote-citoid"); var citoidInput = $("<input type='text'>") .addClass("wiktku-dfn-quote-citoid-input wiktku-start-narrow") .attr("placeholder", "URL, DOI an ISBN binivîse ku otomatîk were tijekirin…"); var citoidBtn = new OO.ui.ButtonWidget({ label: "Bi Citoid bîne", classes: [ "wiktku-dfn-quote-citoid-btn" ] }); var citoidStatus = $("<span></span>").addClass("wiktku-dfn-quote-citoid-status"); /** * Fetches citation data from Citoid and applies it to this * citation's şablon selector + fields. Mirrors the logic in * Form.prototype._fillFromCitoid (Gadget-wikt.add-examples.js): * - only (re)selects the şablon when it actually differs from * what's already chosen, so a repeat fetch doesn't wipe out * a template the user already picked; * - only fills fields that are currently empty, so it never * overwrites something the user typed by hand; * - falls back to the freeform "bi destê xwe binivîsim" source * only when nothing was typed there yet. */ function runCitoidFetch() { var query = $.trim(citoidInput.val()); if (!query) { mw.notify("Ji kerema xwe re pêşî URL, DOI an ISBNyekê binivîse."); return; } citoidBtn.setDisabled(true); citoidStatus.text("Tê anîn…"); wikt.citoidHelper.ensure().then(function () { return wikt.citoid.fetchJederFields(query); }).then(function (result) { var jederKey = result.jederKey; var hasTpl = !!jederKey && srcSel.find("option[value='" + jederKey + "']").length > 0; var targetVal = hasTpl ? jederKey : "__manual__"; // Only (re)select — and thus rebuild — the field rows if // we're switching to a different şablon than what's // already chosen, so a second fetch doesn't clear fields // the user already filled in by hand. if (srcSel.val() !== targetVal) { srcSel.val(targetVal).trigger("change"); srcSel.trigger("chosen:updated"); } if (hasTpl) { // Tenê qadên vala tijî bike. $.each(result.fields, function (key, val) { var input = srcFields.find("[data-field-key='" + key + "']"); if (input.length && !$.trim(input.val())) { input.val(val); } }); } else { // Şablonek nehat naskirin ji bo vê itemType — rêzikeke // çavkaniyê ya bi destan a ji qadên Citoid tê çêkirin, // lê tenê ger qada destan vala be. var manualField = srcFields.find(".wiktku-dfn-quote-src-manual"); if (!$.trim(manualField.val())) { var parts = []; $.each(["nivîskar", "sernav", "websîte", "kovar", "weşanxane", "sal", "url"], function (_, k) { if (result.fields[k]) parts.push(result.fields[k]); }); manualField.val(parts.join(", ")); } } citoidStatus.text(""); }, function (errorMsg) { citoidStatus.text(typeof errorMsg === "string" ? errorMsg : "Nehat dîtin. Kontrol bike ka URL/DOI/ISBN rast e."); }).always(function () { citoidBtn.setDisabled(false); }); } citoidBtn.on("click", runCitoidFetch); citoidInput.on("keydown", function (e) { if (e.which === 13) { // Enter e.preventDefault(); runCitoidFetch(); } }); citoidWrap.append(citoidInput).append(citoidBtn.$element).append(citoidStatus); // Source template selector, specific to this citation. var srcSel = $("<select></select>").addClass("wiktku-dfn-quote-src-sel"); srcSel.append($("<option value=''>— Çavkaniyê hilbijêre —</option>")); srcSel.append($("<option></option>").val("__manual__").text("Bi destê xwe binivîsim")); var jederDefs = steps.dfn.jederDefs || {}; $.each(jederDefs, function (tplName, def) { srcSel.append($("<option></option>").val(tplName).text(def.label)); }); // Dynamic source fields container. var srcFields = $("<div></div>").addClass("wiktku-dfn-quote-src-fields"); srcSel.on("change", function () { srcFields.empty(); var chosen = $(this).val(); if (!chosen) return; if (chosen === "__manual__") { // Freeform source, written by the user — becomes the 2nd // positional param of {{jêder|lang|…}} instead of çavkanî?. srcFields.append( $("<textarea></textarea>") .attr("rows", 4) .addClass("wiktku-dfn-subfield wiktku-dfn-quote-src-manual") .attr("placeholder", "Çavkaniyê bi destê xwe binivîse…") ); return; } var def = (steps.dfn.jederDefs || {})[chosen]; if (!def) return; $.each(def.fields, function (_, f) { var row = $("<div></div>").addClass("wiktku-dfn-quote-src-row"); var fieldLbl = $("<label></label>").text(f.label + ": "); var inp = $("<textarea></textarea>") .attr("rows", 2) .addClass("wiktku-dfn-quote-src-input wiktku-start-narrow") .attr("data-field-key", f.key) .attr("placeholder", f.label + "…"); row.append(fieldLbl).append(inp); srcFields.append(row); }); }); li.append(citoidWrap).append(srcSel).append(srcFields); return li; } jederGroupDiv.data("buildJederLi", buildJederLi); jederList.append(buildJederLi()); // Make citation rows sortable (drag to reorder). // The last row is always the empty trailing row — cancel its drag. mw.loader.using("jquery.ui.sortable", function () { jederList.sortable({ handle: ".wiktku-jeder-drag-handle", axis: "y", items: "li:not(:last-child)", tolerance: "pointer" }); }); jederGroupDiv.append(jederLbl).append(jederList); block.append(jederGroupDiv); }()); // Apply the initial hide/show state for the sub-groups (matches // tplSelect's starting value, which is normally empty). updateFieldVisibility(); return block; }, /** Grows the sense list when the last mane textarea gets content. */ onDfnInput: function (stepDiv, block, textarea) { var val = $.trim($(textarea).val()); var list = stepDiv.find("ol.wiktku-dfn-list"); var isLast = block.is(list.children("li:last-child")); if (val && isLast) { var newBlock = steps.dfn.buildSenseBlock(stepDiv); list.append(newBlock); // Apply Chosen to the new block's template selector on desktop. if (!isMobile) newBlock.find("select.wiktku-dfn-tpl-select").chosen(chosenOptions); } refresh(); }, /** Grows a sub-list (nimûne/formên alternatîv/hevmane/dijmane/termên koordîne) on input. */ onSubInput: function (list, input, rows, narrow) { var val = $.trim($(input).val()); var item = $(input).parent(); var isLast = item.is(list.children("li:last-child")); if (val && isLast) { var next = $("<textarea></textarea>") .attr("name", "wiktku-dfn-sub-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", rows) .attr("class", "wiktku-dfn-subfield" + (narrow ? " wiktku-start-narrow" : "")); next.on("input", function () { steps.dfn.onSubInput(list, this, rows, narrow); }); list.append($("<li></li>").append(next)); } }, // Populated from [[MediaWiki:Gadget-start.js/data.json]] (tplDefs, posExamples, jederDefs). tplDefs: [], posExamples: {}, jederDefs: {}, build: function (stepDiv) { if (stepDiv.find("ol.wiktku-dfn-list").length) return null; var list = $("<ol class='wiktku-dfn-list'></ol>"); list.append(steps.dfn.buildSenseBlock(stepDiv)); stepDiv.append(list); return null; }, /** Reads all sense blocks from the DOM and returns an array of sense objects. */ getSenses: function (stepDiv) { var senses = []; stepDiv.find("li.wiktku-dfn-sense").each(function () { var block = $(this); var tplSel = block.find("select.wiktku-dfn-tpl-select"); var tpl = tplSel.val() || ""; // noLang: template already encodes the language — don't add |lang| param. var tplNoLang = tpl ? tplSel.find("option[value='" + tpl + "']").attr("data-nolang") === "1" : false; var tplTitle = $.trim(block.find("input.wiktku-dfn-tpl-title").val()); var mane = $.trim(block.find("textarea.wiktku-dfn-mane").val()); var etiket = (function () { var vals = []; block.find(".wiktku-dfn-etiket-list textarea").each(function () { var v = $.trim($(this).val()); if (v) vals.push(v); }); return vals; }()); function readList(cls) { var vals = []; block.find("." + cls + "-list textarea").each(function () { var v = $.trim($(this).val()); if (v) vals.push(v); }); return vals; } // Nimûne items are compound: { text, tr?, t? } function readNimuneList() { var items = []; block.find(".wiktku-dfn-nimune-list li.wiktku-dfn-nimune-li").each(function () { var text = $.trim($(this).find(".wiktku-dfn-nimune-text").val()); if (!text) return; var obj = { text: text }; var tr = $.trim($(this).find(".wiktku-dfn-nimune-tr").val()); var t = $.trim($(this).find(".wiktku-dfn-nimune-t").val()); if (tr) obj.tr = tr; if (t) obj.t = t; items.push(obj); }); return items; } // Jêder is a growing list of citations, one per li — mirrors readNimuneList(). function readJederList() { var items = []; block.find(".wiktku-dfn-jeder-list li.wiktku-dfn-jeder-li").each(function () { var li = $(this); var quote = $.trim(li.find(".wiktku-dfn-nimune-quote").val()); if (!quote) return; var obj = { quote: quote }; var qtr = $.trim(li.find(".wiktku-dfn-nimune-quote-tr").val()); var qt = $.trim(li.find(".wiktku-dfn-nimune-quote-t").val()); if (qtr) obj.quoteTr = qtr; if (qt) obj.quoteT = qt; var tplName = li.find(".wiktku-dfn-quote-src-sel").val(); if (tplName === "__manual__") { var manual = $.trim(li.find(".wiktku-dfn-quote-src-manual").val()); if (manual) obj.jederManual = manual; } else if (tplName) { obj.jederTpl = tplName; var fields = {}; li.find(".wiktku-dfn-quote-src-input").each(function () { var k = $(this).attr("data-field-key"); var v = $.trim($(this).val()); if (k && v) fields[k] = v; }); obj.jêderFields = fields; } items.push(obj); }); return items; } senses.push({ tpl: tpl, tplNoLang: tplNoLang, tplTitle: tplTitle, mane: mane, etiket: etiket, nimune: readNimuneList(), jeder: readJederList(), alternativ: readList("wiktku-dfn-alternativ"), hevmane: readList("wiktku-dfn-hevmane"), dijmane: readList("wiktku-dfn-dijmane"), koordine: readList("wiktku-dfn-koordine"), jornav: readList("wiktku-dfn-jornav"), jernav: readList("wiktku-dfn-jernav") }); }); return senses; }, getOutput: function (values, callback) { var stepDiv = $("#wiktku-start-dfn"); var senses = steps.dfn.getSenses(stepDiv); var lang = values.lang; // A sense counts as "filled" if it has a mane, a chosen template + title, // or any other content (etîket/hevmane/nimûne/jêder…) worth keeping. var hasMane = senses.some(function (s) { return s.mane !== "" || (s.tpl && s.tplTitle) || senseHasExtraContent(s); }); // True only when at least one sense has a regular mane (needs linkify). var hasRegularMane = senses.some(function (s) { return !s.tpl && s.mane !== ""; }); // nimûne and jêder lines must never pass through linkify — only // the plain mane text should be linkified. We build two parallel // arrays: defLines (sent to linkify) and citeLines (kept aside). // Each entry in citeLines corresponds 1-to-1 with a defLines entry; // a template token {{wiktku-cite-N}} is embedded in defLines so // that after linkify runs we know exactly where to splice them back. // Template-call syntax is guaranteed safe: linkifiers leave {{ }} // tokens completely untouched. var defLines = []; // one entry per kept sense (goes to linkify) var citeLines = []; // parallel — nimûne+jêder for that same sense $.each(senses, function (_, sense) { // — Template sense (e.g. {{guharto|ku|somepage}}) — if (sense.tpl) { if (!sense.tplTitle) return; // skip empty template senses var tplLabelTpl = ""; if (sense.etiket && sense.etiket.length) { var tplLabelParts = sense.etiket.map(function (part) { return $.trim(part); }).filter(function (part) { return part !== ""; }); if (tplLabelParts.length) { tplLabelTpl = " {{e|" + lang + "|" + tplLabelParts.join("|") + "}} "; } } var tplCall = sense.tplNoLang ? "{{" + sense.tpl + "|" + sense.tplTitle + "}}" : "{{" + sense.tpl + "|" + lang + "|" + sense.tplTitle + "}}"; var tplHasJeder = sense.jeder && $.grep(sense.jeder, function (j) { return j && j.quote; }).length > 0; var idx = defLines.length; var cite = formatNimune(sense.nimune, lang, tplHasJeder) + formatJeder(sense.jeder, lang); defLines.push("#" + (tplLabelTpl ? tplLabelTpl : " ") + tplCall + (cite ? "{{wiktku-cite-" + idx + "}}" : "")); citeLines.push(cite); return; } // — Normal mane sense — var dfn = sense.mane; if (!dfn && !senseHasExtraContent(sense)) return; // truly empty if (dfn) { dfn = stripWikilinks(dfn); if (dfn[0] !== dfn[0].toUpperCase()) dfn = capitalize(dfn); if (!dfn.match(/[.…?!)\]]$/)) dfn += "."; } else { dfn = "{{mane?|" + lang + "}}"; } var labelTpl = ""; if (sense.etiket && sense.etiket.length) { var labelParts = sense.etiket.map(function (part) { return $.trim(part); }).filter(function (part) { return part !== ""; }); if (labelParts.length) { labelTpl = " {{e|" + lang + "|" + labelParts.join("|") + "}} "; } } var out = "#" + (labelTpl ? labelTpl : " ") + dfn; function wordLine(tpl, words) { if (!words.length) return ""; return "\n#: {{" + tpl + "|" + lang + "|" + words.join("|") + "}}"; } out += wordLine("alt-r", sense.alternativ); out += wordLine("hevmane", sense.hevmane); out += wordLine("dijmane", sense.dijmane); out += wordLine("koordîne", sense.koordine); out += wordLine("jornav", sense.jornav); out += wordLine("jêrnav", sense.jernav); var hasJeder = sense.jeder && $.grep(sense.jeder, function (j) { return j && j.quote; }).length > 0; var cite = formatNimune(sense.nimune, lang, hasJeder) + formatJeder(sense.jeder, lang); var idx = defLines.length; defLines.push(out + (cite ? "{{wiktku-cite-" + idx + "}}" : "")); citeLines.push(cite); }); // Splice citeLines back into a linkified string, replacing each // {{wiktku-cite-N}} token with its stored nimûne/jêder block. function restoreCites(t) { return t.replace(/\{\{wiktku-cite-(\d+)\}\}/g, function (_, n) { return citeLines[parseInt(n, 10)] || ""; }); } var text = defLines.join("\n") + "\n"; if (!hasMane) { // No definitions entered — emit {{mane?}} with bênimûne. text = "# {{mane?|" + lang + "}}\n#* {{bênimûne|" + lang + "}}\n"; callback(text); return; } if (!hasRegularMane) { // All filled senses are template senses — no linkify needed. callback(restoreCites(text)); return; } var didTryToLoad = function () { if (typeof $.wiktviLinkify === "function") { $.wiktviLinkify(text, function (linked) { callback(restoreCites(linked)); }); } else { callback(restoreCites(text)); } }; mw.loader.using("ext.gadget.linkify", didTryToLoad, didTryToLoad); } }, je: makeWordListStep("je", "jê", "Kelîmeyên jê çêbûyî binivîse", "Jê", "g"), tekildar: makeWordListStep("tekildar", "têkildar", "Kelîmeyên ji aliyê etîmolojiyê ve têkildarî vê kelîmeyê binivîse", "Têkildar", "g"), binereherwiha: makeWordListStep("binereherwiha", "binêre herwiha", "Kelîmeyên din ên eleqedar binivîse", "Binêre herwiha", "g"), etym: { id: "etym", name: "etîmolojî", question_fmt: "Etîmolojiya kelîmeyê binivîse", // etymTpls populated from data.json etymTpls: [], visible: function (values) { return values.lang && values.pos; }, /** Fills (or refills) the insert-dropdown from the current etymTpls array. */ refreshTplSelect: function () { var sel = $("#wiktku-start-etym .wiktku-tpl-insert-select"); if (!sel.length) return; sel.find("option[value!='']").remove(); $.each(steps.etym.etymTpls, function (_, tpl) { sel.append($("<option></option>").val(tpl.snippet).text(tpl.name + " — " + tpl.desc)); }); // Notify Chosen that the option list has changed (no-op on mobile). if (!isMobile) sel.trigger("chosen:updated"); }, build: function (stepDiv) { if (stepDiv.find(".wiktku-etym-wrap").length) return null; var wrap = $("<div class='wiktku-etym-wrap'></div>"); var ta = $("<textarea></textarea>") .attr("name", "wiktku-etym-" + $.now()) .attr("class", "wiktku-start-step-field wiktku-etym-text") .attr("rows", 4) .attr("placeholder", "Nimûne: Ji {{ji|en|ku|apple}}. yan rasterast binivîse…"); // Template insert dropdown — options also refreshed after data.json loads. var sel = $("<select class='wiktku-tpl-insert-select'></select>"); sel.append($("<option value=''>— şablonek lê zêde bike —</option>")); $.each(steps.etym.etymTpls, function (_, tpl) { sel.append($("<option></option>").val(tpl.snippet).text(tpl.name + " — " + tpl.desc)); }); sel.on("change", function () { var snippet = $(this).val(); if (!snippet) return; var lang = getValues().lang || ""; snippet = snippet.replace(/CODE/g, lang).replace(/SOURCELANG/g, "?"); insertAtCursor(ta[0], snippet); $(this).val(""); ta.focus(); }); wrap.append(sel).append($("<br>")).append(ta); stepDiv.append(wrap); return ta; }, output: function (values) { var text = $.trim($("#wiktku-start-etym .wiktku-etym-text").val()); if (text) { return "\n==== Etîmolojî ====\n" + text + "\n"; } // No etymology entered — emit {{ji?|lang}} as a placeholder, // but only when the entry has at least one regular (non-şablon) // sense with content — either real mane text, or an empty mane // with other fields filled in (which dfn.getOutput() renders as // {{mane?|lang}} with those fields attached). A şablon sense // like {{guharto|…}} never counts, filled in or not. var dfnSenses = steps.dfn.getSenses($("#wiktku-start-dfn")); var hasRegularMane = dfnSenses.some(function (s) { return !s.tpl && (s.mane !== "" || senseHasExtraContent(s)); }); if (!hasRegularMane) return ""; return "\n==== Etîmolojî ====\n{{ji?|" + values.lang + "}}\n"; } }, dunde: { id: "dunde", name: "dûnde", question_fmt: "Eger ev kelîme ji vî zimanî ketibe zimanekî din, vî zimanî û kelîmeya wî binivîse", visible: function (values) { return !!values.pos; }, disabledKeys: { "navz": true}, /** * Builds one row: a language dropdown + a growing list of word * inputs. When the dropdown gets a value the next empty row is * appended automatically. Mirrors steps.trans's row widget, but * flat (one shared list — dûnde isn't tied to individual senses). */ buildRow: function (stepDiv) { var row = $("<li class='wiktku-dunde-row wiktku-lang-row'></li>"); // Language selector — chosen is applied after insertion into DOM. var langSel = $(mw.html.element("select", { "class": "wiktku-start-step-keyfield wiktku-start-narrow" })); langSel.attr("data-placeholder", "Zimanekî lê bigere"); populateMenus(langSel, steps.dunde.keys || [], steps.dunde.disabledKeys); // When a language is chosen, ensure a next empty row exists. langSel.on("change", function () { steps.dunde.onLangChange(stepDiv, row); }); // Word list for this language. var wordList = $("<ul class='wiktku-dunde-words wiktku-lang-row-words'></ul>"); var firstWord = steps.dunde.makeWordInput(); wordList.append($("<li></li>").append(firstWord)); if (isMobile) { row.append(wrapNativeSelect(langSel)).append(wordList); } else { row.append(langSel).append(wordList); } return row; }, makeWordInput: function () { var input = $("<textarea></textarea>") .attr("name", "wiktku-dunde-word-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 1) .attr("class", "wiktku-dfn-subfield wiktku-start-narrow") .attr("placeholder", "Kelîme…"); input.on("input", function () { var list = $(this).closest("ul.wiktku-dunde-words"); var item = $(this).parent(); var val = $.trim($(this).val()); if (val && item.is(list.children("li:last-child"))) { var next = steps.dunde.makeWordInput(); list.append($("<li></li>").append(next)); } }); return input; }, onLangChange: function (stepDiv, row) { var list = stepDiv.find("ul.wiktku-dunde-list"); var isLast = row.is(list.children("li.wiktku-dunde-row:last-child")); if (isLast) { var newRow = steps.dunde.buildRow(stepDiv); list.append(newRow); // Init chosen after the new row is in the DOM (desktop only). if (!isMobile) newRow.find("select").chosen(chosenOptions); } // Keep disabled keys in sync across all lang selectors. steps.dunde.syncDisabledKeys(stepDiv); }, /** Disables already-selected languages in all other dropdowns. */ syncDisabledKeys: function (stepDiv) { var taken = $.extend({}, steps.dunde.disabledKeys); stepDiv.find("li.wiktku-dunde-row select").each(function () { var v = $(this).val(); if (v) taken[v] = true; }); stepDiv.find("li.wiktku-dunde-row select").each(function () { var self = $(this); var own = self.val(); self.find("option").each(function () { var code = $(this).val(); if (!code) return; $(this).prop("disabled", taken[code] && code !== own); }); self.trigger("chosen:updated"); }); }, build: function (stepDiv) { if (stepDiv.find("ul.wiktku-dunde-list").length) return null; var list = $("<ul class='wiktku-dunde-list wiktku-lang-row-list'></ul>"); list.append(steps.dunde.buildRow(stepDiv)); stepDiv.append(list); // Init chosen after the select is in the DOM (desktop only). if (!isMobile) list.find("select").chosen(chosenOptions); return null; }, /** Reads all [langcode, words[]] rows from the DOM. */ getRows: function (stepDiv) { var result = []; stepDiv.find("li.wiktku-dunde-row").each(function () { var lang = $(this).find("select").val(); if (!lang) return; var words = []; $(this).find("ul.wiktku-dunde-words textarea").each(function () { var v = $.trim($(this).val()); if (v) words.push(v); }); if (words.length) result.push([lang, words]); }); return result; }, output: function () { var stepDiv = $("#wiktku-start-dunde"); var rows = steps.dunde.getRows(stepDiv); if (!rows.length) return ""; var lines = $.map(rows, function (row) { var lang = row[0], words = row[1]; return "* {{dû|" + lang + "|" + words.join("|") + "}}"; }); return "\n==== Dûnde ====\n" + lines.join("\n") + "\n"; } }, zarava: { id: "zarava", name: "bi zaravayên din", visible: function (values) { return steps.trans.visible(values); }, disabledKeys: { "navz": true }, buildRow: function (group) { var row = $("<li class='wiktku-zarava-row wiktku-lang-row'></li>"); var langSel = $(mw.html.element("select", { "class": "wiktku-start-step-keyfield wiktku-start-narrow" })); populateMenus(langSel, steps.zarava.keys || [], steps.zarava.disabledKeys); langSel.on("change", function () { steps.zarava.onLangChange(group, row); }); var wordList = $("<ul class='wiktku-zarava-words wiktku-lang-row-words'></ul>"); var firstWord = steps.zarava.makeWordInput(); wordList.append($("<li></li>").append(firstWord)); row.append(langSel).append(wordList); return row; }, makeWordInput: function () { var input = $("<textarea></textarea>") .attr("name", "wiktku-zarava-word-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 1) .attr("class", "wiktku-dfn-subfield wiktku-start-narrow") .attr("placeholder", "Tercime…"); input.on("input", function () { var list = $(this).closest("ul.wiktku-zarava-words"); var item = $(this).parent(); var val = $.trim($(this).val()); if (val && item.is(list.children("li:last-child"))) { var next = steps.zarava.makeWordInput(); list.append($("<li></li>").append(next)); } }); return input; }, onLangChange: function (group, row) { var list = group.find("ul.wiktku-zarava-list"); var isLast = row.is(list.children("li.wiktku-zarava-row:last-child")); if (isLast) { var newRow = steps.zarava.buildRow(group); list.append(newRow); } steps.zarava.syncDisabledKeys(group); }, /** Disables already-selected dialects in all other dropdowns within one group. */ syncDisabledKeys: function (group) { var taken = $.extend({}, steps.zarava.disabledKeys); group.find("li.wiktku-zarava-row select").each(function () { var v = $(this).val(); if (v) taken[v] = true; }); group.find("li.wiktku-zarava-row select").each(function () { var self = $(this); var own = self.val(); self.find("option").each(function () { var code = $(this).val(); if (!code) return; $(this).prop("disabled", taken[code] && code !== own); }); }); }, /** Builds (or fetches) the .wiktku-zarava-group for one gloss. */ buildGroup: function (stepDiv, gi) { var group = $("<div class='wiktku-zarava-group'></div>").attr("data-gloss-pos", gi); var list = $("<ul class='wiktku-zarava-list wiktku-lang-row-list'></ul>"); list.append(steps.zarava.buildRow(group)); group.append(list); stepDiv.append(group); return group; }, /** Syncs one .wiktku-zarava-group per current gloss (same logic as steps.trans.build). */ build: function (stepDiv) { var glosses = steps.trans.glossList(); if (!glosses.length) { stepDiv.find(".wiktku-zarava-group").remove(); return null; } var existingGroups = stepDiv.find(".wiktku-zarava-group"); if (existingGroups.length > glosses.length) { existingGroups.slice(glosses.length).remove(); } $.each(glosses, function (gi, gloss) { var group = stepDiv.find(".wiktku-zarava-group[data-gloss-pos='" + gi + "']"); if (!group.length) group = steps.zarava.buildGroup(stepDiv, gi); var label = group.find(".wiktku-zarava-group-label"); if (glosses.length > 1) { if (!label.length) { label = $("<div class='wiktku-zarava-group-label'></div>"); group.prepend(label); } label.text(gloss.index + " " + gloss.text); } else if (label.length) { label.remove(); } }); return null; }, /** Reads the dialect rows for a single gloss group. */ getGroupTranslations: function (group) { var result = []; group.find("li.wiktku-zarava-row").each(function () { var lang = $(this).find("select").val(); if (!lang) return; var words = []; $(this).find("ul.wiktku-zarava-words textarea").each(function () { var v = $.trim($(this).val()); if (v) words.push(v); }); if (words.length) result.push([lang, words]); }); return result; }, /** Reads all rows from the DOM, grouped by gloss position. */ getTranslations: function (stepDiv) { var result = []; stepDiv.find(".wiktku-zarava-group").each(function () { result.push(steps.zarava.getGroupTranslations($(this))); }); return result; }, output: function (values) { if (values.lang !== "ku") return ""; var stepDiv = $("#wiktku-start-zarava"); var glosses = steps.trans.glossList(); if (!glosses.length) return ""; var blocks = $.map(glosses, function (gloss, gi) { var group = stepDiv.find(".wiktku-zarava-group[data-gloss-pos='" + gi + "']"); var rows = group.length ? steps.zarava.getGroupTranslations(group) : []; if (!gloss.text && !rows.length) return undefined; if (rows.length) { rows.sort(function (a, b) { var aLang = langsByCode[a[0]] || []; var bLang = langsByCode[b[0]] || []; return (aLang[2] || "").localeCompare(bLang[2] || "", "ku"); }); } var wordLines = $.map(rows, function (row) { var lang = row[0]; var words = row[1]; var wikiWords = words.map(function (w) { return "{{W|" + lang + "|" + w + "}}"; }).join(", "); return "* {{Z|" + lang + "}}: " + wikiWords; }).join("\n"); if (!wordLines) return undefined; var block = "{{werger-ser|" + (gloss.text || "?") + "|" + gloss.index + "}}"; block += "\n" + wordLines; block += "\n{{werger-bin}}"; return block; }); if (!blocks.length) return ""; return "\n==== Bi zaravayên din ====\n" + blocks.join("\n") + "\n"; } }, trans: { id: "trans", name: "werger", visible: function (values) { if (!(values.lang === "ku" && values.pos)) return false; // Hide Werger only when EVERY sense is a template sense (Guharto etc.) // with a title filled in — i.e. there is real content but no plain // gloss to attach a translation table to. A mix of real + template // senses still shows Werger; the template senses are simply skipped // in output(). // // "Real" here means a non-şablon sense with either mane text or // other filled-in fields (etîket/hevmane/nimûne/jêder…), since // dfn.getOutput() renders the latter too, as {{mane?|lang}} plus // whatever else was filled in. // // When nothing has been filled in at all, output() will emit // {{mane?|lang}} instead of a gloss — but Werger should still show, // since the user may want to add translations before they've // settled on a gloss. var dfnSenses = steps.dfn.getSenses($("#wiktku-start-dfn")); var hasRealSense = dfnSenses.some(function (s) { return !s.tpl && (s.mane !== "" || senseHasExtraContent(s)); }); var hasFilledTplSense = dfnSenses.some(function (s) { return s.tpl && s.tplTitle; }); return hasRealSense || !hasFilledTplSense; }, disabledKeys: { "navz": true, "ku": true, "ckb": true, "sdh": true, "lki": true, "hac": true, "zza": true }, /** * Builds one translation row: a language dropdown + a growing list * of word inputs. When the dropdown gets a value the next empty row * is appended automatically. * * @param group the specific .wiktku-trans-group this row belongs to * (each gloss has its own group and its own list of rows, so the * lookups below must stay scoped to that group rather than the * whole step — the step now holds one list per gloss). */ buildRow: function (group) { var row = $("<li class='wiktku-trans-row wiktku-lang-row'></li>"); // Language selector — chosen is applied after insertion into DOM. var langSel = $(mw.html.element("select", { "class": "wiktku-start-step-keyfield wiktku-start-narrow" })); langSel.attr("data-placeholder", "Zimanekî lê bigere"); populateMenus(langSel, steps.trans.keys || [], steps.trans.disabledKeys); // When a language is chosen, ensure a next empty row exists. langSel.on("change", function () { steps.trans.onLangChange(group, row); }); // Word list for this language. var wordList = $("<ul class='wiktku-trans-words wiktku-lang-row-words'></ul>"); var firstWord = steps.trans.makeWordInput(); wordList.append($("<li></li>").append(firstWord)); if (isMobile) { row.append(wrapNativeSelect(langSel)).append(wordList); } else { row.append(langSel).append(wordList); } return row; }, makeWordInput: function () { var input = $("<textarea></textarea>") .attr("name", "wiktku-trans-word-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 1) .attr("class", "wiktku-dfn-subfield wiktku-start-narrow") .attr("placeholder", "Tercime…"); input.on("input", function () { var list = $(this).closest("ul.wiktku-trans-words"); var item = $(this).parent(); var val = $.trim($(this).val()); if (val && item.is(list.children("li:last-child"))) { var next = steps.trans.makeWordInput(); list.append($("<li></li>").append(next)); } }); return input; }, onLangChange: function (group, row) { var list = group.find("ul.wiktku-trans-list"); var isLast = row.is(list.children("li.wiktku-trans-row:last-child")); if (isLast) { var newRow = steps.trans.buildRow(group); list.append(newRow); // Init chosen after the new row is in the DOM (desktop only). if (!isMobile) newRow.find("select").chosen(chosenOptions); } // Keep disabled keys in sync across this gloss's lang selectors // only — the same language can be used for different senses. steps.trans.syncDisabledKeys(group); }, /** Disables already-selected languages in all other dropdowns within one group. */ syncDisabledKeys: function (group) { var taken = $.extend({}, steps.trans.disabledKeys); group.find("li.wiktku-trans-row select").each(function () { var v = $(this).val(); if (v) taken[v] = true; }); group.find("li.wiktku-trans-row select").each(function () { var self = $(this); var own = self.val(); self.find("option").each(function () { var code = $(this).val(); if (!code) return; $(this).prop("disabled", taken[code] && code !== own); }); self.trigger("chosen:updated"); }); }, /** * Builds (or fetches) the .wiktku-trans-group for one gloss, with * its own label and its own list of translation rows. */ buildGroup: function (stepDiv, gi) { var group = $("<div class='wiktku-trans-group'></div>").attr("data-gloss-pos", gi); var list = $("<ul class='wiktku-trans-list wiktku-lang-row-list'></ul>"); list.append(steps.trans.buildRow(group)); group.append(list); stepDiv.append(group); // Init chosen after the select is in the DOM (desktop only). if (!isMobile) list.find("select").chosen(chosenOptions); return group; }, /** * Syncs one .wiktku-trans-group per current gloss, adding new * groups and removing stale ones as senses are added or removed, * while leaving existing groups (and whatever translations the * user has already typed into them) untouched. Groups are keyed * to their gloss's position in glossList() via data-gloss-pos, so * a group always matches the same sense across rebuilds as long * as senses aren't reordered relative to each other. */ build: function (stepDiv) { var glosses = steps.trans.glossList(); if (!glosses.length) { stepDiv.find(".wiktku-trans-group").remove(); return null; } // Drop groups for glosses that no longer exist (always from the // tail — groups are only ever appended in gloss order below). var existingGroups = stepDiv.find(".wiktku-trans-group"); if (existingGroups.length > glosses.length) { existingGroups.slice(glosses.length).remove(); } $.each(glosses, function (gi, gloss) { var group = stepDiv.find(".wiktku-trans-group[data-gloss-pos='" + gi + "']"); if (!group.length) group = steps.trans.buildGroup(stepDiv, gi); // Only label groups when there's more than one gloss to // distinguish between — a single gloss needs no caption. var label = group.find(".wiktku-trans-group-label"); if (glosses.length > 1) { if (!label.length) { label = $("<div class='wiktku-trans-group-label'></div>"); group.prepend(label); } label.text(gloss.index + " " + gloss.text); } else if (label.length) { label.remove(); } }); return null; }, /** Reads the translation rows for a single gloss group. */ getGroupTranslations: function (group) { var result = []; group.find("li.wiktku-trans-row").each(function () { var lang = $(this).find("select").val(); if (!lang) return; var words = []; $(this).find("ul.wiktku-trans-words textarea").each(function () { var v = $.trim($(this).val()); if (v) words.push(v); }); if (words.length) result.push([lang, words]); }); return result; }, /** * Reads all translation rows from the DOM, grouped by gloss * position — one array of [lang, words] rows per gloss group, in * the same order as the .wiktku-trans-group elements. */ getTranslations: function (stepDiv) { var result = []; stepDiv.find(".wiktku-trans-group").each(function () { result.push(steps.trans.getGroupTranslations($(this))); }); return result; }, /** * Builds the numbered "{ index, gloss }" list — one entry per dfn * sense that has a real mane (skips template senses like Guharto, * which have nothing to caption a translation table with). The * index matches the sense's actual position in the numbered "#" * definition list (1-based), including template senses in the count, * so the number printed next to {{werger-ser}} lines up with the * gloss the reader sees in the entry. * * When nothing has been filled in at all (dfn.getOutput() will emit * {{mane?|lang}} as sense 1), this returns a single placeholder * entry with empty text instead of an empty array, so Werger still * has one group to attach translations to before a gloss exists. * When every filled sense is a template sense instead, this stays * empty — that mirrors trans.visible()'s hidden case, where there's * no group in the DOM for a placeholder to attach to anyway. */ glossList: function () { var dfnSenses = steps.dfn.getSenses($("#wiktku-start-dfn")); var glosses = []; var hasFilledTplSense = false; $.each(dfnSenses, function (i, s) { if (s.tpl) { if (s.tplTitle) hasFilledTplSense = true; return; // template sense — no gloss to caption with } var dfn = s.mane; if (!dfn) { // No mane text, but other fields (etîket/hevmane/nimûne/ // jêder…) are filled — dfn.getOutput() still emits this // sense as a numbered line using {{mane?|lang}}, so it // needs its own gloss group too, just with no caption text. if (senseHasExtraContent(s)) glosses.push({ index: i + 1, text: "" }); return; } if (dfn[0] !== dfn[0].toLowerCase()) dfn = decapitalize(dfn); dfn = stripWikilinks(dfn).replace(/[.…?!)\]،؟]+$/, ""); glosses.push({ index: i + 1, text: dfn }); }); if (!glosses.length && !hasFilledTplSense) { glosses.push({ index: 1, text: "" }); } return glosses; }, output: function (values) { if (values.lang !== "ku") return ""; var stepDiv = $("#wiktku-start-trans"); var glosses = steps.trans.glossList(); // Every sense is a template sense — there's no real gloss // anywhere and no group in the DOM either (glossList() only // returns empty in that case), so skip the section entirely. if (!glosses.length) return ""; // Each gloss now has its own group of translation rows — // attach every gloss's own words under its own werger-ser/-bin // pair instead of dumping everything under the first one. var blocks = $.map(glosses, function (gloss, gi) { var group = stepDiv.find(".wiktku-trans-group[data-gloss-pos='" + gi + "']"); var rows = group.length ? steps.trans.getGroupTranslations(group) : []; // Placeholder gloss (no real mane entered yet) with nothing // translated into it — nothing to output, and gloss.text is // empty so there's no caption to give {{werger-ser}} anyway. if (!gloss.text && !rows.length) return undefined; if (rows.length) { // Sort by Kurdish sort key. rows.sort(function (a, b) { var aLang = langsByCode[a[0]] || []; var bLang = langsByCode[b[0]] || []; return (aLang[2] || "").localeCompare(bLang[2] || "", "ku"); }); } var wordLines = $.map(rows, function (row) { var lang = row[0]; var words = row[1]; var wikiWords = words.map(function (w) { return "{{W|" + lang + "|" + w + "}}"; }).join(", "); return "* {{Z|" + lang + "}}: " + wikiWords; }).join("\n"); var block = "{{werger-ser|" + (gloss.text || "?") + "|" + gloss.index + "}}"; if (wordLines) block += "\n" + wordLines; block += "\n{{werger-bin}}"; return block; }); if (!blocks.length) return ""; return "\n==== Werger ====\n" + blocks.join("\n") + "\n"; } }, }; steps.trans.keys = steps.lang.choices; steps.dunde.keys = steps.lang.choices; steps.zarava.keys = getZaravaKeys(steps.lang.choices); var ordered_steps = [ steps.lang, steps.pron, steps.pos, steps.cinsiyet, steps.lektur, steps.tr, steps.dfn, steps.je, steps.tekildar, steps.etym, steps.dunde, steps.binereherwiha, steps.zarava, steps.trans]; // Step ids that belong to each section (not shared across sections). var PER_SECTION_STEP_IDS = [ "pos", "cinsiyet", "lektur", "tr", "dfn", "je", "tekildar", "etym", "dunde", "binereherwiha", "zarava", "trans" ]; // ── Multi-section state ────────────────────────────────────────────────── // Each entry is a plain snapshot: { pos, cinsiyet, lektur, tr, dfn (senses[]), // je, tekildar, binereherwiha, trans (rows[]) }. var sections = [{}]; // section 0 starts empty (DOM is the truth) var activeSection = 0; function snapshotDfn() { return steps.dfn.getSenses($("#wiktku-start-dfn")); } /** * Rebuild the dfn DOM from a previously snapshotted senses array. */ function restoreDfn(senses) { var stepDiv = $("#wiktku-start-dfn"); // Tear down the existing list so build() recreates it cleanly. stepDiv.find("ol.wiktku-dfn-list").remove(); steps.dfn.build(stepDiv); var list = stepDiv.find("ol.wiktku-dfn-list"); $.each(senses, function (i, sense) { // Ensure enough blocks exist (build() seeds one). var blocks = list.find("li.wiktku-dfn-sense"); var block = blocks.eq(i); if (!block.length) { var nb = steps.dfn.buildSenseBlock(stepDiv); list.append(nb); block = list.find("li.wiktku-dfn-sense").last(); } // Template selector. block.find("select.wiktku-dfn-tpl-select").val(sense.tpl || ""); if (sense.tpl) { block.find("textarea.wiktku-dfn-mane").hide(); block.find("input.wiktku-dfn-tpl-title").val(sense.tplTitle || "").show(); } else { block.find("textarea.wiktku-dfn-mane").val(sense.mane || "").show(); block.find("input.wiktku-dfn-tpl-title").hide().val(""); } // Re-sync the formên alternatîv/hevmane/… hide state now that // tplSelect's value was set programmatically (its own "change" // handler doesn't fire from .val(), so this doesn't happen otherwise). var updateVis = block.data("updateFieldVisibility"); if (updateVis) updateVis(); // Restore a sub-list (etiket, formên alternatîv, hevmane …) from a values array. function restoreSubList(cls, values) { if (!values || !values.length) return; var groupDiv = block.find("." + cls + "-group"); var subList = groupDiv.find("ol, ul").first(); if (!subList.length) return; // group not found // Fill existing items, append new ones as needed. $.each(values, function (j, val) { var items = subList.find("li"); if (j < items.length) { items.eq(j).find("textarea").val(val); } else { var ta = $("<textarea></textarea>") .attr("name", "wiktku-dfn-restore-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 1) .attr("class", "wiktku-dfn-subfield wiktku-start-narrow") .val(val); ta.on("input", function () { steps.dfn.onSubInput(subList, this, 1, true); }); subList.append($("<li></li>").append(ta)); } }); } // Reveal and populate lazy groups that have data. var lazyMap = { "wiktku-dfn-etiket": sense.etiket, "wiktku-dfn-alternativ": sense.alternativ, "wiktku-dfn-hevmane": sense.hevmane, "wiktku-dfn-dijmane": sense.dijmane, "wiktku-dfn-koordine": sense.koordine, "wiktku-dfn-jornav": sense.jornav, "wiktku-dfn-jernav": sense.jernav }; $.each(lazyMap, function (cls, vals) { if (vals && vals.length) restoreSubList(cls, vals); }); // Nimûne items are objects { text, tr?, t? } — restore using the builder. if (sense.nimune && sense.nimune.length) { var nimuneGroupDiv = block.find(".wiktku-dfn-nimune-group"); var nimuneList = nimuneGroupDiv.find("ol.wiktku-dfn-nimune-list"); var buildFn = nimuneGroupDiv.data("buildNimuneLi"); nimuneList.empty(); $.each(sense.nimune, function (_, n) { var text = typeof n === "object" ? (n.text || "") : n; if (!text) return; var li = buildFn ? buildFn() : $("<li class='wiktku-dfn-nimune-li'></li>"); li.find(".wiktku-dfn-nimune-text").val(text); if (n.tr) li.find(".wiktku-dfn-nimune-tr").val(n.tr); if (n.t) li.find(".wiktku-dfn-nimune-t").val(n.t); nimuneList.append(li); }); // Always leave a blank trailing item. if (buildFn) nimuneList.append(buildFn()); } // Restore jêder (quote/citation) entries — a growing list, restored using the // builder just like Nimûne. Accepts either the current array shape or a // single legacy object (from older saved sections) for backwards compatibility. var jederArr = $.isArray(sense.jeder) ? sense.jeder : (sense.jeder ? [sense.jeder] : []); if (jederArr.length) { var jederGroupDiv = block.find(".wiktku-dfn-jeder-group"); var jederList = jederGroupDiv.find("ol.wiktku-dfn-jeder-list"); var buildJederFn = jederGroupDiv.data("buildJederLi"); jederList.empty(); $.each(jederArr, function (_, j) { if (!j || !j.quote) return; var li = buildJederFn ? buildJederFn() : $("<li class='wiktku-dfn-jeder-li'></li>"); li.find(".wiktku-dfn-nimune-quote").val(j.quote); if (j.quoteTr) li.find(".wiktku-dfn-nimune-quote-tr").val(j.quoteTr); if (j.quoteT) li.find(".wiktku-dfn-nimune-quote-t").val(j.quoteT); if (j.jederManual) { var manualSel = li.find(".wiktku-dfn-quote-src-sel"); manualSel.val("__manual__").trigger("change"); li.find(".wiktku-dfn-quote-src-manual").val(j.jederManual); } else if (j.jederTpl) { var srcSel = li.find(".wiktku-dfn-quote-src-sel"); srcSel.val(j.jederTpl).trigger("change"); if (j.jêderFields) { $.each(j.jêderFields, function (key, val) { li.find(".wiktku-dfn-quote-src-input[data-field-key='" + key + "']").val(val); }); } } jederList.append(li); }); // Always leave a blank trailing item, same as Nimûne. if (buildJederFn) jederList.append(buildJederFn()); } }); } /** * Snapshot simple (non-dfn) per-section steps from current DOM into obj. */ function saveCurrentSection() { var snap = {}; $.each(PER_SECTION_STEP_IDS, function (_, id) { if (id === "dfn") { snap.dfn = snapshotDfn(); return; } if (id === "etym") { snap.etym = $.trim($("#wiktku-start-etym .wiktku-etym-text").val()); return; } var step = steps[id]; if (!step) return; var stepDiv = $("#wiktku-start-" + id); if (id === "trans") { snap.trans = steps.trans.getTranslations(stepDiv); return; } if (id === "zarava") { snap.zarava = steps.zarava.getTranslations(stepDiv); return; } if (id === "dunde") { snap.dunde = steps.dunde.getRows(stepDiv); return; } // Generic: read all step fields. var fields = stepDiv.find(".wiktku-start-step-field"); if (step.multiple) { snap[id] = fields.map(function () { return $(this).val(); }).get(); } else { snap[id] = fields.val(); } }); sections[activeSection] = snap; } /** * Restore a previously saved snapshot into the form DOM. */ function restoreSection(snap) { $.each(PER_SECTION_STEP_IDS, function (_, id) { if (id === "dfn") { restoreDfn(snap.dfn || []); return; } if (id === "etym") { $("#wiktku-start-etym .wiktku-etym-wrap").remove(); steps.etym.build($("#wiktku-start-etym")); $("#wiktku-start-etym .wiktku-etym-text").val(snap.etym || ""); return; } if (id === "trans") { // Rebuild trans groups (dfn must already be restored by this // point in the $.each loop, so glossList() reflects it). var transDiv = $("#wiktku-start-trans"); transDiv.find(".wiktku-trans-group").remove(); steps.trans.build(transDiv); var groupsSnap = snap.trans || []; $.each(groupsSnap, function (gi, rows) { var group = transDiv.find(".wiktku-trans-group[data-gloss-pos='" + gi + "']"); if (!group.length) return; // gloss no longer exists — drop its rows var list = group.find("ul.wiktku-trans-list"); $.each(rows, function (j, row) { var lang = row[0], words = row[1]; var lastRow = list.find("li.wiktku-trans-row").last(); lastRow.find("select").val(lang).trigger("change"); var wordList = lastRow.find("ul.wiktku-trans-words"); $.each(words, function (k, word) { var wordItems = wordList.find("li"); if (k < wordItems.length) { wordItems.eq(k).find("textarea").val(word); } else { // .val() below doesn't fire "input", so the normal // auto-grow never runs — append a matching item // ourselves instead of silently dropping the word. var extraInput = steps.trans.makeWordInput(); wordList.append($("<li></li>").append(extraInput)); extraInput.val(word); } }); // Leave one trailing empty field so the row can still grow // when the user types, matching a freshly-built row. if ($.trim(wordList.children("li").last().find("textarea").val())) { wordList.append($("<li></li>").append(steps.trans.makeWordInput())); } }); }); return; } if (id === "zarava") { // Rebuild zarava groups (dfn must already be restored by this // point in the $.each loop, so glossList() reflects it). var zaravaDiv = $("#wiktku-start-zarava"); zaravaDiv.find(".wiktku-zarava-group").remove(); steps.zarava.build(zaravaDiv); var zaravaGroupsSnap = snap.zarava || []; $.each(zaravaGroupsSnap, function (gi, rows) { var group = zaravaDiv.find(".wiktku-zarava-group[data-gloss-pos='" + gi + "']"); if (!group.length) return; // gloss no longer exists — drop its rows var list = group.find("ul.wiktku-zarava-list"); $.each(rows, function (j, row) { var lang = row[0], words = row[1]; var lastRow = list.find("li.wiktku-zarava-row").last(); lastRow.find("select").val(lang).trigger("change"); var wordList = lastRow.find("ul.wiktku-zarava-words"); $.each(words, function (k, word) { var wordItems = wordList.find("li"); if (k < wordItems.length) { wordItems.eq(k).find("textarea").val(word); } else { var extraInput = steps.zarava.makeWordInput(); wordList.append($("<li></li>").append(extraInput)); extraInput.val(word); } }); if ($.trim(wordList.children("li").last().find("textarea").val())) { wordList.append($("<li></li>").append(steps.zarava.makeWordInput())); } }); }); return; } if (id === "dunde") { // Rebuild dunde rows. var dundeDiv = $("#wiktku-start-dunde"); dundeDiv.find("ul.wiktku-dunde-list").remove(); steps.dunde.build(dundeDiv); var dundeRows = snap.dunde || []; $.each(dundeRows, function (i, row) { var lang = row[0], words = row[1]; var list = dundeDiv.find("ul.wiktku-dunde-list"); var lastRow = list.find("li.wiktku-dunde-row").last(); lastRow.find("select").val(lang).trigger("change"); var wordList = lastRow.find("ul.wiktku-dunde-words"); $.each(words, function (j, word) { var wordItems = wordList.find("li"); if (j < wordItems.length) { wordItems.eq(j).find("textarea").val(word); } else { // .val() below doesn't fire "input", so the normal // auto-grow never runs — append a matching item // ourselves instead of silently dropping the word. var extraInput = steps.dunde.makeWordInput(); wordList.append($("<li></li>").append(extraInput)); extraInput.val(word); } }); // Leave one trailing empty field so the row can still grow // when the user types, matching a freshly-built row. if ($.trim(wordList.children("li").last().find("textarea").val())) { wordList.append($("<li></li>").append(steps.dunde.makeWordInput())); } }); return; } var step = steps[id]; if (!step) return; var stepDiv = $("#wiktku-start-" + id); var fields = stepDiv.find(".wiktku-start-step-field"); var val = snap[id]; if (val === undefined || val === null) return; if (step.multiple) { var arr = val; fields.each(function (i) { if (i < arr.length) $(this).val(arr[i]); }); } else { fields.val(val); } // Notify chosen widgets of the programmatic value change. if (!isMobile) fields.filter("select").trigger("chosen:updated"); }); } function getWikitextForCurrentSection(callback) { var values = getValues(); var entry = steps.pos.output(values); steps.dfn.getOutput(values, function (output) { entry += output; entry += steps.je.output(values); entry += steps.tekildar.output(values); entry += steps.etym.output(values); entry += steps.dunde.output(values); entry += steps.binereherwiha.output(values); entry += steps.zarava.output(values); entry += steps.trans.output(values); callback(entry, values); }); } function getWikitextAllSections(callback) { saveCurrentSection(); var results = new Array(sections.length); var sharedValues = getValues(); // lang/pron are shared function processSection(i) { if (i >= sections.length) { // All done — restore original active section. restoreSection(sections[activeSection]); refresh(); callback(results, sharedValues); return; } restoreSection(sections[i]); refresh(); getWikitextForCurrentSection(function (sectionText) { results[i] = sectionText; processSection(i + 1); }); } processSection(0); } /** * Assembles wikitext for all sections plus the shared lang/pron header. */ function getWikitext(callback) { getWikitextAllSections(function (sectionTexts, sharedValues) { var entry = steps.lang.output(sharedValues); entry += steps.pron.output(sharedValues); entry += sectionTexts.join("\n"); // Edit summary uses section 0's values. Read from the saved snapshot // (not the live DOM) so it doesn't mix section 0's pos with whichever // section happens to be active/restored at this point. var dfnSenses = (sections[0] && sections[0].dfn) || []; var dfnSummary = dfnSenses.map(function (s) { return s.mane; }).filter(Boolean).join("; "); var summaryLabel = addLangMode ? "WF:Ziman lê zêde" : "WF:Nû"; var summary = "([[Mediawiki:Gadget-start.js|" + summaryLabel + "]] v.2.0) +" + sharedValues.lang + ":" + sections[0].pos + ":" + dfnSummary; var summaryField = document.getElementById("wpSummary"); if (addLangMode && summaryField.value) { summary = summaryField.value + " " + summary; } summaryField.value = summary; callback(entry); }); } var continueBtn; function getValuesForStep(stepId) { var fields = $("#wiktku-start-" + stepId + " .wiktku-start-step-field"); var step = steps[stepId]; if (step.keys) { var values = {}; fields.each(function (i, field) { var key = $(field).prevAll(".wiktku-start-step-keyfield").val(); if (key) values[key] = $(field).val(); }); return values; } else if (step.multiple) { return fields.map(function () { return $(this).val(); }).get(); } return fields.val(); } function getValues() { var values = {}; $.each(steps, function (stepId) { values[stepId] = getValuesForStep(stepId); }); return values; } function populateMenus(inputs, choices, disabledValues) { if (!disabledValues) disabledValues = {}; var vals = inputs.map(function (i, input) { return $(input).val(); }); inputs.empty(); inputs.append($("<option></option>")); $.each(choices, function (j, choice) { // Append the language code in parentheses so that typing a code // (e.g. "ku") in the search box still finds the language name. var displayText = capitalize(choice[1]); if (choice[2] !== undefined) { // This is a language choice [code, name, sortKey] — show code. displayText = capitalize(choice[1]) + " (" + choice[0] + ")"; } var option = $(mw.html.element("option", { value: choice[0] }, displayText)); if (disabledValues[choice[0]]) option.prop("disabled", true); inputs.append(option); }); inputs.val(function (i) { return vals[i]; }); } /** * Returns a bitmap containing the keys that should be disabled for a key * menu in the given step because they are disabled or already taken by * another key menu. */ function getDisabledKeys(step) { var occupiedKeys = {}; $("#wiktku-start-" + step.id + " .wiktku-start-step-keyfield").each(function () { occupiedKeys[$(this).val()] = true; }); if (step.disabledKeys) $.extend(occupiedKeys, step.disabledKeys); return occupiedKeys; } function buildKeyInput(step) { if (!step.keys) return undefined; var input = $(mw.html.element("select", { "class": "wiktku-start-step-keyfield wiktku-start-narrow" })); input.attr("data-placeholder", "Hilbijêre " + step.keyName); if (isMobile) { populateMenus(input, step.keys, getDisabledKeys(step)); // On mobile return the wrapper; the select is inside it. // Change events still fire on the inner select. return wrapNativeSelect(input); } input.on("chosen:showing_dropdown", function () { $(this).data("wiktku-defaultValue", $(this).val()); }); input.change(function (_, context) { var inputs = $("#wiktku-start-" + step.id + " .wiktku-start-step-keyfield").not(this); var oldValue = $(this).data("wiktku-defaultValue"); var newValue = context.selected; inputs.find("option[value='" + oldValue + "']").prop('disabled', false); inputs.find("option[value='" + newValue + "']").prop('disabled', true); inputs.trigger("chosen:updated"); }); populateMenus(input, step.keys, getDisabledKeys(step)); return input; } /** * If the current text field has text and there are no more text fields after * the current text field in the list, add another text field to the list. */ function refreshForTextField(currentInput, step) { currentInput = $(currentInput); var value = currentInput.val(); var item = currentInput.parent(); if (value && !item.next("li").length) { var nextInput = $("<textarea></textarea>") .attr("name", "wiktku-field-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("class", currentInput.attr("class")) .attr("rows", currentInput.attr("rows") || 1); nextInput.on("input", function (evt) { refreshForTextField(evt.target, step); }); var nextKeyInput = buildKeyInput(step); var nextItem = $("<li></li>").append(nextKeyInput).append(nextInput); item.parent().append(nextItem); if (nextKeyInput) nextKeyInput.chosen(chosenOptions); } var canContinue = !continueBtn.isDisabled(); if ((value && !canContinue) || (!value && canContinue)) { refresh(step); } } function prepareInput(input, step) { if (!input) return; if (step.required) input.prop('required', true); input.change(step, refresh); } /** * Shows and hides all the steps based on whether their prerequisites are met, * and updates placeholders where applicable. */ function refresh(evt) { var values = getValues(); var changedStep = evt && evt.data; var didFocus = false; var canContinue = true; // Re-filter template options in every sense block whenever lang changes. $("#wiktku-start-dfn .wiktku-dfn-tpl-select").each(function () { var fn = $(this).data("updateOptions"); if (typeof fn === "function") fn(); }); // Re-filter pronunciation and etymology template dropdowns when language changes. steps.pron.refreshTplSelect(); steps.etym.refreshTplSelect(); // Sync tr/t sub-fields in every nimûne item to the current language. // tr shown when language needs transliteration; t shown when lang !== "ku". (function () { var lang = values.lang || ""; var showTr = needsTransliteration(lang); var showT = lang && lang !== "ku"; $("#wiktku-start-dfn .wiktku-dfn-nimune-list li.wiktku-dfn-nimune-li").each(function () { var li = $(this); // Ensure the sub-wrapper exists when we need it. var subWrap = li.find(".wiktku-dfn-nimune-sub"); // tr field var trTa = li.find(".wiktku-dfn-nimune-tr"); if (showTr && !trTa.length) { if (!subWrap.length) { subWrap = $("<div></div>").addClass("wiktku-dfn-nimune-sub"); li.append(subWrap); } trTa = $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-tr-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 5) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-tr") .attr("placeholder", "Transkrîpsiyon…"); subWrap.prepend(trTa); } else if (!showTr && trTa.length) { trTa.remove(); } // t field var tTa = li.find(".wiktku-dfn-nimune-t"); if (showT && !tTa.length) { if (!subWrap.length) { subWrap = $("<div></div>").addClass("wiktku-dfn-nimune-sub"); li.append(subWrap); } tTa = $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-t-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 5) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-t") .attr("placeholder", "Tercimeya nimûneyê kurmancî…"); subWrap.append(tTa); } else if (!showT && tTa.length) { tTa.remove(); } // Remove the wrapper if it ended up empty. subWrap = li.find(".wiktku-dfn-nimune-sub"); if (subWrap.length && !subWrap.children().length) subWrap.remove(); }); }()); // Sync tr/t sub-fields in every jêder citation to the current language. // tr shown when language needs transliteration; t shown when lang !== "ku". (function () { var lang = values.lang || ""; var showTr = needsTransliteration(lang); var showT = lang && lang !== "ku"; $("#wiktku-start-dfn .wiktku-dfn-jeder-list li.wiktku-dfn-jeder-li").each(function () { var li = $(this); // Ensure the sub-wrapper exists when we need it. It must sit right // after the quote textarea and before the source selector. var subWrap = li.find(".wiktku-dfn-quote-sub"); // tr field var trTa = li.find(".wiktku-dfn-nimune-quote-tr"); if (showTr && !trTa.length) { if (!subWrap.length) { subWrap = $("<div></div>").addClass("wiktku-dfn-quote-sub"); li.find(".wiktku-dfn-nimune-quote").after(subWrap); } trTa = $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-quote-tr-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 2) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-quote-tr") .attr("placeholder", "Transkrîpsiyona jêgirtinê…"); subWrap.prepend(trTa); } else if (!showTr && trTa.length) { trTa.remove(); } // t field var tTa = li.find(".wiktku-dfn-nimune-quote-t"); if (showT && !tTa.length) { if (!subWrap.length) { subWrap = $("<div></div>").addClass("wiktku-dfn-quote-sub"); li.find(".wiktku-dfn-nimune-quote").after(subWrap); } tTa = $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-quote-t-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 2) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-quote-t") .attr("placeholder", "Tercimeya jêgirtinê ya kurmancî…"); subWrap.append(tTa); } else if (!showT && tTa.length) { tTa.remove(); } // Remove the wrapper if it ended up empty. subWrap = li.find(".wiktku-dfn-quote-sub"); if (subWrap.length && !subWrap.children().length) subWrap.remove(); }); }()); $.each(steps, function (stepId, step) { if (typeof(step.visible) === "function" && !step.visible(values)) { $("#wiktku-start-" + stepId).slideUp(); } else { var stepDiv = $("#wiktku-start-" + stepId); if (changedStep !== step && typeof(step.build) === "function") { prepareInput(step.build(stepDiv, values), step); } var input = stepDiv.find(".wiktku-start-step-field"); if (typeof(step.example) === "function") { // .find() above already reaches nested fields (e.g. the dfn // step's mane textareas inside each sense block), so one // assignment covers every step; dfn keeps its own fallback. var exampleText = step.example(values) || (step.id === "dfn" ? "Mane…" : ""); input.attr("placeholder", exampleText); } var didSlideDown; if (!didFocus && stepDiv.css("display") === "none" && step.required) { didSlideDown = function (evt) { input.focus(); }; didFocus = true; } stepDiv.slideDown(didSlideDown); } if (step.required && (values[stepId] === "" || (step.multiple && values[stepId].join("") === ""))) { canContinue = false; } }); continueBtn.setDisabled(!canContinue); } function destroy() { $("#wiktku-start-form, .noafterwizard").slideUp(function () { $(this).remove(); }); $(".noarticletext .nowizard, #editform").slideDown(); $("#ca-edit").removeClass("selected"); $("#ca-wiktku-nowizard").addClass("selected"); } // Priority order for Kurdish dialects and the navz pseudo-code. // Codes listed here come before all other languages; unlisted codes // are sorted alphabetically by their display name via localeCompare. var LANG_PRIORITY = ["navz", "ku", "hac", "sdh", "lki", "ckb", "zza"]; /** * Inserts a new == {{ziman|code}} == section into existing page wikitext * at the correct sorted position: * 1. Any content before the first language section is preserved at the top. * 2. navz is always first, then ku/hac/sdh/lki/ckb/zza in that order, * then all other languages sorted by display name (localeCompare). */ function insertNewLangSection(existing, wikitext) { var newCodeMatch = wikitext.match(/^== \{\{ziman\|([^}]+)\}\} ==/); var newCode = newCodeMatch ? newCodeMatch[1] : ""; var sections = []; var preamble = ""; var firstMatch = existing.match(/(?:^|\n)== \{\{ziman\|/); if (!firstMatch) { // No existing lang sections at all — just append. var sep = existing && !/\n\s*$/.test(existing) ? "\n\n" : ""; return existing + sep + wikitext; } // Everything before the first == {{ziman|...}} == is the preamble. var firstSectionStart = existing.indexOf("== {{ziman|"); // Walk back to the start of that line. var lineStart = existing.lastIndexOf("\n", firstSectionStart - 1); var preambleEnd = lineStart !== -1 ? lineStart + 1 : 0; preamble = existing.slice(0, preambleEnd); // Parse each language section: header line + everything until the next header. var body = existing.slice(preambleEnd); // NOTE: with the /m flag, a bare "$" matches end-of-*line*, not just // end-of-string — that previously made the non-greedy content group // stop at the section's first line break instead of running to the // next language header (or the real end of the text), silently // dropping the rest of that section's wikitext. (?![\s\S]) matches // only the true end of the string, /m flag or not. var langSectionRe = /^(== \{\{ziman\|([^}]+)\}\} ==\n?)([\s\S]*?)(?=\n== \{\{ziman\||(?![\s\S]))/gm; var m; while ((m = langSectionRe.exec(body)) !== null) { sections.push({ code: m[2], content: m[0] // full text of this section including header }); } // Determine sort rank: priority list first (by index), then alphabetical. function getLangName(code) { var entry = langsByCode[code]; return entry ? entry[1] : code; } function sortRank(code) { var idx = LANG_PRIORITY.indexOf(code); return idx !== -1 ? idx : LANG_PRIORITY.length; } function compareLangs(a, b) { var ra = sortRank(a), rb = sortRank(b); if (ra !== rb) return ra - rb; // Both are outside priority list — sort by display name. return getLangName(a).localeCompare(getLangName(b), userLang); } // Insert the new section into the sorted list. var newSection = { code: newCode, content: wikitext }; var inserted = false; for (var i = 0; i < sections.length; i++) { if (compareLangs(newCode, sections[i].code) < 0) { sections.splice(i, 0, newSection); inserted = true; break; } } if (!inserted) sections.push(newSection); // Re-join: preamble + sections separated by newlines. var joined = sections.map(function (s) { // Ensure each section ends with exactly one newline before the next. return s.content.replace(/\n+$/, ""); }).join("\n"); return preamble + joined + "\n"; } function build() { $(".nowizard, .nowizard .noafterwizard").hide(); var callToAction = $("#wiktku-calltoaction"); var origCallToActionText = callToAction.text(); $(mw.util.addPortletLink("p-views", "#", "Edîtora çavkaniyê veke", "ca-wiktku-nowizard", "Vê rûpelê bi edîtora çavkaniyê çêke", undefined, "#ca-watch")).click(function (evt) { evt.preventDefault(); callToAction.text(origCallToActionText); destroy(); }); if (callToAction.length) { callToAction.text(origCallToActionText + " Forma li jêr ji bo çêkirina madeyeke nû bi kar bîne."); } var startForm = $("<form id='wiktku-start-form'></form>"); if (addLangMode) { startForm.append($("<p class='wiktku-addlang-notice'></p>").text( "Bi vê formê tu yê beşeke nû li rûpelê îlaw bikî. Eger ev zimanê ku tu îlawe dikî jixwe di rûpelê de hebe, beşa nû li dawiya vî zimanî dê were îlawekirin. " + "Ji kerema xwe netîceya dawî kontrol bikin, eger problemek derkeve, li [[Mediawiki talk:Gadget-start.js|nîqaşa vê amûrê]] problemê ragihîne.")); } var spinner; // Tab bar for switching between POS sections. var sectionTabsDiv = $("<div id='wiktku-section-tabs'></div>"); startForm.submit(function (evt) { evt.preventDefault(); continueBtn.setDisabled(true); spinner.show(); getWikitext(function (wikitext) { if (addLangMode) { var textbox = $("#wpTextbox1"); var existing = textbox.val() || ""; // Check whether the generated lang header already exists in the page. // wikitext always starts with "== {{ziman|CODE}} ==\n" (from steps.lang.output). // If that exact section heading is already present in the existing content, // strip it from the new output and insert the remaining content at the end // of that lang section (just before the next == level-2 heading, or at the // very end of the page if there is no following section). var langHeaderMatch = wikitext.match(/^(== \{\{ziman\|[^}]+\}\} ==\n)/); if (langHeaderMatch) { var langHeader = langHeaderMatch[1]; // e.g. "== {{ziman|ku}} ==\n" // Escape for use in RegExp. var escapedHeader = langHeader.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); if (new RegExp(escapedHeader).test(existing)) { // Strip the header from the new output. var newContent = wikitext.slice(langHeader.length); // Find the insertion point: end of the existing lang section. // A new L2 heading marks the start of the next language block. var afterHeader = existing.indexOf(langHeader); var searchFrom = afterHeader + langHeader.length; // Find the next == … == heading after this section's start. var nextL2 = existing.indexOf("\n== ", searchFrom); var insertAt = nextL2 !== -1 ? nextL2 : existing.length; // Ensure there's a blank line before the inserted block. var before = existing.slice(0, insertAt); var after = existing.slice(insertAt); var sep = /\n\s*$/.test(before) ? "" : "\n"; textbox.val(before + sep + newContent + after); } else { // New language — insert at the correct sorted position. textbox.val(insertNewLangSection(existing, wikitext)); } } else { // Unexpected format — insert at sorted position anyway. textbox.val(insertNewLangSection(existing, wikitext)); } } else { $("#wpTextbox1").val(wikitext); } $("html, body").animate({scrollTop: 0}); callToAction.text("Hindik ma!"); $("#wiktku-preview-container").remove(); destroy(); }); }); $.each(ordered_steps, function (i, step) { var stepDiv = $(mw.html.element("div", { "class": "wiktku-start-step", id: "wiktku-start-" + step.id })); var name = capitalize(step.name); stepDiv.append($(mw.html.element("h3", { "class": "wiktku-start-step-name" }, new mw.html.Raw(mw.html.element("label", { "for": "wiktku-start-" + step.id + "-field" }, name))))); if (step.question_fmt) { stepDiv.append($(mw.html.element("label", { "class": "wiktku-start-step-question", "for": "wiktku-start-" + step.id + "-field" }, step.question_fmt))); if (step.question_br) stepDiv.append($("<br>")); } var input; if (step.choices) { input = $(mw.html.element("select", { "class": "wiktku-start-step-field", id: "wiktku-start-" + step.id + "-field" })); input.attr("data-placeholder", capitalize(step.name) + " hilbijêre "); populateMenus(input, step.choices); if (step.multiple) input.attr("multiple", true); if (isMobile) { stepDiv.append(wrapNativeSelect(input)); } else { stepDiv.append(input); } } else if (typeof(step.build) === "function") { input = step.build(stepDiv); } else { input = $("<textarea></textarea>") .attr("class", "wiktku-start-step-field") .attr("id", "wiktku-start-" + step.id + "-field") .attr("rows", step.rows || 2); if (step.narrow) input.addClass("wiktku-start-narrow"); if (step.multiple) { input.on("input", function (evt) { refreshForTextField(evt.target, step); }); var keyInput = buildKeyInput(step); var list = $(step.ordered ? "<ol></ol>" : "<ul></ul>") .append($("<li></li>").append(keyInput).append(input)); stepDiv.append(list); } else stepDiv.append(input); } prepareInput(input, step); stepDiv.hide(); // Insert tab bar just before the first per-section step. if (step.id === "pos") startForm.append(sectionTabsDiv); startForm.append(stepDiv); }); // ── Section tab helpers ────────────────────────────────────────────── // ── Add-section button — lives in the tab bar, disabled until pos chosen ── var addSectionBtn = new OO.ui.ButtonWidget({ label: "+ Beş zêde bike", disabled: true }); addSectionBtn.on("click", function () { saveCurrentSection(); sections.push({}); activeSection = sections.length - 1; $.each(PER_SECTION_STEP_IDS, function (_, id) { if (id === "dfn") { var stepDiv = $("#wiktku-start-dfn"); stepDiv.find("ol.wiktku-dfn-list").remove(); steps.dfn.build(stepDiv); return; } if (id === "etym") { $("#wiktku-start-etym .wiktku-etym-wrap").remove(); steps.etym.build($("#wiktku-start-etym")); return; } if (id === "trans") { var transDiv = $("#wiktku-start-trans"); transDiv.find(".wiktku-trans-group").remove(); return; } if (id === "zarava") { var zaravaDiv = $("#wiktku-start-zarava"); zaravaDiv.find(".wiktku-zarava-group").remove(); return; } if (id === "dunde") { var dundeDiv = $("#wiktku-start-dunde"); dundeDiv.find("ul.wiktku-dunde-list").remove(); return; } var stepDiv = $("#wiktku-start-" + id); stepDiv.find(".wiktku-start-step-field").val(""); if (!isMobile) stepDiv.find("select.wiktku-start-step-field").trigger("chosen:updated"); }); renderSectionTabs(); refresh(); $("html, body").animate({ scrollTop: sectionTabsDiv.offset().top - 20 }, 300); }); /** Re-render the tab bar to reflect current sections[] and activeSection. */ function renderSectionTabs() { // Detach (not remove) the button first: .empty() strips bound // event data from any children left inside it, which would // silently kill addSectionBtn's click handler on every re-render. addSectionBtn.$element.detach(); sectionTabsDiv.empty(); var lang = getValues().lang || ""; if (!lang) { sectionTabsDiv.hide(); return; } sectionTabsDiv.show(); $.each(sections, function (i) { var posVal = sections[i].pos || ""; var tabLabel = posVal ? capitalize(posVal) : ("Beş " + (i + 1)); var tab = $("<span></span>") .addClass("wiktku-section-tab") .text(tabLabel) .toggleClass("wiktku-tab-active", i === activeSection); (function (idx) { tab.on("click", function () { if (idx === activeSection) return; saveCurrentSection(); activeSection = idx; restoreSection(sections[activeSection]); refresh(); renderSectionTabs(); }); }(i)); sectionTabsDiv.append(tab); }); // Enable "Beş zêde bike" only when the active section has a pos chosen. var activePos = sections[activeSection] && sections[activeSection].pos ? sections[activeSection].pos : getValues().pos; addSectionBtn.setDisabled(!activePos); sectionTabsDiv.append(addSectionBtn.$element); } renderSectionTabs(); // Update the active tab's label whenever pos changes. startForm.on("change", "#wiktku-start-pos-field", function () { renderSectionTabs(); }); // Show the tab bar as soon as a language is selected. startForm.on("change", "#wiktku-start-lang-field", function () { renderSectionTabs(); }); var footer = $("<div id='wiktku-start-footer'></div>"); spinner = $(mw.html.element("img", { id: "wiktku-start-spinner", src: "//upload.wikimedia.org/wikipedia/commons/d/de/Ajax-loader.gif", alt: "Tê barkirin…", title: "Tê barkirin…" })); footer.append(spinner.hide()); continueBtn = new OO.ui.ButtonWidget({ id: "wiktku-unhide-editform", label: "Bişîne", flags: [ "primary", "progressive" ] }); continueBtn.on("click", function () { mw.notify("Tê şandin…", { type: "info", tag: "wiktku-submit" }); startForm.trigger("submit"); }); footer.append(continueBtn.$element); // "Edîtora çavkaniyê veke" button — inline fallback for the portlet link // which is invisible on mobile and easy to miss on desktop. var sourceEditorBtn = new OO.ui.ButtonWidget({ label: "Edîtora çavkaniyê veke", framed: false }); sourceEditorBtn.on("click", function () { destroy(); }); footer.append(sourceEditorBtn.$element); // ── Preview checkboxes ─────────────────────────────────────────────── // Wikitext preview (raw text panel) var previewCheck = $("<input type='checkbox' id='wiktku-preview-toggle'>"); var previewLabel = $("<label for='wiktku-preview-toggle'></label>") .text(" Pêşdîtina wîkîtekstê"); var previewPanel = $("<pre id='wiktku-preview-panel'></pre>").hide(); // Live rendered preview (parsed HTML panel, same logic as AjaxEdit). // Not available on mobile — API polling causes too many problems on small screens. var livePreviewCheck = null; var livePreviewPanel = null; if (!isMobile) { livePreviewCheck = $("<input type='checkbox' id='wiktku-live-preview-toggle'>"); livePreviewPanel = $("<div id='wiktku-live-preview-panel'></div>").hide(); } // Container that holds both panels and switches between stacked / side-by-side. var previewContainer = $("<div id='wiktku-preview-container'></div>"); previewContainer.append(previewPanel); if (!isMobile) previewContainer.append(livePreviewPanel); var previewTimer = null; var livePreviewIntervalId = -1; var livePreviewActive = false; // guards in-flight fetches after uncheck /** Rebuilds wikitext preview if its checkbox is checked. */ function schedulePreview() { if (!previewCheck.prop("checked")) return; clearTimeout(previewTimer); // Debounce: wait 400 ms after the last keystroke before rebuilding. previewTimer = setTimeout(function () { getWikitext(function (wikitext) { previewPanel.text(wikitext).show(); updatePanelLayout(); }); }, 400); } /** Fetches parsed HTML and populates the live preview panel. */ function loadLivePreview() { getWikitext(function (wikitext) { new mw.Api().parse(wikitext, { title: mw.config.get("wgPageName") }).done(function (html) { // Discard result if the user unchecked while the fetch was in flight. if (!livePreviewActive) return; livePreviewPanel.html(html).show(); updatePanelLayout(); }); }); } /** Adjusts panel widths depending on which previews are visible. */ function updatePanelLayout() { var wikitextVisible = previewCheck.prop("checked"); var liveVisible = livePreviewCheck && livePreviewCheck.prop("checked"); if (wikitextVisible && liveVisible) { // Side by side — each panel takes roughly half the available width. previewPanel.css({ "flex": "1 1 45%", "min-width": "280px" }); livePreviewPanel.css({ "flex": "1 1 45%", "min-width": "280px" }); } else { // Full width for whichever is visible — only touch panels that are // actually shown so that setting flex doesn't override display:none. if (wikitextVisible) previewPanel.css({ "flex": "1 1 100%", "min-width": "" }); if (liveVisible && livePreviewPanel) livePreviewPanel.css({ "flex": "1 1 100%", "min-width": "" }); } } previewCheck.on("change", function () { if ($(this).prop("checked")) { schedulePreview(); } else { clearTimeout(previewTimer); previewPanel.hide(); updatePanelLayout(); } }); if (!isMobile) { livePreviewCheck.on("change", function () { if ($(this).prop("checked")) { livePreviewActive = true; livePreviewPanel.show(); loadLivePreview(); livePreviewIntervalId = setInterval(loadLivePreview, 500); } else { livePreviewActive = false; clearInterval(livePreviewIntervalId); livePreviewIntervalId = -1; livePreviewPanel.hide().empty(); updatePanelLayout(); } }); } // Listen on all input/change events on the form and update both previews. startForm.on("input change", function () { schedulePreview(); }); footer.append($("<span style='margin-left:1em'></span>") .append(previewCheck).append(previewLabel)); if (!isMobile) { var livePreviewLabel = $("<label for='wiktku-live-preview-toggle'></label>") .text(" Pêşdîtina zindî"); footer.append($("<span style='margin-left:1em'></span>") .append(livePreviewCheck).append(livePreviewLabel)); } startForm.append(footer); $("#editform").hide().before(startForm); // Insert preview container (holds both panels) after the form. startForm.after(previewContainer); if (!isMobile) startForm.find("select").chosen(chosenOptions); refresh(); // Zimanan ji MediaWiki:Gadget-translation_editor.js/ziman.json bar bike. // Kodên ku bi "-pro" diqedin û navên ku "zimanê destan" tê de heye // tên derxistin. Zimanên xardkirî li serî dimînin, yên din // bi alfabeyê li dû wan tên. // Pinned choices come from MediaWiki:Gadget-start.js/data.json (langChoices), // already loaded into steps.lang.choices before build() runs. var pinnedChoices = steps.lang.choices.slice(); var pinnedCodes = $.map(pinnedChoices, function (choice) { return choice[0]; }); new mw.Api().get({ action: "query", prop: "revisions", titles: "MediaWiki:Gadget-translation_editor.js/ziman.json", rvprop: "content", rvslots: "main", formatversion: 2 }).then(function (data) { var page = data.query.pages[0]; var content = page && page.revisions && page.revisions[0].slots.main.content; var zimanData; try { zimanData = JSON.parse(content); } catch (e) { zimanData = {}; } var extraChoices = []; $.each(zimanData, function (code, name) { // Filter: skip proto-language codes and legendary/reconstructed langs. if (/-pro$/i.test(code)) return; if (/ziman[eê]\s+destan/i.test(name)) return; // Skip codes already in the pinned list (they are handled above). if (pinnedCodes.indexOf(code) !== -1) return; // sortKey: bare name without leading "zimanê " for sorting. var sortKey = name.replace(/^ziman[eê]\s+/i, ""); var choice = [code, name, sortKey]; extraChoices.push(choice); langsByCode[code] = choice; }); // Populate langsByCode for pinned choices too. $.each(pinnedChoices, function (i, choice) { // Ensure pinned choices have a sortKey (index 2). if (choice.length < 3) choice[2] = choice[1]; langsByCode[choice[0]] = choice; }); // Sort the extra choices alphabetically by sort key. extraChoices.sort(function (a, b) { return a[2].localeCompare(b[2], userLang); }); // Final list: pinned first, then the rest. var allChoices = pinnedChoices.concat(extraChoices); steps.lang.choices = allChoices; steps.trans.keys = allChoices; steps.dunde.keys = allChoices; steps.zarava.keys = getZaravaKeys(allChoices); var langMenu = $("#wiktku-start-lang-field"); populateMenus(langMenu, steps.lang.choices); langMenu.trigger("chosen:updated"); var transMenus = $("#wiktku-start-trans .wiktku-start-step-keyfield"); populateMenus(transMenus, steps.trans.keys, getDisabledKeys(steps.trans)); transMenus.trigger("chosen:updated"); var dundeMenus = $("#wiktku-start-dunde .wiktku-start-step-keyfield"); populateMenus(dundeMenus, steps.dunde.keys, getDisabledKeys(steps.dunde)); dundeMenus.trigger("chosen:updated"); var zaravaMenus = $("#wiktku-start-zarava .wiktku-start-step-keyfield"); populateMenus(zaravaMenus, steps.zarava.keys, getDisabledKeys(steps.zarava)); }); } mw.loader.using(["jquery.chosen", "mediawiki.api", "oojs-ui-core"], function () { if (!isMobile) { mw.notify( "Amûr dest pê dike, hinek bisekinin. Not: jkx Sentaks (sentaks highlighter) neaktîv bikin", { type: "info", tag: "wiktku-start-notice", autoHide: true, autoHideSeconds: 10 } ); } // Load metadata, langChoices, posChoices and tplDefs from the companion // data page so they can be updated without touching this script. new mw.Api().get({ action: "query", prop: "revisions", titles: "MediaWiki:Gadget-start.js/data.json", rvprop: "content", rvslots: "main", formatversion: 2 }).then(function (data) { var page = data.query.pages[0]; var content = page && page.revisions && page.revisions[0].slots.main.content; var d; try { d = JSON.parse(content); } catch (e) { d = {}; } // Populate metadata. if (d.metadata) $.extend(metadata, d.metadata); // Populate gender labels. if (d.genderLabels) $.extend(GENDER_BASE_LABELS, d.genderLabels); // Populate lang choices (pinned list used by build() → ziman.json loader). if (d.langChoices) steps.lang.choices = d.langChoices; // Populate POS choices. if (d.posChoices) steps.pos.choices = d.posChoices; // Populate template definitions for the dfn sense-block builder. if (d.tplDefs) steps.dfn.tplDefs = d.tplDefs; // Populate pos placeholder examples. if (d.posExamples) steps.dfn.posExamples = d.posExamples; // Populate citation template definitions for the quote widget. if (d.jederDefs) steps.dfn.jederDefs = d.jederDefs; // Populate pronunciation and etymology template insert lists. if (d.pronTpls) { steps.pron.pronTpls = d.pronTpls; steps.pron.refreshTplSelect(); } if (d.etymTpls) { steps.etym.etymTpls = d.etymTpls; steps.etym.refreshTplSelect(); } // Sync trans/dunde/zarava keys with the (now populated) lang choices. steps.trans.keys = steps.lang.choices; steps.dunde.keys = steps.lang.choices; steps.zarava.keys = getZaravaKeys(steps.lang.choices); }).always(build); }); }); //</nowiki> t7qx8ipx9k21cd9k0rn2ri3pafi8xdh 6265569 6265568 2026-07-19T14:00:51Z Wikihez 7344 6265569 javascript text/javascript // Li ser [[vi:MediaWiki:Gadget-start.js]] hatiye refaktorkirin. //<nowiki> $(function () { if (window.location.href.includes("editintro=User:Wikihez/creation/intro")) { return; // Do not run the script wextê WF:Bilez dişuxile } var ns = mw.config.get("wgNamespaceNumber"); if (ns && !(ns === 2 && mw.config.get("wgPageName").match(/\/ceribandin$|\/test$/))) { return; } var action = mw.config.get("wgAction"); var pageExists = !!mw.config.get("wgArticleId"); // "Zimanek lê zêde bike" mode: triggered from the portlet link below. var addLangMode = pageExists && mw.util.getParamValue("wiktkuaddlang") === "1"; // On a normal page view of an existing page, add the portlet link if (action === "view" && pageExists) { var targetContainer = mw.config.get('skin') === 'vector-2022' ? 'p-cactions' : 'p-tb'; mw.util.addPortletLink(targetContainer, mw.util.getUrl(mw.config.get("wgPageName"), { action: "submit", wiktkuaddlang: "1" }), "+Ziman/beşeke din", "ca-wiktku-addlang", "Ji vê rûpelê re zimanekî nû zêde bike"); return; } if (!(action === "edit" || action === "submit")) { return; } if (!addLangMode && !$(".mw-newarticletext, .mw-newarticletextanon").length) { return; } function capitalize(str) { if (!str) return str; return str[0].toUpperCase() + str.substr(1); } function decapitalize(str) { if (!str) return str; return str[0].toLowerCase() + str.substr(1); } function escapeRegExp(str) { return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); } function stripWikilinks(str) { return str.replace(/\[\[([^\]|]+)(?:\|([^\]]+))?\]\]/g, function (m, target, display) { return display || target; }); } function insertAtCursor(el, text) { var start = el.selectionStart; var end = el.selectionEnd; var val = el.value; el.value = val.slice(0, start) + text + val.slice(end); var pos = start + text.length; el.selectionStart = el.selectionEnd = pos; } var pageName = mw.config.get("wgPageName").replaceAll(/_/g, " "); if (ns) pageName = pageName.replace(/.*\//, ""); var pageNameRe = escapeRegExp(pageName); var userLang = mw.config.get("wgUserLanguage"); // Mobile detection: MobileFrontend sets wgMFMode, or fall back to touch check. var isMobile = !!mw.config.get("wgMFMode") || window.matchMedia("(pointer: coarse)").matches; var chosenOptions = { width: "20em", disable_search_threshold: 0, placeholder_text_single: "Yekî hilbijêre", placeholder_text_multiple: "Hilbijêre", no_results_text: "Nehat dîtin", enable_split_word_search: true, search_contains: true }; function wrapNativeSelect(select) { var placeholder = select.attr("data-placeholder") || "Lê bigere…"; // Hide the native select — we drive it programmatically. select.hide(); var wrapper = $("<span class='wiktku-native-select-wrap'></span>"); var textInput = $("<input type='search' autocomplete='off'>") .attr("placeholder", placeholder) .addClass("wiktku-start-narrow wiktku-ac-input"); var resultsList = $("<ul class='wiktku-ac-results'></ul>").hide(); // Full option cache — rebuilt when chosen:updated fires. var allOptions = []; function cacheOptions() { allOptions = []; select.find("option").each(function () { var v = $(this).val(); if (!v) return; // skip the empty placeholder option allOptions.push({ value: v, text: $(this).text(), disabled: $(this).prop("disabled") }); }); } cacheOptions(); function showResults(query) { var q = query.trim().toLowerCase(); resultsList.empty(); var matched; if (q) { matched = []; $.each(allOptions, function (_, o) { if (o.disabled) return; var codeMatch = o.value.toLowerCase().indexOf(q) !== -1; var nameMatch = o.text.toLowerCase().indexOf(q) !== -1; if (codeMatch || nameMatch) { matched.push({ opt: o, codeMatch: codeMatch }); } }); // Code matches (especially prefix matches) come first. matched.sort(function (a, b) { var aCode = a.opt.value.toLowerCase(); var bCode = b.opt.value.toLowerCase(); var aPrefix = aCode.indexOf(q) === 0; var bPrefix = bCode.indexOf(q) === 0; if (aPrefix !== bPrefix) return aPrefix ? -1 : 1; if (a.codeMatch !== b.codeMatch) return a.codeMatch ? -1 : 1; return 0; }); matched = matched.map(function (item) { return item.opt; }); } else { matched = allOptions.filter(function (o) { return !o.disabled; }); } if (!matched.length) { resultsList.hide(); return; } $.each(matched.slice(0, 50), function (_, opt) { var li = $("<li></li>").text(opt.text).attr("data-value", opt.value); // Use touchend instead of touchstart so that a scroll gesture does // not accidentally select an item. We track whether the finger moved // between touchstart and touchend — if it did, it was a scroll. var touchMoved = false; li.on("touchstart", function () { touchMoved = false; }); li.on("touchmove", function () { touchMoved = true; }); li.on("touchend", function (e) { if (touchMoved) return; // was a scroll, not a tap e.preventDefault(); selectOption(opt.value, opt.text); }); // Keep mousedown for desktop fallback. li.on("mousedown", function (e) { e.preventDefault(); selectOption(opt.value, opt.text); }); resultsList.append(li); }); // Position the list above or below depending on available viewport space. var inputRect = textInput[0].getBoundingClientRect(); var viewportH = window.innerHeight; var spaceBelow = viewportH - inputRect.bottom - 8; var spaceAbove = inputRect.top - 8; var maxH = Math.min(224, Math.max(spaceBelow, spaceAbove)); // 224px ≈ 14em resultsList.css({ "max-height": maxH + "px", "top": spaceBelow >= spaceAbove ? "100%" : "auto", "bottom": spaceBelow >= spaceAbove ? "auto" : "100%" }); resultsList.show(); } function selectOption(value, text) { textInput.val(text); select.val(value); resultsList.hide(); select.trigger("change"); } textInput.on("input focus", function () { showResults($(this).val()); }); textInput.on("blur", function () { // Short delay so a touchstart on a result item fires first. setTimeout(function () { resultsList.hide(); }, 200); }); // chosen:updated → re-cache (called after ziman.json loads). select.on("chosen:updated", function () { cacheOptions(); // If a value is already selected, keep the display text in sync. var cur = select.val(); if (cur) { var match = $.grep(allOptions, function (o) { return o.value === cur; })[0]; if (match) textInput.val(match.text); } }); // No-op .chosen() so desktop call-sites don't need guarding. select.chosen = function () { return select; }; wrapper.append(textInput).append(resultsList).append(select); return wrapper; } var langsByCode = {}; // Populated from [[MediaWiki:Gadget-start.js/data.json]] at runtime. var metadata = {}; // Zaravayên kurdî yên ku di beşa "Bi zaravayên din" de tên pêşkêşkirin — // ev kod ji beşa Werger têne derxistin daku heman zimên du caran neyê xwendin. var ZARAVA_LANG_CODES = ["ckb", "sdh", "lki", "hac", "zza"]; function getZaravaKeys(choices) { var byCode = {}; $.each(choices || [], function (_, c) { byCode[c[0]] = c; }); var result = []; $.each(ZARAVA_LANG_CODES, function (_, code) { if (byCode[code]) result.push(byCode[code]); }); return result; } function needsTransliteration(langCode) { var meta = metadata[langCode]; if (!meta || !meta.sc) return false; var scripts = Array.isArray(meta.sc) ? meta.sc : [meta.sc]; return scripts.length > 0 && scripts[0] !== "Latn"; } // Kodên cinsiyetê yên di metadata.g de — ji data.json tê dagirtin var GENDER_BASE_LABELS = {}; // Sub-lists that only make sense for a plain (non-şablon) sense — hidden // when a şablon (e.g. {{guharto|…}}) is chosen for that sense, since a // template-based sense has no "own" gloss for alternate forms, synonyms, // antonyms, coordinate terms, hypernyms or hyponyms to attach to. Etîket, // Nimûne and Jêgirtin stay visible either way. var HIDDEN_ON_TPL_GROUPS = [ "wiktku-dfn-alternativ", "wiktku-dfn-hevmane", "wiktku-dfn-dijmane", "wiktku-dfn-koordine", "wiktku-dfn-jornav", "wiktku-dfn-jernav" ]; function genderLabel(code) { if (code === "p") return "Pirjimar"; var pluralMatch = code.match(/^(.+)-p$/); if (pluralMatch && GENDER_BASE_LABELS[pluralMatch[1]]) { return GENDER_BASE_LABELS[pluralMatch[1]] + " (pirjimar)"; } return GENDER_BASE_LABELS[code] || code; } /** * True if a sense has any content worth keeping besides its mane text — * etîket, hevmane/dijmane/koordîne/etc. word lists, nimûne, or jêder * (quote). Used so a sense with an empty mane but filled-in extra * fields still gets emitted (with {{mane?}} standing in for the gloss) * instead of being silently dropped. */ function senseHasExtraContent(s) { if (s.etiket && $.grep(s.etiket, function (e) { return $.trim(e) !== ""; }).length) return true; if (s.alternativ.length || s.hevmane.length || s.dijmane.length || s.koordine.length || s.jornav.length || s.jernav.length) return true; if (s.nimune && $.grep(s.nimune, function (n) { return (typeof n === "object" ? n.text : n) !== ""; }).length > 0) return true; if (s.jeder && $.grep(s.jeder, function (j) { return j && j.quote; }).length > 0) return true; return false; } /** * formatNimune: each nimûne item can be { text, tr, t }: * text — example text * tr — transliteration (only when the language needs it) * t — Kurdish translation (third positional param, no key) */ function formatNimune(nimunes, lang, hasJeder) { var hasNimune = nimunes && $.grep(nimunes, function (n) { return (typeof n === "object" ? n.text : n) !== ""; }).length > 0; if (!hasNimune) { return hasJeder ? "" : "\n#* {{bênimûne|" + lang + "}}"; } return $.map(nimunes, function (n) { var text = typeof n === "object" ? n.text : n; if (!text) return undefined; var bolded = text.replace( new RegExp("(" + pageNameRe + "([^( |,|;|\\?|\\.|\\!)]+)?)", "ig"), "'''$1'''"); var tpl = "\n#: {{nm|" + lang + "|" + bolded; if (typeof n === "object") { if (n.tr) tpl += "|tr=" + n.tr; // Translation as third positional param (no key needed). if (n.t) tpl += "|" + n.t; } // Short examples fit on one line together with their translation. // rêz=1 is not used for ku — definitions are shown on separate lines there. if (text.length < 200 && lang !== "ku") tpl += "|rêz=1"; tpl += "}}"; return tpl; }).join(""); } /** * Formats a list of jêder (quote/citation) objects into wikitext lines. * Each entry that has no quote text is skipped. Returns "" when the list * is empty or every entry is blank. * * #* {{jêder-…|lang|jêgirtin=…|tr=…|tercime=…|…fields…}} * * When no template is chosen, the generic {{jêder|…}} template is used * instead. Its 2nd positional param is the user's freeform "bi destê xwe * binivîsim" source text when supplied, or the çavkanî? placeholder otherwise. * If that text contains "=" it is passed as |2=… instead of a bare * positional param, since MediaWiki would otherwise misparse it as its * own key=value pair and break the template: * #* {{jêder|lang|jêgirtin=…|tr=…|tercime=…|<manual source or çavkanî?>}} */ function formatJeder(jederList, lang) { if (!jederList || !jederList.length) return ""; return $.map(jederList, function (jeder) { if (!jeder || !jeder.quote) return undefined; if (jeder.jederTpl) { var cite = "\n#* {{" + jeder.jederTpl + "|" + lang; cite += "|jêgirtin=" + jeder.quote; if (jeder.quoteTr) cite += "|tr=" + jeder.quoteTr; if (jeder.quoteT) cite += "|tercime=" + jeder.quoteT; $.each(jeder.jêderFields || {}, function (key, val) { if (val) cite += "|" + key + "=" + val; }); cite += "}}"; return cite; } var out = "\n#* {{jêder|" + lang + "|jêgirtin=" + jeder.quote; if (jeder.quoteTr) out += "|tr=" + jeder.quoteTr; if (jeder.quoteT) out += "|tercime=" + jeder.quoteT; var srcParam = jeder.jederManual ? jeder.jederManual : "çavkanî?"; // A positional param containing "=" gets parsed as its own key=value // pair by MediaWiki and breaks the template, so force it to be // explicitly named (|2=) whenever that's the case. out += (srcParam.indexOf("=") !== -1 ? "|2=" : "|") + srcParam; out += "}}"; return out; }).join(""); } function makeWordListStep(id, name, question_fmt, header, templateName) { return { id: id, name: name, question_fmt: question_fmt, multiple: true, narrow: true, visible: function (values) { return values.lang && values.pos; }, output: function (values) { var words = $.grep(values[id] || [], function (w) { return !!w; }); if (!words.length) return ""; var lang = values.lang; var section = "\n==== " + header + " ====\n"; if (words.length === 1) { // Single word — keep the simple inline template. return section + "* {{" + templateName + "|" + lang + "|" + words[0] + "}}\n"; } // Multiple words — use {{kol3}} with one positional param per word. var params = "cure=" + header + "\n" + $.map(words, function (w) { return "|" + w; }).join("\n"); return section + "{{kol3|" + lang + "|" + params + "\n}}\n"; } }; } var steps = { lang: { id: "lang", required: true, name: "ziman", question_fmt: '"' + pageName + '" bi çi zimanî ye?', question_br: true, // Populated from [[MediaWiki:Gadget-start.js/data.json]] (langChoices). choices: [], output: function (values) { return "== {{ziman|" + values.lang + "}} ==\n"; } }, pron: { id: "pron", name: "bilêvkirin", question_fmt: '"' + pageName + '" çawa tê telafûzkirin?', // pronTpls populated from data.json pronTpls: [], visible: function (values) { if (!values.lang) return false; // In addLangMode, only skip pron when this langcode's section // already exists in the page — if it's a new language, show it. if (addLangMode) { var existing = $("#wpTextbox1").val() || ""; var header = "== {{ziman|" + values.lang + "}} =="; return existing.indexOf(header) === -1; } return true; }, /** Fills (or refills) the insert-dropdown from the current pronTpls array, filtering by language. */ refreshTplSelect: function () { var sel = $("#wiktku-start-pron .wiktku-tpl-insert-select"); if (!sel.length) return; var lang = getValues().lang || ""; sel.find("option[value!='']").remove(); $.each(steps.pron.pronTpls, function (_, tpl) { // Filter: if tpl.langs exists, only show if lang is in that list; otherwise show always var allowed = !tpl.langs || tpl.langs.indexOf(lang) !== -1; if (allowed) { sel.append($("<option></option>") .val(tpl.snippet) .text(tpl.name + " — " + tpl.desc) .attr("data-nolang", tpl.noLang ? "1" : "")); } }); // Notify Chosen that the option list has changed (no-op on mobile). if (!isMobile) sel.trigger("chosen:updated"); }, build: function (stepDiv) { if (stepDiv.find(".wiktku-pron-wrap").length) return null; var wrap = $("<div class='wiktku-pron-wrap'></div>"); var ta = $("<textarea></textarea>") .attr("name", "wiktku-pron-" + $.now()) .attr("class", "wiktku-start-step-field wiktku-pron-text") .attr("rows", 4) .attr("placeholder", "Nimûne: {{IPA|ku|/pɛɪ̯n/}} yan {{kîte|ku|he|ce|ki|rin}}"); // Template insert dropdown — filtered by language. var sel = $("<select class='wiktku-tpl-insert-select'></select>"); sel.append($("<option value=''>— şablonek lê zêde bike —</option>")); var lang = getValues().lang || ""; $.each(steps.pron.pronTpls, function (_, tpl) { // Filter: if tpl.langs exists, only show if lang is in that list; otherwise show always var allowed = !tpl.langs || tpl.langs.indexOf(lang) !== -1; if (allowed) { sel.append($("<option></option>") .val(tpl.snippet) .text(tpl.name + " — " + tpl.desc) .attr("data-nolang", tpl.noLang ? "1" : "")); } }); sel.on("change", function () { var snippet = $(this).val(); if (!snippet) return; var lang = getValues().lang || ""; // Check if the selected option has noLang flag var selectedOption = sel.find("option:selected"); var hasNoLang = selectedOption.attr("data-nolang") === "1"; if (!hasNoLang) { snippet = snippet.replace(/CODE/g, lang).replace(/SOURCELANG/g, "?"); } insertAtCursor(ta[0], snippet); $(this).val(""); ta.focus(); }); wrap.append(sel).append($("<br>")).append(ta); stepDiv.append(wrap); return ta; }, output: function () { var text = $.trim($("#wiktku-start-pron .wiktku-pron-text").val()); if (!text) return ""; var lines = text.split("\n"); var out = $.map(lines, function (line) { line = $.trim(line); if (!line) return undefined; return line.charAt(0) === "*" ? line : "* " + line; }).join("\n"); return "\n=== Bilêvkirin ===\n" + out + "\n"; } }, pos: { id: "pos", required: true, name: "Cureyê rêzimanî", question_fmt: 'Cureyê rêzimanî yê "' + pageName + '" çi ye?', visible: function (values) { return values.lang; }, question_br: true, // Populated from [[MediaWiki:Gadget-start.js/data.json]] (posChoices). choices: [], output: function (values) { var pos = values.pos || ""; var cinsiyet = values.cinsiyet || ""; // from the cinsiyet step var lekTur = values.lektur || ""; // from the lêker transitivity step var capitalizedPos = capitalize(pos); var outputString = "\n=== " + capitalizedPos + " ===\n"; // Add ku-tewîn-nav for single-word navdêr/serenav with known gender. if (!pageName.includes(" ") && cinsiyet && GENDER_BASE_LABELS[cinsiyet] && (pos === "navdêr" || pos === "serenav") && values.lang === "ku") { outputString += "{{ku-tewîn-nav|" + pageName + "|" + GENDER_BASE_LABELS[cinsiyet]; if (pos === "serenav") outputString += "|y"; outputString += "}}\n"; } outputString += "{{" + pos + "|" + values.lang; if (pos === "navdêr" || pos === "serenav") { if (cinsiyet) { outputString += "|c=" + cinsiyet; } else if (values.lang === "ku") { // Unknown gender — prompt editor to fill it in. outputString += "|c=?"; } } else if (/^lêker/.test(pos) && lekTur) { outputString += "|c=" + lekTur; } if (values.tr) { outputString += "|tr=" + values.tr; } outputString += "}}\n"; return outputString; } }, /** * cinsiyet (grammatical gender) — only shown for navdêr/serenav, û * tenê ger metadata ji bo zimanê hilbijartî lîsteyeke "g" (cinsiyet) * were dayîn. Opsiyonên vê gavê ne sabît in — ji metadata[values.lang].g * têne çêkirin, ji ber ku di hemû zimanan de cinsiyet tine. */ cinsiyet: { id: "cinsiyet", name: "cinsiyet", question_fmt: 'Cinsiyeta "' + pageName + '" çi ye?', question_br: true, visible: function (values) { var meta = metadata[values.lang]; return !!(values.lang && (values.pos === "navdêr" || values.pos === "serenav") && meta && meta.g && meta.g.length); }, build: function (stepDiv, values) { var select = stepDiv.find("select.wiktku-start-step-field"); if (!select.length) { select = $(mw.html.element("select", { "class": "wiktku-start-step-field", id: "wiktku-start-cinsiyet-field" })); stepDiv.append(select); } if (!values) return select; var meta = metadata[values.lang]; var codes = (meta && meta.g) || []; var prevVal = select.val(); var choices = $.map(codes, function (code) { return [[code, genderLabel(code)]]; }); populateMenus(select, choices); if ($.grep(choices, function (c) { return c[0] === prevVal; }).length) { select.val(prevVal); } if (!isMobile) select.trigger("chosen:updated"); return select; }, output: function () { return ""; } // consumed by pos.output }, /** * Lêker transitivity — only shown for any lêker variant. */ lektur: { id: "lektur", name: "Cureyê lêkerê (fiîlê)", question_fmt: "Cureyê lêkerê (fiîlê) çi ye?", question_br: true, visible: function (values) { return values.lang && values.pos && /^lêker/.test(values.pos); }, // Dictionary: value → display label. Add new types here. choices: [ ["gh", "gerguhêz"], ['x-gh', 'xwerû-gerguhêz'], ['p-gh', 'pêkhatî-gerguhêz'], ['h-gh', 'hevedudanî-gerguhêz'], ['b-gh', 'biwêjî-gerguhêz'], ["ngh", "negerguhêz"], ['x-ngh', 'xwerû-negerguhêz'], ['p-ngh', 'pêkhatî-negerguhêz'], ['h-ngh', 'hevedudanî-negerguhêz'], ['b-ngh', 'biwêjî-negerguhêz'] ], output: function () { return ""; } // consumed by pos.output }, tr: { id: "tr", name: "transkrîpsiyon", question_fmt: "Transkrîpsiyona kelîmeyê", multiple: false, narrow: true, visible: function (values) { return values.lang && values.pos && needsTransliteration(values.lang); } }, dfn: { id: "dfn", // required: true, ger mane tinebe [[Şablon:mane?]] bi kar bîne name: "Mane", question_fmt: "Maneya kelîmeyê binivîse. Mane otomatîk tê lînkkirin! Ji bo tercimeyan beşa 'Werger' bi kar bîne!", multiple: true, ordered: true, rows: 3, visible: function (values) { return values.lang && values.pos; }, example: function (values) { // posExamples loaded from [[MediaWiki:Gadget-start.js/data.json]]. var examples = steps.dfn.posExamples || {}; var full = values.pos || ""; return examples[full] || ""; }, /** * Builds one sense block (<li>) inside the ordered list. * Each block contains: * - a textarea for the definition * - an expandable nimûne list * - single-row sub-lists for formên alternatîv, hevmane, dijmane */ buildSenseBlock: function (stepDiv) { var block = $("<li class='wiktku-dfn-sense'></li>"); // — Mane textarea (declared first so the template handler can reference it) — var dfnArea = $("<textarea></textarea>") .attr("name", "wiktku-dfn-mane-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("class", "wiktku-start-step-field wiktku-dfn-mane") .attr("rows", 6) .attr("placeholder", "Mane…"); dfnArea.on("input", function () { steps.dfn.onDfnInput(stepDiv, block, this); }); // — Template selector (optional — replaces mane when chosen) — // Template definitions loaded from [[MediaWiki:Gadget-start.js/data.json]]. var tplDefs = steps.dfn.tplDefs || []; // Cache of all non-placeholder option elements — used by updateTplOptions // to remove/re-add options (the only approach compatible with Chosen.js). var _allTplOptions = []; var tplSelect = $(mw.html.element("select", { "class": "wiktku-dfn-tpl-select" })); tplSelect.append($("<option value=''>— yan jî şablonek hilbijêre —</option>")); $.each(tplDefs, function (_, tpl) { var opt = $("<option></option>") .val(tpl.name) .text(tpl.name) .attr("data-langs", tpl.langs ? tpl.langs.join(",") : "") .attr("data-nolang", tpl.noLang ? "1" : ""); tplSelect.append(opt); _allTplOptions.push(opt[0]); }); function updateTplOptions() { var lang = getValues().lang || ""; var currentVal = tplSelect.val(); var currentStillValid = false; // Detach all non-placeholder options, then re-attach only the visible ones. // This is the only approach that works correctly with both native <select> // and Chosen.js on desktop. tplSelect.find("option[value!='']").detach(); $.each(_allTplOptions, function (_, opt) { var allowed = $(opt).attr("data-langs"); var visible = !allowed || allowed.split(",").indexOf(lang) !== -1; if (visible) { tplSelect.append(opt); if ($(opt).val() === currentVal) currentStillValid = true; } }); if (!isMobile) tplSelect.trigger("chosen:updated"); if (currentVal && !currentStillValid) { tplSelect.val(""); dfnArea.show(); tplTitleInput.hide().val(""); } } // Store updater on the element so refresh() can call it for all blocks. tplSelect.data("updateOptions", updateTplOptions); var tplTitleInput = $("<input type='text'>") .addClass("wiktku-dfn-tpl-title wiktku-start-narrow") .attr("placeholder", "Navê rûpelê…") .hide(); // Grow the sense list when the title field of the last block gets content, // mirroring what onDfnInput does for the plain mane textarea. tplTitleInput.on("input", function () { steps.dfn.onDfnInput(stepDiv, block, this); }); /** * When a şablon sense is chosen, formên alternatîv/hevmane/dijmane/ * termên koordîne/jornav/jêrnav don't apply (there's no plain gloss * to hang them off), so hide those subgroups. Etîket, Nimûne and * Jêgirtin stay visible and still usable for a şablon sense. */ function updateFieldVisibility() { var isTpl = !!tplSelect.val(); $.each(HIDDEN_ON_TPL_GROUPS, function (_, cls) { block.find("." + cls + "-group").toggle(!isTpl); }); } // Store on the block so restoreDfn() can re-sync visibility // after programmatically setting tplSelect's value. block.data("updateFieldVisibility", updateFieldVisibility); tplSelect.on("change", function () { var chosen = $(this).val(); if (chosen) { dfnArea.hide(); tplTitleInput.show().focus(); } else { dfnArea.show(); tplTitleInput.hide().val(""); } updateFieldVisibility(); // Re-run refresh so the Werger step visibility updates. refresh(); }); var tplRow = $("<div></div>").addClass("wiktku-dfn-tpl-row") .append(tplSelect).append(" ").append(tplTitleInput); block.append(tplRow); block.append(dfnArea); // Apply lang filter on initial build. updateTplOptions(); // — Sub-field groups — // All groups are always visible with a placeholder textarea. // Nimûne is last in the DOM and last in the output. var allGroups = [ { cls: "wiktku-dfn-etiket", label: "Etîket", rows: 1, narrow: true, izah: "xisûsen, Mêrdîn, anatomî, Badînî" }, { cls: "wiktku-dfn-alternativ", label: "Formên alternatîv", rows: 1, narrow: true, izah: "Varyantên vê kelîmeyê" }, { cls: "wiktku-dfn-hevmane", label: "Hevmane", rows: 1, narrow: true, izah: "Spehî hevmaneya Bedew e." }, { cls: "wiktku-dfn-dijmane", label: "Dijmane", rows: 1, narrow: true, izah: "Zengîn dijmaneya feqîr e." }, { cls: "wiktku-dfn-koordine", label: "Termên koordîne", rows: 1, narrow: true, izah: "Pisîk û kûçik termên koordîne ne çunkî Jornavên wan gelek in" }, { cls: "wiktku-dfn-jornav", label: "Jornav", rows: 1, narrow: true, izah: "Heywan jornavê guhandar e" }, { cls: "wiktku-dfn-jernav", label: "Jêrnav", rows: 1, narrow: true, izah: "Guhandar jêrnavê heywan e" }, { cls: "wiktku-dfn-nimune", label: "Nimûne", rows: 2, narrow: false } ]; $.each(allGroups, function (_, g) { var groupDiv = $("<div></div>").addClass("wiktku-dfn-subgroup " + g.cls + "-group"); function buildNimuneLi() { var lang = getValues().lang || ""; var li = $("<li></li>").addClass("wiktku-dfn-nimune-li"); var mainTa = $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-text-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", g.rows) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-text") .attr("placeholder", "Nimûneya emilandina kelîmeyê tu bi xwe binivîse…"); mainTa.on("input", function () { var val = $.trim($(this).val()); var isLast = li.is(list.children("li:last-child")); if (val && isLast) { list.append(buildNimuneLi()); } }); li.append(mainTa); var subWrap = $("<div></div>").addClass("wiktku-dfn-nimune-sub"); if (needsTransliteration(lang)) { subWrap.append( $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-tr-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 5) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-tr") .attr("placeholder", "Transkrîpsiyona bi alfabeya latînî") ); } if (lang && lang !== "ku") { subWrap.append( $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-t-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 5) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-t") .attr("placeholder", "Tercimeya kurmancî") ); } if (subWrap.children().length) li.append(subWrap); return li; } if (g.cls === "wiktku-dfn-nimune") { // Nimûne — compound widget with tr/t sub-fields. var lbl = $("<span></span>").addClass("wiktku-dfn-sublabel").text(g.label + ": "); var list = $("<ol></ol>").addClass("wiktku-dfn-sublist " + g.cls + "-list"); groupDiv.data("buildNimuneLi", buildNimuneLi); list.append(buildNimuneLi()); groupDiv.append(lbl).append(list); block.append(groupDiv); } else { // Regular always-visible group — label + growing textarea list. var lbl = $("<span></span>").addClass("wiktku-dfn-sublabel").text(g.label + ": " + g.izah); var list = $("<ol></ol>").addClass("wiktku-dfn-sublist " + g.cls + "-list"); var firstInput = $("<textarea></textarea>") .attr("name", g.cls + "-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", g.rows) .attr("class", "wiktku-dfn-subfield" + (g.narrow ? " wiktku-start-narrow" : "")) .attr("placeholder", g.label + "…"); firstInput.on("input", function () { steps.dfn.onSubInput(list, this, g.rows, g.narrow); }); list.append($("<li></li>").append(firstInput)); groupDiv.append(lbl).append(list); block.append(groupDiv); } }); // — Jêder (quote / citation) group — a growing list, sibling to Nimûne — // Structured the same way as Nimûne (ol.wiktku-dfn-sublist > li) so it // lines up at the same indentation, and so that typing into the last // citation's Jêgirtin box automatically opens a fresh empty one below it. (function () { var jederGroupDiv = $("<div></div>").addClass("wiktku-dfn-subgroup wiktku-dfn-jeder-group"); var jederLbl = $("<span></span>").addClass("wiktku-dfn-sublabel").text("Jêgirtin: "); var jederList = $("<ol></ol>").addClass("wiktku-dfn-sublist wiktku-dfn-jeder-list"); function buildJederLi() { var lang = getValues().lang || ""; var li = $("<li></li>").addClass("wiktku-dfn-jeder-li"); var dragHandle = $("<span></span>") .addClass("wiktku-jeder-drag-handle") .attr("title", "Bişkûne û bikişîne da ku rêzê biguhezîne"); // Quote text textarea var quoteTa = $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-quote-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 2) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-quote") .attr("placeholder", "Nimûneya emilandinê ji kitêb an çavkaniyeke din binivîse"); quoteTa.on("input", function () { var val = $.trim($(this).val()); var isLast = li.is(jederList.children("li:last-child")); if (val && isLast) { jederList.append(buildJederLi()); } }); li.append(dragHandle).append(quoteTa); // tr/t sub-fields for the quote — shown as needed for the language. var quoteSubWrap = $("<div></div>").addClass("wiktku-dfn-quote-sub"); if (needsTransliteration(lang)) { quoteSubWrap.append( $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-quote-tr-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 2) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-quote-tr") .attr("placeholder", "Transkrîpsiyona jêgirtinê…") ); } if (lang && lang !== "ku") { quoteSubWrap.append( $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-quote-t-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 2) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-quote-t") .attr("placeholder", "Tercimeya jêgirtinê bi kurmancî") ); } if (quoteSubWrap.children().length) li.append(quoteSubWrap); // Citoid auto-fill: fetch citation data from a URL, DOI or ISBN and // prefill the source şablon + fields below (see Gadget-citoid-helper.js). var citoidWrap = $("<div></div>").addClass("wiktku-dfn-quote-citoid"); var citoidInput = $("<input type='text'>") .addClass("wiktku-dfn-quote-citoid-input wiktku-start-narrow") .attr("placeholder", "URL, DOI an ISBN binivîse ku otomatîk were tijekirin…"); var citoidBtn = new OO.ui.ButtonWidget({ label: "Bi Citoid bîne", classes: [ "wiktku-dfn-quote-citoid-btn" ] }); var citoidStatus = $("<span></span>").addClass("wiktku-dfn-quote-citoid-status"); /** * Fetches citation data from Citoid and applies it to this * citation's şablon selector + fields. Mirrors the logic in * Form.prototype._fillFromCitoid (Gadget-wikt.add-examples.js): * - only (re)selects the şablon when it actually differs from * what's already chosen, so a repeat fetch doesn't wipe out * a template the user already picked; * - only fills fields that are currently empty, so it never * overwrites something the user typed by hand; * - falls back to the freeform "bi destê xwe binivîsim" source * only when nothing was typed there yet. */ function runCitoidFetch() { var query = $.trim(citoidInput.val()); if (!query) { mw.notify("Ji kerema xwe re pêşî URL, DOI an ISBNyekê binivîse."); return; } citoidBtn.setDisabled(true); citoidStatus.text("Tê anîn…"); wikt.citoidHelper.ensure().then(function () { return wikt.citoid.fetchJederFields(query); }).then(function (result) { var jederKey = result.jederKey; var hasTpl = !!jederKey && srcSel.find("option[value='" + jederKey + "']").length > 0; var targetVal = hasTpl ? jederKey : "__manual__"; // Only (re)select — and thus rebuild — the field rows if // we're switching to a different şablon than what's // already chosen, so a second fetch doesn't clear fields // the user already filled in by hand. if (srcSel.val() !== targetVal) { srcSel.val(targetVal).trigger("change"); srcSel.trigger("chosen:updated"); } if (hasTpl) { // Tenê qadên vala tijî bike. $.each(result.fields, function (key, val) { var input = srcFields.find("[data-field-key='" + key + "']"); if (input.length && !$.trim(input.val())) { input.val(val); } }); } else { // Şablonek nehat naskirin ji bo vê itemType — rêzikeke // çavkaniyê ya bi destan a ji qadên Citoid tê çêkirin, // lê tenê ger qada destan vala be. var manualField = srcFields.find(".wiktku-dfn-quote-src-manual"); if (!$.trim(manualField.val())) { var parts = []; $.each(["nivîskar", "sernav", "websîte", "kovar", "weşanxane", "sal", "url"], function (_, k) { if (result.fields[k]) parts.push(result.fields[k]); }); manualField.val(parts.join(", ")); } } citoidStatus.text(""); }, function (errorMsg) { citoidStatus.text(typeof errorMsg === "string" ? errorMsg : "Nehat dîtin. Kontrol bike ka URL/DOI/ISBN rast e."); }).always(function () { citoidBtn.setDisabled(false); }); } citoidBtn.on("click", runCitoidFetch); citoidInput.on("keydown", function (e) { if (e.which === 13) { // Enter e.preventDefault(); runCitoidFetch(); } }); citoidWrap.append(citoidInput).append(citoidBtn.$element).append(citoidStatus); // Source template selector, specific to this citation. var srcSel = $("<select></select>").addClass("wiktku-dfn-quote-src-sel"); srcSel.append($("<option value=''>— Çavkaniyê hilbijêre —</option>")); srcSel.append($("<option></option>").val("__manual__").text("Bi destê xwe binivîsim")); var jederDefs = steps.dfn.jederDefs || {}; $.each(jederDefs, function (tplName, def) { srcSel.append($("<option></option>").val(tplName).text(def.label)); }); // Dynamic source fields container. var srcFields = $("<div></div>").addClass("wiktku-dfn-quote-src-fields"); srcSel.on("change", function () { srcFields.empty(); var chosen = $(this).val(); if (!chosen) return; if (chosen === "__manual__") { // Freeform source, written by the user — becomes the 2nd // positional param of {{jêder|lang|…}} instead of çavkanî?. srcFields.append( $("<textarea></textarea>") .attr("rows", 4) .addClass("wiktku-dfn-subfield wiktku-dfn-quote-src-manual") .attr("placeholder", "Çavkaniyê bi destê xwe binivîse…") ); return; } var def = (steps.dfn.jederDefs || {})[chosen]; if (!def) return; $.each(def.fields, function (_, f) { var row = $("<div></div>").addClass("wiktku-dfn-quote-src-row"); var fieldLbl = $("<label></label>").text(f.label + ": "); var inp = $("<textarea></textarea>") .attr("rows", 2) .addClass("wiktku-dfn-quote-src-input wiktku-start-narrow") .attr("data-field-key", f.key) .attr("placeholder", f.label + "…"); row.append(fieldLbl).append(inp); srcFields.append(row); }); }); li.append(citoidWrap).append(srcSel).append(srcFields); return li; } jederGroupDiv.data("buildJederLi", buildJederLi); jederList.append(buildJederLi()); // Make citation rows sortable (drag to reorder). // The last row is always the empty trailing row — cancel its drag. mw.loader.using("jquery.ui.sortable", function () { jederList.sortable({ handle: ".wiktku-jeder-drag-handle", axis: "y", items: "li:not(:last-child)", tolerance: "pointer" }); }); jederGroupDiv.append(jederLbl).append(jederList); block.append(jederGroupDiv); }()); // Apply the initial hide/show state for the sub-groups (matches // tplSelect's starting value, which is normally empty). updateFieldVisibility(); return block; }, /** Grows the sense list when the last mane textarea gets content. */ onDfnInput: function (stepDiv, block, textarea) { var val = $.trim($(textarea).val()); var list = stepDiv.find("ol.wiktku-dfn-list"); var isLast = block.is(list.children("li:last-child")); if (val && isLast) { var newBlock = steps.dfn.buildSenseBlock(stepDiv); list.append(newBlock); // Apply Chosen to the new block's template selector on desktop. if (!isMobile) newBlock.find("select.wiktku-dfn-tpl-select").chosen(chosenOptions); } refresh(); }, /** Grows a sub-list (nimûne/formên alternatîv/hevmane/dijmane/termên koordîne) on input. */ onSubInput: function (list, input, rows, narrow) { var val = $.trim($(input).val()); var item = $(input).parent(); var isLast = item.is(list.children("li:last-child")); if (val && isLast) { var next = $("<textarea></textarea>") .attr("name", "wiktku-dfn-sub-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", rows) .attr("class", "wiktku-dfn-subfield" + (narrow ? " wiktku-start-narrow" : "")); next.on("input", function () { steps.dfn.onSubInput(list, this, rows, narrow); }); list.append($("<li></li>").append(next)); } }, // Populated from [[MediaWiki:Gadget-start.js/data.json]] (tplDefs, posExamples, jederDefs). tplDefs: [], posExamples: {}, jederDefs: {}, build: function (stepDiv) { if (stepDiv.find("ol.wiktku-dfn-list").length) return null; var list = $("<ol class='wiktku-dfn-list'></ol>"); list.append(steps.dfn.buildSenseBlock(stepDiv)); stepDiv.append(list); return null; }, /** Reads all sense blocks from the DOM and returns an array of sense objects. */ getSenses: function (stepDiv) { var senses = []; stepDiv.find("li.wiktku-dfn-sense").each(function () { var block = $(this); var tplSel = block.find("select.wiktku-dfn-tpl-select"); var tpl = tplSel.val() || ""; // noLang: template already encodes the language — don't add |lang| param. var tplNoLang = tpl ? tplSel.find("option[value='" + tpl + "']").attr("data-nolang") === "1" : false; var tplTitle = $.trim(block.find("input.wiktku-dfn-tpl-title").val()); var mane = $.trim(block.find("textarea.wiktku-dfn-mane").val()); var etiket = (function () { var vals = []; block.find(".wiktku-dfn-etiket-list textarea").each(function () { var v = $.trim($(this).val()); if (v) vals.push(v); }); return vals; }()); function readList(cls) { var vals = []; block.find("." + cls + "-list textarea").each(function () { var v = $.trim($(this).val()); if (v) vals.push(v); }); return vals; } // Nimûne items are compound: { text, tr?, t? } function readNimuneList() { var items = []; block.find(".wiktku-dfn-nimune-list li.wiktku-dfn-nimune-li").each(function () { var text = $.trim($(this).find(".wiktku-dfn-nimune-text").val()); if (!text) return; var obj = { text: text }; var tr = $.trim($(this).find(".wiktku-dfn-nimune-tr").val()); var t = $.trim($(this).find(".wiktku-dfn-nimune-t").val()); if (tr) obj.tr = tr; if (t) obj.t = t; items.push(obj); }); return items; } // Jêder is a growing list of citations, one per li — mirrors readNimuneList(). function readJederList() { var items = []; block.find(".wiktku-dfn-jeder-list li.wiktku-dfn-jeder-li").each(function () { var li = $(this); var quote = $.trim(li.find(".wiktku-dfn-nimune-quote").val()); if (!quote) return; var obj = { quote: quote }; var qtr = $.trim(li.find(".wiktku-dfn-nimune-quote-tr").val()); var qt = $.trim(li.find(".wiktku-dfn-nimune-quote-t").val()); if (qtr) obj.quoteTr = qtr; if (qt) obj.quoteT = qt; var tplName = li.find(".wiktku-dfn-quote-src-sel").val(); if (tplName === "__manual__") { var manual = $.trim(li.find(".wiktku-dfn-quote-src-manual").val()); if (manual) obj.jederManual = manual; } else if (tplName) { obj.jederTpl = tplName; var fields = {}; li.find(".wiktku-dfn-quote-src-input").each(function () { var k = $(this).attr("data-field-key"); var v = $.trim($(this).val()); if (k && v) fields[k] = v; }); obj.jêderFields = fields; } items.push(obj); }); return items; } senses.push({ tpl: tpl, tplNoLang: tplNoLang, tplTitle: tplTitle, mane: mane, etiket: etiket, nimune: readNimuneList(), jeder: readJederList(), alternativ: readList("wiktku-dfn-alternativ"), hevmane: readList("wiktku-dfn-hevmane"), dijmane: readList("wiktku-dfn-dijmane"), koordine: readList("wiktku-dfn-koordine"), jornav: readList("wiktku-dfn-jornav"), jernav: readList("wiktku-dfn-jernav") }); }); return senses; }, getOutput: function (values, callback) { var stepDiv = $("#wiktku-start-dfn"); var senses = steps.dfn.getSenses(stepDiv); var lang = values.lang; // A sense counts as "filled" if it has a mane, a chosen template + title, // or any other content (etîket/hevmane/nimûne/jêder…) worth keeping. var hasMane = senses.some(function (s) { return s.mane !== "" || (s.tpl && s.tplTitle) || senseHasExtraContent(s); }); // True only when at least one sense has a regular mane (needs linkify). var hasRegularMane = senses.some(function (s) { return !s.tpl && s.mane !== ""; }); // nimûne and jêder lines must never pass through linkify — only // the plain mane text should be linkified. We build two parallel // arrays: defLines (sent to linkify) and citeLines (kept aside). // Each entry in citeLines corresponds 1-to-1 with a defLines entry; // a template token {{wiktku-cite-N}} is embedded in defLines so // that after linkify runs we know exactly where to splice them back. // Template-call syntax is guaranteed safe: linkifiers leave {{ }} // tokens completely untouched. var defLines = []; // one entry per kept sense (goes to linkify) var citeLines = []; // parallel — nimûne+jêder for that same sense $.each(senses, function (_, sense) { // — Template sense (e.g. {{guharto|ku|somepage}}) — if (sense.tpl) { if (!sense.tplTitle) return; // skip empty template senses var tplLabelTpl = ""; if (sense.etiket && sense.etiket.length) { var tplLabelParts = sense.etiket.map(function (part) { return $.trim(part); }).filter(function (part) { return part !== ""; }); if (tplLabelParts.length) { tplLabelTpl = " {{e|" + lang + "|" + tplLabelParts.join("|") + "}} "; } } var tplCall = sense.tplNoLang ? "{{" + sense.tpl + "|" + sense.tplTitle + "}}" : "{{" + sense.tpl + "|" + lang + "|" + sense.tplTitle + "}}"; var tplHasJeder = sense.jeder && $.grep(sense.jeder, function (j) { return j && j.quote; }).length > 0; var idx = defLines.length; var cite = formatNimune(sense.nimune, lang, tplHasJeder) + formatJeder(sense.jeder, lang); defLines.push("#" + (tplLabelTpl ? tplLabelTpl : " ") + tplCall + (cite ? "{{wiktku-cite-" + idx + "}}" : "")); citeLines.push(cite); return; } // — Normal mane sense — var dfn = sense.mane; if (!dfn && !senseHasExtraContent(sense)) return; // truly empty if (dfn) { dfn = stripWikilinks(dfn); if (dfn[0] !== dfn[0].toUpperCase()) dfn = capitalize(dfn); if (!dfn.match(/[.…?!)\]]$/)) dfn += "."; } else { dfn = "{{mane?|" + lang + "}}"; } var labelTpl = ""; if (sense.etiket && sense.etiket.length) { var labelParts = sense.etiket.map(function (part) { return $.trim(part); }).filter(function (part) { return part !== ""; }); if (labelParts.length) { labelTpl = " {{e|" + lang + "|" + labelParts.join("|") + "}} "; } } var out = "#" + (labelTpl ? labelTpl : " ") + dfn; function wordLine(tpl, words) { if (!words.length) return ""; return "\n#: {{" + tpl + "|" + lang + "|" + words.join("|") + "}}"; } out += wordLine("alt-r", sense.alternativ); out += wordLine("hevmane", sense.hevmane); out += wordLine("dijmane", sense.dijmane); out += wordLine("koordîne", sense.koordine); out += wordLine("jornav", sense.jornav); out += wordLine("jêrnav", sense.jernav); var hasJeder = sense.jeder && $.grep(sense.jeder, function (j) { return j && j.quote; }).length > 0; var cite = formatNimune(sense.nimune, lang, hasJeder) + formatJeder(sense.jeder, lang); var idx = defLines.length; defLines.push(out + (cite ? "{{wiktku-cite-" + idx + "}}" : "")); citeLines.push(cite); }); // Splice citeLines back into a linkified string, replacing each // {{wiktku-cite-N}} token with its stored nimûne/jêder block. function restoreCites(t) { return t.replace(/\{\{wiktku-cite-(\d+)\}\}/g, function (_, n) { return citeLines[parseInt(n, 10)] || ""; }); } var text = defLines.join("\n") + "\n"; if (!hasMane) { // No definitions entered — emit {{mane?}} with bênimûne. text = "# {{mane?|" + lang + "}}\n#* {{bênimûne|" + lang + "}}\n"; callback(text); return; } if (!hasRegularMane) { // All filled senses are template senses — no linkify needed. callback(restoreCites(text)); return; } var didTryToLoad = function () { if (typeof $.wiktviLinkify === "function") { $.wiktviLinkify(text, function (linked) { callback(restoreCites(linked)); }); } else { callback(restoreCites(text)); } }; mw.loader.using("ext.gadget.linkify", didTryToLoad, didTryToLoad); } }, je: makeWordListStep("je", "jê", "Kelîmeyên jê çêbûyî binivîse", "Jê", "g"), tekildar: makeWordListStep("tekildar", "têkildar", "Kelîmeyên ji aliyê etîmolojiyê ve têkildarî vê kelîmeyê binivîse", "Têkildar", "g"), binereherwiha: makeWordListStep("binereherwiha", "binêre herwiha", "Kelîmeyên din ên eleqedar binivîse", "Binêre herwiha", "g"), etym: { id: "etym", name: "etîmolojî", question_fmt: "Etîmolojiya kelîmeyê binivîse", // etymTpls populated from data.json etymTpls: [], visible: function (values) { return values.lang && values.pos; }, /** Fills (or refills) the insert-dropdown from the current etymTpls array. */ refreshTplSelect: function () { var sel = $("#wiktku-start-etym .wiktku-tpl-insert-select"); if (!sel.length) return; sel.find("option[value!='']").remove(); $.each(steps.etym.etymTpls, function (_, tpl) { sel.append($("<option></option>").val(tpl.snippet).text(tpl.name + " — " + tpl.desc)); }); // Notify Chosen that the option list has changed (no-op on mobile). if (!isMobile) sel.trigger("chosen:updated"); }, build: function (stepDiv) { if (stepDiv.find(".wiktku-etym-wrap").length) return null; var wrap = $("<div class='wiktku-etym-wrap'></div>"); var ta = $("<textarea></textarea>") .attr("name", "wiktku-etym-" + $.now()) .attr("class", "wiktku-start-step-field wiktku-etym-text") .attr("rows", 4) .attr("placeholder", "Nimûne: Ji {{ji|en|ku|apple}}. yan rasterast binivîse…"); // Template insert dropdown — options also refreshed after data.json loads. var sel = $("<select class='wiktku-tpl-insert-select'></select>"); sel.append($("<option value=''>— şablonek lê zêde bike —</option>")); $.each(steps.etym.etymTpls, function (_, tpl) { sel.append($("<option></option>").val(tpl.snippet).text(tpl.name + " — " + tpl.desc)); }); sel.on("change", function () { var snippet = $(this).val(); if (!snippet) return; var lang = getValues().lang || ""; snippet = snippet.replace(/CODE/g, lang).replace(/SOURCELANG/g, "?"); insertAtCursor(ta[0], snippet); $(this).val(""); ta.focus(); }); wrap.append(sel).append($("<br>")).append(ta); stepDiv.append(wrap); return ta; }, output: function (values) { var text = $.trim($("#wiktku-start-etym .wiktku-etym-text").val()); if (text) { return "\n==== Etîmolojî ====\n" + text + "\n"; } // No etymology entered — emit {{ji?|lang}} as a placeholder, // but only when the entry has at least one regular (non-şablon) // sense with content — either real mane text, or an empty mane // with other fields filled in (which dfn.getOutput() renders as // {{mane?|lang}} with those fields attached). A şablon sense // like {{guharto|…}} never counts, filled in or not. var dfnSenses = steps.dfn.getSenses($("#wiktku-start-dfn")); var hasRegularMane = dfnSenses.some(function (s) { return !s.tpl && (s.mane !== "" || senseHasExtraContent(s)); }); if (!hasRegularMane) return ""; return "\n==== Etîmolojî ====\n{{ji?|" + values.lang + "}}\n"; } }, dunde: { id: "dunde", name: "dûnde", question_fmt: "Eger ev kelîme ji vî zimanî ketibe zimanekî din, vî zimanî û kelîmeya wî binivîse", visible: function (values) { return !!values.pos; }, disabledKeys: { "navz": true}, /** * Builds one row: a language dropdown + a growing list of word * inputs. When the dropdown gets a value the next empty row is * appended automatically. Mirrors steps.trans's row widget, but * flat (one shared list — dûnde isn't tied to individual senses). */ buildRow: function (stepDiv) { var row = $("<li class='wiktku-dunde-row wiktku-lang-row'></li>"); // Language selector — chosen is applied after insertion into DOM. var langSel = $(mw.html.element("select", { "class": "wiktku-start-step-keyfield wiktku-start-narrow" })); langSel.attr("data-placeholder", "Zimanekî lê bigere"); populateMenus(langSel, steps.dunde.keys || [], steps.dunde.disabledKeys); // When a language is chosen, ensure a next empty row exists. langSel.on("change", function () { steps.dunde.onLangChange(stepDiv, row); }); // Word list for this language. var wordList = $("<ul class='wiktku-dunde-words wiktku-lang-row-words'></ul>"); var firstWord = steps.dunde.makeWordInput(); wordList.append($("<li></li>").append(firstWord)); if (isMobile) { row.append(wrapNativeSelect(langSel)).append(wordList); } else { row.append(langSel).append(wordList); } return row; }, makeWordInput: function () { var input = $("<textarea></textarea>") .attr("name", "wiktku-dunde-word-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 1) .attr("class", "wiktku-dfn-subfield wiktku-start-narrow") .attr("placeholder", "Kelîme…"); input.on("input", function () { var list = $(this).closest("ul.wiktku-dunde-words"); var item = $(this).parent(); var val = $.trim($(this).val()); if (val && item.is(list.children("li:last-child"))) { var next = steps.dunde.makeWordInput(); list.append($("<li></li>").append(next)); } }); return input; }, onLangChange: function (stepDiv, row) { var list = stepDiv.find("ul.wiktku-dunde-list"); var isLast = row.is(list.children("li.wiktku-dunde-row:last-child")); if (isLast) { var newRow = steps.dunde.buildRow(stepDiv); list.append(newRow); // Init chosen after the new row is in the DOM (desktop only). if (!isMobile) newRow.find("select").chosen(chosenOptions); } // Keep disabled keys in sync across all lang selectors. steps.dunde.syncDisabledKeys(stepDiv); }, /** Disables already-selected languages in all other dropdowns. */ syncDisabledKeys: function (stepDiv) { var taken = $.extend({}, steps.dunde.disabledKeys); stepDiv.find("li.wiktku-dunde-row select").each(function () { var v = $(this).val(); if (v) taken[v] = true; }); stepDiv.find("li.wiktku-dunde-row select").each(function () { var self = $(this); var own = self.val(); self.find("option").each(function () { var code = $(this).val(); if (!code) return; $(this).prop("disabled", taken[code] && code !== own); }); self.trigger("chosen:updated"); }); }, build: function (stepDiv) { if (stepDiv.find("ul.wiktku-dunde-list").length) return null; var list = $("<ul class='wiktku-dunde-list wiktku-lang-row-list'></ul>"); list.append(steps.dunde.buildRow(stepDiv)); stepDiv.append(list); // Init chosen after the select is in the DOM (desktop only). if (!isMobile) list.find("select").chosen(chosenOptions); return null; }, /** Reads all [langcode, words[]] rows from the DOM. */ getRows: function (stepDiv) { var result = []; stepDiv.find("li.wiktku-dunde-row").each(function () { var lang = $(this).find("select").val(); if (!lang) return; var words = []; $(this).find("ul.wiktku-dunde-words textarea").each(function () { var v = $.trim($(this).val()); if (v) words.push(v); }); if (words.length) result.push([lang, words]); }); return result; }, output: function () { var stepDiv = $("#wiktku-start-dunde"); var rows = steps.dunde.getRows(stepDiv); if (!rows.length) return ""; var lines = $.map(rows, function (row) { var lang = row[0], words = row[1]; return "* {{dû|" + lang + "|" + words.join("|") + "}}"; }); return "\n==== Dûnde ====\n" + lines.join("\n") + "\n"; } }, zarava: { id: "zarava", name: "bi zaravayên din", visible: function (values) { return steps.trans.visible(values); }, disabledKeys: { "navz": true }, buildRow: function (group) { var row = $("<li class='wiktku-zarava-row wiktku-lang-row'></li>"); var langSel = $(mw.html.element("select", { "class": "wiktku-start-step-keyfield wiktku-start-narrow" })); populateMenus(langSel, steps.zarava.keys || [], steps.zarava.disabledKeys); langSel.on("change", function () { steps.zarava.onLangChange(group, row); }); var wordList = $("<ul class='wiktku-zarava-words wiktku-lang-row-words'></ul>"); var firstWord = steps.zarava.makeWordInput(); wordList.append($("<li></li>").append(firstWord)); row.append(langSel).append(wordList); return row; }, makeWordInput: function () { var input = $("<textarea></textarea>") .attr("name", "wiktku-zarava-word-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 1) .attr("class", "wiktku-dfn-subfield wiktku-start-narrow") .attr("placeholder", "Tercime…"); input.on("input", function () { var list = $(this).closest("ul.wiktku-zarava-words"); var item = $(this).parent(); var val = $.trim($(this).val()); if (val && item.is(list.children("li:last-child"))) { var next = steps.zarava.makeWordInput(); list.append($("<li></li>").append(next)); } }); return input; }, onLangChange: function (group, row) { var list = group.find("ul.wiktku-zarava-list"); var isLast = row.is(list.children("li.wiktku-zarava-row:last-child")); if (isLast) { var newRow = steps.zarava.buildRow(group); list.append(newRow); } steps.zarava.syncDisabledKeys(group); }, /** Disables already-selected dialects in all other dropdowns within one group. */ syncDisabledKeys: function (group) { var taken = $.extend({}, steps.zarava.disabledKeys); group.find("li.wiktku-zarava-row select").each(function () { var v = $(this).val(); if (v) taken[v] = true; }); group.find("li.wiktku-zarava-row select").each(function () { var self = $(this); var own = self.val(); self.find("option").each(function () { var code = $(this).val(); if (!code) return; $(this).prop("disabled", taken[code] && code !== own); }); }); }, /** Builds (or fetches) the .wiktku-zarava-group for one gloss. */ buildGroup: function (stepDiv, gi) { var group = $("<div class='wiktku-zarava-group'></div>").attr("data-gloss-pos", gi); var list = $("<ul class='wiktku-zarava-list wiktku-lang-row-list'></ul>"); list.append(steps.zarava.buildRow(group)); group.append(list); stepDiv.append(group); return group; }, /** Syncs one .wiktku-zarava-group per current gloss (same logic as steps.trans.build). */ build: function (stepDiv) { var glosses = steps.trans.glossList(); if (!glosses.length) { stepDiv.find(".wiktku-zarava-group").remove(); return null; } var existingGroups = stepDiv.find(".wiktku-zarava-group"); if (existingGroups.length > glosses.length) { existingGroups.slice(glosses.length).remove(); } $.each(glosses, function (gi, gloss) { var group = stepDiv.find(".wiktku-zarava-group[data-gloss-pos='" + gi + "']"); if (!group.length) group = steps.zarava.buildGroup(stepDiv, gi); var label = group.find(".wiktku-zarava-group-label"); if (glosses.length > 1) { if (!label.length) { label = $("<div class='wiktku-zarava-group-label'></div>"); group.prepend(label); } label.text(gloss.index + " " + gloss.text); } else if (label.length) { label.remove(); } }); return null; }, /** Reads the dialect rows for a single gloss group. */ getGroupTranslations: function (group) { var result = []; group.find("li.wiktku-zarava-row").each(function () { var lang = $(this).find("select").val(); if (!lang) return; var words = []; $(this).find("ul.wiktku-zarava-words textarea").each(function () { var v = $.trim($(this).val()); if (v) words.push(v); }); if (words.length) result.push([lang, words]); }); return result; }, /** Reads all rows from the DOM, grouped by gloss position. */ getTranslations: function (stepDiv) { var result = []; stepDiv.find(".wiktku-zarava-group").each(function () { result.push(steps.zarava.getGroupTranslations($(this))); }); return result; }, output: function (values) { if (values.lang !== "ku") return ""; var stepDiv = $("#wiktku-start-zarava"); var glosses = steps.trans.glossList(); if (!glosses.length) return ""; var blocks = $.map(glosses, function (gloss, gi) { var group = stepDiv.find(".wiktku-zarava-group[data-gloss-pos='" + gi + "']"); var rows = group.length ? steps.zarava.getGroupTranslations(group) : []; if (!gloss.text && !rows.length) return undefined; if (rows.length) { rows.sort(function (a, b) { var aLang = langsByCode[a[0]] || []; var bLang = langsByCode[b[0]] || []; return (aLang[2] || "").localeCompare(bLang[2] || "", "ku"); }); } var wordLines = $.map(rows, function (row) { var lang = row[0]; var words = row[1]; var wikiWords = words.map(function (w) { return "{{W|" + lang + "|" + w + "}}"; }).join(", "); return "* {{Z|" + lang + "}}: " + wikiWords; }).join("\n"); if (!wordLines) return undefined; var block = "{{werger-ser|" + (gloss.text || "?") + "|" + gloss.index + "}}"; block += "\n" + wordLines; block += "\n{{werger-bin}}"; return block; }); if (!blocks.length) return ""; return "\n==== Bi zaravayên din ====\n" + blocks.join("\n") + "\n"; } }, trans: { id: "trans", name: "werger", visible: function (values) { if (!(values.lang === "ku" && values.pos)) return false; // Hide Werger only when EVERY sense is a template sense (Guharto etc.) // with a title filled in — i.e. there is real content but no plain // gloss to attach a translation table to. A mix of real + template // senses still shows Werger; the template senses are simply skipped // in output(). // // "Real" here means a non-şablon sense with either mane text or // other filled-in fields (etîket/hevmane/nimûne/jêder…), since // dfn.getOutput() renders the latter too, as {{mane?|lang}} plus // whatever else was filled in. // // When nothing has been filled in at all, output() will emit // {{mane?|lang}} instead of a gloss — but Werger should still show, // since the user may want to add translations before they've // settled on a gloss. var dfnSenses = steps.dfn.getSenses($("#wiktku-start-dfn")); var hasRealSense = dfnSenses.some(function (s) { return !s.tpl && (s.mane !== "" || senseHasExtraContent(s)); }); var hasFilledTplSense = dfnSenses.some(function (s) { return s.tpl && s.tplTitle; }); return hasRealSense || !hasFilledTplSense; }, disabledKeys: { "navz": true, "ku": true, "ckb": true, "sdh": true, "lki": true, "hac": true, "zza": true }, /** * Builds one translation row: a language dropdown + a growing list * of word inputs. When the dropdown gets a value the next empty row * is appended automatically. * * @param group the specific .wiktku-trans-group this row belongs to * (each gloss has its own group and its own list of rows, so the * lookups below must stay scoped to that group rather than the * whole step — the step now holds one list per gloss). */ buildRow: function (group) { var row = $("<li class='wiktku-trans-row wiktku-lang-row'></li>"); // Language selector — chosen is applied after insertion into DOM. var langSel = $(mw.html.element("select", { "class": "wiktku-start-step-keyfield wiktku-start-narrow" })); langSel.attr("data-placeholder", "Zimanekî lê bigere"); populateMenus(langSel, steps.trans.keys || [], steps.trans.disabledKeys); // When a language is chosen, ensure a next empty row exists. langSel.on("change", function () { steps.trans.onLangChange(group, row); }); // Word list for this language. var wordList = $("<ul class='wiktku-trans-words wiktku-lang-row-words'></ul>"); var firstWord = steps.trans.makeWordInput(); wordList.append($("<li></li>").append(firstWord)); if (isMobile) { row.append(wrapNativeSelect(langSel)).append(wordList); } else { row.append(langSel).append(wordList); } return row; }, makeWordInput: function () { var input = $("<textarea></textarea>") .attr("name", "wiktku-trans-word-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 1) .attr("class", "wiktku-dfn-subfield wiktku-start-narrow") .attr("placeholder", "Tercime…"); input.on("input", function () { var list = $(this).closest("ul.wiktku-trans-words"); var item = $(this).parent(); var val = $.trim($(this).val()); if (val && item.is(list.children("li:last-child"))) { var next = steps.trans.makeWordInput(); list.append($("<li></li>").append(next)); } }); return input; }, onLangChange: function (group, row) { var list = group.find("ul.wiktku-trans-list"); var isLast = row.is(list.children("li.wiktku-trans-row:last-child")); if (isLast) { var newRow = steps.trans.buildRow(group); list.append(newRow); // Init chosen after the new row is in the DOM (desktop only). if (!isMobile) newRow.find("select").chosen(chosenOptions); } // Keep disabled keys in sync across this gloss's lang selectors // only — the same language can be used for different senses. steps.trans.syncDisabledKeys(group); }, /** Disables already-selected languages in all other dropdowns within one group. */ syncDisabledKeys: function (group) { var taken = $.extend({}, steps.trans.disabledKeys); group.find("li.wiktku-trans-row select").each(function () { var v = $(this).val(); if (v) taken[v] = true; }); group.find("li.wiktku-trans-row select").each(function () { var self = $(this); var own = self.val(); self.find("option").each(function () { var code = $(this).val(); if (!code) return; $(this).prop("disabled", taken[code] && code !== own); }); self.trigger("chosen:updated"); }); }, /** * Builds (or fetches) the .wiktku-trans-group for one gloss, with * its own label and its own list of translation rows. */ buildGroup: function (stepDiv, gi) { var group = $("<div class='wiktku-trans-group'></div>").attr("data-gloss-pos", gi); var list = $("<ul class='wiktku-trans-list wiktku-lang-row-list'></ul>"); list.append(steps.trans.buildRow(group)); group.append(list); stepDiv.append(group); // Init chosen after the select is in the DOM (desktop only). if (!isMobile) list.find("select").chosen(chosenOptions); return group; }, /** * Syncs one .wiktku-trans-group per current gloss, adding new * groups and removing stale ones as senses are added or removed, * while leaving existing groups (and whatever translations the * user has already typed into them) untouched. Groups are keyed * to their gloss's position in glossList() via data-gloss-pos, so * a group always matches the same sense across rebuilds as long * as senses aren't reordered relative to each other. */ build: function (stepDiv) { var glosses = steps.trans.glossList(); if (!glosses.length) { stepDiv.find(".wiktku-trans-group").remove(); return null; } // Drop groups for glosses that no longer exist (always from the // tail — groups are only ever appended in gloss order below). var existingGroups = stepDiv.find(".wiktku-trans-group"); if (existingGroups.length > glosses.length) { existingGroups.slice(glosses.length).remove(); } $.each(glosses, function (gi, gloss) { var group = stepDiv.find(".wiktku-trans-group[data-gloss-pos='" + gi + "']"); if (!group.length) group = steps.trans.buildGroup(stepDiv, gi); // Only label groups when there's more than one gloss to // distinguish between — a single gloss needs no caption. var label = group.find(".wiktku-trans-group-label"); if (glosses.length > 1) { if (!label.length) { label = $("<div class='wiktku-trans-group-label'></div>"); group.prepend(label); } label.text(gloss.index + " " + gloss.text); } else if (label.length) { label.remove(); } }); return null; }, /** Reads the translation rows for a single gloss group. */ getGroupTranslations: function (group) { var result = []; group.find("li.wiktku-trans-row").each(function () { var lang = $(this).find("select").val(); if (!lang) return; var words = []; $(this).find("ul.wiktku-trans-words textarea").each(function () { var v = $.trim($(this).val()); if (v) words.push(v); }); if (words.length) result.push([lang, words]); }); return result; }, /** * Reads all translation rows from the DOM, grouped by gloss * position — one array of [lang, words] rows per gloss group, in * the same order as the .wiktku-trans-group elements. */ getTranslations: function (stepDiv) { var result = []; stepDiv.find(".wiktku-trans-group").each(function () { result.push(steps.trans.getGroupTranslations($(this))); }); return result; }, /** * Builds the numbered "{ index, gloss }" list — one entry per dfn * sense that has a real mane (skips template senses like Guharto, * which have nothing to caption a translation table with). The * index matches the sense's actual position in the numbered "#" * definition list (1-based), including template senses in the count, * so the number printed next to {{werger-ser}} lines up with the * gloss the reader sees in the entry. * * When nothing has been filled in at all (dfn.getOutput() will emit * {{mane?|lang}} as sense 1), this returns a single placeholder * entry with empty text instead of an empty array, so Werger still * has one group to attach translations to before a gloss exists. * When every filled sense is a template sense instead, this stays * empty — that mirrors trans.visible()'s hidden case, where there's * no group in the DOM for a placeholder to attach to anyway. */ glossList: function () { var dfnSenses = steps.dfn.getSenses($("#wiktku-start-dfn")); var glosses = []; var hasFilledTplSense = false; $.each(dfnSenses, function (i, s) { if (s.tpl) { if (s.tplTitle) hasFilledTplSense = true; return; // template sense — no gloss to caption with } var dfn = s.mane; if (!dfn) { // No mane text, but other fields (etîket/hevmane/nimûne/ // jêder…) are filled — dfn.getOutput() still emits this // sense as a numbered line using {{mane?|lang}}, so it // needs its own gloss group too, just with no caption text. if (senseHasExtraContent(s)) glosses.push({ index: i + 1, text: "" }); return; } if (dfn[0] !== dfn[0].toLowerCase()) dfn = decapitalize(dfn); dfn = stripWikilinks(dfn).replace(/[.…?!)\]،؟]+$/, ""); glosses.push({ index: i + 1, text: dfn }); }); if (!glosses.length && !hasFilledTplSense) { glosses.push({ index: 1, text: "" }); } return glosses; }, output: function (values) { if (values.lang !== "ku") return ""; var stepDiv = $("#wiktku-start-trans"); var glosses = steps.trans.glossList(); // Every sense is a template sense — there's no real gloss // anywhere and no group in the DOM either (glossList() only // returns empty in that case), so skip the section entirely. if (!glosses.length) return ""; // Each gloss now has its own group of translation rows — // attach every gloss's own words under its own werger-ser/-bin // pair instead of dumping everything under the first one. var blocks = $.map(glosses, function (gloss, gi) { var group = stepDiv.find(".wiktku-trans-group[data-gloss-pos='" + gi + "']"); var rows = group.length ? steps.trans.getGroupTranslations(group) : []; // Placeholder gloss (no real mane entered yet) with nothing // translated into it — nothing to output, and gloss.text is // empty so there's no caption to give {{werger-ser}} anyway. if (!gloss.text && !rows.length) return undefined; if (rows.length) { // Sort by Kurdish sort key. rows.sort(function (a, b) { var aLang = langsByCode[a[0]] || []; var bLang = langsByCode[b[0]] || []; return (aLang[2] || "").localeCompare(bLang[2] || "", "ku"); }); } var wordLines = $.map(rows, function (row) { var lang = row[0]; var words = row[1]; var wikiWords = words.map(function (w) { return "{{W|" + lang + "|" + w + "}}"; }).join(", "); return "* {{Z|" + lang + "}}: " + wikiWords; }).join("\n"); var block = "{{werger-ser|" + (gloss.text || "?") + "|" + gloss.index + "}}"; if (wordLines) block += "\n" + wordLines; block += "\n{{werger-bin}}"; return block; }); if (!blocks.length) return ""; return "\n==== Werger ====\n" + blocks.join("\n") + "\n"; } }, }; steps.trans.keys = steps.lang.choices; steps.dunde.keys = steps.lang.choices; steps.zarava.keys = getZaravaKeys(steps.lang.choices); var ordered_steps = [ steps.lang, steps.pron, steps.pos, steps.cinsiyet, steps.lektur, steps.tr, steps.dfn, steps.je, steps.tekildar, steps.etym, steps.dunde, steps.binereherwiha, steps.zarava, steps.trans]; // Step ids that belong to each section (not shared across sections). var PER_SECTION_STEP_IDS = [ "pos", "cinsiyet", "lektur", "tr", "dfn", "je", "tekildar", "etym", "dunde", "binereherwiha", "zarava", "trans" ]; // ── Multi-section state ────────────────────────────────────────────────── // Each entry is a plain snapshot: { pos, cinsiyet, lektur, tr, dfn (senses[]), // je, tekildar, binereherwiha, trans (rows[]) }. var sections = [{}]; // section 0 starts empty (DOM is the truth) var activeSection = 0; function snapshotDfn() { return steps.dfn.getSenses($("#wiktku-start-dfn")); } /** * Rebuild the dfn DOM from a previously snapshotted senses array. */ function restoreDfn(senses) { var stepDiv = $("#wiktku-start-dfn"); // Tear down the existing list so build() recreates it cleanly. stepDiv.find("ol.wiktku-dfn-list").remove(); steps.dfn.build(stepDiv); var list = stepDiv.find("ol.wiktku-dfn-list"); $.each(senses, function (i, sense) { // Ensure enough blocks exist (build() seeds one). var blocks = list.find("li.wiktku-dfn-sense"); var block = blocks.eq(i); if (!block.length) { var nb = steps.dfn.buildSenseBlock(stepDiv); list.append(nb); block = list.find("li.wiktku-dfn-sense").last(); } // Template selector. block.find("select.wiktku-dfn-tpl-select").val(sense.tpl || ""); if (sense.tpl) { block.find("textarea.wiktku-dfn-mane").hide(); block.find("input.wiktku-dfn-tpl-title").val(sense.tplTitle || "").show(); } else { block.find("textarea.wiktku-dfn-mane").val(sense.mane || "").show(); block.find("input.wiktku-dfn-tpl-title").hide().val(""); } // Re-sync the formên alternatîv/hevmane/… hide state now that // tplSelect's value was set programmatically (its own "change" // handler doesn't fire from .val(), so this doesn't happen otherwise). var updateVis = block.data("updateFieldVisibility"); if (updateVis) updateVis(); // Restore a sub-list (etiket, formên alternatîv, hevmane …) from a values array. function restoreSubList(cls, values) { if (!values || !values.length) return; var groupDiv = block.find("." + cls + "-group"); var subList = groupDiv.find("ol, ul").first(); if (!subList.length) return; // group not found // Fill existing items, append new ones as needed. $.each(values, function (j, val) { var items = subList.find("li"); if (j < items.length) { items.eq(j).find("textarea").val(val); } else { var ta = $("<textarea></textarea>") .attr("name", "wiktku-dfn-restore-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 1) .attr("class", "wiktku-dfn-subfield wiktku-start-narrow") .val(val); ta.on("input", function () { steps.dfn.onSubInput(subList, this, 1, true); }); subList.append($("<li></li>").append(ta)); } }); } // Reveal and populate lazy groups that have data. var lazyMap = { "wiktku-dfn-etiket": sense.etiket, "wiktku-dfn-alternativ": sense.alternativ, "wiktku-dfn-hevmane": sense.hevmane, "wiktku-dfn-dijmane": sense.dijmane, "wiktku-dfn-koordine": sense.koordine, "wiktku-dfn-jornav": sense.jornav, "wiktku-dfn-jernav": sense.jernav }; $.each(lazyMap, function (cls, vals) { if (vals && vals.length) restoreSubList(cls, vals); }); // Nimûne items are objects { text, tr?, t? } — restore using the builder. if (sense.nimune && sense.nimune.length) { var nimuneGroupDiv = block.find(".wiktku-dfn-nimune-group"); var nimuneList = nimuneGroupDiv.find("ol.wiktku-dfn-nimune-list"); var buildFn = nimuneGroupDiv.data("buildNimuneLi"); nimuneList.empty(); $.each(sense.nimune, function (_, n) { var text = typeof n === "object" ? (n.text || "") : n; if (!text) return; var li = buildFn ? buildFn() : $("<li class='wiktku-dfn-nimune-li'></li>"); li.find(".wiktku-dfn-nimune-text").val(text); if (n.tr) li.find(".wiktku-dfn-nimune-tr").val(n.tr); if (n.t) li.find(".wiktku-dfn-nimune-t").val(n.t); nimuneList.append(li); }); // Always leave a blank trailing item. if (buildFn) nimuneList.append(buildFn()); } // Restore jêder (quote/citation) entries — a growing list, restored using the // builder just like Nimûne. Accepts either the current array shape or a // single legacy object (from older saved sections) for backwards compatibility. var jederArr = $.isArray(sense.jeder) ? sense.jeder : (sense.jeder ? [sense.jeder] : []); if (jederArr.length) { var jederGroupDiv = block.find(".wiktku-dfn-jeder-group"); var jederList = jederGroupDiv.find("ol.wiktku-dfn-jeder-list"); var buildJederFn = jederGroupDiv.data("buildJederLi"); jederList.empty(); $.each(jederArr, function (_, j) { if (!j || !j.quote) return; var li = buildJederFn ? buildJederFn() : $("<li class='wiktku-dfn-jeder-li'></li>"); li.find(".wiktku-dfn-nimune-quote").val(j.quote); if (j.quoteTr) li.find(".wiktku-dfn-nimune-quote-tr").val(j.quoteTr); if (j.quoteT) li.find(".wiktku-dfn-nimune-quote-t").val(j.quoteT); if (j.jederManual) { var manualSel = li.find(".wiktku-dfn-quote-src-sel"); manualSel.val("__manual__").trigger("change"); li.find(".wiktku-dfn-quote-src-manual").val(j.jederManual); } else if (j.jederTpl) { var srcSel = li.find(".wiktku-dfn-quote-src-sel"); srcSel.val(j.jederTpl).trigger("change"); if (j.jêderFields) { $.each(j.jêderFields, function (key, val) { li.find(".wiktku-dfn-quote-src-input[data-field-key='" + key + "']").val(val); }); } } jederList.append(li); }); // Always leave a blank trailing item, same as Nimûne. if (buildJederFn) jederList.append(buildJederFn()); } }); } /** * Snapshot simple (non-dfn) per-section steps from current DOM into obj. */ function saveCurrentSection() { var snap = {}; $.each(PER_SECTION_STEP_IDS, function (_, id) { if (id === "dfn") { snap.dfn = snapshotDfn(); return; } if (id === "etym") { snap.etym = $.trim($("#wiktku-start-etym .wiktku-etym-text").val()); return; } var step = steps[id]; if (!step) return; var stepDiv = $("#wiktku-start-" + id); if (id === "trans") { snap.trans = steps.trans.getTranslations(stepDiv); return; } if (id === "zarava") { snap.zarava = steps.zarava.getTranslations(stepDiv); return; } if (id === "dunde") { snap.dunde = steps.dunde.getRows(stepDiv); return; } // Generic: read all step fields. var fields = stepDiv.find(".wiktku-start-step-field"); if (step.multiple) { snap[id] = fields.map(function () { return $(this).val(); }).get(); } else { snap[id] = fields.val(); } }); sections[activeSection] = snap; } /** * Restore a previously saved snapshot into the form DOM. */ function restoreSection(snap) { $.each(PER_SECTION_STEP_IDS, function (_, id) { if (id === "dfn") { restoreDfn(snap.dfn || []); return; } if (id === "etym") { $("#wiktku-start-etym .wiktku-etym-wrap").remove(); steps.etym.build($("#wiktku-start-etym")); $("#wiktku-start-etym .wiktku-etym-text").val(snap.etym || ""); return; } if (id === "trans") { // Rebuild trans groups (dfn must already be restored by this // point in the $.each loop, so glossList() reflects it). var transDiv = $("#wiktku-start-trans"); transDiv.find(".wiktku-trans-group").remove(); steps.trans.build(transDiv); var groupsSnap = snap.trans || []; $.each(groupsSnap, function (gi, rows) { var group = transDiv.find(".wiktku-trans-group[data-gloss-pos='" + gi + "']"); if (!group.length) return; // gloss no longer exists — drop its rows var list = group.find("ul.wiktku-trans-list"); $.each(rows, function (j, row) { var lang = row[0], words = row[1]; var lastRow = list.find("li.wiktku-trans-row").last(); lastRow.find("select").val(lang).trigger("change"); var wordList = lastRow.find("ul.wiktku-trans-words"); $.each(words, function (k, word) { var wordItems = wordList.find("li"); if (k < wordItems.length) { wordItems.eq(k).find("textarea").val(word); } else { // .val() below doesn't fire "input", so the normal // auto-grow never runs — append a matching item // ourselves instead of silently dropping the word. var extraInput = steps.trans.makeWordInput(); wordList.append($("<li></li>").append(extraInput)); extraInput.val(word); } }); // Leave one trailing empty field so the row can still grow // when the user types, matching a freshly-built row. if ($.trim(wordList.children("li").last().find("textarea").val())) { wordList.append($("<li></li>").append(steps.trans.makeWordInput())); } }); }); return; } if (id === "zarava") { // Rebuild zarava groups (dfn must already be restored by this // point in the $.each loop, so glossList() reflects it). var zaravaDiv = $("#wiktku-start-zarava"); zaravaDiv.find(".wiktku-zarava-group").remove(); steps.zarava.build(zaravaDiv); var zaravaGroupsSnap = snap.zarava || []; $.each(zaravaGroupsSnap, function (gi, rows) { var group = zaravaDiv.find(".wiktku-zarava-group[data-gloss-pos='" + gi + "']"); if (!group.length) return; // gloss no longer exists — drop its rows var list = group.find("ul.wiktku-zarava-list"); $.each(rows, function (j, row) { var lang = row[0], words = row[1]; var lastRow = list.find("li.wiktku-zarava-row").last(); lastRow.find("select").val(lang).trigger("change"); var wordList = lastRow.find("ul.wiktku-zarava-words"); $.each(words, function (k, word) { var wordItems = wordList.find("li"); if (k < wordItems.length) { wordItems.eq(k).find("textarea").val(word); } else { var extraInput = steps.zarava.makeWordInput(); wordList.append($("<li></li>").append(extraInput)); extraInput.val(word); } }); if ($.trim(wordList.children("li").last().find("textarea").val())) { wordList.append($("<li></li>").append(steps.zarava.makeWordInput())); } }); }); return; } if (id === "dunde") { // Rebuild dunde rows. var dundeDiv = $("#wiktku-start-dunde"); dundeDiv.find("ul.wiktku-dunde-list").remove(); steps.dunde.build(dundeDiv); var dundeRows = snap.dunde || []; $.each(dundeRows, function (i, row) { var lang = row[0], words = row[1]; var list = dundeDiv.find("ul.wiktku-dunde-list"); var lastRow = list.find("li.wiktku-dunde-row").last(); lastRow.find("select").val(lang).trigger("change"); var wordList = lastRow.find("ul.wiktku-dunde-words"); $.each(words, function (j, word) { var wordItems = wordList.find("li"); if (j < wordItems.length) { wordItems.eq(j).find("textarea").val(word); } else { // .val() below doesn't fire "input", so the normal // auto-grow never runs — append a matching item // ourselves instead of silently dropping the word. var extraInput = steps.dunde.makeWordInput(); wordList.append($("<li></li>").append(extraInput)); extraInput.val(word); } }); // Leave one trailing empty field so the row can still grow // when the user types, matching a freshly-built row. if ($.trim(wordList.children("li").last().find("textarea").val())) { wordList.append($("<li></li>").append(steps.dunde.makeWordInput())); } }); return; } var step = steps[id]; if (!step) return; var stepDiv = $("#wiktku-start-" + id); var fields = stepDiv.find(".wiktku-start-step-field"); var val = snap[id]; if (val === undefined || val === null) return; if (step.multiple) { var arr = val; fields.each(function (i) { if (i < arr.length) $(this).val(arr[i]); }); } else { fields.val(val); } // Notify chosen widgets of the programmatic value change. if (!isMobile) fields.filter("select").trigger("chosen:updated"); }); } function getWikitextForCurrentSection(callback) { var values = getValues(); var entry = steps.pos.output(values); steps.dfn.getOutput(values, function (output) { entry += output; entry += steps.je.output(values); entry += steps.tekildar.output(values); entry += steps.etym.output(values); entry += steps.dunde.output(values); entry += steps.binereherwiha.output(values); entry += steps.zarava.output(values); entry += steps.trans.output(values); callback(entry, values); }); } function getWikitextAllSections(callback) { saveCurrentSection(); var results = new Array(sections.length); var sharedValues = getValues(); // lang/pron are shared function processSection(i) { if (i >= sections.length) { // All done — restore original active section. restoreSection(sections[activeSection]); refresh(); callback(results, sharedValues); return; } restoreSection(sections[i]); refresh(); getWikitextForCurrentSection(function (sectionText) { results[i] = sectionText; processSection(i + 1); }); } processSection(0); } /** * Assembles wikitext for all sections plus the shared lang/pron header. */ function getWikitext(callback) { getWikitextAllSections(function (sectionTexts, sharedValues) { var entry = steps.lang.output(sharedValues); entry += steps.pron.output(sharedValues); entry += sectionTexts.join("\n"); // Edit summary uses section 0's values. Read from the saved snapshot // (not the live DOM) so it doesn't mix section 0's pos with whichever // section happens to be active/restored at this point. var dfnSenses = (sections[0] && sections[0].dfn) || []; var dfnSummary = dfnSenses.map(function (s) { return s.mane; }).filter(Boolean).join("; "); var summaryLabel = addLangMode ? "WF:Ziman lê zêde" : "WF:Nû"; var summary = "([[Mediawiki:Gadget-start.js|" + summaryLabel + "]] v.2.0) +" + sharedValues.lang + ":" + sections[0].pos + ":" + dfnSummary; var summaryField = document.getElementById("wpSummary"); if (addLangMode && summaryField.value) { summary = summaryField.value + " " + summary; } summaryField.value = summary; callback(entry); }); } var continueBtn; function getValuesForStep(stepId) { var fields = $("#wiktku-start-" + stepId + " .wiktku-start-step-field"); var step = steps[stepId]; if (step.keys) { var values = {}; fields.each(function (i, field) { var key = $(field).prevAll(".wiktku-start-step-keyfield").val(); if (key) values[key] = $(field).val(); }); return values; } else if (step.multiple) { return fields.map(function () { return $(this).val(); }).get(); } return fields.val(); } function getValues() { var values = {}; $.each(steps, function (stepId) { values[stepId] = getValuesForStep(stepId); }); return values; } function populateMenus(inputs, choices, disabledValues) { if (!disabledValues) disabledValues = {}; var vals = inputs.map(function (i, input) { return $(input).val(); }); inputs.empty(); inputs.append($("<option></option>")); $.each(choices, function (j, choice) { // Append the language code in parentheses so that typing a code // (e.g. "ku") in the search box still finds the language name. var displayText = capitalize(choice[1]); if (choice[2] !== undefined) { // This is a language choice [code, name, sortKey] — show code. displayText = capitalize(choice[1]) + " (" + choice[0] + ")"; } var option = $(mw.html.element("option", { value: choice[0] }, displayText)); if (disabledValues[choice[0]]) option.prop("disabled", true); inputs.append(option); }); inputs.val(function (i) { return vals[i]; }); } /** * Returns a bitmap containing the keys that should be disabled for a key * menu in the given step because they are disabled or already taken by * another key menu. */ function getDisabledKeys(step) { var occupiedKeys = {}; $("#wiktku-start-" + step.id + " .wiktku-start-step-keyfield").each(function () { occupiedKeys[$(this).val()] = true; }); if (step.disabledKeys) $.extend(occupiedKeys, step.disabledKeys); return occupiedKeys; } function buildKeyInput(step) { if (!step.keys) return undefined; var input = $(mw.html.element("select", { "class": "wiktku-start-step-keyfield wiktku-start-narrow" })); input.attr("data-placeholder", "Hilbijêre " + step.keyName); if (isMobile) { populateMenus(input, step.keys, getDisabledKeys(step)); // On mobile return the wrapper; the select is inside it. // Change events still fire on the inner select. return wrapNativeSelect(input); } input.on("chosen:showing_dropdown", function () { $(this).data("wiktku-defaultValue", $(this).val()); }); input.change(function (_, context) { var inputs = $("#wiktku-start-" + step.id + " .wiktku-start-step-keyfield").not(this); var oldValue = $(this).data("wiktku-defaultValue"); var newValue = context.selected; inputs.find("option[value='" + oldValue + "']").prop('disabled', false); inputs.find("option[value='" + newValue + "']").prop('disabled', true); inputs.trigger("chosen:updated"); }); populateMenus(input, step.keys, getDisabledKeys(step)); return input; } /** * If the current text field has text and there are no more text fields after * the current text field in the list, add another text field to the list. */ function refreshForTextField(currentInput, step) { currentInput = $(currentInput); var value = currentInput.val(); var item = currentInput.parent(); if (value && !item.next("li").length) { var nextInput = $("<textarea></textarea>") .attr("name", "wiktku-field-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("class", currentInput.attr("class")) .attr("rows", currentInput.attr("rows") || 1); nextInput.on("input", function (evt) { refreshForTextField(evt.target, step); }); var nextKeyInput = buildKeyInput(step); var nextItem = $("<li></li>").append(nextKeyInput).append(nextInput); item.parent().append(nextItem); if (nextKeyInput) nextKeyInput.chosen(chosenOptions); } var canContinue = !continueBtn.isDisabled(); if ((value && !canContinue) || (!value && canContinue)) { refresh(step); } } function prepareInput(input, step) { if (!input) return; if (step.required) input.prop('required', true); input.change(step, refresh); } /** * Shows and hides all the steps based on whether their prerequisites are met, * and updates placeholders where applicable. */ function refresh(evt) { var values = getValues(); var changedStep = evt && evt.data; var didFocus = false; var canContinue = true; // Re-filter template options in every sense block whenever lang changes. $("#wiktku-start-dfn .wiktku-dfn-tpl-select").each(function () { var fn = $(this).data("updateOptions"); if (typeof fn === "function") fn(); }); // Re-filter pronunciation and etymology template dropdowns when language changes. steps.pron.refreshTplSelect(); steps.etym.refreshTplSelect(); // Sync tr/t sub-fields in every nimûne item to the current language. // tr shown when language needs transliteration; t shown when lang !== "ku". (function () { var lang = values.lang || ""; var showTr = needsTransliteration(lang); var showT = lang && lang !== "ku"; $("#wiktku-start-dfn .wiktku-dfn-nimune-list li.wiktku-dfn-nimune-li").each(function () { var li = $(this); // Ensure the sub-wrapper exists when we need it. var subWrap = li.find(".wiktku-dfn-nimune-sub"); // tr field var trTa = li.find(".wiktku-dfn-nimune-tr"); if (showTr && !trTa.length) { if (!subWrap.length) { subWrap = $("<div></div>").addClass("wiktku-dfn-nimune-sub"); li.append(subWrap); } trTa = $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-tr-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 5) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-tr") .attr("placeholder", "Transkrîpsiyon…"); subWrap.prepend(trTa); } else if (!showTr && trTa.length) { trTa.remove(); } // t field var tTa = li.find(".wiktku-dfn-nimune-t"); if (showT && !tTa.length) { if (!subWrap.length) { subWrap = $("<div></div>").addClass("wiktku-dfn-nimune-sub"); li.append(subWrap); } tTa = $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-t-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 5) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-t") .attr("placeholder", "Tercimeya nimûneyê kurmancî…"); subWrap.append(tTa); } else if (!showT && tTa.length) { tTa.remove(); } // Remove the wrapper if it ended up empty. subWrap = li.find(".wiktku-dfn-nimune-sub"); if (subWrap.length && !subWrap.children().length) subWrap.remove(); }); }()); // Sync tr/t sub-fields in every jêder citation to the current language. // tr shown when language needs transliteration; t shown when lang !== "ku". (function () { var lang = values.lang || ""; var showTr = needsTransliteration(lang); var showT = lang && lang !== "ku"; $("#wiktku-start-dfn .wiktku-dfn-jeder-list li.wiktku-dfn-jeder-li").each(function () { var li = $(this); // Ensure the sub-wrapper exists when we need it. It must sit right // after the quote textarea and before the source selector. var subWrap = li.find(".wiktku-dfn-quote-sub"); // tr field var trTa = li.find(".wiktku-dfn-nimune-quote-tr"); if (showTr && !trTa.length) { if (!subWrap.length) { subWrap = $("<div></div>").addClass("wiktku-dfn-quote-sub"); li.find(".wiktku-dfn-nimune-quote").after(subWrap); } trTa = $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-quote-tr-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 2) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-quote-tr") .attr("placeholder", "Transkrîpsiyona jêgirtinê…"); subWrap.prepend(trTa); } else if (!showTr && trTa.length) { trTa.remove(); } // t field var tTa = li.find(".wiktku-dfn-nimune-quote-t"); if (showT && !tTa.length) { if (!subWrap.length) { subWrap = $("<div></div>").addClass("wiktku-dfn-quote-sub"); li.find(".wiktku-dfn-nimune-quote").after(subWrap); } tTa = $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-quote-t-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 2) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-quote-t") .attr("placeholder", "Tercimeya jêgirtinê ya kurmancî…"); subWrap.append(tTa); } else if (!showT && tTa.length) { tTa.remove(); } // Remove the wrapper if it ended up empty. subWrap = li.find(".wiktku-dfn-quote-sub"); if (subWrap.length && !subWrap.children().length) subWrap.remove(); }); }()); $.each(steps, function (stepId, step) { if (typeof(step.visible) === "function" && !step.visible(values)) { $("#wiktku-start-" + stepId).slideUp(); } else { var stepDiv = $("#wiktku-start-" + stepId); if (changedStep !== step && typeof(step.build) === "function") { prepareInput(step.build(stepDiv, values), step); } var input = stepDiv.find(".wiktku-start-step-field"); if (typeof(step.example) === "function") { // .find() above already reaches nested fields (e.g. the dfn // step's mane textareas inside each sense block), so one // assignment covers every step; dfn keeps its own fallback. var exampleText = step.example(values) || (step.id === "dfn" ? "Mane…" : ""); input.attr("placeholder", exampleText); } var didSlideDown; if (!didFocus && stepDiv.css("display") === "none" && step.required) { didSlideDown = function (evt) { input.focus(); }; didFocus = true; } stepDiv.slideDown(didSlideDown); } if (step.required && (values[stepId] === "" || (step.multiple && values[stepId].join("") === ""))) { canContinue = false; } }); continueBtn.setDisabled(!canContinue); } function destroy() { $("#wiktku-start-form, .noafterwizard").slideUp(function () { $(this).remove(); }); $(".noarticletext .nowizard, #editform").slideDown(); $("#ca-edit").removeClass("selected"); $("#ca-wiktku-nowizard").addClass("selected"); } // Priority order for Kurdish dialects and the navz pseudo-code. // Codes listed here come before all other languages; unlisted codes // are sorted alphabetically by their display name via localeCompare. var LANG_PRIORITY = ["navz", "ku", "hac", "sdh", "lki", "ckb", "zza"]; /** * Inserts a new == {{ziman|code}} == section into existing page wikitext * at the correct sorted position: * 1. Any content before the first language section is preserved at the top. * 2. navz is always first, then ku/hac/sdh/lki/ckb/zza in that order, * then all other languages sorted by display name (localeCompare). */ function insertNewLangSection(existing, wikitext) { var newCodeMatch = wikitext.match(/^== \{\{ziman\|([^}]+)\}\} ==/); var newCode = newCodeMatch ? newCodeMatch[1] : ""; var sections = []; var preamble = ""; var firstMatch = existing.match(/(?:^|\n)== \{\{ziman\|/); if (!firstMatch) { // No existing lang sections at all — just append. var sep = existing && !/\n\s*$/.test(existing) ? "\n\n" : ""; return existing + sep + wikitext; } // Everything before the first == {{ziman|...}} == is the preamble. var firstSectionStart = existing.indexOf("== {{ziman|"); // Walk back to the start of that line. var lineStart = existing.lastIndexOf("\n", firstSectionStart - 1); var preambleEnd = lineStart !== -1 ? lineStart + 1 : 0; preamble = existing.slice(0, preambleEnd); // Parse each language section: header line + everything until the next header. var body = existing.slice(preambleEnd); // NOTE: with the /m flag, a bare "$" matches end-of-*line*, not just // end-of-string — that previously made the non-greedy content group // stop at the section's first line break instead of running to the // next language header (or the real end of the text), silently // dropping the rest of that section's wikitext. (?![\s\S]) matches // only the true end of the string, /m flag or not. var langSectionRe = /^(== \{\{ziman\|([^}]+)\}\} ==\n?)([\s\S]*?)(?=\n== \{\{ziman\||(?![\s\S]))/gm; var m; while ((m = langSectionRe.exec(body)) !== null) { sections.push({ code: m[2], content: m[0] // full text of this section including header }); } // Determine sort rank: priority list first (by index), then alphabetical. function getLangName(code) { var entry = langsByCode[code]; return entry ? entry[1] : code; } function sortRank(code) { var idx = LANG_PRIORITY.indexOf(code); return idx !== -1 ? idx : LANG_PRIORITY.length; } function compareLangs(a, b) { var ra = sortRank(a), rb = sortRank(b); if (ra !== rb) return ra - rb; // Both are outside priority list — sort by display name. return getLangName(a).localeCompare(getLangName(b), userLang); } // Insert the new section into the sorted list. var newSection = { code: newCode, content: wikitext }; var inserted = false; for (var i = 0; i < sections.length; i++) { if (compareLangs(newCode, sections[i].code) < 0) { sections.splice(i, 0, newSection); inserted = true; break; } } if (!inserted) sections.push(newSection); // Re-join: preamble + sections separated by newlines. var joined = sections.map(function (s) { // Ensure each section ends with exactly one newline before the next. return s.content.replace(/\n+$/, ""); }).join("\n"); return preamble + joined + "\n"; } function build() { $(".nowizard, .nowizard .noafterwizard").hide(); var callToAction = $("#wiktku-calltoaction"); var origCallToActionText = callToAction.text(); $(mw.util.addPortletLink("p-views", "#", "Edîtora çavkaniyê veke", "ca-wiktku-nowizard", "Vê rûpelê bi edîtora çavkaniyê çêke", undefined, "#ca-watch")).click(function (evt) { evt.preventDefault(); callToAction.text(origCallToActionText); destroy(); }); if (callToAction.length) { callToAction.text(origCallToActionText + " Forma li jêr ji bo çêkirina madeyeke nû bi kar bîne."); } var startForm = $("<form id='wiktku-start-form'></form>"); if (addLangMode) { startForm.append($("<p class='wiktku-addlang-notice'></p>").text( "Bi vê formê tu yê beşeke nû li rûpelê îlaw bikî. Eger ev zimanê ku tu îlawe dikî jixwe di rûpelê de hebe, beşa nû li dawiya vî zimanî dê were îlawekirin. " + "Ji kerema xwe netîceya dawî kontrol bikin, eger problemek derkeve, li [[Mediawiki talk:Gadget-start.js|nîqaşa vê amûrê]] problemê ragihîne.")); } var spinner; // Tab bar for switching between POS sections. var sectionTabsDiv = $("<div id='wiktku-section-tabs'></div>"); startForm.submit(function (evt) { evt.preventDefault(); continueBtn.setDisabled(true); spinner.show(); getWikitext(function (wikitext) { if (addLangMode) { var textbox = $("#wpTextbox1"); var existing = textbox.val() || ""; // Check whether the generated lang header already exists in the page. // wikitext always starts with "== {{ziman|CODE}} ==\n" (from steps.lang.output). // If that exact section heading is already present in the existing content, // strip it from the new output and insert the remaining content at the end // of that lang section (just before the next == level-2 heading, or at the // very end of the page if there is no following section). var langHeaderMatch = wikitext.match(/^(== \{\{ziman\|[^}]+\}\} ==\n)/); if (langHeaderMatch) { var langHeader = langHeaderMatch[1]; // e.g. "== {{ziman|ku}} ==\n" // Escape for use in RegExp. var escapedHeader = langHeader.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); if (new RegExp(escapedHeader).test(existing)) { // Strip the header from the new output. var newContent = wikitext.slice(langHeader.length); // Find the insertion point: end of the existing lang section. // A new L2 heading marks the start of the next language block. var afterHeader = existing.indexOf(langHeader); var searchFrom = afterHeader + langHeader.length; // Find the next == … == heading after this section's start. var nextL2 = existing.indexOf("\n== ", searchFrom); var insertAt = nextL2 !== -1 ? nextL2 : existing.length; // Ensure there's a blank line before the inserted block. var before = existing.slice(0, insertAt); var after = existing.slice(insertAt); var sep = /\n\s*$/.test(before) ? "" : "\n"; textbox.val(before + sep + newContent + after); } else { // New language — insert at the correct sorted position. textbox.val(insertNewLangSection(existing, wikitext)); } } else { // Unexpected format — insert at sorted position anyway. textbox.val(insertNewLangSection(existing, wikitext)); } } else { $("#wpTextbox1").val(wikitext); } $("html, body").animate({scrollTop: 0}); callToAction.text("Hindik ma!"); $("#wiktku-preview-container").remove(); destroy(); }); }); $.each(ordered_steps, function (i, step) { var stepDiv = $(mw.html.element("div", { "class": "wiktku-start-step", id: "wiktku-start-" + step.id })); var name = capitalize(step.name); stepDiv.append($(mw.html.element("h3", { "class": "wiktku-start-step-name" }, new mw.html.Raw(mw.html.element("label", { "for": "wiktku-start-" + step.id + "-field" }, name))))); if (step.question_fmt) { stepDiv.append($(mw.html.element("label", { "class": "wiktku-start-step-question", "for": "wiktku-start-" + step.id + "-field" }, step.question_fmt))); if (step.question_br) stepDiv.append($("<br>")); } var input; if (step.choices) { input = $(mw.html.element("select", { "class": "wiktku-start-step-field", id: "wiktku-start-" + step.id + "-field" })); input.attr("data-placeholder", capitalize(step.name) + " hilbijêre "); populateMenus(input, step.choices); if (step.multiple) input.attr("multiple", true); if (isMobile) { stepDiv.append(wrapNativeSelect(input)); } else { stepDiv.append(input); } } else if (typeof(step.build) === "function") { input = step.build(stepDiv); } else { input = $("<textarea></textarea>") .attr("class", "wiktku-start-step-field") .attr("id", "wiktku-start-" + step.id + "-field") .attr("rows", step.rows || 2); if (step.narrow) input.addClass("wiktku-start-narrow"); if (step.multiple) { input.on("input", function (evt) { refreshForTextField(evt.target, step); }); var keyInput = buildKeyInput(step); var list = $(step.ordered ? "<ol></ol>" : "<ul></ul>") .append($("<li></li>").append(keyInput).append(input)); stepDiv.append(list); } else stepDiv.append(input); } prepareInput(input, step); stepDiv.hide(); // Insert tab bar just before the first per-section step. if (step.id === "pos") startForm.append(sectionTabsDiv); startForm.append(stepDiv); }); // ── Section tab helpers ────────────────────────────────────────────── // ── Add-section button — lives in the tab bar, disabled until pos chosen ── var addSectionBtn = new OO.ui.ButtonWidget({ label: "+ Beş zêde bike", disabled: true }); addSectionBtn.on("click", function () { saveCurrentSection(); sections.push({}); activeSection = sections.length - 1; $.each(PER_SECTION_STEP_IDS, function (_, id) { if (id === "dfn") { var stepDiv = $("#wiktku-start-dfn"); stepDiv.find("ol.wiktku-dfn-list").remove(); steps.dfn.build(stepDiv); return; } if (id === "etym") { $("#wiktku-start-etym .wiktku-etym-wrap").remove(); steps.etym.build($("#wiktku-start-etym")); return; } if (id === "trans") { var transDiv = $("#wiktku-start-trans"); transDiv.find(".wiktku-trans-group").remove(); return; } if (id === "zarava") { var zaravaDiv = $("#wiktku-start-zarava"); zaravaDiv.find(".wiktku-zarava-group").remove(); return; } if (id === "dunde") { var dundeDiv = $("#wiktku-start-dunde"); dundeDiv.find("ul.wiktku-dunde-list").remove(); return; } var stepDiv = $("#wiktku-start-" + id); stepDiv.find(".wiktku-start-step-field").val(""); if (!isMobile) stepDiv.find("select.wiktku-start-step-field").trigger("chosen:updated"); }); renderSectionTabs(); refresh(); $("html, body").animate({ scrollTop: sectionTabsDiv.offset().top - 20 }, 300); }); /** Re-render the tab bar to reflect current sections[] and activeSection. */ function renderSectionTabs() { // Detach (not remove) the button first: .empty() strips bound // event data from any children left inside it, which would // silently kill addSectionBtn's click handler on every re-render. addSectionBtn.$element.detach(); sectionTabsDiv.empty(); var lang = getValues().lang || ""; if (!lang) { sectionTabsDiv.hide(); return; } sectionTabsDiv.show(); $.each(sections, function (i) { var posVal = sections[i].pos || ""; var tabLabel = posVal ? capitalize(posVal) : ("Beş " + (i + 1)); var tab = $("<span></span>") .addClass("wiktku-section-tab") .text(tabLabel) .toggleClass("wiktku-tab-active", i === activeSection); (function (idx) { tab.on("click", function () { if (idx === activeSection) return; saveCurrentSection(); activeSection = idx; restoreSection(sections[activeSection]); refresh(); renderSectionTabs(); }); }(i)); sectionTabsDiv.append(tab); }); // Enable "Beş zêde bike" only when the active section has a pos chosen. var activePos = sections[activeSection] && sections[activeSection].pos ? sections[activeSection].pos : getValues().pos; addSectionBtn.setDisabled(!activePos); sectionTabsDiv.append(addSectionBtn.$element); } renderSectionTabs(); // Update the active tab's label whenever pos changes. startForm.on("change", "#wiktku-start-pos-field", function () { renderSectionTabs(); }); // Show the tab bar as soon as a language is selected. startForm.on("change", "#wiktku-start-lang-field", function () { renderSectionTabs(); }); var footer = $("<div id='wiktku-start-footer'></div>"); spinner = $(mw.html.element("img", { id: "wiktku-start-spinner", src: "//upload.wikimedia.org/wikipedia/commons/d/de/Ajax-loader.gif", alt: "Tê barkirin…", title: "Tê barkirin…" })); footer.append(spinner.hide()); continueBtn = new OO.ui.ButtonWidget({ id: "wiktku-unhide-editform", label: "Bişîne", flags: [ "primary", "progressive" ] }); continueBtn.on("click", function () { mw.notify("Tê şandin…", { type: "info", tag: "wiktku-submit" }); startForm.trigger("submit"); }); footer.append(continueBtn.$element); // "Edîtora çavkaniyê veke" button — inline fallback for the portlet link // which is invisible on mobile and easy to miss on desktop. var sourceEditorBtn = new OO.ui.ButtonWidget({ label: "Edîtora çavkaniyê veke", framed: false }); sourceEditorBtn.on("click", function () { destroy(); }); footer.append(sourceEditorBtn.$element); // ── Preview checkboxes ─────────────────────────────────────────────── // Wikitext preview (raw text panel) var previewCheck = $("<input type='checkbox' id='wiktku-preview-toggle'>"); var previewLabel = $("<label for='wiktku-preview-toggle'></label>") .text(" Pêşdîtina wîkîtekstê"); var previewPanel = $("<pre id='wiktku-preview-panel'></pre>").hide(); // Live rendered preview (parsed HTML panel, same logic as AjaxEdit). // Not available on mobile — API polling causes too many problems on small screens. var livePreviewCheck = null; var livePreviewPanel = null; if (!isMobile) { livePreviewCheck = $("<input type='checkbox' id='wiktku-live-preview-toggle'>"); livePreviewPanel = $("<div id='wiktku-live-preview-panel'></div>").hide(); } // Container that holds both panels and switches between stacked / side-by-side. var previewContainer = $("<div id='wiktku-preview-container'></div>"); previewContainer.append(previewPanel); if (!isMobile) previewContainer.append(livePreviewPanel); var previewTimer = null; var livePreviewIntervalId = -1; var livePreviewActive = false; // guards in-flight fetches after uncheck /** Rebuilds wikitext preview if its checkbox is checked. */ function schedulePreview() { if (!previewCheck.prop("checked")) return; clearTimeout(previewTimer); // Debounce: wait 400 ms after the last keystroke before rebuilding. previewTimer = setTimeout(function () { getWikitext(function (wikitext) { previewPanel.text(wikitext).show(); updatePanelLayout(); }); }, 400); } /** Fetches parsed HTML and populates the live preview panel. */ function loadLivePreview() { getWikitext(function (wikitext) { new mw.Api().parse(wikitext, { title: mw.config.get("wgPageName") }).done(function (html) { // Discard result if the user unchecked while the fetch was in flight. if (!livePreviewActive) return; livePreviewPanel.html(html).show(); updatePanelLayout(); }); }); } /** Adjusts panel widths depending on which previews are visible. */ function updatePanelLayout() { var wikitextVisible = previewCheck.prop("checked"); var liveVisible = livePreviewCheck && livePreviewCheck.prop("checked"); if (wikitextVisible && liveVisible) { // Side by side — each panel takes roughly half the available width. previewPanel.css({ "flex": "1 1 45%", "min-width": "280px" }); livePreviewPanel.css({ "flex": "1 1 45%", "min-width": "280px" }); } else { // Full width for whichever is visible — only touch panels that are // actually shown so that setting flex doesn't override display:none. if (wikitextVisible) previewPanel.css({ "flex": "1 1 100%", "min-width": "" }); if (liveVisible && livePreviewPanel) livePreviewPanel.css({ "flex": "1 1 100%", "min-width": "" }); } } previewCheck.on("change", function () { if ($(this).prop("checked")) { schedulePreview(); } else { clearTimeout(previewTimer); previewPanel.hide(); updatePanelLayout(); } }); if (!isMobile) { livePreviewCheck.on("change", function () { if ($(this).prop("checked")) { livePreviewActive = true; livePreviewPanel.show(); loadLivePreview(); livePreviewIntervalId = setInterval(loadLivePreview, 500); } else { livePreviewActive = false; clearInterval(livePreviewIntervalId); livePreviewIntervalId = -1; livePreviewPanel.hide().empty(); updatePanelLayout(); } }); } // Listen on all input/change events on the form and update both previews. startForm.on("input change", function () { schedulePreview(); }); footer.append($("<span style='margin-left:1em'></span>") .append(previewCheck).append(previewLabel)); if (!isMobile) { var livePreviewLabel = $("<label for='wiktku-live-preview-toggle'></label>") .text(" Pêşdîtina zindî"); footer.append($("<span style='margin-left:1em'></span>") .append(livePreviewCheck).append(livePreviewLabel)); } startForm.append(footer); $("#editform").hide().before(startForm); // Insert preview container (holds both panels) after the form. startForm.after(previewContainer); if (!isMobile) startForm.find("select").chosen(chosenOptions); refresh(); // Zimanan ji MediaWiki:Gadget-translation_editor.js/ziman.json bar bike. // Kodên ku bi "-pro" diqedin û navên ku "zimanê destan" tê de heye // tên derxistin. Zimanên xardkirî li serî dimînin, yên din // bi alfabeyê li dû wan tên. // Pinned choices come from MediaWiki:Gadget-start.js/data.json (langChoices), // already loaded into steps.lang.choices before build() runs. var pinnedChoices = steps.lang.choices.slice(); var pinnedCodes = $.map(pinnedChoices, function (choice) { return choice[0]; }); new mw.Api().get({ action: "query", prop: "revisions", titles: "MediaWiki:Gadget-translation_editor.js/ziman.json", rvprop: "content", rvslots: "main", formatversion: 2 }).then(function (data) { var page = data.query.pages[0]; var content = page && page.revisions && page.revisions[0].slots.main.content; var zimanData; try { zimanData = JSON.parse(content); } catch (e) { zimanData = {}; } var extraChoices = []; $.each(zimanData, function (code, name) { // Filter: skip proto-language codes and legendary/reconstructed langs. if (/-pro$/i.test(code)) return; if (/ziman[eê]\s+destan/i.test(name)) return; // Skip codes already in the pinned list (they are handled above). if (pinnedCodes.indexOf(code) !== -1) return; // sortKey: bare name without leading "zimanê " for sorting. var sortKey = name.replace(/^ziman[eê]\s+/i, ""); var choice = [code, name, sortKey]; extraChoices.push(choice); langsByCode[code] = choice; }); // Populate langsByCode for pinned choices too. $.each(pinnedChoices, function (i, choice) { // Ensure pinned choices have a sortKey (index 2). if (choice.length < 3) choice[2] = choice[1]; langsByCode[choice[0]] = choice; }); // Sort the extra choices alphabetically by sort key. extraChoices.sort(function (a, b) { return a[2].localeCompare(b[2], userLang); }); // Final list: pinned first, then the rest. var allChoices = pinnedChoices.concat(extraChoices); steps.lang.choices = allChoices; steps.trans.keys = allChoices; steps.dunde.keys = allChoices; steps.zarava.keys = getZaravaKeys(allChoices); var langMenu = $("#wiktku-start-lang-field"); populateMenus(langMenu, steps.lang.choices); langMenu.trigger("chosen:updated"); var transMenus = $("#wiktku-start-trans .wiktku-start-step-keyfield"); populateMenus(transMenus, steps.trans.keys, getDisabledKeys(steps.trans)); transMenus.trigger("chosen:updated"); var dundeMenus = $("#wiktku-start-dunde .wiktku-start-step-keyfield"); populateMenus(dundeMenus, steps.dunde.keys, getDisabledKeys(steps.dunde)); dundeMenus.trigger("chosen:updated"); var zaravaMenus = $("#wiktku-start-zarava .wiktku-start-step-keyfield"); populateMenus(zaravaMenus, steps.zarava.keys, getDisabledKeys(steps.zarava)); }); } mw.loader.using(["jquery.chosen", "mediawiki.api", "oojs-ui-core"], function () { if (!isMobile) { mw.notify( "Amûr dest pê dike, hinek bisekinin. Not: jkx Sentaks (sentaks highlighter) neaktîv bikin", { type: "info", tag: "wiktku-start-notice", autoHide: true, autoHideSeconds: 10 } ); } // Load metadata, langChoices, posChoices and tplDefs from the companion // data page so they can be updated without touching this script. new mw.Api().get({ action: "query", prop: "revisions", titles: "MediaWiki:Gadget-start.js/data.json", rvprop: "content", rvslots: "main", formatversion: 2 }).then(function (data) { var page = data.query.pages[0]; var content = page && page.revisions && page.revisions[0].slots.main.content; var d; try { d = JSON.parse(content); } catch (e) { d = {}; } // Populate metadata. if (d.metadata) $.extend(metadata, d.metadata); // Populate gender labels. if (d.genderLabels) $.extend(GENDER_BASE_LABELS, d.genderLabels); // Populate lang choices (pinned list used by build() → ziman.json loader). if (d.langChoices) steps.lang.choices = d.langChoices; // Populate POS choices. if (d.posChoices) steps.pos.choices = d.posChoices; // Populate template definitions for the dfn sense-block builder. if (d.tplDefs) steps.dfn.tplDefs = d.tplDefs; // Populate pos placeholder examples. if (d.posExamples) steps.dfn.posExamples = d.posExamples; // Populate citation template definitions for the quote widget. if (d.jederDefs) steps.dfn.jederDefs = d.jederDefs; // Populate pronunciation and etymology template insert lists. if (d.pronTpls) { steps.pron.pronTpls = d.pronTpls; steps.pron.refreshTplSelect(); } if (d.etymTpls) { steps.etym.etymTpls = d.etymTpls; steps.etym.refreshTplSelect(); } // Sync trans/dunde/zarava keys with the (now populated) lang choices. steps.trans.keys = steps.lang.choices; steps.dunde.keys = steps.lang.choices; steps.zarava.keys = getZaravaKeys(steps.lang.choices); }).always(build); }); }); //</nowiki> 23p3ndxxhbu5zkk1phk8urx9h7cfm74 6265570 6265569 2026-07-19T14:06:26Z Wikihez 7344 6265570 javascript text/javascript // Li ser [[vi:MediaWiki:Gadget-start.js]] hatiye refaktorkirin. //<nowiki> $(function () { if (window.location.href.includes("editintro=User:Wikihez/creation/intro")) { return; // Do not run the script wextê WF:Bilez dişuxile } var ns = mw.config.get("wgNamespaceNumber"); if (ns && !(ns === 2 && mw.config.get("wgPageName").match(/\/ceribandin$|\/test$/))) { return; } var action = mw.config.get("wgAction"); var pageExists = !!mw.config.get("wgArticleId"); // "Zimanek lê zêde bike" mode: triggered from the portlet link below. var addLangMode = pageExists && mw.util.getParamValue("wiktkuaddlang") === "1"; // On a normal page view of an existing page, add the portlet link if (action === "view" && pageExists) { var targetContainer; var skin = mw.config.get('skin'); if (skin === 'vector-2022') { targetContainer = 'p-cactions'; } else if (skin === 'vector') { targetContainer = 'p-tb'; } mw.util.addPortletLink(targetContainer, mw.util.getUrl(mw.config.get("wgPageName"), { action: "submit", wiktkuaddlang: "1" }), "+Ziman/beşeke din", "ca-wiktku-addlang", "Ji vê rûpelê re ziman an jî beşeke nû zêde bike"); return; } if (!(action === "edit" || action === "submit")) { return; } if (!addLangMode && !$(".mw-newarticletext, .mw-newarticletextanon").length) { return; } function capitalize(str) { if (!str) return str; return str[0].toUpperCase() + str.substr(1); } function decapitalize(str) { if (!str) return str; return str[0].toLowerCase() + str.substr(1); } function escapeRegExp(str) { return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); } function stripWikilinks(str) { return str.replace(/\[\[([^\]|]+)(?:\|([^\]]+))?\]\]/g, function (m, target, display) { return display || target; }); } function insertAtCursor(el, text) { var start = el.selectionStart; var end = el.selectionEnd; var val = el.value; el.value = val.slice(0, start) + text + val.slice(end); var pos = start + text.length; el.selectionStart = el.selectionEnd = pos; } var pageName = mw.config.get("wgPageName").replaceAll(/_/g, " "); if (ns) pageName = pageName.replace(/.*\//, ""); var pageNameRe = escapeRegExp(pageName); var userLang = mw.config.get("wgUserLanguage"); // Mobile detection: MobileFrontend sets wgMFMode, or fall back to touch check. var isMobile = !!mw.config.get("wgMFMode") || window.matchMedia("(pointer: coarse)").matches; var chosenOptions = { width: "20em", disable_search_threshold: 0, placeholder_text_single: "Yekî hilbijêre", placeholder_text_multiple: "Hilbijêre", no_results_text: "Nehat dîtin", enable_split_word_search: true, search_contains: true }; function wrapNativeSelect(select) { var placeholder = select.attr("data-placeholder") || "Lê bigere…"; // Hide the native select — we drive it programmatically. select.hide(); var wrapper = $("<span class='wiktku-native-select-wrap'></span>"); var textInput = $("<input type='search' autocomplete='off'>") .attr("placeholder", placeholder) .addClass("wiktku-start-narrow wiktku-ac-input"); var resultsList = $("<ul class='wiktku-ac-results'></ul>").hide(); // Full option cache — rebuilt when chosen:updated fires. var allOptions = []; function cacheOptions() { allOptions = []; select.find("option").each(function () { var v = $(this).val(); if (!v) return; // skip the empty placeholder option allOptions.push({ value: v, text: $(this).text(), disabled: $(this).prop("disabled") }); }); } cacheOptions(); function showResults(query) { var q = query.trim().toLowerCase(); resultsList.empty(); var matched; if (q) { matched = []; $.each(allOptions, function (_, o) { if (o.disabled) return; var codeMatch = o.value.toLowerCase().indexOf(q) !== -1; var nameMatch = o.text.toLowerCase().indexOf(q) !== -1; if (codeMatch || nameMatch) { matched.push({ opt: o, codeMatch: codeMatch }); } }); // Code matches (especially prefix matches) come first. matched.sort(function (a, b) { var aCode = a.opt.value.toLowerCase(); var bCode = b.opt.value.toLowerCase(); var aPrefix = aCode.indexOf(q) === 0; var bPrefix = bCode.indexOf(q) === 0; if (aPrefix !== bPrefix) return aPrefix ? -1 : 1; if (a.codeMatch !== b.codeMatch) return a.codeMatch ? -1 : 1; return 0; }); matched = matched.map(function (item) { return item.opt; }); } else { matched = allOptions.filter(function (o) { return !o.disabled; }); } if (!matched.length) { resultsList.hide(); return; } $.each(matched.slice(0, 50), function (_, opt) { var li = $("<li></li>").text(opt.text).attr("data-value", opt.value); // Use touchend instead of touchstart so that a scroll gesture does // not accidentally select an item. We track whether the finger moved // between touchstart and touchend — if it did, it was a scroll. var touchMoved = false; li.on("touchstart", function () { touchMoved = false; }); li.on("touchmove", function () { touchMoved = true; }); li.on("touchend", function (e) { if (touchMoved) return; // was a scroll, not a tap e.preventDefault(); selectOption(opt.value, opt.text); }); // Keep mousedown for desktop fallback. li.on("mousedown", function (e) { e.preventDefault(); selectOption(opt.value, opt.text); }); resultsList.append(li); }); // Position the list above or below depending on available viewport space. var inputRect = textInput[0].getBoundingClientRect(); var viewportH = window.innerHeight; var spaceBelow = viewportH - inputRect.bottom - 8; var spaceAbove = inputRect.top - 8; var maxH = Math.min(224, Math.max(spaceBelow, spaceAbove)); // 224px ≈ 14em resultsList.css({ "max-height": maxH + "px", "top": spaceBelow >= spaceAbove ? "100%" : "auto", "bottom": spaceBelow >= spaceAbove ? "auto" : "100%" }); resultsList.show(); } function selectOption(value, text) { textInput.val(text); select.val(value); resultsList.hide(); select.trigger("change"); } textInput.on("input focus", function () { showResults($(this).val()); }); textInput.on("blur", function () { // Short delay so a touchstart on a result item fires first. setTimeout(function () { resultsList.hide(); }, 200); }); // chosen:updated → re-cache (called after ziman.json loads). select.on("chosen:updated", function () { cacheOptions(); // If a value is already selected, keep the display text in sync. var cur = select.val(); if (cur) { var match = $.grep(allOptions, function (o) { return o.value === cur; })[0]; if (match) textInput.val(match.text); } }); // No-op .chosen() so desktop call-sites don't need guarding. select.chosen = function () { return select; }; wrapper.append(textInput).append(resultsList).append(select); return wrapper; } var langsByCode = {}; // Populated from [[MediaWiki:Gadget-start.js/data.json]] at runtime. var metadata = {}; // Zaravayên kurdî yên ku di beşa "Bi zaravayên din" de tên pêşkêşkirin — // ev kod ji beşa Werger têne derxistin daku heman zimên du caran neyê xwendin. var ZARAVA_LANG_CODES = ["ckb", "sdh", "lki", "hac", "zza"]; function getZaravaKeys(choices) { var byCode = {}; $.each(choices || [], function (_, c) { byCode[c[0]] = c; }); var result = []; $.each(ZARAVA_LANG_CODES, function (_, code) { if (byCode[code]) result.push(byCode[code]); }); return result; } function needsTransliteration(langCode) { var meta = metadata[langCode]; if (!meta || !meta.sc) return false; var scripts = Array.isArray(meta.sc) ? meta.sc : [meta.sc]; return scripts.length > 0 && scripts[0] !== "Latn"; } // Kodên cinsiyetê yên di metadata.g de — ji data.json tê dagirtin var GENDER_BASE_LABELS = {}; // Sub-lists that only make sense for a plain (non-şablon) sense — hidden // when a şablon (e.g. {{guharto|…}}) is chosen for that sense, since a // template-based sense has no "own" gloss for alternate forms, synonyms, // antonyms, coordinate terms, hypernyms or hyponyms to attach to. Etîket, // Nimûne and Jêgirtin stay visible either way. var HIDDEN_ON_TPL_GROUPS = [ "wiktku-dfn-alternativ", "wiktku-dfn-hevmane", "wiktku-dfn-dijmane", "wiktku-dfn-koordine", "wiktku-dfn-jornav", "wiktku-dfn-jernav" ]; function genderLabel(code) { if (code === "p") return "Pirjimar"; var pluralMatch = code.match(/^(.+)-p$/); if (pluralMatch && GENDER_BASE_LABELS[pluralMatch[1]]) { return GENDER_BASE_LABELS[pluralMatch[1]] + " (pirjimar)"; } return GENDER_BASE_LABELS[code] || code; } /** * True if a sense has any content worth keeping besides its mane text — * etîket, hevmane/dijmane/koordîne/etc. word lists, nimûne, or jêder * (quote). Used so a sense with an empty mane but filled-in extra * fields still gets emitted (with {{mane?}} standing in for the gloss) * instead of being silently dropped. */ function senseHasExtraContent(s) { if (s.etiket && $.grep(s.etiket, function (e) { return $.trim(e) !== ""; }).length) return true; if (s.alternativ.length || s.hevmane.length || s.dijmane.length || s.koordine.length || s.jornav.length || s.jernav.length) return true; if (s.nimune && $.grep(s.nimune, function (n) { return (typeof n === "object" ? n.text : n) !== ""; }).length > 0) return true; if (s.jeder && $.grep(s.jeder, function (j) { return j && j.quote; }).length > 0) return true; return false; } /** * formatNimune: each nimûne item can be { text, tr, t }: * text — example text * tr — transliteration (only when the language needs it) * t — Kurdish translation (third positional param, no key) */ function formatNimune(nimunes, lang, hasJeder) { var hasNimune = nimunes && $.grep(nimunes, function (n) { return (typeof n === "object" ? n.text : n) !== ""; }).length > 0; if (!hasNimune) { return hasJeder ? "" : "\n#* {{bênimûne|" + lang + "}}"; } return $.map(nimunes, function (n) { var text = typeof n === "object" ? n.text : n; if (!text) return undefined; var bolded = text.replace( new RegExp("(" + pageNameRe + "([^( |,|;|\\?|\\.|\\!)]+)?)", "ig"), "'''$1'''"); var tpl = "\n#: {{nm|" + lang + "|" + bolded; if (typeof n === "object") { if (n.tr) tpl += "|tr=" + n.tr; // Translation as third positional param (no key needed). if (n.t) tpl += "|" + n.t; } // Short examples fit on one line together with their translation. // rêz=1 is not used for ku — definitions are shown on separate lines there. if (text.length < 200 && lang !== "ku") tpl += "|rêz=1"; tpl += "}}"; return tpl; }).join(""); } /** * Formats a list of jêder (quote/citation) objects into wikitext lines. * Each entry that has no quote text is skipped. Returns "" when the list * is empty or every entry is blank. * * #* {{jêder-…|lang|jêgirtin=…|tr=…|tercime=…|…fields…}} * * When no template is chosen, the generic {{jêder|…}} template is used * instead. Its 2nd positional param is the user's freeform "bi destê xwe * binivîsim" source text when supplied, or the çavkanî? placeholder otherwise. * If that text contains "=" it is passed as |2=… instead of a bare * positional param, since MediaWiki would otherwise misparse it as its * own key=value pair and break the template: * #* {{jêder|lang|jêgirtin=…|tr=…|tercime=…|<manual source or çavkanî?>}} */ function formatJeder(jederList, lang) { if (!jederList || !jederList.length) return ""; return $.map(jederList, function (jeder) { if (!jeder || !jeder.quote) return undefined; if (jeder.jederTpl) { var cite = "\n#* {{" + jeder.jederTpl + "|" + lang; cite += "|jêgirtin=" + jeder.quote; if (jeder.quoteTr) cite += "|tr=" + jeder.quoteTr; if (jeder.quoteT) cite += "|tercime=" + jeder.quoteT; $.each(jeder.jêderFields || {}, function (key, val) { if (val) cite += "|" + key + "=" + val; }); cite += "}}"; return cite; } var out = "\n#* {{jêder|" + lang + "|jêgirtin=" + jeder.quote; if (jeder.quoteTr) out += "|tr=" + jeder.quoteTr; if (jeder.quoteT) out += "|tercime=" + jeder.quoteT; var srcParam = jeder.jederManual ? jeder.jederManual : "çavkanî?"; // A positional param containing "=" gets parsed as its own key=value // pair by MediaWiki and breaks the template, so force it to be // explicitly named (|2=) whenever that's the case. out += (srcParam.indexOf("=") !== -1 ? "|2=" : "|") + srcParam; out += "}}"; return out; }).join(""); } function makeWordListStep(id, name, question_fmt, header, templateName) { return { id: id, name: name, question_fmt: question_fmt, multiple: true, narrow: true, visible: function (values) { return values.lang && values.pos; }, output: function (values) { var words = $.grep(values[id] || [], function (w) { return !!w; }); if (!words.length) return ""; var lang = values.lang; var section = "\n==== " + header + " ====\n"; if (words.length === 1) { // Single word — keep the simple inline template. return section + "* {{" + templateName + "|" + lang + "|" + words[0] + "}}\n"; } // Multiple words — use {{kol3}} with one positional param per word. var params = "cure=" + header + "\n" + $.map(words, function (w) { return "|" + w; }).join("\n"); return section + "{{kol3|" + lang + "|" + params + "\n}}\n"; } }; } var steps = { lang: { id: "lang", required: true, name: "ziman", question_fmt: '"' + pageName + '" bi çi zimanî ye?', question_br: true, // Populated from [[MediaWiki:Gadget-start.js/data.json]] (langChoices). choices: [], output: function (values) { return "== {{ziman|" + values.lang + "}} ==\n"; } }, pron: { id: "pron", name: "bilêvkirin", question_fmt: '"' + pageName + '" çawa tê telafûzkirin?', // pronTpls populated from data.json pronTpls: [], visible: function (values) { if (!values.lang) return false; // In addLangMode, only skip pron when this langcode's section // already exists in the page — if it's a new language, show it. if (addLangMode) { var existing = $("#wpTextbox1").val() || ""; var header = "== {{ziman|" + values.lang + "}} =="; return existing.indexOf(header) === -1; } return true; }, /** Fills (or refills) the insert-dropdown from the current pronTpls array, filtering by language. */ refreshTplSelect: function () { var sel = $("#wiktku-start-pron .wiktku-tpl-insert-select"); if (!sel.length) return; var lang = getValues().lang || ""; sel.find("option[value!='']").remove(); $.each(steps.pron.pronTpls, function (_, tpl) { // Filter: if tpl.langs exists, only show if lang is in that list; otherwise show always var allowed = !tpl.langs || tpl.langs.indexOf(lang) !== -1; if (allowed) { sel.append($("<option></option>") .val(tpl.snippet) .text(tpl.name + " — " + tpl.desc) .attr("data-nolang", tpl.noLang ? "1" : "")); } }); // Notify Chosen that the option list has changed (no-op on mobile). if (!isMobile) sel.trigger("chosen:updated"); }, build: function (stepDiv) { if (stepDiv.find(".wiktku-pron-wrap").length) return null; var wrap = $("<div class='wiktku-pron-wrap'></div>"); var ta = $("<textarea></textarea>") .attr("name", "wiktku-pron-" + $.now()) .attr("class", "wiktku-start-step-field wiktku-pron-text") .attr("rows", 4) .attr("placeholder", "Nimûne: {{IPA|ku|/pɛɪ̯n/}} yan {{kîte|ku|he|ce|ki|rin}}"); // Template insert dropdown — filtered by language. var sel = $("<select class='wiktku-tpl-insert-select'></select>"); sel.append($("<option value=''>— şablonek lê zêde bike —</option>")); var lang = getValues().lang || ""; $.each(steps.pron.pronTpls, function (_, tpl) { // Filter: if tpl.langs exists, only show if lang is in that list; otherwise show always var allowed = !tpl.langs || tpl.langs.indexOf(lang) !== -1; if (allowed) { sel.append($("<option></option>") .val(tpl.snippet) .text(tpl.name + " — " + tpl.desc) .attr("data-nolang", tpl.noLang ? "1" : "")); } }); sel.on("change", function () { var snippet = $(this).val(); if (!snippet) return; var lang = getValues().lang || ""; // Check if the selected option has noLang flag var selectedOption = sel.find("option:selected"); var hasNoLang = selectedOption.attr("data-nolang") === "1"; if (!hasNoLang) { snippet = snippet.replace(/CODE/g, lang).replace(/SOURCELANG/g, "?"); } insertAtCursor(ta[0], snippet); $(this).val(""); ta.focus(); }); wrap.append(sel).append($("<br>")).append(ta); stepDiv.append(wrap); return ta; }, output: function () { var text = $.trim($("#wiktku-start-pron .wiktku-pron-text").val()); if (!text) return ""; var lines = text.split("\n"); var out = $.map(lines, function (line) { line = $.trim(line); if (!line) return undefined; return line.charAt(0) === "*" ? line : "* " + line; }).join("\n"); return "\n=== Bilêvkirin ===\n" + out + "\n"; } }, pos: { id: "pos", required: true, name: "Cureyê rêzimanî", question_fmt: 'Cureyê rêzimanî yê "' + pageName + '" çi ye?', visible: function (values) { return values.lang; }, question_br: true, // Populated from [[MediaWiki:Gadget-start.js/data.json]] (posChoices). choices: [], output: function (values) { var pos = values.pos || ""; var cinsiyet = values.cinsiyet || ""; // from the cinsiyet step var lekTur = values.lektur || ""; // from the lêker transitivity step var capitalizedPos = capitalize(pos); var outputString = "\n=== " + capitalizedPos + " ===\n"; // Add ku-tewîn-nav for single-word navdêr/serenav with known gender. if (!pageName.includes(" ") && cinsiyet && GENDER_BASE_LABELS[cinsiyet] && (pos === "navdêr" || pos === "serenav") && values.lang === "ku") { outputString += "{{ku-tewîn-nav|" + pageName + "|" + GENDER_BASE_LABELS[cinsiyet]; if (pos === "serenav") outputString += "|y"; outputString += "}}\n"; } outputString += "{{" + pos + "|" + values.lang; if (pos === "navdêr" || pos === "serenav") { if (cinsiyet) { outputString += "|c=" + cinsiyet; } else if (values.lang === "ku") { // Unknown gender — prompt editor to fill it in. outputString += "|c=?"; } } else if (/^lêker/.test(pos) && lekTur) { outputString += "|c=" + lekTur; } if (values.tr) { outputString += "|tr=" + values.tr; } outputString += "}}\n"; return outputString; } }, /** * cinsiyet (grammatical gender) — only shown for navdêr/serenav, û * tenê ger metadata ji bo zimanê hilbijartî lîsteyeke "g" (cinsiyet) * were dayîn. Opsiyonên vê gavê ne sabît in — ji metadata[values.lang].g * têne çêkirin, ji ber ku di hemû zimanan de cinsiyet tine. */ cinsiyet: { id: "cinsiyet", name: "cinsiyet", question_fmt: 'Cinsiyeta "' + pageName + '" çi ye?', question_br: true, visible: function (values) { var meta = metadata[values.lang]; return !!(values.lang && (values.pos === "navdêr" || values.pos === "serenav") && meta && meta.g && meta.g.length); }, build: function (stepDiv, values) { var select = stepDiv.find("select.wiktku-start-step-field"); if (!select.length) { select = $(mw.html.element("select", { "class": "wiktku-start-step-field", id: "wiktku-start-cinsiyet-field" })); stepDiv.append(select); } if (!values) return select; var meta = metadata[values.lang]; var codes = (meta && meta.g) || []; var prevVal = select.val(); var choices = $.map(codes, function (code) { return [[code, genderLabel(code)]]; }); populateMenus(select, choices); if ($.grep(choices, function (c) { return c[0] === prevVal; }).length) { select.val(prevVal); } if (!isMobile) select.trigger("chosen:updated"); return select; }, output: function () { return ""; } // consumed by pos.output }, /** * Lêker transitivity — only shown for any lêker variant. */ lektur: { id: "lektur", name: "Cureyê lêkerê (fiîlê)", question_fmt: "Cureyê lêkerê (fiîlê) çi ye?", question_br: true, visible: function (values) { return values.lang && values.pos && /^lêker/.test(values.pos); }, // Dictionary: value → display label. Add new types here. choices: [ ["gh", "gerguhêz"], ['x-gh', 'xwerû-gerguhêz'], ['p-gh', 'pêkhatî-gerguhêz'], ['h-gh', 'hevedudanî-gerguhêz'], ['b-gh', 'biwêjî-gerguhêz'], ["ngh", "negerguhêz"], ['x-ngh', 'xwerû-negerguhêz'], ['p-ngh', 'pêkhatî-negerguhêz'], ['h-ngh', 'hevedudanî-negerguhêz'], ['b-ngh', 'biwêjî-negerguhêz'] ], output: function () { return ""; } // consumed by pos.output }, tr: { id: "tr", name: "transkrîpsiyon", question_fmt: "Transkrîpsiyona kelîmeyê", multiple: false, narrow: true, visible: function (values) { return values.lang && values.pos && needsTransliteration(values.lang); } }, dfn: { id: "dfn", // required: true, ger mane tinebe [[Şablon:mane?]] bi kar bîne name: "Mane", question_fmt: "Maneya kelîmeyê binivîse. Mane otomatîk tê lînkkirin! Ji bo tercimeyan beşa 'Werger' bi kar bîne!", multiple: true, ordered: true, rows: 3, visible: function (values) { return values.lang && values.pos; }, example: function (values) { // posExamples loaded from [[MediaWiki:Gadget-start.js/data.json]]. var examples = steps.dfn.posExamples || {}; var full = values.pos || ""; return examples[full] || ""; }, /** * Builds one sense block (<li>) inside the ordered list. * Each block contains: * - a textarea for the definition * - an expandable nimûne list * - single-row sub-lists for formên alternatîv, hevmane, dijmane */ buildSenseBlock: function (stepDiv) { var block = $("<li class='wiktku-dfn-sense'></li>"); // — Mane textarea (declared first so the template handler can reference it) — var dfnArea = $("<textarea></textarea>") .attr("name", "wiktku-dfn-mane-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("class", "wiktku-start-step-field wiktku-dfn-mane") .attr("rows", 6) .attr("placeholder", "Mane…"); dfnArea.on("input", function () { steps.dfn.onDfnInput(stepDiv, block, this); }); // — Template selector (optional — replaces mane when chosen) — // Template definitions loaded from [[MediaWiki:Gadget-start.js/data.json]]. var tplDefs = steps.dfn.tplDefs || []; // Cache of all non-placeholder option elements — used by updateTplOptions // to remove/re-add options (the only approach compatible with Chosen.js). var _allTplOptions = []; var tplSelect = $(mw.html.element("select", { "class": "wiktku-dfn-tpl-select" })); tplSelect.append($("<option value=''>— yan jî şablonek hilbijêre —</option>")); $.each(tplDefs, function (_, tpl) { var opt = $("<option></option>") .val(tpl.name) .text(tpl.name) .attr("data-langs", tpl.langs ? tpl.langs.join(",") : "") .attr("data-nolang", tpl.noLang ? "1" : ""); tplSelect.append(opt); _allTplOptions.push(opt[0]); }); function updateTplOptions() { var lang = getValues().lang || ""; var currentVal = tplSelect.val(); var currentStillValid = false; // Detach all non-placeholder options, then re-attach only the visible ones. // This is the only approach that works correctly with both native <select> // and Chosen.js on desktop. tplSelect.find("option[value!='']").detach(); $.each(_allTplOptions, function (_, opt) { var allowed = $(opt).attr("data-langs"); var visible = !allowed || allowed.split(",").indexOf(lang) !== -1; if (visible) { tplSelect.append(opt); if ($(opt).val() === currentVal) currentStillValid = true; } }); if (!isMobile) tplSelect.trigger("chosen:updated"); if (currentVal && !currentStillValid) { tplSelect.val(""); dfnArea.show(); tplTitleInput.hide().val(""); } } // Store updater on the element so refresh() can call it for all blocks. tplSelect.data("updateOptions", updateTplOptions); var tplTitleInput = $("<input type='text'>") .addClass("wiktku-dfn-tpl-title wiktku-start-narrow") .attr("placeholder", "Navê rûpelê…") .hide(); // Grow the sense list when the title field of the last block gets content, // mirroring what onDfnInput does for the plain mane textarea. tplTitleInput.on("input", function () { steps.dfn.onDfnInput(stepDiv, block, this); }); /** * When a şablon sense is chosen, formên alternatîv/hevmane/dijmane/ * termên koordîne/jornav/jêrnav don't apply (there's no plain gloss * to hang them off), so hide those subgroups. Etîket, Nimûne and * Jêgirtin stay visible and still usable for a şablon sense. */ function updateFieldVisibility() { var isTpl = !!tplSelect.val(); $.each(HIDDEN_ON_TPL_GROUPS, function (_, cls) { block.find("." + cls + "-group").toggle(!isTpl); }); } // Store on the block so restoreDfn() can re-sync visibility // after programmatically setting tplSelect's value. block.data("updateFieldVisibility", updateFieldVisibility); tplSelect.on("change", function () { var chosen = $(this).val(); if (chosen) { dfnArea.hide(); tplTitleInput.show().focus(); } else { dfnArea.show(); tplTitleInput.hide().val(""); } updateFieldVisibility(); // Re-run refresh so the Werger step visibility updates. refresh(); }); var tplRow = $("<div></div>").addClass("wiktku-dfn-tpl-row") .append(tplSelect).append(" ").append(tplTitleInput); block.append(tplRow); block.append(dfnArea); // Apply lang filter on initial build. updateTplOptions(); // — Sub-field groups — // All groups are always visible with a placeholder textarea. // Nimûne is last in the DOM and last in the output. var allGroups = [ { cls: "wiktku-dfn-etiket", label: "Etîket", rows: 1, narrow: true, izah: "xisûsen, Mêrdîn, anatomî, Badînî" }, { cls: "wiktku-dfn-alternativ", label: "Formên alternatîv", rows: 1, narrow: true, izah: "Varyantên vê kelîmeyê" }, { cls: "wiktku-dfn-hevmane", label: "Hevmane", rows: 1, narrow: true, izah: "Spehî hevmaneya Bedew e." }, { cls: "wiktku-dfn-dijmane", label: "Dijmane", rows: 1, narrow: true, izah: "Zengîn dijmaneya feqîr e." }, { cls: "wiktku-dfn-koordine", label: "Termên koordîne", rows: 1, narrow: true, izah: "Pisîk û kûçik termên koordîne ne çunkî Jornavên wan gelek in" }, { cls: "wiktku-dfn-jornav", label: "Jornav", rows: 1, narrow: true, izah: "Heywan jornavê guhandar e" }, { cls: "wiktku-dfn-jernav", label: "Jêrnav", rows: 1, narrow: true, izah: "Guhandar jêrnavê heywan e" }, { cls: "wiktku-dfn-nimune", label: "Nimûne", rows: 2, narrow: false } ]; $.each(allGroups, function (_, g) { var groupDiv = $("<div></div>").addClass("wiktku-dfn-subgroup " + g.cls + "-group"); function buildNimuneLi() { var lang = getValues().lang || ""; var li = $("<li></li>").addClass("wiktku-dfn-nimune-li"); var mainTa = $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-text-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", g.rows) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-text") .attr("placeholder", "Nimûneya emilandina kelîmeyê tu bi xwe binivîse…"); mainTa.on("input", function () { var val = $.trim($(this).val()); var isLast = li.is(list.children("li:last-child")); if (val && isLast) { list.append(buildNimuneLi()); } }); li.append(mainTa); var subWrap = $("<div></div>").addClass("wiktku-dfn-nimune-sub"); if (needsTransliteration(lang)) { subWrap.append( $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-tr-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 5) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-tr") .attr("placeholder", "Transkrîpsiyona bi alfabeya latînî") ); } if (lang && lang !== "ku") { subWrap.append( $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-t-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 5) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-t") .attr("placeholder", "Tercimeya kurmancî") ); } if (subWrap.children().length) li.append(subWrap); return li; } if (g.cls === "wiktku-dfn-nimune") { // Nimûne — compound widget with tr/t sub-fields. var lbl = $("<span></span>").addClass("wiktku-dfn-sublabel").text(g.label + ": "); var list = $("<ol></ol>").addClass("wiktku-dfn-sublist " + g.cls + "-list"); groupDiv.data("buildNimuneLi", buildNimuneLi); list.append(buildNimuneLi()); groupDiv.append(lbl).append(list); block.append(groupDiv); } else { // Regular always-visible group — label + growing textarea list. var lbl = $("<span></span>").addClass("wiktku-dfn-sublabel").text(g.label + ": " + g.izah); var list = $("<ol></ol>").addClass("wiktku-dfn-sublist " + g.cls + "-list"); var firstInput = $("<textarea></textarea>") .attr("name", g.cls + "-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", g.rows) .attr("class", "wiktku-dfn-subfield" + (g.narrow ? " wiktku-start-narrow" : "")) .attr("placeholder", g.label + "…"); firstInput.on("input", function () { steps.dfn.onSubInput(list, this, g.rows, g.narrow); }); list.append($("<li></li>").append(firstInput)); groupDiv.append(lbl).append(list); block.append(groupDiv); } }); // — Jêder (quote / citation) group — a growing list, sibling to Nimûne — // Structured the same way as Nimûne (ol.wiktku-dfn-sublist > li) so it // lines up at the same indentation, and so that typing into the last // citation's Jêgirtin box automatically opens a fresh empty one below it. (function () { var jederGroupDiv = $("<div></div>").addClass("wiktku-dfn-subgroup wiktku-dfn-jeder-group"); var jederLbl = $("<span></span>").addClass("wiktku-dfn-sublabel").text("Jêgirtin: "); var jederList = $("<ol></ol>").addClass("wiktku-dfn-sublist wiktku-dfn-jeder-list"); function buildJederLi() { var lang = getValues().lang || ""; var li = $("<li></li>").addClass("wiktku-dfn-jeder-li"); var dragHandle = $("<span></span>") .addClass("wiktku-jeder-drag-handle") .attr("title", "Bişkûne û bikişîne da ku rêzê biguhezîne"); // Quote text textarea var quoteTa = $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-quote-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 2) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-quote") .attr("placeholder", "Nimûneya emilandinê ji kitêb an çavkaniyeke din binivîse"); quoteTa.on("input", function () { var val = $.trim($(this).val()); var isLast = li.is(jederList.children("li:last-child")); if (val && isLast) { jederList.append(buildJederLi()); } }); li.append(dragHandle).append(quoteTa); // tr/t sub-fields for the quote — shown as needed for the language. var quoteSubWrap = $("<div></div>").addClass("wiktku-dfn-quote-sub"); if (needsTransliteration(lang)) { quoteSubWrap.append( $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-quote-tr-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 2) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-quote-tr") .attr("placeholder", "Transkrîpsiyona jêgirtinê…") ); } if (lang && lang !== "ku") { quoteSubWrap.append( $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-quote-t-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 2) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-quote-t") .attr("placeholder", "Tercimeya jêgirtinê bi kurmancî") ); } if (quoteSubWrap.children().length) li.append(quoteSubWrap); // Citoid auto-fill: fetch citation data from a URL, DOI or ISBN and // prefill the source şablon + fields below (see Gadget-citoid-helper.js). var citoidWrap = $("<div></div>").addClass("wiktku-dfn-quote-citoid"); var citoidInput = $("<input type='text'>") .addClass("wiktku-dfn-quote-citoid-input wiktku-start-narrow") .attr("placeholder", "URL, DOI an ISBN binivîse ku otomatîk were tijekirin…"); var citoidBtn = new OO.ui.ButtonWidget({ label: "Bi Citoid bîne", classes: [ "wiktku-dfn-quote-citoid-btn" ] }); var citoidStatus = $("<span></span>").addClass("wiktku-dfn-quote-citoid-status"); /** * Fetches citation data from Citoid and applies it to this * citation's şablon selector + fields. Mirrors the logic in * Form.prototype._fillFromCitoid (Gadget-wikt.add-examples.js): * - only (re)selects the şablon when it actually differs from * what's already chosen, so a repeat fetch doesn't wipe out * a template the user already picked; * - only fills fields that are currently empty, so it never * overwrites something the user typed by hand; * - falls back to the freeform "bi destê xwe binivîsim" source * only when nothing was typed there yet. */ function runCitoidFetch() { var query = $.trim(citoidInput.val()); if (!query) { mw.notify("Ji kerema xwe re pêşî URL, DOI an ISBNyekê binivîse."); return; } citoidBtn.setDisabled(true); citoidStatus.text("Tê anîn…"); wikt.citoidHelper.ensure().then(function () { return wikt.citoid.fetchJederFields(query); }).then(function (result) { var jederKey = result.jederKey; var hasTpl = !!jederKey && srcSel.find("option[value='" + jederKey + "']").length > 0; var targetVal = hasTpl ? jederKey : "__manual__"; // Only (re)select — and thus rebuild — the field rows if // we're switching to a different şablon than what's // already chosen, so a second fetch doesn't clear fields // the user already filled in by hand. if (srcSel.val() !== targetVal) { srcSel.val(targetVal).trigger("change"); srcSel.trigger("chosen:updated"); } if (hasTpl) { // Tenê qadên vala tijî bike. $.each(result.fields, function (key, val) { var input = srcFields.find("[data-field-key='" + key + "']"); if (input.length && !$.trim(input.val())) { input.val(val); } }); } else { // Şablonek nehat naskirin ji bo vê itemType — rêzikeke // çavkaniyê ya bi destan a ji qadên Citoid tê çêkirin, // lê tenê ger qada destan vala be. var manualField = srcFields.find(".wiktku-dfn-quote-src-manual"); if (!$.trim(manualField.val())) { var parts = []; $.each(["nivîskar", "sernav", "websîte", "kovar", "weşanxane", "sal", "url"], function (_, k) { if (result.fields[k]) parts.push(result.fields[k]); }); manualField.val(parts.join(", ")); } } citoidStatus.text(""); }, function (errorMsg) { citoidStatus.text(typeof errorMsg === "string" ? errorMsg : "Nehat dîtin. Kontrol bike ka URL/DOI/ISBN rast e."); }).always(function () { citoidBtn.setDisabled(false); }); } citoidBtn.on("click", runCitoidFetch); citoidInput.on("keydown", function (e) { if (e.which === 13) { // Enter e.preventDefault(); runCitoidFetch(); } }); citoidWrap.append(citoidInput).append(citoidBtn.$element).append(citoidStatus); // Source template selector, specific to this citation. var srcSel = $("<select></select>").addClass("wiktku-dfn-quote-src-sel"); srcSel.append($("<option value=''>— Çavkaniyê hilbijêre —</option>")); srcSel.append($("<option></option>").val("__manual__").text("Bi destê xwe binivîsim")); var jederDefs = steps.dfn.jederDefs || {}; $.each(jederDefs, function (tplName, def) { srcSel.append($("<option></option>").val(tplName).text(def.label)); }); // Dynamic source fields container. var srcFields = $("<div></div>").addClass("wiktku-dfn-quote-src-fields"); srcSel.on("change", function () { srcFields.empty(); var chosen = $(this).val(); if (!chosen) return; if (chosen === "__manual__") { // Freeform source, written by the user — becomes the 2nd // positional param of {{jêder|lang|…}} instead of çavkanî?. srcFields.append( $("<textarea></textarea>") .attr("rows", 4) .addClass("wiktku-dfn-subfield wiktku-dfn-quote-src-manual") .attr("placeholder", "Çavkaniyê bi destê xwe binivîse…") ); return; } var def = (steps.dfn.jederDefs || {})[chosen]; if (!def) return; $.each(def.fields, function (_, f) { var row = $("<div></div>").addClass("wiktku-dfn-quote-src-row"); var fieldLbl = $("<label></label>").text(f.label + ": "); var inp = $("<textarea></textarea>") .attr("rows", 2) .addClass("wiktku-dfn-quote-src-input wiktku-start-narrow") .attr("data-field-key", f.key) .attr("placeholder", f.label + "…"); row.append(fieldLbl).append(inp); srcFields.append(row); }); }); li.append(citoidWrap).append(srcSel).append(srcFields); return li; } jederGroupDiv.data("buildJederLi", buildJederLi); jederList.append(buildJederLi()); // Make citation rows sortable (drag to reorder). // The last row is always the empty trailing row — cancel its drag. mw.loader.using("jquery.ui.sortable", function () { jederList.sortable({ handle: ".wiktku-jeder-drag-handle", axis: "y", items: "li:not(:last-child)", tolerance: "pointer" }); }); jederGroupDiv.append(jederLbl).append(jederList); block.append(jederGroupDiv); }()); // Apply the initial hide/show state for the sub-groups (matches // tplSelect's starting value, which is normally empty). updateFieldVisibility(); return block; }, /** Grows the sense list when the last mane textarea gets content. */ onDfnInput: function (stepDiv, block, textarea) { var val = $.trim($(textarea).val()); var list = stepDiv.find("ol.wiktku-dfn-list"); var isLast = block.is(list.children("li:last-child")); if (val && isLast) { var newBlock = steps.dfn.buildSenseBlock(stepDiv); list.append(newBlock); // Apply Chosen to the new block's template selector on desktop. if (!isMobile) newBlock.find("select.wiktku-dfn-tpl-select").chosen(chosenOptions); } refresh(); }, /** Grows a sub-list (nimûne/formên alternatîv/hevmane/dijmane/termên koordîne) on input. */ onSubInput: function (list, input, rows, narrow) { var val = $.trim($(input).val()); var item = $(input).parent(); var isLast = item.is(list.children("li:last-child")); if (val && isLast) { var next = $("<textarea></textarea>") .attr("name", "wiktku-dfn-sub-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", rows) .attr("class", "wiktku-dfn-subfield" + (narrow ? " wiktku-start-narrow" : "")); next.on("input", function () { steps.dfn.onSubInput(list, this, rows, narrow); }); list.append($("<li></li>").append(next)); } }, // Populated from [[MediaWiki:Gadget-start.js/data.json]] (tplDefs, posExamples, jederDefs). tplDefs: [], posExamples: {}, jederDefs: {}, build: function (stepDiv) { if (stepDiv.find("ol.wiktku-dfn-list").length) return null; var list = $("<ol class='wiktku-dfn-list'></ol>"); list.append(steps.dfn.buildSenseBlock(stepDiv)); stepDiv.append(list); return null; }, /** Reads all sense blocks from the DOM and returns an array of sense objects. */ getSenses: function (stepDiv) { var senses = []; stepDiv.find("li.wiktku-dfn-sense").each(function () { var block = $(this); var tplSel = block.find("select.wiktku-dfn-tpl-select"); var tpl = tplSel.val() || ""; // noLang: template already encodes the language — don't add |lang| param. var tplNoLang = tpl ? tplSel.find("option[value='" + tpl + "']").attr("data-nolang") === "1" : false; var tplTitle = $.trim(block.find("input.wiktku-dfn-tpl-title").val()); var mane = $.trim(block.find("textarea.wiktku-dfn-mane").val()); var etiket = (function () { var vals = []; block.find(".wiktku-dfn-etiket-list textarea").each(function () { var v = $.trim($(this).val()); if (v) vals.push(v); }); return vals; }()); function readList(cls) { var vals = []; block.find("." + cls + "-list textarea").each(function () { var v = $.trim($(this).val()); if (v) vals.push(v); }); return vals; } // Nimûne items are compound: { text, tr?, t? } function readNimuneList() { var items = []; block.find(".wiktku-dfn-nimune-list li.wiktku-dfn-nimune-li").each(function () { var text = $.trim($(this).find(".wiktku-dfn-nimune-text").val()); if (!text) return; var obj = { text: text }; var tr = $.trim($(this).find(".wiktku-dfn-nimune-tr").val()); var t = $.trim($(this).find(".wiktku-dfn-nimune-t").val()); if (tr) obj.tr = tr; if (t) obj.t = t; items.push(obj); }); return items; } // Jêder is a growing list of citations, one per li — mirrors readNimuneList(). function readJederList() { var items = []; block.find(".wiktku-dfn-jeder-list li.wiktku-dfn-jeder-li").each(function () { var li = $(this); var quote = $.trim(li.find(".wiktku-dfn-nimune-quote").val()); if (!quote) return; var obj = { quote: quote }; var qtr = $.trim(li.find(".wiktku-dfn-nimune-quote-tr").val()); var qt = $.trim(li.find(".wiktku-dfn-nimune-quote-t").val()); if (qtr) obj.quoteTr = qtr; if (qt) obj.quoteT = qt; var tplName = li.find(".wiktku-dfn-quote-src-sel").val(); if (tplName === "__manual__") { var manual = $.trim(li.find(".wiktku-dfn-quote-src-manual").val()); if (manual) obj.jederManual = manual; } else if (tplName) { obj.jederTpl = tplName; var fields = {}; li.find(".wiktku-dfn-quote-src-input").each(function () { var k = $(this).attr("data-field-key"); var v = $.trim($(this).val()); if (k && v) fields[k] = v; }); obj.jêderFields = fields; } items.push(obj); }); return items; } senses.push({ tpl: tpl, tplNoLang: tplNoLang, tplTitle: tplTitle, mane: mane, etiket: etiket, nimune: readNimuneList(), jeder: readJederList(), alternativ: readList("wiktku-dfn-alternativ"), hevmane: readList("wiktku-dfn-hevmane"), dijmane: readList("wiktku-dfn-dijmane"), koordine: readList("wiktku-dfn-koordine"), jornav: readList("wiktku-dfn-jornav"), jernav: readList("wiktku-dfn-jernav") }); }); return senses; }, getOutput: function (values, callback) { var stepDiv = $("#wiktku-start-dfn"); var senses = steps.dfn.getSenses(stepDiv); var lang = values.lang; // A sense counts as "filled" if it has a mane, a chosen template + title, // or any other content (etîket/hevmane/nimûne/jêder…) worth keeping. var hasMane = senses.some(function (s) { return s.mane !== "" || (s.tpl && s.tplTitle) || senseHasExtraContent(s); }); // True only when at least one sense has a regular mane (needs linkify). var hasRegularMane = senses.some(function (s) { return !s.tpl && s.mane !== ""; }); // nimûne and jêder lines must never pass through linkify — only // the plain mane text should be linkified. We build two parallel // arrays: defLines (sent to linkify) and citeLines (kept aside). // Each entry in citeLines corresponds 1-to-1 with a defLines entry; // a template token {{wiktku-cite-N}} is embedded in defLines so // that after linkify runs we know exactly where to splice them back. // Template-call syntax is guaranteed safe: linkifiers leave {{ }} // tokens completely untouched. var defLines = []; // one entry per kept sense (goes to linkify) var citeLines = []; // parallel — nimûne+jêder for that same sense $.each(senses, function (_, sense) { // — Template sense (e.g. {{guharto|ku|somepage}}) — if (sense.tpl) { if (!sense.tplTitle) return; // skip empty template senses var tplLabelTpl = ""; if (sense.etiket && sense.etiket.length) { var tplLabelParts = sense.etiket.map(function (part) { return $.trim(part); }).filter(function (part) { return part !== ""; }); if (tplLabelParts.length) { tplLabelTpl = " {{e|" + lang + "|" + tplLabelParts.join("|") + "}} "; } } var tplCall = sense.tplNoLang ? "{{" + sense.tpl + "|" + sense.tplTitle + "}}" : "{{" + sense.tpl + "|" + lang + "|" + sense.tplTitle + "}}"; var tplHasJeder = sense.jeder && $.grep(sense.jeder, function (j) { return j && j.quote; }).length > 0; var idx = defLines.length; var cite = formatNimune(sense.nimune, lang, tplHasJeder) + formatJeder(sense.jeder, lang); defLines.push("#" + (tplLabelTpl ? tplLabelTpl : " ") + tplCall + (cite ? "{{wiktku-cite-" + idx + "}}" : "")); citeLines.push(cite); return; } // — Normal mane sense — var dfn = sense.mane; if (!dfn && !senseHasExtraContent(sense)) return; // truly empty if (dfn) { dfn = stripWikilinks(dfn); if (dfn[0] !== dfn[0].toUpperCase()) dfn = capitalize(dfn); if (!dfn.match(/[.…?!)\]]$/)) dfn += "."; } else { dfn = "{{mane?|" + lang + "}}"; } var labelTpl = ""; if (sense.etiket && sense.etiket.length) { var labelParts = sense.etiket.map(function (part) { return $.trim(part); }).filter(function (part) { return part !== ""; }); if (labelParts.length) { labelTpl = " {{e|" + lang + "|" + labelParts.join("|") + "}} "; } } var out = "#" + (labelTpl ? labelTpl : " ") + dfn; function wordLine(tpl, words) { if (!words.length) return ""; return "\n#: {{" + tpl + "|" + lang + "|" + words.join("|") + "}}"; } out += wordLine("alt-r", sense.alternativ); out += wordLine("hevmane", sense.hevmane); out += wordLine("dijmane", sense.dijmane); out += wordLine("koordîne", sense.koordine); out += wordLine("jornav", sense.jornav); out += wordLine("jêrnav", sense.jernav); var hasJeder = sense.jeder && $.grep(sense.jeder, function (j) { return j && j.quote; }).length > 0; var cite = formatNimune(sense.nimune, lang, hasJeder) + formatJeder(sense.jeder, lang); var idx = defLines.length; defLines.push(out + (cite ? "{{wiktku-cite-" + idx + "}}" : "")); citeLines.push(cite); }); // Splice citeLines back into a linkified string, replacing each // {{wiktku-cite-N}} token with its stored nimûne/jêder block. function restoreCites(t) { return t.replace(/\{\{wiktku-cite-(\d+)\}\}/g, function (_, n) { return citeLines[parseInt(n, 10)] || ""; }); } var text = defLines.join("\n") + "\n"; if (!hasMane) { // No definitions entered — emit {{mane?}} with bênimûne. text = "# {{mane?|" + lang + "}}\n#* {{bênimûne|" + lang + "}}\n"; callback(text); return; } if (!hasRegularMane) { // All filled senses are template senses — no linkify needed. callback(restoreCites(text)); return; } var didTryToLoad = function () { if (typeof $.wiktviLinkify === "function") { $.wiktviLinkify(text, function (linked) { callback(restoreCites(linked)); }); } else { callback(restoreCites(text)); } }; mw.loader.using("ext.gadget.linkify", didTryToLoad, didTryToLoad); } }, je: makeWordListStep("je", "jê", "Kelîmeyên jê çêbûyî binivîse", "Jê", "g"), tekildar: makeWordListStep("tekildar", "têkildar", "Kelîmeyên ji aliyê etîmolojiyê ve têkildarî vê kelîmeyê binivîse", "Têkildar", "g"), binereherwiha: makeWordListStep("binereherwiha", "binêre herwiha", "Kelîmeyên din ên eleqedar binivîse", "Binêre herwiha", "g"), etym: { id: "etym", name: "etîmolojî", question_fmt: "Etîmolojiya kelîmeyê binivîse", // etymTpls populated from data.json etymTpls: [], visible: function (values) { return values.lang && values.pos; }, /** Fills (or refills) the insert-dropdown from the current etymTpls array. */ refreshTplSelect: function () { var sel = $("#wiktku-start-etym .wiktku-tpl-insert-select"); if (!sel.length) return; sel.find("option[value!='']").remove(); $.each(steps.etym.etymTpls, function (_, tpl) { sel.append($("<option></option>").val(tpl.snippet).text(tpl.name + " — " + tpl.desc)); }); // Notify Chosen that the option list has changed (no-op on mobile). if (!isMobile) sel.trigger("chosen:updated"); }, build: function (stepDiv) { if (stepDiv.find(".wiktku-etym-wrap").length) return null; var wrap = $("<div class='wiktku-etym-wrap'></div>"); var ta = $("<textarea></textarea>") .attr("name", "wiktku-etym-" + $.now()) .attr("class", "wiktku-start-step-field wiktku-etym-text") .attr("rows", 4) .attr("placeholder", "Nimûne: Ji {{ji|en|ku|apple}}. yan rasterast binivîse…"); // Template insert dropdown — options also refreshed after data.json loads. var sel = $("<select class='wiktku-tpl-insert-select'></select>"); sel.append($("<option value=''>— şablonek lê zêde bike —</option>")); $.each(steps.etym.etymTpls, function (_, tpl) { sel.append($("<option></option>").val(tpl.snippet).text(tpl.name + " — " + tpl.desc)); }); sel.on("change", function () { var snippet = $(this).val(); if (!snippet) return; var lang = getValues().lang || ""; snippet = snippet.replace(/CODE/g, lang).replace(/SOURCELANG/g, "?"); insertAtCursor(ta[0], snippet); $(this).val(""); ta.focus(); }); wrap.append(sel).append($("<br>")).append(ta); stepDiv.append(wrap); return ta; }, output: function (values) { var text = $.trim($("#wiktku-start-etym .wiktku-etym-text").val()); if (text) { return "\n==== Etîmolojî ====\n" + text + "\n"; } // No etymology entered — emit {{ji?|lang}} as a placeholder, // but only when the entry has at least one regular (non-şablon) // sense with content — either real mane text, or an empty mane // with other fields filled in (which dfn.getOutput() renders as // {{mane?|lang}} with those fields attached). A şablon sense // like {{guharto|…}} never counts, filled in or not. var dfnSenses = steps.dfn.getSenses($("#wiktku-start-dfn")); var hasRegularMane = dfnSenses.some(function (s) { return !s.tpl && (s.mane !== "" || senseHasExtraContent(s)); }); if (!hasRegularMane) return ""; return "\n==== Etîmolojî ====\n{{ji?|" + values.lang + "}}\n"; } }, dunde: { id: "dunde", name: "dûnde", question_fmt: "Eger ev kelîme ji vî zimanî ketibe zimanekî din, vî zimanî û kelîmeya wî binivîse", visible: function (values) { return !!values.pos; }, disabledKeys: { "navz": true}, /** * Builds one row: a language dropdown + a growing list of word * inputs. When the dropdown gets a value the next empty row is * appended automatically. Mirrors steps.trans's row widget, but * flat (one shared list — dûnde isn't tied to individual senses). */ buildRow: function (stepDiv) { var row = $("<li class='wiktku-dunde-row wiktku-lang-row'></li>"); // Language selector — chosen is applied after insertion into DOM. var langSel = $(mw.html.element("select", { "class": "wiktku-start-step-keyfield wiktku-start-narrow" })); langSel.attr("data-placeholder", "Zimanekî lê bigere"); populateMenus(langSel, steps.dunde.keys || [], steps.dunde.disabledKeys); // When a language is chosen, ensure a next empty row exists. langSel.on("change", function () { steps.dunde.onLangChange(stepDiv, row); }); // Word list for this language. var wordList = $("<ul class='wiktku-dunde-words wiktku-lang-row-words'></ul>"); var firstWord = steps.dunde.makeWordInput(); wordList.append($("<li></li>").append(firstWord)); if (isMobile) { row.append(wrapNativeSelect(langSel)).append(wordList); } else { row.append(langSel).append(wordList); } return row; }, makeWordInput: function () { var input = $("<textarea></textarea>") .attr("name", "wiktku-dunde-word-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 1) .attr("class", "wiktku-dfn-subfield wiktku-start-narrow") .attr("placeholder", "Kelîme…"); input.on("input", function () { var list = $(this).closest("ul.wiktku-dunde-words"); var item = $(this).parent(); var val = $.trim($(this).val()); if (val && item.is(list.children("li:last-child"))) { var next = steps.dunde.makeWordInput(); list.append($("<li></li>").append(next)); } }); return input; }, onLangChange: function (stepDiv, row) { var list = stepDiv.find("ul.wiktku-dunde-list"); var isLast = row.is(list.children("li.wiktku-dunde-row:last-child")); if (isLast) { var newRow = steps.dunde.buildRow(stepDiv); list.append(newRow); // Init chosen after the new row is in the DOM (desktop only). if (!isMobile) newRow.find("select").chosen(chosenOptions); } // Keep disabled keys in sync across all lang selectors. steps.dunde.syncDisabledKeys(stepDiv); }, /** Disables already-selected languages in all other dropdowns. */ syncDisabledKeys: function (stepDiv) { var taken = $.extend({}, steps.dunde.disabledKeys); stepDiv.find("li.wiktku-dunde-row select").each(function () { var v = $(this).val(); if (v) taken[v] = true; }); stepDiv.find("li.wiktku-dunde-row select").each(function () { var self = $(this); var own = self.val(); self.find("option").each(function () { var code = $(this).val(); if (!code) return; $(this).prop("disabled", taken[code] && code !== own); }); self.trigger("chosen:updated"); }); }, build: function (stepDiv) { if (stepDiv.find("ul.wiktku-dunde-list").length) return null; var list = $("<ul class='wiktku-dunde-list wiktku-lang-row-list'></ul>"); list.append(steps.dunde.buildRow(stepDiv)); stepDiv.append(list); // Init chosen after the select is in the DOM (desktop only). if (!isMobile) list.find("select").chosen(chosenOptions); return null; }, /** Reads all [langcode, words[]] rows from the DOM. */ getRows: function (stepDiv) { var result = []; stepDiv.find("li.wiktku-dunde-row").each(function () { var lang = $(this).find("select").val(); if (!lang) return; var words = []; $(this).find("ul.wiktku-dunde-words textarea").each(function () { var v = $.trim($(this).val()); if (v) words.push(v); }); if (words.length) result.push([lang, words]); }); return result; }, output: function () { var stepDiv = $("#wiktku-start-dunde"); var rows = steps.dunde.getRows(stepDiv); if (!rows.length) return ""; var lines = $.map(rows, function (row) { var lang = row[0], words = row[1]; return "* {{dû|" + lang + "|" + words.join("|") + "}}"; }); return "\n==== Dûnde ====\n" + lines.join("\n") + "\n"; } }, zarava: { id: "zarava", name: "bi zaravayên din", visible: function (values) { return steps.trans.visible(values); }, disabledKeys: { "navz": true }, buildRow: function (group) { var row = $("<li class='wiktku-zarava-row wiktku-lang-row'></li>"); var langSel = $(mw.html.element("select", { "class": "wiktku-start-step-keyfield wiktku-start-narrow" })); populateMenus(langSel, steps.zarava.keys || [], steps.zarava.disabledKeys); langSel.on("change", function () { steps.zarava.onLangChange(group, row); }); var wordList = $("<ul class='wiktku-zarava-words wiktku-lang-row-words'></ul>"); var firstWord = steps.zarava.makeWordInput(); wordList.append($("<li></li>").append(firstWord)); row.append(langSel).append(wordList); return row; }, makeWordInput: function () { var input = $("<textarea></textarea>") .attr("name", "wiktku-zarava-word-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 1) .attr("class", "wiktku-dfn-subfield wiktku-start-narrow") .attr("placeholder", "Tercime…"); input.on("input", function () { var list = $(this).closest("ul.wiktku-zarava-words"); var item = $(this).parent(); var val = $.trim($(this).val()); if (val && item.is(list.children("li:last-child"))) { var next = steps.zarava.makeWordInput(); list.append($("<li></li>").append(next)); } }); return input; }, onLangChange: function (group, row) { var list = group.find("ul.wiktku-zarava-list"); var isLast = row.is(list.children("li.wiktku-zarava-row:last-child")); if (isLast) { var newRow = steps.zarava.buildRow(group); list.append(newRow); } steps.zarava.syncDisabledKeys(group); }, /** Disables already-selected dialects in all other dropdowns within one group. */ syncDisabledKeys: function (group) { var taken = $.extend({}, steps.zarava.disabledKeys); group.find("li.wiktku-zarava-row select").each(function () { var v = $(this).val(); if (v) taken[v] = true; }); group.find("li.wiktku-zarava-row select").each(function () { var self = $(this); var own = self.val(); self.find("option").each(function () { var code = $(this).val(); if (!code) return; $(this).prop("disabled", taken[code] && code !== own); }); }); }, /** Builds (or fetches) the .wiktku-zarava-group for one gloss. */ buildGroup: function (stepDiv, gi) { var group = $("<div class='wiktku-zarava-group'></div>").attr("data-gloss-pos", gi); var list = $("<ul class='wiktku-zarava-list wiktku-lang-row-list'></ul>"); list.append(steps.zarava.buildRow(group)); group.append(list); stepDiv.append(group); return group; }, /** Syncs one .wiktku-zarava-group per current gloss (same logic as steps.trans.build). */ build: function (stepDiv) { var glosses = steps.trans.glossList(); if (!glosses.length) { stepDiv.find(".wiktku-zarava-group").remove(); return null; } var existingGroups = stepDiv.find(".wiktku-zarava-group"); if (existingGroups.length > glosses.length) { existingGroups.slice(glosses.length).remove(); } $.each(glosses, function (gi, gloss) { var group = stepDiv.find(".wiktku-zarava-group[data-gloss-pos='" + gi + "']"); if (!group.length) group = steps.zarava.buildGroup(stepDiv, gi); var label = group.find(".wiktku-zarava-group-label"); if (glosses.length > 1) { if (!label.length) { label = $("<div class='wiktku-zarava-group-label'></div>"); group.prepend(label); } label.text(gloss.index + " " + gloss.text); } else if (label.length) { label.remove(); } }); return null; }, /** Reads the dialect rows for a single gloss group. */ getGroupTranslations: function (group) { var result = []; group.find("li.wiktku-zarava-row").each(function () { var lang = $(this).find("select").val(); if (!lang) return; var words = []; $(this).find("ul.wiktku-zarava-words textarea").each(function () { var v = $.trim($(this).val()); if (v) words.push(v); }); if (words.length) result.push([lang, words]); }); return result; }, /** Reads all rows from the DOM, grouped by gloss position. */ getTranslations: function (stepDiv) { var result = []; stepDiv.find(".wiktku-zarava-group").each(function () { result.push(steps.zarava.getGroupTranslations($(this))); }); return result; }, output: function (values) { if (values.lang !== "ku") return ""; var stepDiv = $("#wiktku-start-zarava"); var glosses = steps.trans.glossList(); if (!glosses.length) return ""; var blocks = $.map(glosses, function (gloss, gi) { var group = stepDiv.find(".wiktku-zarava-group[data-gloss-pos='" + gi + "']"); var rows = group.length ? steps.zarava.getGroupTranslations(group) : []; if (!gloss.text && !rows.length) return undefined; if (rows.length) { rows.sort(function (a, b) { var aLang = langsByCode[a[0]] || []; var bLang = langsByCode[b[0]] || []; return (aLang[2] || "").localeCompare(bLang[2] || "", "ku"); }); } var wordLines = $.map(rows, function (row) { var lang = row[0]; var words = row[1]; var wikiWords = words.map(function (w) { return "{{W|" + lang + "|" + w + "}}"; }).join(", "); return "* {{Z|" + lang + "}}: " + wikiWords; }).join("\n"); if (!wordLines) return undefined; var block = "{{werger-ser|" + (gloss.text || "?") + "|" + gloss.index + "}}"; block += "\n" + wordLines; block += "\n{{werger-bin}}"; return block; }); if (!blocks.length) return ""; return "\n==== Bi zaravayên din ====\n" + blocks.join("\n") + "\n"; } }, trans: { id: "trans", name: "werger", visible: function (values) { if (!(values.lang === "ku" && values.pos)) return false; // Hide Werger only when EVERY sense is a template sense (Guharto etc.) // with a title filled in — i.e. there is real content but no plain // gloss to attach a translation table to. A mix of real + template // senses still shows Werger; the template senses are simply skipped // in output(). // // "Real" here means a non-şablon sense with either mane text or // other filled-in fields (etîket/hevmane/nimûne/jêder…), since // dfn.getOutput() renders the latter too, as {{mane?|lang}} plus // whatever else was filled in. // // When nothing has been filled in at all, output() will emit // {{mane?|lang}} instead of a gloss — but Werger should still show, // since the user may want to add translations before they've // settled on a gloss. var dfnSenses = steps.dfn.getSenses($("#wiktku-start-dfn")); var hasRealSense = dfnSenses.some(function (s) { return !s.tpl && (s.mane !== "" || senseHasExtraContent(s)); }); var hasFilledTplSense = dfnSenses.some(function (s) { return s.tpl && s.tplTitle; }); return hasRealSense || !hasFilledTplSense; }, disabledKeys: { "navz": true, "ku": true, "ckb": true, "sdh": true, "lki": true, "hac": true, "zza": true }, /** * Builds one translation row: a language dropdown + a growing list * of word inputs. When the dropdown gets a value the next empty row * is appended automatically. * * @param group the specific .wiktku-trans-group this row belongs to * (each gloss has its own group and its own list of rows, so the * lookups below must stay scoped to that group rather than the * whole step — the step now holds one list per gloss). */ buildRow: function (group) { var row = $("<li class='wiktku-trans-row wiktku-lang-row'></li>"); // Language selector — chosen is applied after insertion into DOM. var langSel = $(mw.html.element("select", { "class": "wiktku-start-step-keyfield wiktku-start-narrow" })); langSel.attr("data-placeholder", "Zimanekî lê bigere"); populateMenus(langSel, steps.trans.keys || [], steps.trans.disabledKeys); // When a language is chosen, ensure a next empty row exists. langSel.on("change", function () { steps.trans.onLangChange(group, row); }); // Word list for this language. var wordList = $("<ul class='wiktku-trans-words wiktku-lang-row-words'></ul>"); var firstWord = steps.trans.makeWordInput(); wordList.append($("<li></li>").append(firstWord)); if (isMobile) { row.append(wrapNativeSelect(langSel)).append(wordList); } else { row.append(langSel).append(wordList); } return row; }, makeWordInput: function () { var input = $("<textarea></textarea>") .attr("name", "wiktku-trans-word-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 1) .attr("class", "wiktku-dfn-subfield wiktku-start-narrow") .attr("placeholder", "Tercime…"); input.on("input", function () { var list = $(this).closest("ul.wiktku-trans-words"); var item = $(this).parent(); var val = $.trim($(this).val()); if (val && item.is(list.children("li:last-child"))) { var next = steps.trans.makeWordInput(); list.append($("<li></li>").append(next)); } }); return input; }, onLangChange: function (group, row) { var list = group.find("ul.wiktku-trans-list"); var isLast = row.is(list.children("li.wiktku-trans-row:last-child")); if (isLast) { var newRow = steps.trans.buildRow(group); list.append(newRow); // Init chosen after the new row is in the DOM (desktop only). if (!isMobile) newRow.find("select").chosen(chosenOptions); } // Keep disabled keys in sync across this gloss's lang selectors // only — the same language can be used for different senses. steps.trans.syncDisabledKeys(group); }, /** Disables already-selected languages in all other dropdowns within one group. */ syncDisabledKeys: function (group) { var taken = $.extend({}, steps.trans.disabledKeys); group.find("li.wiktku-trans-row select").each(function () { var v = $(this).val(); if (v) taken[v] = true; }); group.find("li.wiktku-trans-row select").each(function () { var self = $(this); var own = self.val(); self.find("option").each(function () { var code = $(this).val(); if (!code) return; $(this).prop("disabled", taken[code] && code !== own); }); self.trigger("chosen:updated"); }); }, /** * Builds (or fetches) the .wiktku-trans-group for one gloss, with * its own label and its own list of translation rows. */ buildGroup: function (stepDiv, gi) { var group = $("<div class='wiktku-trans-group'></div>").attr("data-gloss-pos", gi); var list = $("<ul class='wiktku-trans-list wiktku-lang-row-list'></ul>"); list.append(steps.trans.buildRow(group)); group.append(list); stepDiv.append(group); // Init chosen after the select is in the DOM (desktop only). if (!isMobile) list.find("select").chosen(chosenOptions); return group; }, /** * Syncs one .wiktku-trans-group per current gloss, adding new * groups and removing stale ones as senses are added or removed, * while leaving existing groups (and whatever translations the * user has already typed into them) untouched. Groups are keyed * to their gloss's position in glossList() via data-gloss-pos, so * a group always matches the same sense across rebuilds as long * as senses aren't reordered relative to each other. */ build: function (stepDiv) { var glosses = steps.trans.glossList(); if (!glosses.length) { stepDiv.find(".wiktku-trans-group").remove(); return null; } // Drop groups for glosses that no longer exist (always from the // tail — groups are only ever appended in gloss order below). var existingGroups = stepDiv.find(".wiktku-trans-group"); if (existingGroups.length > glosses.length) { existingGroups.slice(glosses.length).remove(); } $.each(glosses, function (gi, gloss) { var group = stepDiv.find(".wiktku-trans-group[data-gloss-pos='" + gi + "']"); if (!group.length) group = steps.trans.buildGroup(stepDiv, gi); // Only label groups when there's more than one gloss to // distinguish between — a single gloss needs no caption. var label = group.find(".wiktku-trans-group-label"); if (glosses.length > 1) { if (!label.length) { label = $("<div class='wiktku-trans-group-label'></div>"); group.prepend(label); } label.text(gloss.index + " " + gloss.text); } else if (label.length) { label.remove(); } }); return null; }, /** Reads the translation rows for a single gloss group. */ getGroupTranslations: function (group) { var result = []; group.find("li.wiktku-trans-row").each(function () { var lang = $(this).find("select").val(); if (!lang) return; var words = []; $(this).find("ul.wiktku-trans-words textarea").each(function () { var v = $.trim($(this).val()); if (v) words.push(v); }); if (words.length) result.push([lang, words]); }); return result; }, /** * Reads all translation rows from the DOM, grouped by gloss * position — one array of [lang, words] rows per gloss group, in * the same order as the .wiktku-trans-group elements. */ getTranslations: function (stepDiv) { var result = []; stepDiv.find(".wiktku-trans-group").each(function () { result.push(steps.trans.getGroupTranslations($(this))); }); return result; }, /** * Builds the numbered "{ index, gloss }" list — one entry per dfn * sense that has a real mane (skips template senses like Guharto, * which have nothing to caption a translation table with). The * index matches the sense's actual position in the numbered "#" * definition list (1-based), including template senses in the count, * so the number printed next to {{werger-ser}} lines up with the * gloss the reader sees in the entry. * * When nothing has been filled in at all (dfn.getOutput() will emit * {{mane?|lang}} as sense 1), this returns a single placeholder * entry with empty text instead of an empty array, so Werger still * has one group to attach translations to before a gloss exists. * When every filled sense is a template sense instead, this stays * empty — that mirrors trans.visible()'s hidden case, where there's * no group in the DOM for a placeholder to attach to anyway. */ glossList: function () { var dfnSenses = steps.dfn.getSenses($("#wiktku-start-dfn")); var glosses = []; var hasFilledTplSense = false; $.each(dfnSenses, function (i, s) { if (s.tpl) { if (s.tplTitle) hasFilledTplSense = true; return; // template sense — no gloss to caption with } var dfn = s.mane; if (!dfn) { // No mane text, but other fields (etîket/hevmane/nimûne/ // jêder…) are filled — dfn.getOutput() still emits this // sense as a numbered line using {{mane?|lang}}, so it // needs its own gloss group too, just with no caption text. if (senseHasExtraContent(s)) glosses.push({ index: i + 1, text: "" }); return; } if (dfn[0] !== dfn[0].toLowerCase()) dfn = decapitalize(dfn); dfn = stripWikilinks(dfn).replace(/[.…?!)\]،؟]+$/, ""); glosses.push({ index: i + 1, text: dfn }); }); if (!glosses.length && !hasFilledTplSense) { glosses.push({ index: 1, text: "" }); } return glosses; }, output: function (values) { if (values.lang !== "ku") return ""; var stepDiv = $("#wiktku-start-trans"); var glosses = steps.trans.glossList(); // Every sense is a template sense — there's no real gloss // anywhere and no group in the DOM either (glossList() only // returns empty in that case), so skip the section entirely. if (!glosses.length) return ""; // Each gloss now has its own group of translation rows — // attach every gloss's own words under its own werger-ser/-bin // pair instead of dumping everything under the first one. var blocks = $.map(glosses, function (gloss, gi) { var group = stepDiv.find(".wiktku-trans-group[data-gloss-pos='" + gi + "']"); var rows = group.length ? steps.trans.getGroupTranslations(group) : []; // Placeholder gloss (no real mane entered yet) with nothing // translated into it — nothing to output, and gloss.text is // empty so there's no caption to give {{werger-ser}} anyway. if (!gloss.text && !rows.length) return undefined; if (rows.length) { // Sort by Kurdish sort key. rows.sort(function (a, b) { var aLang = langsByCode[a[0]] || []; var bLang = langsByCode[b[0]] || []; return (aLang[2] || "").localeCompare(bLang[2] || "", "ku"); }); } var wordLines = $.map(rows, function (row) { var lang = row[0]; var words = row[1]; var wikiWords = words.map(function (w) { return "{{W|" + lang + "|" + w + "}}"; }).join(", "); return "* {{Z|" + lang + "}}: " + wikiWords; }).join("\n"); var block = "{{werger-ser|" + (gloss.text || "?") + "|" + gloss.index + "}}"; if (wordLines) block += "\n" + wordLines; block += "\n{{werger-bin}}"; return block; }); if (!blocks.length) return ""; return "\n==== Werger ====\n" + blocks.join("\n") + "\n"; } }, }; steps.trans.keys = steps.lang.choices; steps.dunde.keys = steps.lang.choices; steps.zarava.keys = getZaravaKeys(steps.lang.choices); var ordered_steps = [ steps.lang, steps.pron, steps.pos, steps.cinsiyet, steps.lektur, steps.tr, steps.dfn, steps.je, steps.tekildar, steps.etym, steps.dunde, steps.binereherwiha, steps.zarava, steps.trans]; // Step ids that belong to each section (not shared across sections). var PER_SECTION_STEP_IDS = [ "pos", "cinsiyet", "lektur", "tr", "dfn", "je", "tekildar", "etym", "dunde", "binereherwiha", "zarava", "trans" ]; // ── Multi-section state ────────────────────────────────────────────────── // Each entry is a plain snapshot: { pos, cinsiyet, lektur, tr, dfn (senses[]), // je, tekildar, binereherwiha, trans (rows[]) }. var sections = [{}]; // section 0 starts empty (DOM is the truth) var activeSection = 0; function snapshotDfn() { return steps.dfn.getSenses($("#wiktku-start-dfn")); } /** * Rebuild the dfn DOM from a previously snapshotted senses array. */ function restoreDfn(senses) { var stepDiv = $("#wiktku-start-dfn"); // Tear down the existing list so build() recreates it cleanly. stepDiv.find("ol.wiktku-dfn-list").remove(); steps.dfn.build(stepDiv); var list = stepDiv.find("ol.wiktku-dfn-list"); $.each(senses, function (i, sense) { // Ensure enough blocks exist (build() seeds one). var blocks = list.find("li.wiktku-dfn-sense"); var block = blocks.eq(i); if (!block.length) { var nb = steps.dfn.buildSenseBlock(stepDiv); list.append(nb); block = list.find("li.wiktku-dfn-sense").last(); } // Template selector. block.find("select.wiktku-dfn-tpl-select").val(sense.tpl || ""); if (sense.tpl) { block.find("textarea.wiktku-dfn-mane").hide(); block.find("input.wiktku-dfn-tpl-title").val(sense.tplTitle || "").show(); } else { block.find("textarea.wiktku-dfn-mane").val(sense.mane || "").show(); block.find("input.wiktku-dfn-tpl-title").hide().val(""); } // Re-sync the formên alternatîv/hevmane/… hide state now that // tplSelect's value was set programmatically (its own "change" // handler doesn't fire from .val(), so this doesn't happen otherwise). var updateVis = block.data("updateFieldVisibility"); if (updateVis) updateVis(); // Restore a sub-list (etiket, formên alternatîv, hevmane …) from a values array. function restoreSubList(cls, values) { if (!values || !values.length) return; var groupDiv = block.find("." + cls + "-group"); var subList = groupDiv.find("ol, ul").first(); if (!subList.length) return; // group not found // Fill existing items, append new ones as needed. $.each(values, function (j, val) { var items = subList.find("li"); if (j < items.length) { items.eq(j).find("textarea").val(val); } else { var ta = $("<textarea></textarea>") .attr("name", "wiktku-dfn-restore-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 1) .attr("class", "wiktku-dfn-subfield wiktku-start-narrow") .val(val); ta.on("input", function () { steps.dfn.onSubInput(subList, this, 1, true); }); subList.append($("<li></li>").append(ta)); } }); } // Reveal and populate lazy groups that have data. var lazyMap = { "wiktku-dfn-etiket": sense.etiket, "wiktku-dfn-alternativ": sense.alternativ, "wiktku-dfn-hevmane": sense.hevmane, "wiktku-dfn-dijmane": sense.dijmane, "wiktku-dfn-koordine": sense.koordine, "wiktku-dfn-jornav": sense.jornav, "wiktku-dfn-jernav": sense.jernav }; $.each(lazyMap, function (cls, vals) { if (vals && vals.length) restoreSubList(cls, vals); }); // Nimûne items are objects { text, tr?, t? } — restore using the builder. if (sense.nimune && sense.nimune.length) { var nimuneGroupDiv = block.find(".wiktku-dfn-nimune-group"); var nimuneList = nimuneGroupDiv.find("ol.wiktku-dfn-nimune-list"); var buildFn = nimuneGroupDiv.data("buildNimuneLi"); nimuneList.empty(); $.each(sense.nimune, function (_, n) { var text = typeof n === "object" ? (n.text || "") : n; if (!text) return; var li = buildFn ? buildFn() : $("<li class='wiktku-dfn-nimune-li'></li>"); li.find(".wiktku-dfn-nimune-text").val(text); if (n.tr) li.find(".wiktku-dfn-nimune-tr").val(n.tr); if (n.t) li.find(".wiktku-dfn-nimune-t").val(n.t); nimuneList.append(li); }); // Always leave a blank trailing item. if (buildFn) nimuneList.append(buildFn()); } // Restore jêder (quote/citation) entries — a growing list, restored using the // builder just like Nimûne. Accepts either the current array shape or a // single legacy object (from older saved sections) for backwards compatibility. var jederArr = $.isArray(sense.jeder) ? sense.jeder : (sense.jeder ? [sense.jeder] : []); if (jederArr.length) { var jederGroupDiv = block.find(".wiktku-dfn-jeder-group"); var jederList = jederGroupDiv.find("ol.wiktku-dfn-jeder-list"); var buildJederFn = jederGroupDiv.data("buildJederLi"); jederList.empty(); $.each(jederArr, function (_, j) { if (!j || !j.quote) return; var li = buildJederFn ? buildJederFn() : $("<li class='wiktku-dfn-jeder-li'></li>"); li.find(".wiktku-dfn-nimune-quote").val(j.quote); if (j.quoteTr) li.find(".wiktku-dfn-nimune-quote-tr").val(j.quoteTr); if (j.quoteT) li.find(".wiktku-dfn-nimune-quote-t").val(j.quoteT); if (j.jederManual) { var manualSel = li.find(".wiktku-dfn-quote-src-sel"); manualSel.val("__manual__").trigger("change"); li.find(".wiktku-dfn-quote-src-manual").val(j.jederManual); } else if (j.jederTpl) { var srcSel = li.find(".wiktku-dfn-quote-src-sel"); srcSel.val(j.jederTpl).trigger("change"); if (j.jêderFields) { $.each(j.jêderFields, function (key, val) { li.find(".wiktku-dfn-quote-src-input[data-field-key='" + key + "']").val(val); }); } } jederList.append(li); }); // Always leave a blank trailing item, same as Nimûne. if (buildJederFn) jederList.append(buildJederFn()); } }); } /** * Snapshot simple (non-dfn) per-section steps from current DOM into obj. */ function saveCurrentSection() { var snap = {}; $.each(PER_SECTION_STEP_IDS, function (_, id) { if (id === "dfn") { snap.dfn = snapshotDfn(); return; } if (id === "etym") { snap.etym = $.trim($("#wiktku-start-etym .wiktku-etym-text").val()); return; } var step = steps[id]; if (!step) return; var stepDiv = $("#wiktku-start-" + id); if (id === "trans") { snap.trans = steps.trans.getTranslations(stepDiv); return; } if (id === "zarava") { snap.zarava = steps.zarava.getTranslations(stepDiv); return; } if (id === "dunde") { snap.dunde = steps.dunde.getRows(stepDiv); return; } // Generic: read all step fields. var fields = stepDiv.find(".wiktku-start-step-field"); if (step.multiple) { snap[id] = fields.map(function () { return $(this).val(); }).get(); } else { snap[id] = fields.val(); } }); sections[activeSection] = snap; } /** * Restore a previously saved snapshot into the form DOM. */ function restoreSection(snap) { $.each(PER_SECTION_STEP_IDS, function (_, id) { if (id === "dfn") { restoreDfn(snap.dfn || []); return; } if (id === "etym") { $("#wiktku-start-etym .wiktku-etym-wrap").remove(); steps.etym.build($("#wiktku-start-etym")); $("#wiktku-start-etym .wiktku-etym-text").val(snap.etym || ""); return; } if (id === "trans") { // Rebuild trans groups (dfn must already be restored by this // point in the $.each loop, so glossList() reflects it). var transDiv = $("#wiktku-start-trans"); transDiv.find(".wiktku-trans-group").remove(); steps.trans.build(transDiv); var groupsSnap = snap.trans || []; $.each(groupsSnap, function (gi, rows) { var group = transDiv.find(".wiktku-trans-group[data-gloss-pos='" + gi + "']"); if (!group.length) return; // gloss no longer exists — drop its rows var list = group.find("ul.wiktku-trans-list"); $.each(rows, function (j, row) { var lang = row[0], words = row[1]; var lastRow = list.find("li.wiktku-trans-row").last(); lastRow.find("select").val(lang).trigger("change"); var wordList = lastRow.find("ul.wiktku-trans-words"); $.each(words, function (k, word) { var wordItems = wordList.find("li"); if (k < wordItems.length) { wordItems.eq(k).find("textarea").val(word); } else { // .val() below doesn't fire "input", so the normal // auto-grow never runs — append a matching item // ourselves instead of silently dropping the word. var extraInput = steps.trans.makeWordInput(); wordList.append($("<li></li>").append(extraInput)); extraInput.val(word); } }); // Leave one trailing empty field so the row can still grow // when the user types, matching a freshly-built row. if ($.trim(wordList.children("li").last().find("textarea").val())) { wordList.append($("<li></li>").append(steps.trans.makeWordInput())); } }); }); return; } if (id === "zarava") { // Rebuild zarava groups (dfn must already be restored by this // point in the $.each loop, so glossList() reflects it). var zaravaDiv = $("#wiktku-start-zarava"); zaravaDiv.find(".wiktku-zarava-group").remove(); steps.zarava.build(zaravaDiv); var zaravaGroupsSnap = snap.zarava || []; $.each(zaravaGroupsSnap, function (gi, rows) { var group = zaravaDiv.find(".wiktku-zarava-group[data-gloss-pos='" + gi + "']"); if (!group.length) return; // gloss no longer exists — drop its rows var list = group.find("ul.wiktku-zarava-list"); $.each(rows, function (j, row) { var lang = row[0], words = row[1]; var lastRow = list.find("li.wiktku-zarava-row").last(); lastRow.find("select").val(lang).trigger("change"); var wordList = lastRow.find("ul.wiktku-zarava-words"); $.each(words, function (k, word) { var wordItems = wordList.find("li"); if (k < wordItems.length) { wordItems.eq(k).find("textarea").val(word); } else { var extraInput = steps.zarava.makeWordInput(); wordList.append($("<li></li>").append(extraInput)); extraInput.val(word); } }); if ($.trim(wordList.children("li").last().find("textarea").val())) { wordList.append($("<li></li>").append(steps.zarava.makeWordInput())); } }); }); return; } if (id === "dunde") { // Rebuild dunde rows. var dundeDiv = $("#wiktku-start-dunde"); dundeDiv.find("ul.wiktku-dunde-list").remove(); steps.dunde.build(dundeDiv); var dundeRows = snap.dunde || []; $.each(dundeRows, function (i, row) { var lang = row[0], words = row[1]; var list = dundeDiv.find("ul.wiktku-dunde-list"); var lastRow = list.find("li.wiktku-dunde-row").last(); lastRow.find("select").val(lang).trigger("change"); var wordList = lastRow.find("ul.wiktku-dunde-words"); $.each(words, function (j, word) { var wordItems = wordList.find("li"); if (j < wordItems.length) { wordItems.eq(j).find("textarea").val(word); } else { // .val() below doesn't fire "input", so the normal // auto-grow never runs — append a matching item // ourselves instead of silently dropping the word. var extraInput = steps.dunde.makeWordInput(); wordList.append($("<li></li>").append(extraInput)); extraInput.val(word); } }); // Leave one trailing empty field so the row can still grow // when the user types, matching a freshly-built row. if ($.trim(wordList.children("li").last().find("textarea").val())) { wordList.append($("<li></li>").append(steps.dunde.makeWordInput())); } }); return; } var step = steps[id]; if (!step) return; var stepDiv = $("#wiktku-start-" + id); var fields = stepDiv.find(".wiktku-start-step-field"); var val = snap[id]; if (val === undefined || val === null) return; if (step.multiple) { var arr = val; fields.each(function (i) { if (i < arr.length) $(this).val(arr[i]); }); } else { fields.val(val); } // Notify chosen widgets of the programmatic value change. if (!isMobile) fields.filter("select").trigger("chosen:updated"); }); } function getWikitextForCurrentSection(callback) { var values = getValues(); var entry = steps.pos.output(values); steps.dfn.getOutput(values, function (output) { entry += output; entry += steps.je.output(values); entry += steps.tekildar.output(values); entry += steps.etym.output(values); entry += steps.dunde.output(values); entry += steps.binereherwiha.output(values); entry += steps.zarava.output(values); entry += steps.trans.output(values); callback(entry, values); }); } function getWikitextAllSections(callback) { saveCurrentSection(); var results = new Array(sections.length); var sharedValues = getValues(); // lang/pron are shared function processSection(i) { if (i >= sections.length) { // All done — restore original active section. restoreSection(sections[activeSection]); refresh(); callback(results, sharedValues); return; } restoreSection(sections[i]); refresh(); getWikitextForCurrentSection(function (sectionText) { results[i] = sectionText; processSection(i + 1); }); } processSection(0); } /** * Assembles wikitext for all sections plus the shared lang/pron header. */ function getWikitext(callback) { getWikitextAllSections(function (sectionTexts, sharedValues) { var entry = steps.lang.output(sharedValues); entry += steps.pron.output(sharedValues); entry += sectionTexts.join("\n"); // Edit summary uses section 0's values. Read from the saved snapshot // (not the live DOM) so it doesn't mix section 0's pos with whichever // section happens to be active/restored at this point. var dfnSenses = (sections[0] && sections[0].dfn) || []; var dfnSummary = dfnSenses.map(function (s) { return s.mane; }).filter(Boolean).join("; "); var summaryLabel = addLangMode ? "WF:Ziman lê zêde" : "WF:Nû"; var summary = "([[Mediawiki:Gadget-start.js|" + summaryLabel + "]] v.2.0) +" + sharedValues.lang + ":" + sections[0].pos + ":" + dfnSummary; var summaryField = document.getElementById("wpSummary"); if (addLangMode && summaryField.value) { summary = summaryField.value + " " + summary; } summaryField.value = summary; callback(entry); }); } var continueBtn; function getValuesForStep(stepId) { var fields = $("#wiktku-start-" + stepId + " .wiktku-start-step-field"); var step = steps[stepId]; if (step.keys) { var values = {}; fields.each(function (i, field) { var key = $(field).prevAll(".wiktku-start-step-keyfield").val(); if (key) values[key] = $(field).val(); }); return values; } else if (step.multiple) { return fields.map(function () { return $(this).val(); }).get(); } return fields.val(); } function getValues() { var values = {}; $.each(steps, function (stepId) { values[stepId] = getValuesForStep(stepId); }); return values; } function populateMenus(inputs, choices, disabledValues) { if (!disabledValues) disabledValues = {}; var vals = inputs.map(function (i, input) { return $(input).val(); }); inputs.empty(); inputs.append($("<option></option>")); $.each(choices, function (j, choice) { // Append the language code in parentheses so that typing a code // (e.g. "ku") in the search box still finds the language name. var displayText = capitalize(choice[1]); if (choice[2] !== undefined) { // This is a language choice [code, name, sortKey] — show code. displayText = capitalize(choice[1]) + " (" + choice[0] + ")"; } var option = $(mw.html.element("option", { value: choice[0] }, displayText)); if (disabledValues[choice[0]]) option.prop("disabled", true); inputs.append(option); }); inputs.val(function (i) { return vals[i]; }); } /** * Returns a bitmap containing the keys that should be disabled for a key * menu in the given step because they are disabled or already taken by * another key menu. */ function getDisabledKeys(step) { var occupiedKeys = {}; $("#wiktku-start-" + step.id + " .wiktku-start-step-keyfield").each(function () { occupiedKeys[$(this).val()] = true; }); if (step.disabledKeys) $.extend(occupiedKeys, step.disabledKeys); return occupiedKeys; } function buildKeyInput(step) { if (!step.keys) return undefined; var input = $(mw.html.element("select", { "class": "wiktku-start-step-keyfield wiktku-start-narrow" })); input.attr("data-placeholder", "Hilbijêre " + step.keyName); if (isMobile) { populateMenus(input, step.keys, getDisabledKeys(step)); // On mobile return the wrapper; the select is inside it. // Change events still fire on the inner select. return wrapNativeSelect(input); } input.on("chosen:showing_dropdown", function () { $(this).data("wiktku-defaultValue", $(this).val()); }); input.change(function (_, context) { var inputs = $("#wiktku-start-" + step.id + " .wiktku-start-step-keyfield").not(this); var oldValue = $(this).data("wiktku-defaultValue"); var newValue = context.selected; inputs.find("option[value='" + oldValue + "']").prop('disabled', false); inputs.find("option[value='" + newValue + "']").prop('disabled', true); inputs.trigger("chosen:updated"); }); populateMenus(input, step.keys, getDisabledKeys(step)); return input; } /** * If the current text field has text and there are no more text fields after * the current text field in the list, add another text field to the list. */ function refreshForTextField(currentInput, step) { currentInput = $(currentInput); var value = currentInput.val(); var item = currentInput.parent(); if (value && !item.next("li").length) { var nextInput = $("<textarea></textarea>") .attr("name", "wiktku-field-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("class", currentInput.attr("class")) .attr("rows", currentInput.attr("rows") || 1); nextInput.on("input", function (evt) { refreshForTextField(evt.target, step); }); var nextKeyInput = buildKeyInput(step); var nextItem = $("<li></li>").append(nextKeyInput).append(nextInput); item.parent().append(nextItem); if (nextKeyInput) nextKeyInput.chosen(chosenOptions); } var canContinue = !continueBtn.isDisabled(); if ((value && !canContinue) || (!value && canContinue)) { refresh(step); } } function prepareInput(input, step) { if (!input) return; if (step.required) input.prop('required', true); input.change(step, refresh); } /** * Shows and hides all the steps based on whether their prerequisites are met, * and updates placeholders where applicable. */ function refresh(evt) { var values = getValues(); var changedStep = evt && evt.data; var didFocus = false; var canContinue = true; // Re-filter template options in every sense block whenever lang changes. $("#wiktku-start-dfn .wiktku-dfn-tpl-select").each(function () { var fn = $(this).data("updateOptions"); if (typeof fn === "function") fn(); }); // Re-filter pronunciation and etymology template dropdowns when language changes. steps.pron.refreshTplSelect(); steps.etym.refreshTplSelect(); // Sync tr/t sub-fields in every nimûne item to the current language. // tr shown when language needs transliteration; t shown when lang !== "ku". (function () { var lang = values.lang || ""; var showTr = needsTransliteration(lang); var showT = lang && lang !== "ku"; $("#wiktku-start-dfn .wiktku-dfn-nimune-list li.wiktku-dfn-nimune-li").each(function () { var li = $(this); // Ensure the sub-wrapper exists when we need it. var subWrap = li.find(".wiktku-dfn-nimune-sub"); // tr field var trTa = li.find(".wiktku-dfn-nimune-tr"); if (showTr && !trTa.length) { if (!subWrap.length) { subWrap = $("<div></div>").addClass("wiktku-dfn-nimune-sub"); li.append(subWrap); } trTa = $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-tr-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 5) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-tr") .attr("placeholder", "Transkrîpsiyon…"); subWrap.prepend(trTa); } else if (!showTr && trTa.length) { trTa.remove(); } // t field var tTa = li.find(".wiktku-dfn-nimune-t"); if (showT && !tTa.length) { if (!subWrap.length) { subWrap = $("<div></div>").addClass("wiktku-dfn-nimune-sub"); li.append(subWrap); } tTa = $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-t-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 5) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-t") .attr("placeholder", "Tercimeya nimûneyê kurmancî…"); subWrap.append(tTa); } else if (!showT && tTa.length) { tTa.remove(); } // Remove the wrapper if it ended up empty. subWrap = li.find(".wiktku-dfn-nimune-sub"); if (subWrap.length && !subWrap.children().length) subWrap.remove(); }); }()); // Sync tr/t sub-fields in every jêder citation to the current language. // tr shown when language needs transliteration; t shown when lang !== "ku". (function () { var lang = values.lang || ""; var showTr = needsTransliteration(lang); var showT = lang && lang !== "ku"; $("#wiktku-start-dfn .wiktku-dfn-jeder-list li.wiktku-dfn-jeder-li").each(function () { var li = $(this); // Ensure the sub-wrapper exists when we need it. It must sit right // after the quote textarea and before the source selector. var subWrap = li.find(".wiktku-dfn-quote-sub"); // tr field var trTa = li.find(".wiktku-dfn-nimune-quote-tr"); if (showTr && !trTa.length) { if (!subWrap.length) { subWrap = $("<div></div>").addClass("wiktku-dfn-quote-sub"); li.find(".wiktku-dfn-nimune-quote").after(subWrap); } trTa = $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-quote-tr-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 2) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-quote-tr") .attr("placeholder", "Transkrîpsiyona jêgirtinê…"); subWrap.prepend(trTa); } else if (!showTr && trTa.length) { trTa.remove(); } // t field var tTa = li.find(".wiktku-dfn-nimune-quote-t"); if (showT && !tTa.length) { if (!subWrap.length) { subWrap = $("<div></div>").addClass("wiktku-dfn-quote-sub"); li.find(".wiktku-dfn-nimune-quote").after(subWrap); } tTa = $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-quote-t-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 2) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-quote-t") .attr("placeholder", "Tercimeya jêgirtinê ya kurmancî…"); subWrap.append(tTa); } else if (!showT && tTa.length) { tTa.remove(); } // Remove the wrapper if it ended up empty. subWrap = li.find(".wiktku-dfn-quote-sub"); if (subWrap.length && !subWrap.children().length) subWrap.remove(); }); }()); $.each(steps, function (stepId, step) { if (typeof(step.visible) === "function" && !step.visible(values)) { $("#wiktku-start-" + stepId).slideUp(); } else { var stepDiv = $("#wiktku-start-" + stepId); if (changedStep !== step && typeof(step.build) === "function") { prepareInput(step.build(stepDiv, values), step); } var input = stepDiv.find(".wiktku-start-step-field"); if (typeof(step.example) === "function") { // .find() above already reaches nested fields (e.g. the dfn // step's mane textareas inside each sense block), so one // assignment covers every step; dfn keeps its own fallback. var exampleText = step.example(values) || (step.id === "dfn" ? "Mane…" : ""); input.attr("placeholder", exampleText); } var didSlideDown; if (!didFocus && stepDiv.css("display") === "none" && step.required) { didSlideDown = function (evt) { input.focus(); }; didFocus = true; } stepDiv.slideDown(didSlideDown); } if (step.required && (values[stepId] === "" || (step.multiple && values[stepId].join("") === ""))) { canContinue = false; } }); continueBtn.setDisabled(!canContinue); } function destroy() { $("#wiktku-start-form, .noafterwizard").slideUp(function () { $(this).remove(); }); $(".noarticletext .nowizard, #editform").slideDown(); $("#ca-edit").removeClass("selected"); $("#ca-wiktku-nowizard").addClass("selected"); } // Priority order for Kurdish dialects and the navz pseudo-code. // Codes listed here come before all other languages; unlisted codes // are sorted alphabetically by their display name via localeCompare. var LANG_PRIORITY = ["navz", "ku", "hac", "sdh", "lki", "ckb", "zza"]; /** * Inserts a new == {{ziman|code}} == section into existing page wikitext * at the correct sorted position: * 1. Any content before the first language section is preserved at the top. * 2. navz is always first, then ku/hac/sdh/lki/ckb/zza in that order, * then all other languages sorted by display name (localeCompare). */ function insertNewLangSection(existing, wikitext) { var newCodeMatch = wikitext.match(/^== \{\{ziman\|([^}]+)\}\} ==/); var newCode = newCodeMatch ? newCodeMatch[1] : ""; var sections = []; var preamble = ""; var firstMatch = existing.match(/(?:^|\n)== \{\{ziman\|/); if (!firstMatch) { // No existing lang sections at all — just append. var sep = existing && !/\n\s*$/.test(existing) ? "\n\n" : ""; return existing + sep + wikitext; } // Everything before the first == {{ziman|...}} == is the preamble. var firstSectionStart = existing.indexOf("== {{ziman|"); // Walk back to the start of that line. var lineStart = existing.lastIndexOf("\n", firstSectionStart - 1); var preambleEnd = lineStart !== -1 ? lineStart + 1 : 0; preamble = existing.slice(0, preambleEnd); // Parse each language section: header line + everything until the next header. var body = existing.slice(preambleEnd); // NOTE: with the /m flag, a bare "$" matches end-of-*line*, not just // end-of-string — that previously made the non-greedy content group // stop at the section's first line break instead of running to the // next language header (or the real end of the text), silently // dropping the rest of that section's wikitext. (?![\s\S]) matches // only the true end of the string, /m flag or not. var langSectionRe = /^(== \{\{ziman\|([^}]+)\}\} ==\n?)([\s\S]*?)(?=\n== \{\{ziman\||(?![\s\S]))/gm; var m; while ((m = langSectionRe.exec(body)) !== null) { sections.push({ code: m[2], content: m[0] // full text of this section including header }); } // Determine sort rank: priority list first (by index), then alphabetical. function getLangName(code) { var entry = langsByCode[code]; return entry ? entry[1] : code; } function sortRank(code) { var idx = LANG_PRIORITY.indexOf(code); return idx !== -1 ? idx : LANG_PRIORITY.length; } function compareLangs(a, b) { var ra = sortRank(a), rb = sortRank(b); if (ra !== rb) return ra - rb; // Both are outside priority list — sort by display name. return getLangName(a).localeCompare(getLangName(b), userLang); } // Insert the new section into the sorted list. var newSection = { code: newCode, content: wikitext }; var inserted = false; for (var i = 0; i < sections.length; i++) { if (compareLangs(newCode, sections[i].code) < 0) { sections.splice(i, 0, newSection); inserted = true; break; } } if (!inserted) sections.push(newSection); // Re-join: preamble + sections separated by newlines. var joined = sections.map(function (s) { // Ensure each section ends with exactly one newline before the next. return s.content.replace(/\n+$/, ""); }).join("\n"); return preamble + joined + "\n"; } function build() { $(".nowizard, .nowizard .noafterwizard").hide(); var callToAction = $("#wiktku-calltoaction"); var origCallToActionText = callToAction.text(); $(mw.util.addPortletLink("p-views", "#", "Edîtora çavkaniyê veke", "ca-wiktku-nowizard", "Vê rûpelê bi edîtora çavkaniyê çêke", undefined, "#ca-watch")).click(function (evt) { evt.preventDefault(); callToAction.text(origCallToActionText); destroy(); }); if (callToAction.length) { callToAction.text(origCallToActionText + " Forma li jêr ji bo çêkirina madeyeke nû bi kar bîne."); } var startForm = $("<form id='wiktku-start-form'></form>"); if (addLangMode) { startForm.append($("<p class='wiktku-addlang-notice'></p>").text( "Bi vê formê tu yê beşeke nû li rûpelê îlaw bikî. Eger ev zimanê ku tu îlawe dikî jixwe di rûpelê de hebe, beşa nû li dawiya vî zimanî dê were îlawekirin. " + "Ji kerema xwe netîceya dawî kontrol bikin, eger problemek derkeve, li [[Mediawiki talk:Gadget-start.js|nîqaşa vê amûrê]] problemê ragihîne.")); } var spinner; // Tab bar for switching between POS sections. var sectionTabsDiv = $("<div id='wiktku-section-tabs'></div>"); startForm.submit(function (evt) { evt.preventDefault(); continueBtn.setDisabled(true); spinner.show(); getWikitext(function (wikitext) { if (addLangMode) { var textbox = $("#wpTextbox1"); var existing = textbox.val() || ""; // Check whether the generated lang header already exists in the page. // wikitext always starts with "== {{ziman|CODE}} ==\n" (from steps.lang.output). // If that exact section heading is already present in the existing content, // strip it from the new output and insert the remaining content at the end // of that lang section (just before the next == level-2 heading, or at the // very end of the page if there is no following section). var langHeaderMatch = wikitext.match(/^(== \{\{ziman\|[^}]+\}\} ==\n)/); if (langHeaderMatch) { var langHeader = langHeaderMatch[1]; // e.g. "== {{ziman|ku}} ==\n" // Escape for use in RegExp. var escapedHeader = langHeader.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); if (new RegExp(escapedHeader).test(existing)) { // Strip the header from the new output. var newContent = wikitext.slice(langHeader.length); // Find the insertion point: end of the existing lang section. // A new L2 heading marks the start of the next language block. var afterHeader = existing.indexOf(langHeader); var searchFrom = afterHeader + langHeader.length; // Find the next == … == heading after this section's start. var nextL2 = existing.indexOf("\n== ", searchFrom); var insertAt = nextL2 !== -1 ? nextL2 : existing.length; // Ensure there's a blank line before the inserted block. var before = existing.slice(0, insertAt); var after = existing.slice(insertAt); var sep = /\n\s*$/.test(before) ? "" : "\n"; textbox.val(before + sep + newContent + after); } else { // New language — insert at the correct sorted position. textbox.val(insertNewLangSection(existing, wikitext)); } } else { // Unexpected format — insert at sorted position anyway. textbox.val(insertNewLangSection(existing, wikitext)); } } else { $("#wpTextbox1").val(wikitext); } $("html, body").animate({scrollTop: 0}); callToAction.text("Hindik ma!"); $("#wiktku-preview-container").remove(); destroy(); }); }); $.each(ordered_steps, function (i, step) { var stepDiv = $(mw.html.element("div", { "class": "wiktku-start-step", id: "wiktku-start-" + step.id })); var name = capitalize(step.name); stepDiv.append($(mw.html.element("h3", { "class": "wiktku-start-step-name" }, new mw.html.Raw(mw.html.element("label", { "for": "wiktku-start-" + step.id + "-field" }, name))))); if (step.question_fmt) { stepDiv.append($(mw.html.element("label", { "class": "wiktku-start-step-question", "for": "wiktku-start-" + step.id + "-field" }, step.question_fmt))); if (step.question_br) stepDiv.append($("<br>")); } var input; if (step.choices) { input = $(mw.html.element("select", { "class": "wiktku-start-step-field", id: "wiktku-start-" + step.id + "-field" })); input.attr("data-placeholder", capitalize(step.name) + " hilbijêre "); populateMenus(input, step.choices); if (step.multiple) input.attr("multiple", true); if (isMobile) { stepDiv.append(wrapNativeSelect(input)); } else { stepDiv.append(input); } } else if (typeof(step.build) === "function") { input = step.build(stepDiv); } else { input = $("<textarea></textarea>") .attr("class", "wiktku-start-step-field") .attr("id", "wiktku-start-" + step.id + "-field") .attr("rows", step.rows || 2); if (step.narrow) input.addClass("wiktku-start-narrow"); if (step.multiple) { input.on("input", function (evt) { refreshForTextField(evt.target, step); }); var keyInput = buildKeyInput(step); var list = $(step.ordered ? "<ol></ol>" : "<ul></ul>") .append($("<li></li>").append(keyInput).append(input)); stepDiv.append(list); } else stepDiv.append(input); } prepareInput(input, step); stepDiv.hide(); // Insert tab bar just before the first per-section step. if (step.id === "pos") startForm.append(sectionTabsDiv); startForm.append(stepDiv); }); // ── Section tab helpers ────────────────────────────────────────────── // ── Add-section button — lives in the tab bar, disabled until pos chosen ── var addSectionBtn = new OO.ui.ButtonWidget({ label: "+ Beş zêde bike", disabled: true }); addSectionBtn.on("click", function () { saveCurrentSection(); sections.push({}); activeSection = sections.length - 1; $.each(PER_SECTION_STEP_IDS, function (_, id) { if (id === "dfn") { var stepDiv = $("#wiktku-start-dfn"); stepDiv.find("ol.wiktku-dfn-list").remove(); steps.dfn.build(stepDiv); return; } if (id === "etym") { $("#wiktku-start-etym .wiktku-etym-wrap").remove(); steps.etym.build($("#wiktku-start-etym")); return; } if (id === "trans") { var transDiv = $("#wiktku-start-trans"); transDiv.find(".wiktku-trans-group").remove(); return; } if (id === "zarava") { var zaravaDiv = $("#wiktku-start-zarava"); zaravaDiv.find(".wiktku-zarava-group").remove(); return; } if (id === "dunde") { var dundeDiv = $("#wiktku-start-dunde"); dundeDiv.find("ul.wiktku-dunde-list").remove(); return; } var stepDiv = $("#wiktku-start-" + id); stepDiv.find(".wiktku-start-step-field").val(""); if (!isMobile) stepDiv.find("select.wiktku-start-step-field").trigger("chosen:updated"); }); renderSectionTabs(); refresh(); $("html, body").animate({ scrollTop: sectionTabsDiv.offset().top - 20 }, 300); }); /** Re-render the tab bar to reflect current sections[] and activeSection. */ function renderSectionTabs() { // Detach (not remove) the button first: .empty() strips bound // event data from any children left inside it, which would // silently kill addSectionBtn's click handler on every re-render. addSectionBtn.$element.detach(); sectionTabsDiv.empty(); var lang = getValues().lang || ""; if (!lang) { sectionTabsDiv.hide(); return; } sectionTabsDiv.show(); $.each(sections, function (i) { var posVal = sections[i].pos || ""; var tabLabel = posVal ? capitalize(posVal) : ("Beş " + (i + 1)); var tab = $("<span></span>") .addClass("wiktku-section-tab") .text(tabLabel) .toggleClass("wiktku-tab-active", i === activeSection); (function (idx) { tab.on("click", function () { if (idx === activeSection) return; saveCurrentSection(); activeSection = idx; restoreSection(sections[activeSection]); refresh(); renderSectionTabs(); }); }(i)); sectionTabsDiv.append(tab); }); // Enable "Beş zêde bike" only when the active section has a pos chosen. var activePos = sections[activeSection] && sections[activeSection].pos ? sections[activeSection].pos : getValues().pos; addSectionBtn.setDisabled(!activePos); sectionTabsDiv.append(addSectionBtn.$element); } renderSectionTabs(); // Update the active tab's label whenever pos changes. startForm.on("change", "#wiktku-start-pos-field", function () { renderSectionTabs(); }); // Show the tab bar as soon as a language is selected. startForm.on("change", "#wiktku-start-lang-field", function () { renderSectionTabs(); }); var footer = $("<div id='wiktku-start-footer'></div>"); spinner = $(mw.html.element("img", { id: "wiktku-start-spinner", src: "//upload.wikimedia.org/wikipedia/commons/d/de/Ajax-loader.gif", alt: "Tê barkirin…", title: "Tê barkirin…" })); footer.append(spinner.hide()); continueBtn = new OO.ui.ButtonWidget({ id: "wiktku-unhide-editform", label: "Bişîne", flags: [ "primary", "progressive" ] }); continueBtn.on("click", function () { mw.notify("Tê şandin…", { type: "info", tag: "wiktku-submit" }); startForm.trigger("submit"); }); footer.append(continueBtn.$element); // "Edîtora çavkaniyê veke" button — inline fallback for the portlet link // which is invisible on mobile and easy to miss on desktop. var sourceEditorBtn = new OO.ui.ButtonWidget({ label: "Edîtora çavkaniyê veke", framed: false }); sourceEditorBtn.on("click", function () { destroy(); }); footer.append(sourceEditorBtn.$element); // ── Preview checkboxes ─────────────────────────────────────────────── // Wikitext preview (raw text panel) var previewCheck = $("<input type='checkbox' id='wiktku-preview-toggle'>"); var previewLabel = $("<label for='wiktku-preview-toggle'></label>") .text(" Pêşdîtina wîkîtekstê"); var previewPanel = $("<pre id='wiktku-preview-panel'></pre>").hide(); // Live rendered preview (parsed HTML panel, same logic as AjaxEdit). // Not available on mobile — API polling causes too many problems on small screens. var livePreviewCheck = null; var livePreviewPanel = null; if (!isMobile) { livePreviewCheck = $("<input type='checkbox' id='wiktku-live-preview-toggle'>"); livePreviewPanel = $("<div id='wiktku-live-preview-panel'></div>").hide(); } // Container that holds both panels and switches between stacked / side-by-side. var previewContainer = $("<div id='wiktku-preview-container'></div>"); previewContainer.append(previewPanel); if (!isMobile) previewContainer.append(livePreviewPanel); var previewTimer = null; var livePreviewIntervalId = -1; var livePreviewActive = false; // guards in-flight fetches after uncheck /** Rebuilds wikitext preview if its checkbox is checked. */ function schedulePreview() { if (!previewCheck.prop("checked")) return; clearTimeout(previewTimer); // Debounce: wait 400 ms after the last keystroke before rebuilding. previewTimer = setTimeout(function () { getWikitext(function (wikitext) { previewPanel.text(wikitext).show(); updatePanelLayout(); }); }, 400); } /** Fetches parsed HTML and populates the live preview panel. */ function loadLivePreview() { getWikitext(function (wikitext) { new mw.Api().parse(wikitext, { title: mw.config.get("wgPageName") }).done(function (html) { // Discard result if the user unchecked while the fetch was in flight. if (!livePreviewActive) return; livePreviewPanel.html(html).show(); updatePanelLayout(); }); }); } /** Adjusts panel widths depending on which previews are visible. */ function updatePanelLayout() { var wikitextVisible = previewCheck.prop("checked"); var liveVisible = livePreviewCheck && livePreviewCheck.prop("checked"); if (wikitextVisible && liveVisible) { // Side by side — each panel takes roughly half the available width. previewPanel.css({ "flex": "1 1 45%", "min-width": "280px" }); livePreviewPanel.css({ "flex": "1 1 45%", "min-width": "280px" }); } else { // Full width for whichever is visible — only touch panels that are // actually shown so that setting flex doesn't override display:none. if (wikitextVisible) previewPanel.css({ "flex": "1 1 100%", "min-width": "" }); if (liveVisible && livePreviewPanel) livePreviewPanel.css({ "flex": "1 1 100%", "min-width": "" }); } } previewCheck.on("change", function () { if ($(this).prop("checked")) { schedulePreview(); } else { clearTimeout(previewTimer); previewPanel.hide(); updatePanelLayout(); } }); if (!isMobile) { livePreviewCheck.on("change", function () { if ($(this).prop("checked")) { livePreviewActive = true; livePreviewPanel.show(); loadLivePreview(); livePreviewIntervalId = setInterval(loadLivePreview, 500); } else { livePreviewActive = false; clearInterval(livePreviewIntervalId); livePreviewIntervalId = -1; livePreviewPanel.hide().empty(); updatePanelLayout(); } }); } // Listen on all input/change events on the form and update both previews. startForm.on("input change", function () { schedulePreview(); }); footer.append($("<span style='margin-left:1em'></span>") .append(previewCheck).append(previewLabel)); if (!isMobile) { var livePreviewLabel = $("<label for='wiktku-live-preview-toggle'></label>") .text(" Pêşdîtina zindî"); footer.append($("<span style='margin-left:1em'></span>") .append(livePreviewCheck).append(livePreviewLabel)); } startForm.append(footer); $("#editform").hide().before(startForm); // Insert preview container (holds both panels) after the form. startForm.after(previewContainer); if (!isMobile) startForm.find("select").chosen(chosenOptions); refresh(); // Zimanan ji MediaWiki:Gadget-translation_editor.js/ziman.json bar bike. // Kodên ku bi "-pro" diqedin û navên ku "zimanê destan" tê de heye // tên derxistin. Zimanên xardkirî li serî dimînin, yên din // bi alfabeyê li dû wan tên. // Pinned choices come from MediaWiki:Gadget-start.js/data.json (langChoices), // already loaded into steps.lang.choices before build() runs. var pinnedChoices = steps.lang.choices.slice(); var pinnedCodes = $.map(pinnedChoices, function (choice) { return choice[0]; }); new mw.Api().get({ action: "query", prop: "revisions", titles: "MediaWiki:Gadget-translation_editor.js/ziman.json", rvprop: "content", rvslots: "main", formatversion: 2 }).then(function (data) { var page = data.query.pages[0]; var content = page && page.revisions && page.revisions[0].slots.main.content; var zimanData; try { zimanData = JSON.parse(content); } catch (e) { zimanData = {}; } var extraChoices = []; $.each(zimanData, function (code, name) { // Filter: skip proto-language codes and legendary/reconstructed langs. if (/-pro$/i.test(code)) return; if (/ziman[eê]\s+destan/i.test(name)) return; // Skip codes already in the pinned list (they are handled above). if (pinnedCodes.indexOf(code) !== -1) return; // sortKey: bare name without leading "zimanê " for sorting. var sortKey = name.replace(/^ziman[eê]\s+/i, ""); var choice = [code, name, sortKey]; extraChoices.push(choice); langsByCode[code] = choice; }); // Populate langsByCode for pinned choices too. $.each(pinnedChoices, function (i, choice) { // Ensure pinned choices have a sortKey (index 2). if (choice.length < 3) choice[2] = choice[1]; langsByCode[choice[0]] = choice; }); // Sort the extra choices alphabetically by sort key. extraChoices.sort(function (a, b) { return a[2].localeCompare(b[2], userLang); }); // Final list: pinned first, then the rest. var allChoices = pinnedChoices.concat(extraChoices); steps.lang.choices = allChoices; steps.trans.keys = allChoices; steps.dunde.keys = allChoices; steps.zarava.keys = getZaravaKeys(allChoices); var langMenu = $("#wiktku-start-lang-field"); populateMenus(langMenu, steps.lang.choices); langMenu.trigger("chosen:updated"); var transMenus = $("#wiktku-start-trans .wiktku-start-step-keyfield"); populateMenus(transMenus, steps.trans.keys, getDisabledKeys(steps.trans)); transMenus.trigger("chosen:updated"); var dundeMenus = $("#wiktku-start-dunde .wiktku-start-step-keyfield"); populateMenus(dundeMenus, steps.dunde.keys, getDisabledKeys(steps.dunde)); dundeMenus.trigger("chosen:updated"); var zaravaMenus = $("#wiktku-start-zarava .wiktku-start-step-keyfield"); populateMenus(zaravaMenus, steps.zarava.keys, getDisabledKeys(steps.zarava)); }); } mw.loader.using(["jquery.chosen", "mediawiki.api", "oojs-ui-core"], function () { if (!isMobile) { mw.notify( "Amûr dest pê dike, hinek bisekinin. Not: jkx Sentaks (sentaks highlighter) neaktîv bikin", { type: "info", tag: "wiktku-start-notice", autoHide: true, autoHideSeconds: 10 } ); } // Load metadata, langChoices, posChoices and tplDefs from the companion // data page so they can be updated without touching this script. new mw.Api().get({ action: "query", prop: "revisions", titles: "MediaWiki:Gadget-start.js/data.json", rvprop: "content", rvslots: "main", formatversion: 2 }).then(function (data) { var page = data.query.pages[0]; var content = page && page.revisions && page.revisions[0].slots.main.content; var d; try { d = JSON.parse(content); } catch (e) { d = {}; } // Populate metadata. if (d.metadata) $.extend(metadata, d.metadata); // Populate gender labels. if (d.genderLabels) $.extend(GENDER_BASE_LABELS, d.genderLabels); // Populate lang choices (pinned list used by build() → ziman.json loader). if (d.langChoices) steps.lang.choices = d.langChoices; // Populate POS choices. if (d.posChoices) steps.pos.choices = d.posChoices; // Populate template definitions for the dfn sense-block builder. if (d.tplDefs) steps.dfn.tplDefs = d.tplDefs; // Populate pos placeholder examples. if (d.posExamples) steps.dfn.posExamples = d.posExamples; // Populate citation template definitions for the quote widget. if (d.jederDefs) steps.dfn.jederDefs = d.jederDefs; // Populate pronunciation and etymology template insert lists. if (d.pronTpls) { steps.pron.pronTpls = d.pronTpls; steps.pron.refreshTplSelect(); } if (d.etymTpls) { steps.etym.etymTpls = d.etymTpls; steps.etym.refreshTplSelect(); } // Sync trans/dunde/zarava keys with the (now populated) lang choices. steps.trans.keys = steps.lang.choices; steps.dunde.keys = steps.lang.choices; steps.zarava.keys = getZaravaKeys(steps.lang.choices); }).always(build); }); }); //</nowiki> ogrhbycmue1035l4ol2bbbrcllkfgle 6265571 6265570 2026-07-19T14:08:26Z Wikihez 7344 6265571 javascript text/javascript // Li ser [[vi:MediaWiki:Gadget-start.js]] hatiye refaktorkirin. //<nowiki> $(function () { if (window.location.href.includes("editintro=User:Wikihez/creation/intro")) { return; // Do not run the script wextê WF:Bilez dişuxile } var ns = mw.config.get("wgNamespaceNumber"); if (ns && !(ns === 2 && mw.config.get("wgPageName").match(/\/ceribandin$|\/test$/))) { return; } var action = mw.config.get("wgAction"); var pageExists = !!mw.config.get("wgArticleId"); // "Zimanek lê zêde bike" mode: triggered from the portlet link below. var addLangMode = pageExists && mw.util.getParamValue("wiktkuaddlang") === "1"; // On a normal page view of an existing page, add the portlet link if (action === "view" && pageExists) { var targetContainer; var skin = mw.config.get('skin'); if (skin === 'vector-2022') { targetContainer = 'p-cactions'; } else if (skin === 'vector') { targetContainer = 'p-tb'; } else { targetContainer = 'p-views'; } mw.util.addPortletLink(targetContainer, mw.util.getUrl(mw.config.get("wgPageName"), { action: "submit", wiktkuaddlang: "1" }), "+Ziman/beşeke din", "ca-wiktku-addlang", "Ji vê rûpelê re ziman an jî beşeke nû zêde bike"); return; } if (!(action === "edit" || action === "submit")) { return; } if (!addLangMode && !$(".mw-newarticletext, .mw-newarticletextanon").length) { return; } function capitalize(str) { if (!str) return str; return str[0].toUpperCase() + str.substr(1); } function decapitalize(str) { if (!str) return str; return str[0].toLowerCase() + str.substr(1); } function escapeRegExp(str) { return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); } function stripWikilinks(str) { return str.replace(/\[\[([^\]|]+)(?:\|([^\]]+))?\]\]/g, function (m, target, display) { return display || target; }); } function insertAtCursor(el, text) { var start = el.selectionStart; var end = el.selectionEnd; var val = el.value; el.value = val.slice(0, start) + text + val.slice(end); var pos = start + text.length; el.selectionStart = el.selectionEnd = pos; } var pageName = mw.config.get("wgPageName").replaceAll(/_/g, " "); if (ns) pageName = pageName.replace(/.*\//, ""); var pageNameRe = escapeRegExp(pageName); var userLang = mw.config.get("wgUserLanguage"); // Mobile detection: MobileFrontend sets wgMFMode, or fall back to touch check. var isMobile = !!mw.config.get("wgMFMode") || window.matchMedia("(pointer: coarse)").matches; var chosenOptions = { width: "20em", disable_search_threshold: 0, placeholder_text_single: "Yekî hilbijêre", placeholder_text_multiple: "Hilbijêre", no_results_text: "Nehat dîtin", enable_split_word_search: true, search_contains: true }; function wrapNativeSelect(select) { var placeholder = select.attr("data-placeholder") || "Lê bigere…"; // Hide the native select — we drive it programmatically. select.hide(); var wrapper = $("<span class='wiktku-native-select-wrap'></span>"); var textInput = $("<input type='search' autocomplete='off'>") .attr("placeholder", placeholder) .addClass("wiktku-start-narrow wiktku-ac-input"); var resultsList = $("<ul class='wiktku-ac-results'></ul>").hide(); // Full option cache — rebuilt when chosen:updated fires. var allOptions = []; function cacheOptions() { allOptions = []; select.find("option").each(function () { var v = $(this).val(); if (!v) return; // skip the empty placeholder option allOptions.push({ value: v, text: $(this).text(), disabled: $(this).prop("disabled") }); }); } cacheOptions(); function showResults(query) { var q = query.trim().toLowerCase(); resultsList.empty(); var matched; if (q) { matched = []; $.each(allOptions, function (_, o) { if (o.disabled) return; var codeMatch = o.value.toLowerCase().indexOf(q) !== -1; var nameMatch = o.text.toLowerCase().indexOf(q) !== -1; if (codeMatch || nameMatch) { matched.push({ opt: o, codeMatch: codeMatch }); } }); // Code matches (especially prefix matches) come first. matched.sort(function (a, b) { var aCode = a.opt.value.toLowerCase(); var bCode = b.opt.value.toLowerCase(); var aPrefix = aCode.indexOf(q) === 0; var bPrefix = bCode.indexOf(q) === 0; if (aPrefix !== bPrefix) return aPrefix ? -1 : 1; if (a.codeMatch !== b.codeMatch) return a.codeMatch ? -1 : 1; return 0; }); matched = matched.map(function (item) { return item.opt; }); } else { matched = allOptions.filter(function (o) { return !o.disabled; }); } if (!matched.length) { resultsList.hide(); return; } $.each(matched.slice(0, 50), function (_, opt) { var li = $("<li></li>").text(opt.text).attr("data-value", opt.value); // Use touchend instead of touchstart so that a scroll gesture does // not accidentally select an item. We track whether the finger moved // between touchstart and touchend — if it did, it was a scroll. var touchMoved = false; li.on("touchstart", function () { touchMoved = false; }); li.on("touchmove", function () { touchMoved = true; }); li.on("touchend", function (e) { if (touchMoved) return; // was a scroll, not a tap e.preventDefault(); selectOption(opt.value, opt.text); }); // Keep mousedown for desktop fallback. li.on("mousedown", function (e) { e.preventDefault(); selectOption(opt.value, opt.text); }); resultsList.append(li); }); // Position the list above or below depending on available viewport space. var inputRect = textInput[0].getBoundingClientRect(); var viewportH = window.innerHeight; var spaceBelow = viewportH - inputRect.bottom - 8; var spaceAbove = inputRect.top - 8; var maxH = Math.min(224, Math.max(spaceBelow, spaceAbove)); // 224px ≈ 14em resultsList.css({ "max-height": maxH + "px", "top": spaceBelow >= spaceAbove ? "100%" : "auto", "bottom": spaceBelow >= spaceAbove ? "auto" : "100%" }); resultsList.show(); } function selectOption(value, text) { textInput.val(text); select.val(value); resultsList.hide(); select.trigger("change"); } textInput.on("input focus", function () { showResults($(this).val()); }); textInput.on("blur", function () { // Short delay so a touchstart on a result item fires first. setTimeout(function () { resultsList.hide(); }, 200); }); // chosen:updated → re-cache (called after ziman.json loads). select.on("chosen:updated", function () { cacheOptions(); // If a value is already selected, keep the display text in sync. var cur = select.val(); if (cur) { var match = $.grep(allOptions, function (o) { return o.value === cur; })[0]; if (match) textInput.val(match.text); } }); // No-op .chosen() so desktop call-sites don't need guarding. select.chosen = function () { return select; }; wrapper.append(textInput).append(resultsList).append(select); return wrapper; } var langsByCode = {}; // Populated from [[MediaWiki:Gadget-start.js/data.json]] at runtime. var metadata = {}; // Zaravayên kurdî yên ku di beşa "Bi zaravayên din" de tên pêşkêşkirin — // ev kod ji beşa Werger têne derxistin daku heman zimên du caran neyê xwendin. var ZARAVA_LANG_CODES = ["ckb", "sdh", "lki", "hac", "zza"]; function getZaravaKeys(choices) { var byCode = {}; $.each(choices || [], function (_, c) { byCode[c[0]] = c; }); var result = []; $.each(ZARAVA_LANG_CODES, function (_, code) { if (byCode[code]) result.push(byCode[code]); }); return result; } function needsTransliteration(langCode) { var meta = metadata[langCode]; if (!meta || !meta.sc) return false; var scripts = Array.isArray(meta.sc) ? meta.sc : [meta.sc]; return scripts.length > 0 && scripts[0] !== "Latn"; } // Kodên cinsiyetê yên di metadata.g de — ji data.json tê dagirtin var GENDER_BASE_LABELS = {}; // Sub-lists that only make sense for a plain (non-şablon) sense — hidden // when a şablon (e.g. {{guharto|…}}) is chosen for that sense, since a // template-based sense has no "own" gloss for alternate forms, synonyms, // antonyms, coordinate terms, hypernyms or hyponyms to attach to. Etîket, // Nimûne and Jêgirtin stay visible either way. var HIDDEN_ON_TPL_GROUPS = [ "wiktku-dfn-alternativ", "wiktku-dfn-hevmane", "wiktku-dfn-dijmane", "wiktku-dfn-koordine", "wiktku-dfn-jornav", "wiktku-dfn-jernav" ]; function genderLabel(code) { if (code === "p") return "Pirjimar"; var pluralMatch = code.match(/^(.+)-p$/); if (pluralMatch && GENDER_BASE_LABELS[pluralMatch[1]]) { return GENDER_BASE_LABELS[pluralMatch[1]] + " (pirjimar)"; } return GENDER_BASE_LABELS[code] || code; } /** * True if a sense has any content worth keeping besides its mane text — * etîket, hevmane/dijmane/koordîne/etc. word lists, nimûne, or jêder * (quote). Used so a sense with an empty mane but filled-in extra * fields still gets emitted (with {{mane?}} standing in for the gloss) * instead of being silently dropped. */ function senseHasExtraContent(s) { if (s.etiket && $.grep(s.etiket, function (e) { return $.trim(e) !== ""; }).length) return true; if (s.alternativ.length || s.hevmane.length || s.dijmane.length || s.koordine.length || s.jornav.length || s.jernav.length) return true; if (s.nimune && $.grep(s.nimune, function (n) { return (typeof n === "object" ? n.text : n) !== ""; }).length > 0) return true; if (s.jeder && $.grep(s.jeder, function (j) { return j && j.quote; }).length > 0) return true; return false; } /** * formatNimune: each nimûne item can be { text, tr, t }: * text — example text * tr — transliteration (only when the language needs it) * t — Kurdish translation (third positional param, no key) */ function formatNimune(nimunes, lang, hasJeder) { var hasNimune = nimunes && $.grep(nimunes, function (n) { return (typeof n === "object" ? n.text : n) !== ""; }).length > 0; if (!hasNimune) { return hasJeder ? "" : "\n#* {{bênimûne|" + lang + "}}"; } return $.map(nimunes, function (n) { var text = typeof n === "object" ? n.text : n; if (!text) return undefined; var bolded = text.replace( new RegExp("(" + pageNameRe + "([^( |,|;|\\?|\\.|\\!)]+)?)", "ig"), "'''$1'''"); var tpl = "\n#: {{nm|" + lang + "|" + bolded; if (typeof n === "object") { if (n.tr) tpl += "|tr=" + n.tr; // Translation as third positional param (no key needed). if (n.t) tpl += "|" + n.t; } // Short examples fit on one line together with their translation. // rêz=1 is not used for ku — definitions are shown on separate lines there. if (text.length < 200 && lang !== "ku") tpl += "|rêz=1"; tpl += "}}"; return tpl; }).join(""); } /** * Formats a list of jêder (quote/citation) objects into wikitext lines. * Each entry that has no quote text is skipped. Returns "" when the list * is empty or every entry is blank. * * #* {{jêder-…|lang|jêgirtin=…|tr=…|tercime=…|…fields…}} * * When no template is chosen, the generic {{jêder|…}} template is used * instead. Its 2nd positional param is the user's freeform "bi destê xwe * binivîsim" source text when supplied, or the çavkanî? placeholder otherwise. * If that text contains "=" it is passed as |2=… instead of a bare * positional param, since MediaWiki would otherwise misparse it as its * own key=value pair and break the template: * #* {{jêder|lang|jêgirtin=…|tr=…|tercime=…|<manual source or çavkanî?>}} */ function formatJeder(jederList, lang) { if (!jederList || !jederList.length) return ""; return $.map(jederList, function (jeder) { if (!jeder || !jeder.quote) return undefined; if (jeder.jederTpl) { var cite = "\n#* {{" + jeder.jederTpl + "|" + lang; cite += "|jêgirtin=" + jeder.quote; if (jeder.quoteTr) cite += "|tr=" + jeder.quoteTr; if (jeder.quoteT) cite += "|tercime=" + jeder.quoteT; $.each(jeder.jêderFields || {}, function (key, val) { if (val) cite += "|" + key + "=" + val; }); cite += "}}"; return cite; } var out = "\n#* {{jêder|" + lang + "|jêgirtin=" + jeder.quote; if (jeder.quoteTr) out += "|tr=" + jeder.quoteTr; if (jeder.quoteT) out += "|tercime=" + jeder.quoteT; var srcParam = jeder.jederManual ? jeder.jederManual : "çavkanî?"; // A positional param containing "=" gets parsed as its own key=value // pair by MediaWiki and breaks the template, so force it to be // explicitly named (|2=) whenever that's the case. out += (srcParam.indexOf("=") !== -1 ? "|2=" : "|") + srcParam; out += "}}"; return out; }).join(""); } function makeWordListStep(id, name, question_fmt, header, templateName) { return { id: id, name: name, question_fmt: question_fmt, multiple: true, narrow: true, visible: function (values) { return values.lang && values.pos; }, output: function (values) { var words = $.grep(values[id] || [], function (w) { return !!w; }); if (!words.length) return ""; var lang = values.lang; var section = "\n==== " + header + " ====\n"; if (words.length === 1) { // Single word — keep the simple inline template. return section + "* {{" + templateName + "|" + lang + "|" + words[0] + "}}\n"; } // Multiple words — use {{kol3}} with one positional param per word. var params = "cure=" + header + "\n" + $.map(words, function (w) { return "|" + w; }).join("\n"); return section + "{{kol3|" + lang + "|" + params + "\n}}\n"; } }; } var steps = { lang: { id: "lang", required: true, name: "ziman", question_fmt: '"' + pageName + '" bi çi zimanî ye?', question_br: true, // Populated from [[MediaWiki:Gadget-start.js/data.json]] (langChoices). choices: [], output: function (values) { return "== {{ziman|" + values.lang + "}} ==\n"; } }, pron: { id: "pron", name: "bilêvkirin", question_fmt: '"' + pageName + '" çawa tê telafûzkirin?', // pronTpls populated from data.json pronTpls: [], visible: function (values) { if (!values.lang) return false; // In addLangMode, only skip pron when this langcode's section // already exists in the page — if it's a new language, show it. if (addLangMode) { var existing = $("#wpTextbox1").val() || ""; var header = "== {{ziman|" + values.lang + "}} =="; return existing.indexOf(header) === -1; } return true; }, /** Fills (or refills) the insert-dropdown from the current pronTpls array, filtering by language. */ refreshTplSelect: function () { var sel = $("#wiktku-start-pron .wiktku-tpl-insert-select"); if (!sel.length) return; var lang = getValues().lang || ""; sel.find("option[value!='']").remove(); $.each(steps.pron.pronTpls, function (_, tpl) { // Filter: if tpl.langs exists, only show if lang is in that list; otherwise show always var allowed = !tpl.langs || tpl.langs.indexOf(lang) !== -1; if (allowed) { sel.append($("<option></option>") .val(tpl.snippet) .text(tpl.name + " — " + tpl.desc) .attr("data-nolang", tpl.noLang ? "1" : "")); } }); // Notify Chosen that the option list has changed (no-op on mobile). if (!isMobile) sel.trigger("chosen:updated"); }, build: function (stepDiv) { if (stepDiv.find(".wiktku-pron-wrap").length) return null; var wrap = $("<div class='wiktku-pron-wrap'></div>"); var ta = $("<textarea></textarea>") .attr("name", "wiktku-pron-" + $.now()) .attr("class", "wiktku-start-step-field wiktku-pron-text") .attr("rows", 4) .attr("placeholder", "Nimûne: {{IPA|ku|/pɛɪ̯n/}} yan {{kîte|ku|he|ce|ki|rin}}"); // Template insert dropdown — filtered by language. var sel = $("<select class='wiktku-tpl-insert-select'></select>"); sel.append($("<option value=''>— şablonek lê zêde bike —</option>")); var lang = getValues().lang || ""; $.each(steps.pron.pronTpls, function (_, tpl) { // Filter: if tpl.langs exists, only show if lang is in that list; otherwise show always var allowed = !tpl.langs || tpl.langs.indexOf(lang) !== -1; if (allowed) { sel.append($("<option></option>") .val(tpl.snippet) .text(tpl.name + " — " + tpl.desc) .attr("data-nolang", tpl.noLang ? "1" : "")); } }); sel.on("change", function () { var snippet = $(this).val(); if (!snippet) return; var lang = getValues().lang || ""; // Check if the selected option has noLang flag var selectedOption = sel.find("option:selected"); var hasNoLang = selectedOption.attr("data-nolang") === "1"; if (!hasNoLang) { snippet = snippet.replace(/CODE/g, lang).replace(/SOURCELANG/g, "?"); } insertAtCursor(ta[0], snippet); $(this).val(""); ta.focus(); }); wrap.append(sel).append($("<br>")).append(ta); stepDiv.append(wrap); return ta; }, output: function () { var text = $.trim($("#wiktku-start-pron .wiktku-pron-text").val()); if (!text) return ""; var lines = text.split("\n"); var out = $.map(lines, function (line) { line = $.trim(line); if (!line) return undefined; return line.charAt(0) === "*" ? line : "* " + line; }).join("\n"); return "\n=== Bilêvkirin ===\n" + out + "\n"; } }, pos: { id: "pos", required: true, name: "Cureyê rêzimanî", question_fmt: 'Cureyê rêzimanî yê "' + pageName + '" çi ye?', visible: function (values) { return values.lang; }, question_br: true, // Populated from [[MediaWiki:Gadget-start.js/data.json]] (posChoices). choices: [], output: function (values) { var pos = values.pos || ""; var cinsiyet = values.cinsiyet || ""; // from the cinsiyet step var lekTur = values.lektur || ""; // from the lêker transitivity step var capitalizedPos = capitalize(pos); var outputString = "\n=== " + capitalizedPos + " ===\n"; // Add ku-tewîn-nav for single-word navdêr/serenav with known gender. if (!pageName.includes(" ") && cinsiyet && GENDER_BASE_LABELS[cinsiyet] && (pos === "navdêr" || pos === "serenav") && values.lang === "ku") { outputString += "{{ku-tewîn-nav|" + pageName + "|" + GENDER_BASE_LABELS[cinsiyet]; if (pos === "serenav") outputString += "|y"; outputString += "}}\n"; } outputString += "{{" + pos + "|" + values.lang; if (pos === "navdêr" || pos === "serenav") { if (cinsiyet) { outputString += "|c=" + cinsiyet; } else if (values.lang === "ku") { // Unknown gender — prompt editor to fill it in. outputString += "|c=?"; } } else if (/^lêker/.test(pos) && lekTur) { outputString += "|c=" + lekTur; } if (values.tr) { outputString += "|tr=" + values.tr; } outputString += "}}\n"; return outputString; } }, /** * cinsiyet (grammatical gender) — only shown for navdêr/serenav, û * tenê ger metadata ji bo zimanê hilbijartî lîsteyeke "g" (cinsiyet) * were dayîn. Opsiyonên vê gavê ne sabît in — ji metadata[values.lang].g * têne çêkirin, ji ber ku di hemû zimanan de cinsiyet tine. */ cinsiyet: { id: "cinsiyet", name: "cinsiyet", question_fmt: 'Cinsiyeta "' + pageName + '" çi ye?', question_br: true, visible: function (values) { var meta = metadata[values.lang]; return !!(values.lang && (values.pos === "navdêr" || values.pos === "serenav") && meta && meta.g && meta.g.length); }, build: function (stepDiv, values) { var select = stepDiv.find("select.wiktku-start-step-field"); if (!select.length) { select = $(mw.html.element("select", { "class": "wiktku-start-step-field", id: "wiktku-start-cinsiyet-field" })); stepDiv.append(select); } if (!values) return select; var meta = metadata[values.lang]; var codes = (meta && meta.g) || []; var prevVal = select.val(); var choices = $.map(codes, function (code) { return [[code, genderLabel(code)]]; }); populateMenus(select, choices); if ($.grep(choices, function (c) { return c[0] === prevVal; }).length) { select.val(prevVal); } if (!isMobile) select.trigger("chosen:updated"); return select; }, output: function () { return ""; } // consumed by pos.output }, /** * Lêker transitivity — only shown for any lêker variant. */ lektur: { id: "lektur", name: "Cureyê lêkerê (fiîlê)", question_fmt: "Cureyê lêkerê (fiîlê) çi ye?", question_br: true, visible: function (values) { return values.lang && values.pos && /^lêker/.test(values.pos); }, // Dictionary: value → display label. Add new types here. choices: [ ["gh", "gerguhêz"], ['x-gh', 'xwerû-gerguhêz'], ['p-gh', 'pêkhatî-gerguhêz'], ['h-gh', 'hevedudanî-gerguhêz'], ['b-gh', 'biwêjî-gerguhêz'], ["ngh", "negerguhêz"], ['x-ngh', 'xwerû-negerguhêz'], ['p-ngh', 'pêkhatî-negerguhêz'], ['h-ngh', 'hevedudanî-negerguhêz'], ['b-ngh', 'biwêjî-negerguhêz'] ], output: function () { return ""; } // consumed by pos.output }, tr: { id: "tr", name: "transkrîpsiyon", question_fmt: "Transkrîpsiyona kelîmeyê", multiple: false, narrow: true, visible: function (values) { return values.lang && values.pos && needsTransliteration(values.lang); } }, dfn: { id: "dfn", // required: true, ger mane tinebe [[Şablon:mane?]] bi kar bîne name: "Mane", question_fmt: "Maneya kelîmeyê binivîse. Mane otomatîk tê lînkkirin! Ji bo tercimeyan beşa 'Werger' bi kar bîne!", multiple: true, ordered: true, rows: 3, visible: function (values) { return values.lang && values.pos; }, example: function (values) { // posExamples loaded from [[MediaWiki:Gadget-start.js/data.json]]. var examples = steps.dfn.posExamples || {}; var full = values.pos || ""; return examples[full] || ""; }, /** * Builds one sense block (<li>) inside the ordered list. * Each block contains: * - a textarea for the definition * - an expandable nimûne list * - single-row sub-lists for formên alternatîv, hevmane, dijmane */ buildSenseBlock: function (stepDiv) { var block = $("<li class='wiktku-dfn-sense'></li>"); // — Mane textarea (declared first so the template handler can reference it) — var dfnArea = $("<textarea></textarea>") .attr("name", "wiktku-dfn-mane-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("class", "wiktku-start-step-field wiktku-dfn-mane") .attr("rows", 6) .attr("placeholder", "Mane…"); dfnArea.on("input", function () { steps.dfn.onDfnInput(stepDiv, block, this); }); // — Template selector (optional — replaces mane when chosen) — // Template definitions loaded from [[MediaWiki:Gadget-start.js/data.json]]. var tplDefs = steps.dfn.tplDefs || []; // Cache of all non-placeholder option elements — used by updateTplOptions // to remove/re-add options (the only approach compatible with Chosen.js). var _allTplOptions = []; var tplSelect = $(mw.html.element("select", { "class": "wiktku-dfn-tpl-select" })); tplSelect.append($("<option value=''>— yan jî şablonek hilbijêre —</option>")); $.each(tplDefs, function (_, tpl) { var opt = $("<option></option>") .val(tpl.name) .text(tpl.name) .attr("data-langs", tpl.langs ? tpl.langs.join(",") : "") .attr("data-nolang", tpl.noLang ? "1" : ""); tplSelect.append(opt); _allTplOptions.push(opt[0]); }); function updateTplOptions() { var lang = getValues().lang || ""; var currentVal = tplSelect.val(); var currentStillValid = false; // Detach all non-placeholder options, then re-attach only the visible ones. // This is the only approach that works correctly with both native <select> // and Chosen.js on desktop. tplSelect.find("option[value!='']").detach(); $.each(_allTplOptions, function (_, opt) { var allowed = $(opt).attr("data-langs"); var visible = !allowed || allowed.split(",").indexOf(lang) !== -1; if (visible) { tplSelect.append(opt); if ($(opt).val() === currentVal) currentStillValid = true; } }); if (!isMobile) tplSelect.trigger("chosen:updated"); if (currentVal && !currentStillValid) { tplSelect.val(""); dfnArea.show(); tplTitleInput.hide().val(""); } } // Store updater on the element so refresh() can call it for all blocks. tplSelect.data("updateOptions", updateTplOptions); var tplTitleInput = $("<input type='text'>") .addClass("wiktku-dfn-tpl-title wiktku-start-narrow") .attr("placeholder", "Navê rûpelê…") .hide(); // Grow the sense list when the title field of the last block gets content, // mirroring what onDfnInput does for the plain mane textarea. tplTitleInput.on("input", function () { steps.dfn.onDfnInput(stepDiv, block, this); }); /** * When a şablon sense is chosen, formên alternatîv/hevmane/dijmane/ * termên koordîne/jornav/jêrnav don't apply (there's no plain gloss * to hang them off), so hide those subgroups. Etîket, Nimûne and * Jêgirtin stay visible and still usable for a şablon sense. */ function updateFieldVisibility() { var isTpl = !!tplSelect.val(); $.each(HIDDEN_ON_TPL_GROUPS, function (_, cls) { block.find("." + cls + "-group").toggle(!isTpl); }); } // Store on the block so restoreDfn() can re-sync visibility // after programmatically setting tplSelect's value. block.data("updateFieldVisibility", updateFieldVisibility); tplSelect.on("change", function () { var chosen = $(this).val(); if (chosen) { dfnArea.hide(); tplTitleInput.show().focus(); } else { dfnArea.show(); tplTitleInput.hide().val(""); } updateFieldVisibility(); // Re-run refresh so the Werger step visibility updates. refresh(); }); var tplRow = $("<div></div>").addClass("wiktku-dfn-tpl-row") .append(tplSelect).append(" ").append(tplTitleInput); block.append(tplRow); block.append(dfnArea); // Apply lang filter on initial build. updateTplOptions(); // — Sub-field groups — // All groups are always visible with a placeholder textarea. // Nimûne is last in the DOM and last in the output. var allGroups = [ { cls: "wiktku-dfn-etiket", label: "Etîket", rows: 1, narrow: true, izah: "xisûsen, Mêrdîn, anatomî, Badînî" }, { cls: "wiktku-dfn-alternativ", label: "Formên alternatîv", rows: 1, narrow: true, izah: "Varyantên vê kelîmeyê" }, { cls: "wiktku-dfn-hevmane", label: "Hevmane", rows: 1, narrow: true, izah: "Spehî hevmaneya Bedew e." }, { cls: "wiktku-dfn-dijmane", label: "Dijmane", rows: 1, narrow: true, izah: "Zengîn dijmaneya feqîr e." }, { cls: "wiktku-dfn-koordine", label: "Termên koordîne", rows: 1, narrow: true, izah: "Pisîk û kûçik termên koordîne ne çunkî Jornavên wan gelek in" }, { cls: "wiktku-dfn-jornav", label: "Jornav", rows: 1, narrow: true, izah: "Heywan jornavê guhandar e" }, { cls: "wiktku-dfn-jernav", label: "Jêrnav", rows: 1, narrow: true, izah: "Guhandar jêrnavê heywan e" }, { cls: "wiktku-dfn-nimune", label: "Nimûne", rows: 2, narrow: false } ]; $.each(allGroups, function (_, g) { var groupDiv = $("<div></div>").addClass("wiktku-dfn-subgroup " + g.cls + "-group"); function buildNimuneLi() { var lang = getValues().lang || ""; var li = $("<li></li>").addClass("wiktku-dfn-nimune-li"); var mainTa = $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-text-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", g.rows) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-text") .attr("placeholder", "Nimûneya emilandina kelîmeyê tu bi xwe binivîse…"); mainTa.on("input", function () { var val = $.trim($(this).val()); var isLast = li.is(list.children("li:last-child")); if (val && isLast) { list.append(buildNimuneLi()); } }); li.append(mainTa); var subWrap = $("<div></div>").addClass("wiktku-dfn-nimune-sub"); if (needsTransliteration(lang)) { subWrap.append( $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-tr-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 5) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-tr") .attr("placeholder", "Transkrîpsiyona bi alfabeya latînî") ); } if (lang && lang !== "ku") { subWrap.append( $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-t-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 5) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-t") .attr("placeholder", "Tercimeya kurmancî") ); } if (subWrap.children().length) li.append(subWrap); return li; } if (g.cls === "wiktku-dfn-nimune") { // Nimûne — compound widget with tr/t sub-fields. var lbl = $("<span></span>").addClass("wiktku-dfn-sublabel").text(g.label + ": "); var list = $("<ol></ol>").addClass("wiktku-dfn-sublist " + g.cls + "-list"); groupDiv.data("buildNimuneLi", buildNimuneLi); list.append(buildNimuneLi()); groupDiv.append(lbl).append(list); block.append(groupDiv); } else { // Regular always-visible group — label + growing textarea list. var lbl = $("<span></span>").addClass("wiktku-dfn-sublabel").text(g.label + ": " + g.izah); var list = $("<ol></ol>").addClass("wiktku-dfn-sublist " + g.cls + "-list"); var firstInput = $("<textarea></textarea>") .attr("name", g.cls + "-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", g.rows) .attr("class", "wiktku-dfn-subfield" + (g.narrow ? " wiktku-start-narrow" : "")) .attr("placeholder", g.label + "…"); firstInput.on("input", function () { steps.dfn.onSubInput(list, this, g.rows, g.narrow); }); list.append($("<li></li>").append(firstInput)); groupDiv.append(lbl).append(list); block.append(groupDiv); } }); // — Jêder (quote / citation) group — a growing list, sibling to Nimûne — // Structured the same way as Nimûne (ol.wiktku-dfn-sublist > li) so it // lines up at the same indentation, and so that typing into the last // citation's Jêgirtin box automatically opens a fresh empty one below it. (function () { var jederGroupDiv = $("<div></div>").addClass("wiktku-dfn-subgroup wiktku-dfn-jeder-group"); var jederLbl = $("<span></span>").addClass("wiktku-dfn-sublabel").text("Jêgirtin: "); var jederList = $("<ol></ol>").addClass("wiktku-dfn-sublist wiktku-dfn-jeder-list"); function buildJederLi() { var lang = getValues().lang || ""; var li = $("<li></li>").addClass("wiktku-dfn-jeder-li"); var dragHandle = $("<span></span>") .addClass("wiktku-jeder-drag-handle") .attr("title", "Bişkûne û bikişîne da ku rêzê biguhezîne"); // Quote text textarea var quoteTa = $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-quote-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 2) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-quote") .attr("placeholder", "Nimûneya emilandinê ji kitêb an çavkaniyeke din binivîse"); quoteTa.on("input", function () { var val = $.trim($(this).val()); var isLast = li.is(jederList.children("li:last-child")); if (val && isLast) { jederList.append(buildJederLi()); } }); li.append(dragHandle).append(quoteTa); // tr/t sub-fields for the quote — shown as needed for the language. var quoteSubWrap = $("<div></div>").addClass("wiktku-dfn-quote-sub"); if (needsTransliteration(lang)) { quoteSubWrap.append( $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-quote-tr-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 2) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-quote-tr") .attr("placeholder", "Transkrîpsiyona jêgirtinê…") ); } if (lang && lang !== "ku") { quoteSubWrap.append( $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-quote-t-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 2) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-quote-t") .attr("placeholder", "Tercimeya jêgirtinê bi kurmancî") ); } if (quoteSubWrap.children().length) li.append(quoteSubWrap); // Citoid auto-fill: fetch citation data from a URL, DOI or ISBN and // prefill the source şablon + fields below (see Gadget-citoid-helper.js). var citoidWrap = $("<div></div>").addClass("wiktku-dfn-quote-citoid"); var citoidInput = $("<input type='text'>") .addClass("wiktku-dfn-quote-citoid-input wiktku-start-narrow") .attr("placeholder", "URL, DOI an ISBN binivîse ku otomatîk were tijekirin…"); var citoidBtn = new OO.ui.ButtonWidget({ label: "Bi Citoid bîne", classes: [ "wiktku-dfn-quote-citoid-btn" ] }); var citoidStatus = $("<span></span>").addClass("wiktku-dfn-quote-citoid-status"); /** * Fetches citation data from Citoid and applies it to this * citation's şablon selector + fields. Mirrors the logic in * Form.prototype._fillFromCitoid (Gadget-wikt.add-examples.js): * - only (re)selects the şablon when it actually differs from * what's already chosen, so a repeat fetch doesn't wipe out * a template the user already picked; * - only fills fields that are currently empty, so it never * overwrites something the user typed by hand; * - falls back to the freeform "bi destê xwe binivîsim" source * only when nothing was typed there yet. */ function runCitoidFetch() { var query = $.trim(citoidInput.val()); if (!query) { mw.notify("Ji kerema xwe re pêşî URL, DOI an ISBNyekê binivîse."); return; } citoidBtn.setDisabled(true); citoidStatus.text("Tê anîn…"); wikt.citoidHelper.ensure().then(function () { return wikt.citoid.fetchJederFields(query); }).then(function (result) { var jederKey = result.jederKey; var hasTpl = !!jederKey && srcSel.find("option[value='" + jederKey + "']").length > 0; var targetVal = hasTpl ? jederKey : "__manual__"; // Only (re)select — and thus rebuild — the field rows if // we're switching to a different şablon than what's // already chosen, so a second fetch doesn't clear fields // the user already filled in by hand. if (srcSel.val() !== targetVal) { srcSel.val(targetVal).trigger("change"); srcSel.trigger("chosen:updated"); } if (hasTpl) { // Tenê qadên vala tijî bike. $.each(result.fields, function (key, val) { var input = srcFields.find("[data-field-key='" + key + "']"); if (input.length && !$.trim(input.val())) { input.val(val); } }); } else { // Şablonek nehat naskirin ji bo vê itemType — rêzikeke // çavkaniyê ya bi destan a ji qadên Citoid tê çêkirin, // lê tenê ger qada destan vala be. var manualField = srcFields.find(".wiktku-dfn-quote-src-manual"); if (!$.trim(manualField.val())) { var parts = []; $.each(["nivîskar", "sernav", "websîte", "kovar", "weşanxane", "sal", "url"], function (_, k) { if (result.fields[k]) parts.push(result.fields[k]); }); manualField.val(parts.join(", ")); } } citoidStatus.text(""); }, function (errorMsg) { citoidStatus.text(typeof errorMsg === "string" ? errorMsg : "Nehat dîtin. Kontrol bike ka URL/DOI/ISBN rast e."); }).always(function () { citoidBtn.setDisabled(false); }); } citoidBtn.on("click", runCitoidFetch); citoidInput.on("keydown", function (e) { if (e.which === 13) { // Enter e.preventDefault(); runCitoidFetch(); } }); citoidWrap.append(citoidInput).append(citoidBtn.$element).append(citoidStatus); // Source template selector, specific to this citation. var srcSel = $("<select></select>").addClass("wiktku-dfn-quote-src-sel"); srcSel.append($("<option value=''>— Çavkaniyê hilbijêre —</option>")); srcSel.append($("<option></option>").val("__manual__").text("Bi destê xwe binivîsim")); var jederDefs = steps.dfn.jederDefs || {}; $.each(jederDefs, function (tplName, def) { srcSel.append($("<option></option>").val(tplName).text(def.label)); }); // Dynamic source fields container. var srcFields = $("<div></div>").addClass("wiktku-dfn-quote-src-fields"); srcSel.on("change", function () { srcFields.empty(); var chosen = $(this).val(); if (!chosen) return; if (chosen === "__manual__") { // Freeform source, written by the user — becomes the 2nd // positional param of {{jêder|lang|…}} instead of çavkanî?. srcFields.append( $("<textarea></textarea>") .attr("rows", 4) .addClass("wiktku-dfn-subfield wiktku-dfn-quote-src-manual") .attr("placeholder", "Çavkaniyê bi destê xwe binivîse…") ); return; } var def = (steps.dfn.jederDefs || {})[chosen]; if (!def) return; $.each(def.fields, function (_, f) { var row = $("<div></div>").addClass("wiktku-dfn-quote-src-row"); var fieldLbl = $("<label></label>").text(f.label + ": "); var inp = $("<textarea></textarea>") .attr("rows", 2) .addClass("wiktku-dfn-quote-src-input wiktku-start-narrow") .attr("data-field-key", f.key) .attr("placeholder", f.label + "…"); row.append(fieldLbl).append(inp); srcFields.append(row); }); }); li.append(citoidWrap).append(srcSel).append(srcFields); return li; } jederGroupDiv.data("buildJederLi", buildJederLi); jederList.append(buildJederLi()); // Make citation rows sortable (drag to reorder). // The last row is always the empty trailing row — cancel its drag. mw.loader.using("jquery.ui.sortable", function () { jederList.sortable({ handle: ".wiktku-jeder-drag-handle", axis: "y", items: "li:not(:last-child)", tolerance: "pointer" }); }); jederGroupDiv.append(jederLbl).append(jederList); block.append(jederGroupDiv); }()); // Apply the initial hide/show state for the sub-groups (matches // tplSelect's starting value, which is normally empty). updateFieldVisibility(); return block; }, /** Grows the sense list when the last mane textarea gets content. */ onDfnInput: function (stepDiv, block, textarea) { var val = $.trim($(textarea).val()); var list = stepDiv.find("ol.wiktku-dfn-list"); var isLast = block.is(list.children("li:last-child")); if (val && isLast) { var newBlock = steps.dfn.buildSenseBlock(stepDiv); list.append(newBlock); // Apply Chosen to the new block's template selector on desktop. if (!isMobile) newBlock.find("select.wiktku-dfn-tpl-select").chosen(chosenOptions); } refresh(); }, /** Grows a sub-list (nimûne/formên alternatîv/hevmane/dijmane/termên koordîne) on input. */ onSubInput: function (list, input, rows, narrow) { var val = $.trim($(input).val()); var item = $(input).parent(); var isLast = item.is(list.children("li:last-child")); if (val && isLast) { var next = $("<textarea></textarea>") .attr("name", "wiktku-dfn-sub-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", rows) .attr("class", "wiktku-dfn-subfield" + (narrow ? " wiktku-start-narrow" : "")); next.on("input", function () { steps.dfn.onSubInput(list, this, rows, narrow); }); list.append($("<li></li>").append(next)); } }, // Populated from [[MediaWiki:Gadget-start.js/data.json]] (tplDefs, posExamples, jederDefs). tplDefs: [], posExamples: {}, jederDefs: {}, build: function (stepDiv) { if (stepDiv.find("ol.wiktku-dfn-list").length) return null; var list = $("<ol class='wiktku-dfn-list'></ol>"); list.append(steps.dfn.buildSenseBlock(stepDiv)); stepDiv.append(list); return null; }, /** Reads all sense blocks from the DOM and returns an array of sense objects. */ getSenses: function (stepDiv) { var senses = []; stepDiv.find("li.wiktku-dfn-sense").each(function () { var block = $(this); var tplSel = block.find("select.wiktku-dfn-tpl-select"); var tpl = tplSel.val() || ""; // noLang: template already encodes the language — don't add |lang| param. var tplNoLang = tpl ? tplSel.find("option[value='" + tpl + "']").attr("data-nolang") === "1" : false; var tplTitle = $.trim(block.find("input.wiktku-dfn-tpl-title").val()); var mane = $.trim(block.find("textarea.wiktku-dfn-mane").val()); var etiket = (function () { var vals = []; block.find(".wiktku-dfn-etiket-list textarea").each(function () { var v = $.trim($(this).val()); if (v) vals.push(v); }); return vals; }()); function readList(cls) { var vals = []; block.find("." + cls + "-list textarea").each(function () { var v = $.trim($(this).val()); if (v) vals.push(v); }); return vals; } // Nimûne items are compound: { text, tr?, t? } function readNimuneList() { var items = []; block.find(".wiktku-dfn-nimune-list li.wiktku-dfn-nimune-li").each(function () { var text = $.trim($(this).find(".wiktku-dfn-nimune-text").val()); if (!text) return; var obj = { text: text }; var tr = $.trim($(this).find(".wiktku-dfn-nimune-tr").val()); var t = $.trim($(this).find(".wiktku-dfn-nimune-t").val()); if (tr) obj.tr = tr; if (t) obj.t = t; items.push(obj); }); return items; } // Jêder is a growing list of citations, one per li — mirrors readNimuneList(). function readJederList() { var items = []; block.find(".wiktku-dfn-jeder-list li.wiktku-dfn-jeder-li").each(function () { var li = $(this); var quote = $.trim(li.find(".wiktku-dfn-nimune-quote").val()); if (!quote) return; var obj = { quote: quote }; var qtr = $.trim(li.find(".wiktku-dfn-nimune-quote-tr").val()); var qt = $.trim(li.find(".wiktku-dfn-nimune-quote-t").val()); if (qtr) obj.quoteTr = qtr; if (qt) obj.quoteT = qt; var tplName = li.find(".wiktku-dfn-quote-src-sel").val(); if (tplName === "__manual__") { var manual = $.trim(li.find(".wiktku-dfn-quote-src-manual").val()); if (manual) obj.jederManual = manual; } else if (tplName) { obj.jederTpl = tplName; var fields = {}; li.find(".wiktku-dfn-quote-src-input").each(function () { var k = $(this).attr("data-field-key"); var v = $.trim($(this).val()); if (k && v) fields[k] = v; }); obj.jêderFields = fields; } items.push(obj); }); return items; } senses.push({ tpl: tpl, tplNoLang: tplNoLang, tplTitle: tplTitle, mane: mane, etiket: etiket, nimune: readNimuneList(), jeder: readJederList(), alternativ: readList("wiktku-dfn-alternativ"), hevmane: readList("wiktku-dfn-hevmane"), dijmane: readList("wiktku-dfn-dijmane"), koordine: readList("wiktku-dfn-koordine"), jornav: readList("wiktku-dfn-jornav"), jernav: readList("wiktku-dfn-jernav") }); }); return senses; }, getOutput: function (values, callback) { var stepDiv = $("#wiktku-start-dfn"); var senses = steps.dfn.getSenses(stepDiv); var lang = values.lang; // A sense counts as "filled" if it has a mane, a chosen template + title, // or any other content (etîket/hevmane/nimûne/jêder…) worth keeping. var hasMane = senses.some(function (s) { return s.mane !== "" || (s.tpl && s.tplTitle) || senseHasExtraContent(s); }); // True only when at least one sense has a regular mane (needs linkify). var hasRegularMane = senses.some(function (s) { return !s.tpl && s.mane !== ""; }); // nimûne and jêder lines must never pass through linkify — only // the plain mane text should be linkified. We build two parallel // arrays: defLines (sent to linkify) and citeLines (kept aside). // Each entry in citeLines corresponds 1-to-1 with a defLines entry; // a template token {{wiktku-cite-N}} is embedded in defLines so // that after linkify runs we know exactly where to splice them back. // Template-call syntax is guaranteed safe: linkifiers leave {{ }} // tokens completely untouched. var defLines = []; // one entry per kept sense (goes to linkify) var citeLines = []; // parallel — nimûne+jêder for that same sense $.each(senses, function (_, sense) { // — Template sense (e.g. {{guharto|ku|somepage}}) — if (sense.tpl) { if (!sense.tplTitle) return; // skip empty template senses var tplLabelTpl = ""; if (sense.etiket && sense.etiket.length) { var tplLabelParts = sense.etiket.map(function (part) { return $.trim(part); }).filter(function (part) { return part !== ""; }); if (tplLabelParts.length) { tplLabelTpl = " {{e|" + lang + "|" + tplLabelParts.join("|") + "}} "; } } var tplCall = sense.tplNoLang ? "{{" + sense.tpl + "|" + sense.tplTitle + "}}" : "{{" + sense.tpl + "|" + lang + "|" + sense.tplTitle + "}}"; var tplHasJeder = sense.jeder && $.grep(sense.jeder, function (j) { return j && j.quote; }).length > 0; var idx = defLines.length; var cite = formatNimune(sense.nimune, lang, tplHasJeder) + formatJeder(sense.jeder, lang); defLines.push("#" + (tplLabelTpl ? tplLabelTpl : " ") + tplCall + (cite ? "{{wiktku-cite-" + idx + "}}" : "")); citeLines.push(cite); return; } // — Normal mane sense — var dfn = sense.mane; if (!dfn && !senseHasExtraContent(sense)) return; // truly empty if (dfn) { dfn = stripWikilinks(dfn); if (dfn[0] !== dfn[0].toUpperCase()) dfn = capitalize(dfn); if (!dfn.match(/[.…?!)\]]$/)) dfn += "."; } else { dfn = "{{mane?|" + lang + "}}"; } var labelTpl = ""; if (sense.etiket && sense.etiket.length) { var labelParts = sense.etiket.map(function (part) { return $.trim(part); }).filter(function (part) { return part !== ""; }); if (labelParts.length) { labelTpl = " {{e|" + lang + "|" + labelParts.join("|") + "}} "; } } var out = "#" + (labelTpl ? labelTpl : " ") + dfn; function wordLine(tpl, words) { if (!words.length) return ""; return "\n#: {{" + tpl + "|" + lang + "|" + words.join("|") + "}}"; } out += wordLine("alt-r", sense.alternativ); out += wordLine("hevmane", sense.hevmane); out += wordLine("dijmane", sense.dijmane); out += wordLine("koordîne", sense.koordine); out += wordLine("jornav", sense.jornav); out += wordLine("jêrnav", sense.jernav); var hasJeder = sense.jeder && $.grep(sense.jeder, function (j) { return j && j.quote; }).length > 0; var cite = formatNimune(sense.nimune, lang, hasJeder) + formatJeder(sense.jeder, lang); var idx = defLines.length; defLines.push(out + (cite ? "{{wiktku-cite-" + idx + "}}" : "")); citeLines.push(cite); }); // Splice citeLines back into a linkified string, replacing each // {{wiktku-cite-N}} token with its stored nimûne/jêder block. function restoreCites(t) { return t.replace(/\{\{wiktku-cite-(\d+)\}\}/g, function (_, n) { return citeLines[parseInt(n, 10)] || ""; }); } var text = defLines.join("\n") + "\n"; if (!hasMane) { // No definitions entered — emit {{mane?}} with bênimûne. text = "# {{mane?|" + lang + "}}\n#* {{bênimûne|" + lang + "}}\n"; callback(text); return; } if (!hasRegularMane) { // All filled senses are template senses — no linkify needed. callback(restoreCites(text)); return; } var didTryToLoad = function () { if (typeof $.wiktviLinkify === "function") { $.wiktviLinkify(text, function (linked) { callback(restoreCites(linked)); }); } else { callback(restoreCites(text)); } }; mw.loader.using("ext.gadget.linkify", didTryToLoad, didTryToLoad); } }, je: makeWordListStep("je", "jê", "Kelîmeyên jê çêbûyî binivîse", "Jê", "g"), tekildar: makeWordListStep("tekildar", "têkildar", "Kelîmeyên ji aliyê etîmolojiyê ve têkildarî vê kelîmeyê binivîse", "Têkildar", "g"), binereherwiha: makeWordListStep("binereherwiha", "binêre herwiha", "Kelîmeyên din ên eleqedar binivîse", "Binêre herwiha", "g"), etym: { id: "etym", name: "etîmolojî", question_fmt: "Etîmolojiya kelîmeyê binivîse", // etymTpls populated from data.json etymTpls: [], visible: function (values) { return values.lang && values.pos; }, /** Fills (or refills) the insert-dropdown from the current etymTpls array. */ refreshTplSelect: function () { var sel = $("#wiktku-start-etym .wiktku-tpl-insert-select"); if (!sel.length) return; sel.find("option[value!='']").remove(); $.each(steps.etym.etymTpls, function (_, tpl) { sel.append($("<option></option>").val(tpl.snippet).text(tpl.name + " — " + tpl.desc)); }); // Notify Chosen that the option list has changed (no-op on mobile). if (!isMobile) sel.trigger("chosen:updated"); }, build: function (stepDiv) { if (stepDiv.find(".wiktku-etym-wrap").length) return null; var wrap = $("<div class='wiktku-etym-wrap'></div>"); var ta = $("<textarea></textarea>") .attr("name", "wiktku-etym-" + $.now()) .attr("class", "wiktku-start-step-field wiktku-etym-text") .attr("rows", 4) .attr("placeholder", "Nimûne: Ji {{ji|en|ku|apple}}. yan rasterast binivîse…"); // Template insert dropdown — options also refreshed after data.json loads. var sel = $("<select class='wiktku-tpl-insert-select'></select>"); sel.append($("<option value=''>— şablonek lê zêde bike —</option>")); $.each(steps.etym.etymTpls, function (_, tpl) { sel.append($("<option></option>").val(tpl.snippet).text(tpl.name + " — " + tpl.desc)); }); sel.on("change", function () { var snippet = $(this).val(); if (!snippet) return; var lang = getValues().lang || ""; snippet = snippet.replace(/CODE/g, lang).replace(/SOURCELANG/g, "?"); insertAtCursor(ta[0], snippet); $(this).val(""); ta.focus(); }); wrap.append(sel).append($("<br>")).append(ta); stepDiv.append(wrap); return ta; }, output: function (values) { var text = $.trim($("#wiktku-start-etym .wiktku-etym-text").val()); if (text) { return "\n==== Etîmolojî ====\n" + text + "\n"; } // No etymology entered — emit {{ji?|lang}} as a placeholder, // but only when the entry has at least one regular (non-şablon) // sense with content — either real mane text, or an empty mane // with other fields filled in (which dfn.getOutput() renders as // {{mane?|lang}} with those fields attached). A şablon sense // like {{guharto|…}} never counts, filled in or not. var dfnSenses = steps.dfn.getSenses($("#wiktku-start-dfn")); var hasRegularMane = dfnSenses.some(function (s) { return !s.tpl && (s.mane !== "" || senseHasExtraContent(s)); }); if (!hasRegularMane) return ""; return "\n==== Etîmolojî ====\n{{ji?|" + values.lang + "}}\n"; } }, dunde: { id: "dunde", name: "dûnde", question_fmt: "Eger ev kelîme ji vî zimanî ketibe zimanekî din, vî zimanî û kelîmeya wî binivîse", visible: function (values) { return !!values.pos; }, disabledKeys: { "navz": true}, /** * Builds one row: a language dropdown + a growing list of word * inputs. When the dropdown gets a value the next empty row is * appended automatically. Mirrors steps.trans's row widget, but * flat (one shared list — dûnde isn't tied to individual senses). */ buildRow: function (stepDiv) { var row = $("<li class='wiktku-dunde-row wiktku-lang-row'></li>"); // Language selector — chosen is applied after insertion into DOM. var langSel = $(mw.html.element("select", { "class": "wiktku-start-step-keyfield wiktku-start-narrow" })); langSel.attr("data-placeholder", "Zimanekî lê bigere"); populateMenus(langSel, steps.dunde.keys || [], steps.dunde.disabledKeys); // When a language is chosen, ensure a next empty row exists. langSel.on("change", function () { steps.dunde.onLangChange(stepDiv, row); }); // Word list for this language. var wordList = $("<ul class='wiktku-dunde-words wiktku-lang-row-words'></ul>"); var firstWord = steps.dunde.makeWordInput(); wordList.append($("<li></li>").append(firstWord)); if (isMobile) { row.append(wrapNativeSelect(langSel)).append(wordList); } else { row.append(langSel).append(wordList); } return row; }, makeWordInput: function () { var input = $("<textarea></textarea>") .attr("name", "wiktku-dunde-word-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 1) .attr("class", "wiktku-dfn-subfield wiktku-start-narrow") .attr("placeholder", "Kelîme…"); input.on("input", function () { var list = $(this).closest("ul.wiktku-dunde-words"); var item = $(this).parent(); var val = $.trim($(this).val()); if (val && item.is(list.children("li:last-child"))) { var next = steps.dunde.makeWordInput(); list.append($("<li></li>").append(next)); } }); return input; }, onLangChange: function (stepDiv, row) { var list = stepDiv.find("ul.wiktku-dunde-list"); var isLast = row.is(list.children("li.wiktku-dunde-row:last-child")); if (isLast) { var newRow = steps.dunde.buildRow(stepDiv); list.append(newRow); // Init chosen after the new row is in the DOM (desktop only). if (!isMobile) newRow.find("select").chosen(chosenOptions); } // Keep disabled keys in sync across all lang selectors. steps.dunde.syncDisabledKeys(stepDiv); }, /** Disables already-selected languages in all other dropdowns. */ syncDisabledKeys: function (stepDiv) { var taken = $.extend({}, steps.dunde.disabledKeys); stepDiv.find("li.wiktku-dunde-row select").each(function () { var v = $(this).val(); if (v) taken[v] = true; }); stepDiv.find("li.wiktku-dunde-row select").each(function () { var self = $(this); var own = self.val(); self.find("option").each(function () { var code = $(this).val(); if (!code) return; $(this).prop("disabled", taken[code] && code !== own); }); self.trigger("chosen:updated"); }); }, build: function (stepDiv) { if (stepDiv.find("ul.wiktku-dunde-list").length) return null; var list = $("<ul class='wiktku-dunde-list wiktku-lang-row-list'></ul>"); list.append(steps.dunde.buildRow(stepDiv)); stepDiv.append(list); // Init chosen after the select is in the DOM (desktop only). if (!isMobile) list.find("select").chosen(chosenOptions); return null; }, /** Reads all [langcode, words[]] rows from the DOM. */ getRows: function (stepDiv) { var result = []; stepDiv.find("li.wiktku-dunde-row").each(function () { var lang = $(this).find("select").val(); if (!lang) return; var words = []; $(this).find("ul.wiktku-dunde-words textarea").each(function () { var v = $.trim($(this).val()); if (v) words.push(v); }); if (words.length) result.push([lang, words]); }); return result; }, output: function () { var stepDiv = $("#wiktku-start-dunde"); var rows = steps.dunde.getRows(stepDiv); if (!rows.length) return ""; var lines = $.map(rows, function (row) { var lang = row[0], words = row[1]; return "* {{dû|" + lang + "|" + words.join("|") + "}}"; }); return "\n==== Dûnde ====\n" + lines.join("\n") + "\n"; } }, zarava: { id: "zarava", name: "bi zaravayên din", visible: function (values) { return steps.trans.visible(values); }, disabledKeys: { "navz": true }, buildRow: function (group) { var row = $("<li class='wiktku-zarava-row wiktku-lang-row'></li>"); var langSel = $(mw.html.element("select", { "class": "wiktku-start-step-keyfield wiktku-start-narrow" })); populateMenus(langSel, steps.zarava.keys || [], steps.zarava.disabledKeys); langSel.on("change", function () { steps.zarava.onLangChange(group, row); }); var wordList = $("<ul class='wiktku-zarava-words wiktku-lang-row-words'></ul>"); var firstWord = steps.zarava.makeWordInput(); wordList.append($("<li></li>").append(firstWord)); row.append(langSel).append(wordList); return row; }, makeWordInput: function () { var input = $("<textarea></textarea>") .attr("name", "wiktku-zarava-word-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 1) .attr("class", "wiktku-dfn-subfield wiktku-start-narrow") .attr("placeholder", "Tercime…"); input.on("input", function () { var list = $(this).closest("ul.wiktku-zarava-words"); var item = $(this).parent(); var val = $.trim($(this).val()); if (val && item.is(list.children("li:last-child"))) { var next = steps.zarava.makeWordInput(); list.append($("<li></li>").append(next)); } }); return input; }, onLangChange: function (group, row) { var list = group.find("ul.wiktku-zarava-list"); var isLast = row.is(list.children("li.wiktku-zarava-row:last-child")); if (isLast) { var newRow = steps.zarava.buildRow(group); list.append(newRow); } steps.zarava.syncDisabledKeys(group); }, /** Disables already-selected dialects in all other dropdowns within one group. */ syncDisabledKeys: function (group) { var taken = $.extend({}, steps.zarava.disabledKeys); group.find("li.wiktku-zarava-row select").each(function () { var v = $(this).val(); if (v) taken[v] = true; }); group.find("li.wiktku-zarava-row select").each(function () { var self = $(this); var own = self.val(); self.find("option").each(function () { var code = $(this).val(); if (!code) return; $(this).prop("disabled", taken[code] && code !== own); }); }); }, /** Builds (or fetches) the .wiktku-zarava-group for one gloss. */ buildGroup: function (stepDiv, gi) { var group = $("<div class='wiktku-zarava-group'></div>").attr("data-gloss-pos", gi); var list = $("<ul class='wiktku-zarava-list wiktku-lang-row-list'></ul>"); list.append(steps.zarava.buildRow(group)); group.append(list); stepDiv.append(group); return group; }, /** Syncs one .wiktku-zarava-group per current gloss (same logic as steps.trans.build). */ build: function (stepDiv) { var glosses = steps.trans.glossList(); if (!glosses.length) { stepDiv.find(".wiktku-zarava-group").remove(); return null; } var existingGroups = stepDiv.find(".wiktku-zarava-group"); if (existingGroups.length > glosses.length) { existingGroups.slice(glosses.length).remove(); } $.each(glosses, function (gi, gloss) { var group = stepDiv.find(".wiktku-zarava-group[data-gloss-pos='" + gi + "']"); if (!group.length) group = steps.zarava.buildGroup(stepDiv, gi); var label = group.find(".wiktku-zarava-group-label"); if (glosses.length > 1) { if (!label.length) { label = $("<div class='wiktku-zarava-group-label'></div>"); group.prepend(label); } label.text(gloss.index + " " + gloss.text); } else if (label.length) { label.remove(); } }); return null; }, /** Reads the dialect rows for a single gloss group. */ getGroupTranslations: function (group) { var result = []; group.find("li.wiktku-zarava-row").each(function () { var lang = $(this).find("select").val(); if (!lang) return; var words = []; $(this).find("ul.wiktku-zarava-words textarea").each(function () { var v = $.trim($(this).val()); if (v) words.push(v); }); if (words.length) result.push([lang, words]); }); return result; }, /** Reads all rows from the DOM, grouped by gloss position. */ getTranslations: function (stepDiv) { var result = []; stepDiv.find(".wiktku-zarava-group").each(function () { result.push(steps.zarava.getGroupTranslations($(this))); }); return result; }, output: function (values) { if (values.lang !== "ku") return ""; var stepDiv = $("#wiktku-start-zarava"); var glosses = steps.trans.glossList(); if (!glosses.length) return ""; var blocks = $.map(glosses, function (gloss, gi) { var group = stepDiv.find(".wiktku-zarava-group[data-gloss-pos='" + gi + "']"); var rows = group.length ? steps.zarava.getGroupTranslations(group) : []; if (!gloss.text && !rows.length) return undefined; if (rows.length) { rows.sort(function (a, b) { var aLang = langsByCode[a[0]] || []; var bLang = langsByCode[b[0]] || []; return (aLang[2] || "").localeCompare(bLang[2] || "", "ku"); }); } var wordLines = $.map(rows, function (row) { var lang = row[0]; var words = row[1]; var wikiWords = words.map(function (w) { return "{{W|" + lang + "|" + w + "}}"; }).join(", "); return "* {{Z|" + lang + "}}: " + wikiWords; }).join("\n"); if (!wordLines) return undefined; var block = "{{werger-ser|" + (gloss.text || "?") + "|" + gloss.index + "}}"; block += "\n" + wordLines; block += "\n{{werger-bin}}"; return block; }); if (!blocks.length) return ""; return "\n==== Bi zaravayên din ====\n" + blocks.join("\n") + "\n"; } }, trans: { id: "trans", name: "werger", visible: function (values) { if (!(values.lang === "ku" && values.pos)) return false; // Hide Werger only when EVERY sense is a template sense (Guharto etc.) // with a title filled in — i.e. there is real content but no plain // gloss to attach a translation table to. A mix of real + template // senses still shows Werger; the template senses are simply skipped // in output(). // // "Real" here means a non-şablon sense with either mane text or // other filled-in fields (etîket/hevmane/nimûne/jêder…), since // dfn.getOutput() renders the latter too, as {{mane?|lang}} plus // whatever else was filled in. // // When nothing has been filled in at all, output() will emit // {{mane?|lang}} instead of a gloss — but Werger should still show, // since the user may want to add translations before they've // settled on a gloss. var dfnSenses = steps.dfn.getSenses($("#wiktku-start-dfn")); var hasRealSense = dfnSenses.some(function (s) { return !s.tpl && (s.mane !== "" || senseHasExtraContent(s)); }); var hasFilledTplSense = dfnSenses.some(function (s) { return s.tpl && s.tplTitle; }); return hasRealSense || !hasFilledTplSense; }, disabledKeys: { "navz": true, "ku": true, "ckb": true, "sdh": true, "lki": true, "hac": true, "zza": true }, /** * Builds one translation row: a language dropdown + a growing list * of word inputs. When the dropdown gets a value the next empty row * is appended automatically. * * @param group the specific .wiktku-trans-group this row belongs to * (each gloss has its own group and its own list of rows, so the * lookups below must stay scoped to that group rather than the * whole step — the step now holds one list per gloss). */ buildRow: function (group) { var row = $("<li class='wiktku-trans-row wiktku-lang-row'></li>"); // Language selector — chosen is applied after insertion into DOM. var langSel = $(mw.html.element("select", { "class": "wiktku-start-step-keyfield wiktku-start-narrow" })); langSel.attr("data-placeholder", "Zimanekî lê bigere"); populateMenus(langSel, steps.trans.keys || [], steps.trans.disabledKeys); // When a language is chosen, ensure a next empty row exists. langSel.on("change", function () { steps.trans.onLangChange(group, row); }); // Word list for this language. var wordList = $("<ul class='wiktku-trans-words wiktku-lang-row-words'></ul>"); var firstWord = steps.trans.makeWordInput(); wordList.append($("<li></li>").append(firstWord)); if (isMobile) { row.append(wrapNativeSelect(langSel)).append(wordList); } else { row.append(langSel).append(wordList); } return row; }, makeWordInput: function () { var input = $("<textarea></textarea>") .attr("name", "wiktku-trans-word-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 1) .attr("class", "wiktku-dfn-subfield wiktku-start-narrow") .attr("placeholder", "Tercime…"); input.on("input", function () { var list = $(this).closest("ul.wiktku-trans-words"); var item = $(this).parent(); var val = $.trim($(this).val()); if (val && item.is(list.children("li:last-child"))) { var next = steps.trans.makeWordInput(); list.append($("<li></li>").append(next)); } }); return input; }, onLangChange: function (group, row) { var list = group.find("ul.wiktku-trans-list"); var isLast = row.is(list.children("li.wiktku-trans-row:last-child")); if (isLast) { var newRow = steps.trans.buildRow(group); list.append(newRow); // Init chosen after the new row is in the DOM (desktop only). if (!isMobile) newRow.find("select").chosen(chosenOptions); } // Keep disabled keys in sync across this gloss's lang selectors // only — the same language can be used for different senses. steps.trans.syncDisabledKeys(group); }, /** Disables already-selected languages in all other dropdowns within one group. */ syncDisabledKeys: function (group) { var taken = $.extend({}, steps.trans.disabledKeys); group.find("li.wiktku-trans-row select").each(function () { var v = $(this).val(); if (v) taken[v] = true; }); group.find("li.wiktku-trans-row select").each(function () { var self = $(this); var own = self.val(); self.find("option").each(function () { var code = $(this).val(); if (!code) return; $(this).prop("disabled", taken[code] && code !== own); }); self.trigger("chosen:updated"); }); }, /** * Builds (or fetches) the .wiktku-trans-group for one gloss, with * its own label and its own list of translation rows. */ buildGroup: function (stepDiv, gi) { var group = $("<div class='wiktku-trans-group'></div>").attr("data-gloss-pos", gi); var list = $("<ul class='wiktku-trans-list wiktku-lang-row-list'></ul>"); list.append(steps.trans.buildRow(group)); group.append(list); stepDiv.append(group); // Init chosen after the select is in the DOM (desktop only). if (!isMobile) list.find("select").chosen(chosenOptions); return group; }, /** * Syncs one .wiktku-trans-group per current gloss, adding new * groups and removing stale ones as senses are added or removed, * while leaving existing groups (and whatever translations the * user has already typed into them) untouched. Groups are keyed * to their gloss's position in glossList() via data-gloss-pos, so * a group always matches the same sense across rebuilds as long * as senses aren't reordered relative to each other. */ build: function (stepDiv) { var glosses = steps.trans.glossList(); if (!glosses.length) { stepDiv.find(".wiktku-trans-group").remove(); return null; } // Drop groups for glosses that no longer exist (always from the // tail — groups are only ever appended in gloss order below). var existingGroups = stepDiv.find(".wiktku-trans-group"); if (existingGroups.length > glosses.length) { existingGroups.slice(glosses.length).remove(); } $.each(glosses, function (gi, gloss) { var group = stepDiv.find(".wiktku-trans-group[data-gloss-pos='" + gi + "']"); if (!group.length) group = steps.trans.buildGroup(stepDiv, gi); // Only label groups when there's more than one gloss to // distinguish between — a single gloss needs no caption. var label = group.find(".wiktku-trans-group-label"); if (glosses.length > 1) { if (!label.length) { label = $("<div class='wiktku-trans-group-label'></div>"); group.prepend(label); } label.text(gloss.index + " " + gloss.text); } else if (label.length) { label.remove(); } }); return null; }, /** Reads the translation rows for a single gloss group. */ getGroupTranslations: function (group) { var result = []; group.find("li.wiktku-trans-row").each(function () { var lang = $(this).find("select").val(); if (!lang) return; var words = []; $(this).find("ul.wiktku-trans-words textarea").each(function () { var v = $.trim($(this).val()); if (v) words.push(v); }); if (words.length) result.push([lang, words]); }); return result; }, /** * Reads all translation rows from the DOM, grouped by gloss * position — one array of [lang, words] rows per gloss group, in * the same order as the .wiktku-trans-group elements. */ getTranslations: function (stepDiv) { var result = []; stepDiv.find(".wiktku-trans-group").each(function () { result.push(steps.trans.getGroupTranslations($(this))); }); return result; }, /** * Builds the numbered "{ index, gloss }" list — one entry per dfn * sense that has a real mane (skips template senses like Guharto, * which have nothing to caption a translation table with). The * index matches the sense's actual position in the numbered "#" * definition list (1-based), including template senses in the count, * so the number printed next to {{werger-ser}} lines up with the * gloss the reader sees in the entry. * * When nothing has been filled in at all (dfn.getOutput() will emit * {{mane?|lang}} as sense 1), this returns a single placeholder * entry with empty text instead of an empty array, so Werger still * has one group to attach translations to before a gloss exists. * When every filled sense is a template sense instead, this stays * empty — that mirrors trans.visible()'s hidden case, where there's * no group in the DOM for a placeholder to attach to anyway. */ glossList: function () { var dfnSenses = steps.dfn.getSenses($("#wiktku-start-dfn")); var glosses = []; var hasFilledTplSense = false; $.each(dfnSenses, function (i, s) { if (s.tpl) { if (s.tplTitle) hasFilledTplSense = true; return; // template sense — no gloss to caption with } var dfn = s.mane; if (!dfn) { // No mane text, but other fields (etîket/hevmane/nimûne/ // jêder…) are filled — dfn.getOutput() still emits this // sense as a numbered line using {{mane?|lang}}, so it // needs its own gloss group too, just with no caption text. if (senseHasExtraContent(s)) glosses.push({ index: i + 1, text: "" }); return; } if (dfn[0] !== dfn[0].toLowerCase()) dfn = decapitalize(dfn); dfn = stripWikilinks(dfn).replace(/[.…?!)\]،؟]+$/, ""); glosses.push({ index: i + 1, text: dfn }); }); if (!glosses.length && !hasFilledTplSense) { glosses.push({ index: 1, text: "" }); } return glosses; }, output: function (values) { if (values.lang !== "ku") return ""; var stepDiv = $("#wiktku-start-trans"); var glosses = steps.trans.glossList(); // Every sense is a template sense — there's no real gloss // anywhere and no group in the DOM either (glossList() only // returns empty in that case), so skip the section entirely. if (!glosses.length) return ""; // Each gloss now has its own group of translation rows — // attach every gloss's own words under its own werger-ser/-bin // pair instead of dumping everything under the first one. var blocks = $.map(glosses, function (gloss, gi) { var group = stepDiv.find(".wiktku-trans-group[data-gloss-pos='" + gi + "']"); var rows = group.length ? steps.trans.getGroupTranslations(group) : []; // Placeholder gloss (no real mane entered yet) with nothing // translated into it — nothing to output, and gloss.text is // empty so there's no caption to give {{werger-ser}} anyway. if (!gloss.text && !rows.length) return undefined; if (rows.length) { // Sort by Kurdish sort key. rows.sort(function (a, b) { var aLang = langsByCode[a[0]] || []; var bLang = langsByCode[b[0]] || []; return (aLang[2] || "").localeCompare(bLang[2] || "", "ku"); }); } var wordLines = $.map(rows, function (row) { var lang = row[0]; var words = row[1]; var wikiWords = words.map(function (w) { return "{{W|" + lang + "|" + w + "}}"; }).join(", "); return "* {{Z|" + lang + "}}: " + wikiWords; }).join("\n"); var block = "{{werger-ser|" + (gloss.text || "?") + "|" + gloss.index + "}}"; if (wordLines) block += "\n" + wordLines; block += "\n{{werger-bin}}"; return block; }); if (!blocks.length) return ""; return "\n==== Werger ====\n" + blocks.join("\n") + "\n"; } }, }; steps.trans.keys = steps.lang.choices; steps.dunde.keys = steps.lang.choices; steps.zarava.keys = getZaravaKeys(steps.lang.choices); var ordered_steps = [ steps.lang, steps.pron, steps.pos, steps.cinsiyet, steps.lektur, steps.tr, steps.dfn, steps.je, steps.tekildar, steps.etym, steps.dunde, steps.binereherwiha, steps.zarava, steps.trans]; // Step ids that belong to each section (not shared across sections). var PER_SECTION_STEP_IDS = [ "pos", "cinsiyet", "lektur", "tr", "dfn", "je", "tekildar", "etym", "dunde", "binereherwiha", "zarava", "trans" ]; // ── Multi-section state ────────────────────────────────────────────────── // Each entry is a plain snapshot: { pos, cinsiyet, lektur, tr, dfn (senses[]), // je, tekildar, binereherwiha, trans (rows[]) }. var sections = [{}]; // section 0 starts empty (DOM is the truth) var activeSection = 0; function snapshotDfn() { return steps.dfn.getSenses($("#wiktku-start-dfn")); } /** * Rebuild the dfn DOM from a previously snapshotted senses array. */ function restoreDfn(senses) { var stepDiv = $("#wiktku-start-dfn"); // Tear down the existing list so build() recreates it cleanly. stepDiv.find("ol.wiktku-dfn-list").remove(); steps.dfn.build(stepDiv); var list = stepDiv.find("ol.wiktku-dfn-list"); $.each(senses, function (i, sense) { // Ensure enough blocks exist (build() seeds one). var blocks = list.find("li.wiktku-dfn-sense"); var block = blocks.eq(i); if (!block.length) { var nb = steps.dfn.buildSenseBlock(stepDiv); list.append(nb); block = list.find("li.wiktku-dfn-sense").last(); } // Template selector. block.find("select.wiktku-dfn-tpl-select").val(sense.tpl || ""); if (sense.tpl) { block.find("textarea.wiktku-dfn-mane").hide(); block.find("input.wiktku-dfn-tpl-title").val(sense.tplTitle || "").show(); } else { block.find("textarea.wiktku-dfn-mane").val(sense.mane || "").show(); block.find("input.wiktku-dfn-tpl-title").hide().val(""); } // Re-sync the formên alternatîv/hevmane/… hide state now that // tplSelect's value was set programmatically (its own "change" // handler doesn't fire from .val(), so this doesn't happen otherwise). var updateVis = block.data("updateFieldVisibility"); if (updateVis) updateVis(); // Restore a sub-list (etiket, formên alternatîv, hevmane …) from a values array. function restoreSubList(cls, values) { if (!values || !values.length) return; var groupDiv = block.find("." + cls + "-group"); var subList = groupDiv.find("ol, ul").first(); if (!subList.length) return; // group not found // Fill existing items, append new ones as needed. $.each(values, function (j, val) { var items = subList.find("li"); if (j < items.length) { items.eq(j).find("textarea").val(val); } else { var ta = $("<textarea></textarea>") .attr("name", "wiktku-dfn-restore-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 1) .attr("class", "wiktku-dfn-subfield wiktku-start-narrow") .val(val); ta.on("input", function () { steps.dfn.onSubInput(subList, this, 1, true); }); subList.append($("<li></li>").append(ta)); } }); } // Reveal and populate lazy groups that have data. var lazyMap = { "wiktku-dfn-etiket": sense.etiket, "wiktku-dfn-alternativ": sense.alternativ, "wiktku-dfn-hevmane": sense.hevmane, "wiktku-dfn-dijmane": sense.dijmane, "wiktku-dfn-koordine": sense.koordine, "wiktku-dfn-jornav": sense.jornav, "wiktku-dfn-jernav": sense.jernav }; $.each(lazyMap, function (cls, vals) { if (vals && vals.length) restoreSubList(cls, vals); }); // Nimûne items are objects { text, tr?, t? } — restore using the builder. if (sense.nimune && sense.nimune.length) { var nimuneGroupDiv = block.find(".wiktku-dfn-nimune-group"); var nimuneList = nimuneGroupDiv.find("ol.wiktku-dfn-nimune-list"); var buildFn = nimuneGroupDiv.data("buildNimuneLi"); nimuneList.empty(); $.each(sense.nimune, function (_, n) { var text = typeof n === "object" ? (n.text || "") : n; if (!text) return; var li = buildFn ? buildFn() : $("<li class='wiktku-dfn-nimune-li'></li>"); li.find(".wiktku-dfn-nimune-text").val(text); if (n.tr) li.find(".wiktku-dfn-nimune-tr").val(n.tr); if (n.t) li.find(".wiktku-dfn-nimune-t").val(n.t); nimuneList.append(li); }); // Always leave a blank trailing item. if (buildFn) nimuneList.append(buildFn()); } // Restore jêder (quote/citation) entries — a growing list, restored using the // builder just like Nimûne. Accepts either the current array shape or a // single legacy object (from older saved sections) for backwards compatibility. var jederArr = $.isArray(sense.jeder) ? sense.jeder : (sense.jeder ? [sense.jeder] : []); if (jederArr.length) { var jederGroupDiv = block.find(".wiktku-dfn-jeder-group"); var jederList = jederGroupDiv.find("ol.wiktku-dfn-jeder-list"); var buildJederFn = jederGroupDiv.data("buildJederLi"); jederList.empty(); $.each(jederArr, function (_, j) { if (!j || !j.quote) return; var li = buildJederFn ? buildJederFn() : $("<li class='wiktku-dfn-jeder-li'></li>"); li.find(".wiktku-dfn-nimune-quote").val(j.quote); if (j.quoteTr) li.find(".wiktku-dfn-nimune-quote-tr").val(j.quoteTr); if (j.quoteT) li.find(".wiktku-dfn-nimune-quote-t").val(j.quoteT); if (j.jederManual) { var manualSel = li.find(".wiktku-dfn-quote-src-sel"); manualSel.val("__manual__").trigger("change"); li.find(".wiktku-dfn-quote-src-manual").val(j.jederManual); } else if (j.jederTpl) { var srcSel = li.find(".wiktku-dfn-quote-src-sel"); srcSel.val(j.jederTpl).trigger("change"); if (j.jêderFields) { $.each(j.jêderFields, function (key, val) { li.find(".wiktku-dfn-quote-src-input[data-field-key='" + key + "']").val(val); }); } } jederList.append(li); }); // Always leave a blank trailing item, same as Nimûne. if (buildJederFn) jederList.append(buildJederFn()); } }); } /** * Snapshot simple (non-dfn) per-section steps from current DOM into obj. */ function saveCurrentSection() { var snap = {}; $.each(PER_SECTION_STEP_IDS, function (_, id) { if (id === "dfn") { snap.dfn = snapshotDfn(); return; } if (id === "etym") { snap.etym = $.trim($("#wiktku-start-etym .wiktku-etym-text").val()); return; } var step = steps[id]; if (!step) return; var stepDiv = $("#wiktku-start-" + id); if (id === "trans") { snap.trans = steps.trans.getTranslations(stepDiv); return; } if (id === "zarava") { snap.zarava = steps.zarava.getTranslations(stepDiv); return; } if (id === "dunde") { snap.dunde = steps.dunde.getRows(stepDiv); return; } // Generic: read all step fields. var fields = stepDiv.find(".wiktku-start-step-field"); if (step.multiple) { snap[id] = fields.map(function () { return $(this).val(); }).get(); } else { snap[id] = fields.val(); } }); sections[activeSection] = snap; } /** * Restore a previously saved snapshot into the form DOM. */ function restoreSection(snap) { $.each(PER_SECTION_STEP_IDS, function (_, id) { if (id === "dfn") { restoreDfn(snap.dfn || []); return; } if (id === "etym") { $("#wiktku-start-etym .wiktku-etym-wrap").remove(); steps.etym.build($("#wiktku-start-etym")); $("#wiktku-start-etym .wiktku-etym-text").val(snap.etym || ""); return; } if (id === "trans") { // Rebuild trans groups (dfn must already be restored by this // point in the $.each loop, so glossList() reflects it). var transDiv = $("#wiktku-start-trans"); transDiv.find(".wiktku-trans-group").remove(); steps.trans.build(transDiv); var groupsSnap = snap.trans || []; $.each(groupsSnap, function (gi, rows) { var group = transDiv.find(".wiktku-trans-group[data-gloss-pos='" + gi + "']"); if (!group.length) return; // gloss no longer exists — drop its rows var list = group.find("ul.wiktku-trans-list"); $.each(rows, function (j, row) { var lang = row[0], words = row[1]; var lastRow = list.find("li.wiktku-trans-row").last(); lastRow.find("select").val(lang).trigger("change"); var wordList = lastRow.find("ul.wiktku-trans-words"); $.each(words, function (k, word) { var wordItems = wordList.find("li"); if (k < wordItems.length) { wordItems.eq(k).find("textarea").val(word); } else { // .val() below doesn't fire "input", so the normal // auto-grow never runs — append a matching item // ourselves instead of silently dropping the word. var extraInput = steps.trans.makeWordInput(); wordList.append($("<li></li>").append(extraInput)); extraInput.val(word); } }); // Leave one trailing empty field so the row can still grow // when the user types, matching a freshly-built row. if ($.trim(wordList.children("li").last().find("textarea").val())) { wordList.append($("<li></li>").append(steps.trans.makeWordInput())); } }); }); return; } if (id === "zarava") { // Rebuild zarava groups (dfn must already be restored by this // point in the $.each loop, so glossList() reflects it). var zaravaDiv = $("#wiktku-start-zarava"); zaravaDiv.find(".wiktku-zarava-group").remove(); steps.zarava.build(zaravaDiv); var zaravaGroupsSnap = snap.zarava || []; $.each(zaravaGroupsSnap, function (gi, rows) { var group = zaravaDiv.find(".wiktku-zarava-group[data-gloss-pos='" + gi + "']"); if (!group.length) return; // gloss no longer exists — drop its rows var list = group.find("ul.wiktku-zarava-list"); $.each(rows, function (j, row) { var lang = row[0], words = row[1]; var lastRow = list.find("li.wiktku-zarava-row").last(); lastRow.find("select").val(lang).trigger("change"); var wordList = lastRow.find("ul.wiktku-zarava-words"); $.each(words, function (k, word) { var wordItems = wordList.find("li"); if (k < wordItems.length) { wordItems.eq(k).find("textarea").val(word); } else { var extraInput = steps.zarava.makeWordInput(); wordList.append($("<li></li>").append(extraInput)); extraInput.val(word); } }); if ($.trim(wordList.children("li").last().find("textarea").val())) { wordList.append($("<li></li>").append(steps.zarava.makeWordInput())); } }); }); return; } if (id === "dunde") { // Rebuild dunde rows. var dundeDiv = $("#wiktku-start-dunde"); dundeDiv.find("ul.wiktku-dunde-list").remove(); steps.dunde.build(dundeDiv); var dundeRows = snap.dunde || []; $.each(dundeRows, function (i, row) { var lang = row[0], words = row[1]; var list = dundeDiv.find("ul.wiktku-dunde-list"); var lastRow = list.find("li.wiktku-dunde-row").last(); lastRow.find("select").val(lang).trigger("change"); var wordList = lastRow.find("ul.wiktku-dunde-words"); $.each(words, function (j, word) { var wordItems = wordList.find("li"); if (j < wordItems.length) { wordItems.eq(j).find("textarea").val(word); } else { // .val() below doesn't fire "input", so the normal // auto-grow never runs — append a matching item // ourselves instead of silently dropping the word. var extraInput = steps.dunde.makeWordInput(); wordList.append($("<li></li>").append(extraInput)); extraInput.val(word); } }); // Leave one trailing empty field so the row can still grow // when the user types, matching a freshly-built row. if ($.trim(wordList.children("li").last().find("textarea").val())) { wordList.append($("<li></li>").append(steps.dunde.makeWordInput())); } }); return; } var step = steps[id]; if (!step) return; var stepDiv = $("#wiktku-start-" + id); var fields = stepDiv.find(".wiktku-start-step-field"); var val = snap[id]; if (val === undefined || val === null) return; if (step.multiple) { var arr = val; fields.each(function (i) { if (i < arr.length) $(this).val(arr[i]); }); } else { fields.val(val); } // Notify chosen widgets of the programmatic value change. if (!isMobile) fields.filter("select").trigger("chosen:updated"); }); } function getWikitextForCurrentSection(callback) { var values = getValues(); var entry = steps.pos.output(values); steps.dfn.getOutput(values, function (output) { entry += output; entry += steps.je.output(values); entry += steps.tekildar.output(values); entry += steps.etym.output(values); entry += steps.dunde.output(values); entry += steps.binereherwiha.output(values); entry += steps.zarava.output(values); entry += steps.trans.output(values); callback(entry, values); }); } function getWikitextAllSections(callback) { saveCurrentSection(); var results = new Array(sections.length); var sharedValues = getValues(); // lang/pron are shared function processSection(i) { if (i >= sections.length) { // All done — restore original active section. restoreSection(sections[activeSection]); refresh(); callback(results, sharedValues); return; } restoreSection(sections[i]); refresh(); getWikitextForCurrentSection(function (sectionText) { results[i] = sectionText; processSection(i + 1); }); } processSection(0); } /** * Assembles wikitext for all sections plus the shared lang/pron header. */ function getWikitext(callback) { getWikitextAllSections(function (sectionTexts, sharedValues) { var entry = steps.lang.output(sharedValues); entry += steps.pron.output(sharedValues); entry += sectionTexts.join("\n"); // Edit summary uses section 0's values. Read from the saved snapshot // (not the live DOM) so it doesn't mix section 0's pos with whichever // section happens to be active/restored at this point. var dfnSenses = (sections[0] && sections[0].dfn) || []; var dfnSummary = dfnSenses.map(function (s) { return s.mane; }).filter(Boolean).join("; "); var summaryLabel = addLangMode ? "WF:Ziman lê zêde" : "WF:Nû"; var summary = "([[Mediawiki:Gadget-start.js|" + summaryLabel + "]] v.2.0) +" + sharedValues.lang + ":" + sections[0].pos + ":" + dfnSummary; var summaryField = document.getElementById("wpSummary"); if (addLangMode && summaryField.value) { summary = summaryField.value + " " + summary; } summaryField.value = summary; callback(entry); }); } var continueBtn; function getValuesForStep(stepId) { var fields = $("#wiktku-start-" + stepId + " .wiktku-start-step-field"); var step = steps[stepId]; if (step.keys) { var values = {}; fields.each(function (i, field) { var key = $(field).prevAll(".wiktku-start-step-keyfield").val(); if (key) values[key] = $(field).val(); }); return values; } else if (step.multiple) { return fields.map(function () { return $(this).val(); }).get(); } return fields.val(); } function getValues() { var values = {}; $.each(steps, function (stepId) { values[stepId] = getValuesForStep(stepId); }); return values; } function populateMenus(inputs, choices, disabledValues) { if (!disabledValues) disabledValues = {}; var vals = inputs.map(function (i, input) { return $(input).val(); }); inputs.empty(); inputs.append($("<option></option>")); $.each(choices, function (j, choice) { // Append the language code in parentheses so that typing a code // (e.g. "ku") in the search box still finds the language name. var displayText = capitalize(choice[1]); if (choice[2] !== undefined) { // This is a language choice [code, name, sortKey] — show code. displayText = capitalize(choice[1]) + " (" + choice[0] + ")"; } var option = $(mw.html.element("option", { value: choice[0] }, displayText)); if (disabledValues[choice[0]]) option.prop("disabled", true); inputs.append(option); }); inputs.val(function (i) { return vals[i]; }); } /** * Returns a bitmap containing the keys that should be disabled for a key * menu in the given step because they are disabled or already taken by * another key menu. */ function getDisabledKeys(step) { var occupiedKeys = {}; $("#wiktku-start-" + step.id + " .wiktku-start-step-keyfield").each(function () { occupiedKeys[$(this).val()] = true; }); if (step.disabledKeys) $.extend(occupiedKeys, step.disabledKeys); return occupiedKeys; } function buildKeyInput(step) { if (!step.keys) return undefined; var input = $(mw.html.element("select", { "class": "wiktku-start-step-keyfield wiktku-start-narrow" })); input.attr("data-placeholder", "Hilbijêre " + step.keyName); if (isMobile) { populateMenus(input, step.keys, getDisabledKeys(step)); // On mobile return the wrapper; the select is inside it. // Change events still fire on the inner select. return wrapNativeSelect(input); } input.on("chosen:showing_dropdown", function () { $(this).data("wiktku-defaultValue", $(this).val()); }); input.change(function (_, context) { var inputs = $("#wiktku-start-" + step.id + " .wiktku-start-step-keyfield").not(this); var oldValue = $(this).data("wiktku-defaultValue"); var newValue = context.selected; inputs.find("option[value='" + oldValue + "']").prop('disabled', false); inputs.find("option[value='" + newValue + "']").prop('disabled', true); inputs.trigger("chosen:updated"); }); populateMenus(input, step.keys, getDisabledKeys(step)); return input; } /** * If the current text field has text and there are no more text fields after * the current text field in the list, add another text field to the list. */ function refreshForTextField(currentInput, step) { currentInput = $(currentInput); var value = currentInput.val(); var item = currentInput.parent(); if (value && !item.next("li").length) { var nextInput = $("<textarea></textarea>") .attr("name", "wiktku-field-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("class", currentInput.attr("class")) .attr("rows", currentInput.attr("rows") || 1); nextInput.on("input", function (evt) { refreshForTextField(evt.target, step); }); var nextKeyInput = buildKeyInput(step); var nextItem = $("<li></li>").append(nextKeyInput).append(nextInput); item.parent().append(nextItem); if (nextKeyInput) nextKeyInput.chosen(chosenOptions); } var canContinue = !continueBtn.isDisabled(); if ((value && !canContinue) || (!value && canContinue)) { refresh(step); } } function prepareInput(input, step) { if (!input) return; if (step.required) input.prop('required', true); input.change(step, refresh); } /** * Shows and hides all the steps based on whether their prerequisites are met, * and updates placeholders where applicable. */ function refresh(evt) { var values = getValues(); var changedStep = evt && evt.data; var didFocus = false; var canContinue = true; // Re-filter template options in every sense block whenever lang changes. $("#wiktku-start-dfn .wiktku-dfn-tpl-select").each(function () { var fn = $(this).data("updateOptions"); if (typeof fn === "function") fn(); }); // Re-filter pronunciation and etymology template dropdowns when language changes. steps.pron.refreshTplSelect(); steps.etym.refreshTplSelect(); // Sync tr/t sub-fields in every nimûne item to the current language. // tr shown when language needs transliteration; t shown when lang !== "ku". (function () { var lang = values.lang || ""; var showTr = needsTransliteration(lang); var showT = lang && lang !== "ku"; $("#wiktku-start-dfn .wiktku-dfn-nimune-list li.wiktku-dfn-nimune-li").each(function () { var li = $(this); // Ensure the sub-wrapper exists when we need it. var subWrap = li.find(".wiktku-dfn-nimune-sub"); // tr field var trTa = li.find(".wiktku-dfn-nimune-tr"); if (showTr && !trTa.length) { if (!subWrap.length) { subWrap = $("<div></div>").addClass("wiktku-dfn-nimune-sub"); li.append(subWrap); } trTa = $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-tr-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 5) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-tr") .attr("placeholder", "Transkrîpsiyon…"); subWrap.prepend(trTa); } else if (!showTr && trTa.length) { trTa.remove(); } // t field var tTa = li.find(".wiktku-dfn-nimune-t"); if (showT && !tTa.length) { if (!subWrap.length) { subWrap = $("<div></div>").addClass("wiktku-dfn-nimune-sub"); li.append(subWrap); } tTa = $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-t-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 5) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-t") .attr("placeholder", "Tercimeya nimûneyê kurmancî…"); subWrap.append(tTa); } else if (!showT && tTa.length) { tTa.remove(); } // Remove the wrapper if it ended up empty. subWrap = li.find(".wiktku-dfn-nimune-sub"); if (subWrap.length && !subWrap.children().length) subWrap.remove(); }); }()); // Sync tr/t sub-fields in every jêder citation to the current language. // tr shown when language needs transliteration; t shown when lang !== "ku". (function () { var lang = values.lang || ""; var showTr = needsTransliteration(lang); var showT = lang && lang !== "ku"; $("#wiktku-start-dfn .wiktku-dfn-jeder-list li.wiktku-dfn-jeder-li").each(function () { var li = $(this); // Ensure the sub-wrapper exists when we need it. It must sit right // after the quote textarea and before the source selector. var subWrap = li.find(".wiktku-dfn-quote-sub"); // tr field var trTa = li.find(".wiktku-dfn-nimune-quote-tr"); if (showTr && !trTa.length) { if (!subWrap.length) { subWrap = $("<div></div>").addClass("wiktku-dfn-quote-sub"); li.find(".wiktku-dfn-nimune-quote").after(subWrap); } trTa = $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-quote-tr-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 2) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-quote-tr") .attr("placeholder", "Transkrîpsiyona jêgirtinê…"); subWrap.prepend(trTa); } else if (!showTr && trTa.length) { trTa.remove(); } // t field var tTa = li.find(".wiktku-dfn-nimune-quote-t"); if (showT && !tTa.length) { if (!subWrap.length) { subWrap = $("<div></div>").addClass("wiktku-dfn-quote-sub"); li.find(".wiktku-dfn-nimune-quote").after(subWrap); } tTa = $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-quote-t-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 2) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-quote-t") .attr("placeholder", "Tercimeya jêgirtinê ya kurmancî…"); subWrap.append(tTa); } else if (!showT && tTa.length) { tTa.remove(); } // Remove the wrapper if it ended up empty. subWrap = li.find(".wiktku-dfn-quote-sub"); if (subWrap.length && !subWrap.children().length) subWrap.remove(); }); }()); $.each(steps, function (stepId, step) { if (typeof(step.visible) === "function" && !step.visible(values)) { $("#wiktku-start-" + stepId).slideUp(); } else { var stepDiv = $("#wiktku-start-" + stepId); if (changedStep !== step && typeof(step.build) === "function") { prepareInput(step.build(stepDiv, values), step); } var input = stepDiv.find(".wiktku-start-step-field"); if (typeof(step.example) === "function") { // .find() above already reaches nested fields (e.g. the dfn // step's mane textareas inside each sense block), so one // assignment covers every step; dfn keeps its own fallback. var exampleText = step.example(values) || (step.id === "dfn" ? "Mane…" : ""); input.attr("placeholder", exampleText); } var didSlideDown; if (!didFocus && stepDiv.css("display") === "none" && step.required) { didSlideDown = function (evt) { input.focus(); }; didFocus = true; } stepDiv.slideDown(didSlideDown); } if (step.required && (values[stepId] === "" || (step.multiple && values[stepId].join("") === ""))) { canContinue = false; } }); continueBtn.setDisabled(!canContinue); } function destroy() { $("#wiktku-start-form, .noafterwizard").slideUp(function () { $(this).remove(); }); $(".noarticletext .nowizard, #editform").slideDown(); $("#ca-edit").removeClass("selected"); $("#ca-wiktku-nowizard").addClass("selected"); } // Priority order for Kurdish dialects and the navz pseudo-code. // Codes listed here come before all other languages; unlisted codes // are sorted alphabetically by their display name via localeCompare. var LANG_PRIORITY = ["navz", "ku", "hac", "sdh", "lki", "ckb", "zza"]; /** * Inserts a new == {{ziman|code}} == section into existing page wikitext * at the correct sorted position: * 1. Any content before the first language section is preserved at the top. * 2. navz is always first, then ku/hac/sdh/lki/ckb/zza in that order, * then all other languages sorted by display name (localeCompare). */ function insertNewLangSection(existing, wikitext) { var newCodeMatch = wikitext.match(/^== \{\{ziman\|([^}]+)\}\} ==/); var newCode = newCodeMatch ? newCodeMatch[1] : ""; var sections = []; var preamble = ""; var firstMatch = existing.match(/(?:^|\n)== \{\{ziman\|/); if (!firstMatch) { // No existing lang sections at all — just append. var sep = existing && !/\n\s*$/.test(existing) ? "\n\n" : ""; return existing + sep + wikitext; } // Everything before the first == {{ziman|...}} == is the preamble. var firstSectionStart = existing.indexOf("== {{ziman|"); // Walk back to the start of that line. var lineStart = existing.lastIndexOf("\n", firstSectionStart - 1); var preambleEnd = lineStart !== -1 ? lineStart + 1 : 0; preamble = existing.slice(0, preambleEnd); // Parse each language section: header line + everything until the next header. var body = existing.slice(preambleEnd); // NOTE: with the /m flag, a bare "$" matches end-of-*line*, not just // end-of-string — that previously made the non-greedy content group // stop at the section's first line break instead of running to the // next language header (or the real end of the text), silently // dropping the rest of that section's wikitext. (?![\s\S]) matches // only the true end of the string, /m flag or not. var langSectionRe = /^(== \{\{ziman\|([^}]+)\}\} ==\n?)([\s\S]*?)(?=\n== \{\{ziman\||(?![\s\S]))/gm; var m; while ((m = langSectionRe.exec(body)) !== null) { sections.push({ code: m[2], content: m[0] // full text of this section including header }); } // Determine sort rank: priority list first (by index), then alphabetical. function getLangName(code) { var entry = langsByCode[code]; return entry ? entry[1] : code; } function sortRank(code) { var idx = LANG_PRIORITY.indexOf(code); return idx !== -1 ? idx : LANG_PRIORITY.length; } function compareLangs(a, b) { var ra = sortRank(a), rb = sortRank(b); if (ra !== rb) return ra - rb; // Both are outside priority list — sort by display name. return getLangName(a).localeCompare(getLangName(b), userLang); } // Insert the new section into the sorted list. var newSection = { code: newCode, content: wikitext }; var inserted = false; for (var i = 0; i < sections.length; i++) { if (compareLangs(newCode, sections[i].code) < 0) { sections.splice(i, 0, newSection); inserted = true; break; } } if (!inserted) sections.push(newSection); // Re-join: preamble + sections separated by newlines. var joined = sections.map(function (s) { // Ensure each section ends with exactly one newline before the next. return s.content.replace(/\n+$/, ""); }).join("\n"); return preamble + joined + "\n"; } function build() { $(".nowizard, .nowizard .noafterwizard").hide(); var callToAction = $("#wiktku-calltoaction"); var origCallToActionText = callToAction.text(); $(mw.util.addPortletLink("p-views", "#", "Edîtora çavkaniyê veke", "ca-wiktku-nowizard", "Vê rûpelê bi edîtora çavkaniyê çêke", undefined, "#ca-watch")).click(function (evt) { evt.preventDefault(); callToAction.text(origCallToActionText); destroy(); }); if (callToAction.length) { callToAction.text(origCallToActionText + " Forma li jêr ji bo çêkirina madeyeke nû bi kar bîne."); } var startForm = $("<form id='wiktku-start-form'></form>"); if (addLangMode) { startForm.append($("<p class='wiktku-addlang-notice'></p>").text( "Bi vê formê tu yê beşeke nû li rûpelê îlaw bikî. Eger ev zimanê ku tu îlawe dikî jixwe di rûpelê de hebe, beşa nû li dawiya vî zimanî dê were îlawekirin. " + "Ji kerema xwe netîceya dawî kontrol bikin, eger problemek derkeve, li [[Mediawiki talk:Gadget-start.js|nîqaşa vê amûrê]] problemê ragihîne.")); } var spinner; // Tab bar for switching between POS sections. var sectionTabsDiv = $("<div id='wiktku-section-tabs'></div>"); startForm.submit(function (evt) { evt.preventDefault(); continueBtn.setDisabled(true); spinner.show(); getWikitext(function (wikitext) { if (addLangMode) { var textbox = $("#wpTextbox1"); var existing = textbox.val() || ""; // Check whether the generated lang header already exists in the page. // wikitext always starts with "== {{ziman|CODE}} ==\n" (from steps.lang.output). // If that exact section heading is already present in the existing content, // strip it from the new output and insert the remaining content at the end // of that lang section (just before the next == level-2 heading, or at the // very end of the page if there is no following section). var langHeaderMatch = wikitext.match(/^(== \{\{ziman\|[^}]+\}\} ==\n)/); if (langHeaderMatch) { var langHeader = langHeaderMatch[1]; // e.g. "== {{ziman|ku}} ==\n" // Escape for use in RegExp. var escapedHeader = langHeader.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); if (new RegExp(escapedHeader).test(existing)) { // Strip the header from the new output. var newContent = wikitext.slice(langHeader.length); // Find the insertion point: end of the existing lang section. // A new L2 heading marks the start of the next language block. var afterHeader = existing.indexOf(langHeader); var searchFrom = afterHeader + langHeader.length; // Find the next == … == heading after this section's start. var nextL2 = existing.indexOf("\n== ", searchFrom); var insertAt = nextL2 !== -1 ? nextL2 : existing.length; // Ensure there's a blank line before the inserted block. var before = existing.slice(0, insertAt); var after = existing.slice(insertAt); var sep = /\n\s*$/.test(before) ? "" : "\n"; textbox.val(before + sep + newContent + after); } else { // New language — insert at the correct sorted position. textbox.val(insertNewLangSection(existing, wikitext)); } } else { // Unexpected format — insert at sorted position anyway. textbox.val(insertNewLangSection(existing, wikitext)); } } else { $("#wpTextbox1").val(wikitext); } $("html, body").animate({scrollTop: 0}); callToAction.text("Hindik ma!"); $("#wiktku-preview-container").remove(); destroy(); }); }); $.each(ordered_steps, function (i, step) { var stepDiv = $(mw.html.element("div", { "class": "wiktku-start-step", id: "wiktku-start-" + step.id })); var name = capitalize(step.name); stepDiv.append($(mw.html.element("h3", { "class": "wiktku-start-step-name" }, new mw.html.Raw(mw.html.element("label", { "for": "wiktku-start-" + step.id + "-field" }, name))))); if (step.question_fmt) { stepDiv.append($(mw.html.element("label", { "class": "wiktku-start-step-question", "for": "wiktku-start-" + step.id + "-field" }, step.question_fmt))); if (step.question_br) stepDiv.append($("<br>")); } var input; if (step.choices) { input = $(mw.html.element("select", { "class": "wiktku-start-step-field", id: "wiktku-start-" + step.id + "-field" })); input.attr("data-placeholder", capitalize(step.name) + " hilbijêre "); populateMenus(input, step.choices); if (step.multiple) input.attr("multiple", true); if (isMobile) { stepDiv.append(wrapNativeSelect(input)); } else { stepDiv.append(input); } } else if (typeof(step.build) === "function") { input = step.build(stepDiv); } else { input = $("<textarea></textarea>") .attr("class", "wiktku-start-step-field") .attr("id", "wiktku-start-" + step.id + "-field") .attr("rows", step.rows || 2); if (step.narrow) input.addClass("wiktku-start-narrow"); if (step.multiple) { input.on("input", function (evt) { refreshForTextField(evt.target, step); }); var keyInput = buildKeyInput(step); var list = $(step.ordered ? "<ol></ol>" : "<ul></ul>") .append($("<li></li>").append(keyInput).append(input)); stepDiv.append(list); } else stepDiv.append(input); } prepareInput(input, step); stepDiv.hide(); // Insert tab bar just before the first per-section step. if (step.id === "pos") startForm.append(sectionTabsDiv); startForm.append(stepDiv); }); // ── Section tab helpers ────────────────────────────────────────────── // ── Add-section button — lives in the tab bar, disabled until pos chosen ── var addSectionBtn = new OO.ui.ButtonWidget({ label: "+ Beş zêde bike", disabled: true }); addSectionBtn.on("click", function () { saveCurrentSection(); sections.push({}); activeSection = sections.length - 1; $.each(PER_SECTION_STEP_IDS, function (_, id) { if (id === "dfn") { var stepDiv = $("#wiktku-start-dfn"); stepDiv.find("ol.wiktku-dfn-list").remove(); steps.dfn.build(stepDiv); return; } if (id === "etym") { $("#wiktku-start-etym .wiktku-etym-wrap").remove(); steps.etym.build($("#wiktku-start-etym")); return; } if (id === "trans") { var transDiv = $("#wiktku-start-trans"); transDiv.find(".wiktku-trans-group").remove(); return; } if (id === "zarava") { var zaravaDiv = $("#wiktku-start-zarava"); zaravaDiv.find(".wiktku-zarava-group").remove(); return; } if (id === "dunde") { var dundeDiv = $("#wiktku-start-dunde"); dundeDiv.find("ul.wiktku-dunde-list").remove(); return; } var stepDiv = $("#wiktku-start-" + id); stepDiv.find(".wiktku-start-step-field").val(""); if (!isMobile) stepDiv.find("select.wiktku-start-step-field").trigger("chosen:updated"); }); renderSectionTabs(); refresh(); $("html, body").animate({ scrollTop: sectionTabsDiv.offset().top - 20 }, 300); }); /** Re-render the tab bar to reflect current sections[] and activeSection. */ function renderSectionTabs() { // Detach (not remove) the button first: .empty() strips bound // event data from any children left inside it, which would // silently kill addSectionBtn's click handler on every re-render. addSectionBtn.$element.detach(); sectionTabsDiv.empty(); var lang = getValues().lang || ""; if (!lang) { sectionTabsDiv.hide(); return; } sectionTabsDiv.show(); $.each(sections, function (i) { var posVal = sections[i].pos || ""; var tabLabel = posVal ? capitalize(posVal) : ("Beş " + (i + 1)); var tab = $("<span></span>") .addClass("wiktku-section-tab") .text(tabLabel) .toggleClass("wiktku-tab-active", i === activeSection); (function (idx) { tab.on("click", function () { if (idx === activeSection) return; saveCurrentSection(); activeSection = idx; restoreSection(sections[activeSection]); refresh(); renderSectionTabs(); }); }(i)); sectionTabsDiv.append(tab); }); // Enable "Beş zêde bike" only when the active section has a pos chosen. var activePos = sections[activeSection] && sections[activeSection].pos ? sections[activeSection].pos : getValues().pos; addSectionBtn.setDisabled(!activePos); sectionTabsDiv.append(addSectionBtn.$element); } renderSectionTabs(); // Update the active tab's label whenever pos changes. startForm.on("change", "#wiktku-start-pos-field", function () { renderSectionTabs(); }); // Show the tab bar as soon as a language is selected. startForm.on("change", "#wiktku-start-lang-field", function () { renderSectionTabs(); }); var footer = $("<div id='wiktku-start-footer'></div>"); spinner = $(mw.html.element("img", { id: "wiktku-start-spinner", src: "//upload.wikimedia.org/wikipedia/commons/d/de/Ajax-loader.gif", alt: "Tê barkirin…", title: "Tê barkirin…" })); footer.append(spinner.hide()); continueBtn = new OO.ui.ButtonWidget({ id: "wiktku-unhide-editform", label: "Bişîne", flags: [ "primary", "progressive" ] }); continueBtn.on("click", function () { mw.notify("Tê şandin…", { type: "info", tag: "wiktku-submit" }); startForm.trigger("submit"); }); footer.append(continueBtn.$element); // "Edîtora çavkaniyê veke" button — inline fallback for the portlet link // which is invisible on mobile and easy to miss on desktop. var sourceEditorBtn = new OO.ui.ButtonWidget({ label: "Edîtora çavkaniyê veke", framed: false }); sourceEditorBtn.on("click", function () { destroy(); }); footer.append(sourceEditorBtn.$element); // ── Preview checkboxes ─────────────────────────────────────────────── // Wikitext preview (raw text panel) var previewCheck = $("<input type='checkbox' id='wiktku-preview-toggle'>"); var previewLabel = $("<label for='wiktku-preview-toggle'></label>") .text(" Pêşdîtina wîkîtekstê"); var previewPanel = $("<pre id='wiktku-preview-panel'></pre>").hide(); // Live rendered preview (parsed HTML panel, same logic as AjaxEdit). // Not available on mobile — API polling causes too many problems on small screens. var livePreviewCheck = null; var livePreviewPanel = null; if (!isMobile) { livePreviewCheck = $("<input type='checkbox' id='wiktku-live-preview-toggle'>"); livePreviewPanel = $("<div id='wiktku-live-preview-panel'></div>").hide(); } // Container that holds both panels and switches between stacked / side-by-side. var previewContainer = $("<div id='wiktku-preview-container'></div>"); previewContainer.append(previewPanel); if (!isMobile) previewContainer.append(livePreviewPanel); var previewTimer = null; var livePreviewIntervalId = -1; var livePreviewActive = false; // guards in-flight fetches after uncheck /** Rebuilds wikitext preview if its checkbox is checked. */ function schedulePreview() { if (!previewCheck.prop("checked")) return; clearTimeout(previewTimer); // Debounce: wait 400 ms after the last keystroke before rebuilding. previewTimer = setTimeout(function () { getWikitext(function (wikitext) { previewPanel.text(wikitext).show(); updatePanelLayout(); }); }, 400); } /** Fetches parsed HTML and populates the live preview panel. */ function loadLivePreview() { getWikitext(function (wikitext) { new mw.Api().parse(wikitext, { title: mw.config.get("wgPageName") }).done(function (html) { // Discard result if the user unchecked while the fetch was in flight. if (!livePreviewActive) return; livePreviewPanel.html(html).show(); updatePanelLayout(); }); }); } /** Adjusts panel widths depending on which previews are visible. */ function updatePanelLayout() { var wikitextVisible = previewCheck.prop("checked"); var liveVisible = livePreviewCheck && livePreviewCheck.prop("checked"); if (wikitextVisible && liveVisible) { // Side by side — each panel takes roughly half the available width. previewPanel.css({ "flex": "1 1 45%", "min-width": "280px" }); livePreviewPanel.css({ "flex": "1 1 45%", "min-width": "280px" }); } else { // Full width for whichever is visible — only touch panels that are // actually shown so that setting flex doesn't override display:none. if (wikitextVisible) previewPanel.css({ "flex": "1 1 100%", "min-width": "" }); if (liveVisible && livePreviewPanel) livePreviewPanel.css({ "flex": "1 1 100%", "min-width": "" }); } } previewCheck.on("change", function () { if ($(this).prop("checked")) { schedulePreview(); } else { clearTimeout(previewTimer); previewPanel.hide(); updatePanelLayout(); } }); if (!isMobile) { livePreviewCheck.on("change", function () { if ($(this).prop("checked")) { livePreviewActive = true; livePreviewPanel.show(); loadLivePreview(); livePreviewIntervalId = setInterval(loadLivePreview, 500); } else { livePreviewActive = false; clearInterval(livePreviewIntervalId); livePreviewIntervalId = -1; livePreviewPanel.hide().empty(); updatePanelLayout(); } }); } // Listen on all input/change events on the form and update both previews. startForm.on("input change", function () { schedulePreview(); }); footer.append($("<span style='margin-left:1em'></span>") .append(previewCheck).append(previewLabel)); if (!isMobile) { var livePreviewLabel = $("<label for='wiktku-live-preview-toggle'></label>") .text(" Pêşdîtina zindî"); footer.append($("<span style='margin-left:1em'></span>") .append(livePreviewCheck).append(livePreviewLabel)); } startForm.append(footer); $("#editform").hide().before(startForm); // Insert preview container (holds both panels) after the form. startForm.after(previewContainer); if (!isMobile) startForm.find("select").chosen(chosenOptions); refresh(); // Zimanan ji MediaWiki:Gadget-translation_editor.js/ziman.json bar bike. // Kodên ku bi "-pro" diqedin û navên ku "zimanê destan" tê de heye // tên derxistin. Zimanên xardkirî li serî dimînin, yên din // bi alfabeyê li dû wan tên. // Pinned choices come from MediaWiki:Gadget-start.js/data.json (langChoices), // already loaded into steps.lang.choices before build() runs. var pinnedChoices = steps.lang.choices.slice(); var pinnedCodes = $.map(pinnedChoices, function (choice) { return choice[0]; }); new mw.Api().get({ action: "query", prop: "revisions", titles: "MediaWiki:Gadget-translation_editor.js/ziman.json", rvprop: "content", rvslots: "main", formatversion: 2 }).then(function (data) { var page = data.query.pages[0]; var content = page && page.revisions && page.revisions[0].slots.main.content; var zimanData; try { zimanData = JSON.parse(content); } catch (e) { zimanData = {}; } var extraChoices = []; $.each(zimanData, function (code, name) { // Filter: skip proto-language codes and legendary/reconstructed langs. if (/-pro$/i.test(code)) return; if (/ziman[eê]\s+destan/i.test(name)) return; // Skip codes already in the pinned list (they are handled above). if (pinnedCodes.indexOf(code) !== -1) return; // sortKey: bare name without leading "zimanê " for sorting. var sortKey = name.replace(/^ziman[eê]\s+/i, ""); var choice = [code, name, sortKey]; extraChoices.push(choice); langsByCode[code] = choice; }); // Populate langsByCode for pinned choices too. $.each(pinnedChoices, function (i, choice) { // Ensure pinned choices have a sortKey (index 2). if (choice.length < 3) choice[2] = choice[1]; langsByCode[choice[0]] = choice; }); // Sort the extra choices alphabetically by sort key. extraChoices.sort(function (a, b) { return a[2].localeCompare(b[2], userLang); }); // Final list: pinned first, then the rest. var allChoices = pinnedChoices.concat(extraChoices); steps.lang.choices = allChoices; steps.trans.keys = allChoices; steps.dunde.keys = allChoices; steps.zarava.keys = getZaravaKeys(allChoices); var langMenu = $("#wiktku-start-lang-field"); populateMenus(langMenu, steps.lang.choices); langMenu.trigger("chosen:updated"); var transMenus = $("#wiktku-start-trans .wiktku-start-step-keyfield"); populateMenus(transMenus, steps.trans.keys, getDisabledKeys(steps.trans)); transMenus.trigger("chosen:updated"); var dundeMenus = $("#wiktku-start-dunde .wiktku-start-step-keyfield"); populateMenus(dundeMenus, steps.dunde.keys, getDisabledKeys(steps.dunde)); dundeMenus.trigger("chosen:updated"); var zaravaMenus = $("#wiktku-start-zarava .wiktku-start-step-keyfield"); populateMenus(zaravaMenus, steps.zarava.keys, getDisabledKeys(steps.zarava)); }); } mw.loader.using(["jquery.chosen", "mediawiki.api", "oojs-ui-core"], function () { if (!isMobile) { mw.notify( "Amûr dest pê dike, hinek bisekinin. Not: jkx Sentaks (sentaks highlighter) neaktîv bikin", { type: "info", tag: "wiktku-start-notice", autoHide: true, autoHideSeconds: 10 } ); } // Load metadata, langChoices, posChoices and tplDefs from the companion // data page so they can be updated without touching this script. new mw.Api().get({ action: "query", prop: "revisions", titles: "MediaWiki:Gadget-start.js/data.json", rvprop: "content", rvslots: "main", formatversion: 2 }).then(function (data) { var page = data.query.pages[0]; var content = page && page.revisions && page.revisions[0].slots.main.content; var d; try { d = JSON.parse(content); } catch (e) { d = {}; } // Populate metadata. if (d.metadata) $.extend(metadata, d.metadata); // Populate gender labels. if (d.genderLabels) $.extend(GENDER_BASE_LABELS, d.genderLabels); // Populate lang choices (pinned list used by build() → ziman.json loader). if (d.langChoices) steps.lang.choices = d.langChoices; // Populate POS choices. if (d.posChoices) steps.pos.choices = d.posChoices; // Populate template definitions for the dfn sense-block builder. if (d.tplDefs) steps.dfn.tplDefs = d.tplDefs; // Populate pos placeholder examples. if (d.posExamples) steps.dfn.posExamples = d.posExamples; // Populate citation template definitions for the quote widget. if (d.jederDefs) steps.dfn.jederDefs = d.jederDefs; // Populate pronunciation and etymology template insert lists. if (d.pronTpls) { steps.pron.pronTpls = d.pronTpls; steps.pron.refreshTplSelect(); } if (d.etymTpls) { steps.etym.etymTpls = d.etymTpls; steps.etym.refreshTplSelect(); } // Sync trans/dunde/zarava keys with the (now populated) lang choices. steps.trans.keys = steps.lang.choices; steps.dunde.keys = steps.lang.choices; steps.zarava.keys = getZaravaKeys(steps.lang.choices); }).always(build); }); }); //</nowiki> rjc3lue3ledcaegwkfdnmhn738xjmud 6265572 6265571 2026-07-19T14:10:11Z Wikihez 7344 6265572 javascript text/javascript // Li ser [[vi:MediaWiki:Gadget-start.js]] hatiye refaktorkirin. //<nowiki> $(function () { if (window.location.href.includes("editintro=User:Wikihez/creation/intro")) { return; // Do not run the script wextê WF:Bilez dişuxile } var ns = mw.config.get("wgNamespaceNumber"); if (ns && !(ns === 2 && mw.config.get("wgPageName").match(/\/ceribandin$|\/test$/))) { return; } var action = mw.config.get("wgAction"); var pageExists = !!mw.config.get("wgArticleId"); // "Zimanek lê zêde bike" mode: triggered from the portlet link below. var addLangMode = pageExists && mw.util.getParamValue("wiktkuaddlang") === "1"; // On a normal page view of an existing page, add the portlet link if (action === "view" && pageExists) { var targetContainer; var skin = mw.config.get('skin'); if (skin === 'vector-2022') { targetContainer = 'p-cactions'; } else if (skin === 'vector') { targetContainer = 'p-tb'; } else { targetContainer = 'p-views'; } mw.util.addPortletLink(targetContainer, mw.util.getUrl(mw.config.get("wgPageName"), { action: "submit", wiktkuaddlang: "1" }), "+Ziman/beşeke din", "ca-wiktku-addlang", "Ji vê rûpelê re ziman an jî beşeke nû zêde bike"); return; } if (!(action === "edit" || action === "submit")) { return; } if (!addLangMode && !$(".mw-newarticletext, .mw-newarticletextanon").length) { return; } function capitalize(str) { if (!str) return str; return str[0].toUpperCase() + str.substr(1); } function decapitalize(str) { if (!str) return str; return str[0].toLowerCase() + str.substr(1); } function escapeRegExp(str) { return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); } function stripWikilinks(str) { return str.replace(/\[\[([^\]|]+)(?:\|([^\]]+))?\]\]/g, function (m, target, display) { return display || target; }); } function insertAtCursor(el, text) { var start = el.selectionStart; var end = el.selectionEnd; var val = el.value; el.value = val.slice(0, start) + text + val.slice(end); var pos = start + text.length; el.selectionStart = el.selectionEnd = pos; } var pageName = mw.config.get("wgPageName").replaceAll(/_/g, " "); if (ns) pageName = pageName.replace(/.*\//, ""); var pageNameRe = escapeRegExp(pageName); var userLang = mw.config.get("wgUserLanguage"); // Mobile detection: MobileFrontend sets wgMFMode, or fall back to touch check. var isMobile = !!mw.config.get("wgMFMode") || window.matchMedia("(pointer: coarse)").matches; var chosenOptions = { width: "20em", disable_search_threshold: 0, placeholder_text_single: "Yekî hilbijêre", placeholder_text_multiple: "Hilbijêre", no_results_text: "Nehat dîtin", enable_split_word_search: true, search_contains: true }; function wrapNativeSelect(select) { var placeholder = select.attr("data-placeholder") || "Lê bigere…"; // Hide the native select — we drive it programmatically. select.hide(); var wrapper = $("<span class='wiktku-native-select-wrap'></span>"); var textInput = $("<input type='search' autocomplete='off'>") .attr("placeholder", placeholder) .addClass("wiktku-start-narrow wiktku-ac-input"); var resultsList = $("<ul class='wiktku-ac-results'></ul>").hide(); // Full option cache — rebuilt when chosen:updated fires. var allOptions = []; function cacheOptions() { allOptions = []; select.find("option").each(function () { var v = $(this).val(); if (!v) return; // skip the empty placeholder option allOptions.push({ value: v, text: $(this).text(), disabled: $(this).prop("disabled") }); }); } cacheOptions(); function showResults(query) { var q = query.trim().toLowerCase(); resultsList.empty(); var matched; if (q) { matched = []; $.each(allOptions, function (_, o) { if (o.disabled) return; var codeMatch = o.value.toLowerCase().indexOf(q) !== -1; var nameMatch = o.text.toLowerCase().indexOf(q) !== -1; if (codeMatch || nameMatch) { matched.push({ opt: o, codeMatch: codeMatch }); } }); // Code matches (especially prefix matches) come first. matched.sort(function (a, b) { var aCode = a.opt.value.toLowerCase(); var bCode = b.opt.value.toLowerCase(); var aPrefix = aCode.indexOf(q) === 0; var bPrefix = bCode.indexOf(q) === 0; if (aPrefix !== bPrefix) return aPrefix ? -1 : 1; if (a.codeMatch !== b.codeMatch) return a.codeMatch ? -1 : 1; return 0; }); matched = matched.map(function (item) { return item.opt; }); } else { matched = allOptions.filter(function (o) { return !o.disabled; }); } if (!matched.length) { resultsList.hide(); return; } $.each(matched.slice(0, 50), function (_, opt) { var li = $("<li></li>").text(opt.text).attr("data-value", opt.value); // Use touchend instead of touchstart so that a scroll gesture does // not accidentally select an item. We track whether the finger moved // between touchstart and touchend — if it did, it was a scroll. var touchMoved = false; li.on("touchstart", function () { touchMoved = false; }); li.on("touchmove", function () { touchMoved = true; }); li.on("touchend", function (e) { if (touchMoved) return; // was a scroll, not a tap e.preventDefault(); selectOption(opt.value, opt.text); }); // Keep mousedown for desktop fallback. li.on("mousedown", function (e) { e.preventDefault(); selectOption(opt.value, opt.text); }); resultsList.append(li); }); // Position the list above or below depending on available viewport space. var inputRect = textInput[0].getBoundingClientRect(); var viewportH = window.innerHeight; var spaceBelow = viewportH - inputRect.bottom - 8; var spaceAbove = inputRect.top - 8; var maxH = Math.min(224, Math.max(spaceBelow, spaceAbove)); // 224px ≈ 14em resultsList.css({ "max-height": maxH + "px", "top": spaceBelow >= spaceAbove ? "100%" : "auto", "bottom": spaceBelow >= spaceAbove ? "auto" : "100%" }); resultsList.show(); } function selectOption(value, text) { textInput.val(text); select.val(value); resultsList.hide(); select.trigger("change"); } textInput.on("input focus", function () { showResults($(this).val()); }); textInput.on("blur", function () { // Short delay so a touchstart on a result item fires first. setTimeout(function () { resultsList.hide(); }, 200); }); // chosen:updated → re-cache (called after ziman.json loads). select.on("chosen:updated", function () { cacheOptions(); // If a value is already selected, keep the display text in sync. var cur = select.val(); if (cur) { var match = $.grep(allOptions, function (o) { return o.value === cur; })[0]; if (match) textInput.val(match.text); } }); // No-op .chosen() so desktop call-sites don't need guarding. select.chosen = function () { return select; }; wrapper.append(textInput).append(resultsList).append(select); return wrapper; } var langsByCode = {}; // Populated from [[MediaWiki:Gadget-start.js/data.json]] at runtime. var metadata = {}; // Zaravayên kurdî yên ku di beşa "Bi zaravayên din" de tên pêşkêşkirin — // ev kod ji beşa Werger têne derxistin daku heman zimên du caran neyê xwendin. var ZARAVA_LANG_CODES = ["ckb", "sdh", "lki", "hac", "zza"]; function getZaravaKeys(choices) { var byCode = {}; $.each(choices || [], function (_, c) { byCode[c[0]] = c; }); var result = []; $.each(ZARAVA_LANG_CODES, function (_, code) { if (byCode[code]) result.push(byCode[code]); }); return result; } function needsTransliteration(langCode) { var meta = metadata[langCode]; if (!meta || !meta.sc) return false; var scripts = Array.isArray(meta.sc) ? meta.sc : [meta.sc]; return scripts.length > 0 && scripts[0] !== "Latn"; } // Kodên cinsiyetê yên di metadata.g de — ji data.json tê dagirtin var GENDER_BASE_LABELS = {}; // Sub-lists that only make sense for a plain (non-şablon) sense — hidden // when a şablon (e.g. {{guharto|…}}) is chosen for that sense, since a // template-based sense has no "own" gloss for alternate forms, synonyms, // antonyms, coordinate terms, hypernyms or hyponyms to attach to. Etîket, // Nimûne and Jêgirtin stay visible either way. var HIDDEN_ON_TPL_GROUPS = [ "wiktku-dfn-alternativ", "wiktku-dfn-hevmane", "wiktku-dfn-dijmane", "wiktku-dfn-koordine", "wiktku-dfn-jornav", "wiktku-dfn-jernav" ]; function genderLabel(code) { if (code === "p") return "Pirjimar"; var pluralMatch = code.match(/^(.+)-p$/); if (pluralMatch && GENDER_BASE_LABELS[pluralMatch[1]]) { return GENDER_BASE_LABELS[pluralMatch[1]] + " (pirjimar)"; } return GENDER_BASE_LABELS[code] || code; } /** * True if a sense has any content worth keeping besides its mane text — * etîket, hevmane/dijmane/koordîne/etc. word lists, nimûne, or jêder * (quote). Used so a sense with an empty mane but filled-in extra * fields still gets emitted (with {{mane?}} standing in for the gloss) * instead of being silently dropped. */ function senseHasExtraContent(s) { if (s.etiket && $.grep(s.etiket, function (e) { return $.trim(e) !== ""; }).length) return true; if (s.alternativ.length || s.hevmane.length || s.dijmane.length || s.koordine.length || s.jornav.length || s.jernav.length) return true; if (s.nimune && $.grep(s.nimune, function (n) { return (typeof n === "object" ? n.text : n) !== ""; }).length > 0) return true; if (s.jeder && $.grep(s.jeder, function (j) { return j && j.quote; }).length > 0) return true; return false; } /** * formatNimune: each nimûne item can be { text, tr, t }: * text — example text * tr — transliteration (only when the language needs it) * t — Kurdish translation (third positional param, no key) */ function formatNimune(nimunes, lang, hasJeder) { var hasNimune = nimunes && $.grep(nimunes, function (n) { return (typeof n === "object" ? n.text : n) !== ""; }).length > 0; if (!hasNimune) { return hasJeder ? "" : "\n#* {{bênimûne|" + lang + "}}"; } return $.map(nimunes, function (n) { var text = typeof n === "object" ? n.text : n; if (!text) return undefined; var bolded = text.replace( new RegExp("(" + pageNameRe + "([^( |,|;|\\?|\\.|\\!)]+)?)", "ig"), "'''$1'''"); var tpl = "\n#: {{nm|" + lang + "|" + bolded; if (typeof n === "object") { if (n.tr) tpl += "|tr=" + n.tr; // Translation as third positional param (no key needed). if (n.t) tpl += "|" + n.t; } // Short examples fit on one line together with their translation. // rêz=1 is not used for ku — definitions are shown on separate lines there. if (text.length < 200 && lang !== "ku") tpl += "|rêz=1"; tpl += "}}"; return tpl; }).join(""); } /** * Formats a list of jêder (quote/citation) objects into wikitext lines. * Each entry that has no quote text is skipped. Returns "" when the list * is empty or every entry is blank. * * #* {{jêder-…|lang|jêgirtin=…|tr=…|tercime=…|…fields…}} * * When no template is chosen, the generic {{jêder|…}} template is used * instead. Its 2nd positional param is the user's freeform "bi destê xwe * binivîsim" source text when supplied, or the çavkanî? placeholder otherwise. * If that text contains "=" it is passed as |2=… instead of a bare * positional param, since MediaWiki would otherwise misparse it as its * own key=value pair and break the template: * #* {{jêder|lang|jêgirtin=…|tr=…|tercime=…|<manual source or çavkanî?>}} */ function formatJeder(jederList, lang) { if (!jederList || !jederList.length) return ""; return $.map(jederList, function (jeder) { if (!jeder || !jeder.quote) return undefined; if (jeder.jederTpl) { var cite = "\n#* {{" + jeder.jederTpl + "|" + lang; cite += "|jêgirtin=" + jeder.quote; if (jeder.quoteTr) cite += "|tr=" + jeder.quoteTr; if (jeder.quoteT) cite += "|tercime=" + jeder.quoteT; $.each(jeder.jêderFields || {}, function (key, val) { if (val) cite += "|" + key + "=" + val; }); cite += "}}"; return cite; } var out = "\n#* {{jêder|" + lang + "|jêgirtin=" + jeder.quote; if (jeder.quoteTr) out += "|tr=" + jeder.quoteTr; if (jeder.quoteT) out += "|tercime=" + jeder.quoteT; var srcParam = jeder.jederManual ? jeder.jederManual : "çavkanî?"; // A positional param containing "=" gets parsed as its own key=value // pair by MediaWiki and breaks the template, so force it to be // explicitly named (|2=) whenever that's the case. out += (srcParam.indexOf("=") !== -1 ? "|2=" : "|") + srcParam; out += "}}"; return out; }).join(""); } function makeWordListStep(id, name, question_fmt, header, templateName) { return { id: id, name: name, question_fmt: question_fmt, multiple: true, narrow: true, visible: function (values) { return values.lang && values.pos; }, output: function (values) { var words = $.grep(values[id] || [], function (w) { return !!w; }); if (!words.length) return ""; var lang = values.lang; var section = "\n==== " + header + " ====\n"; if (words.length === 1) { // Single word — keep the simple inline template. return section + "* {{" + templateName + "|" + lang + "|" + words[0] + "}}\n"; } // Multiple words — use {{kol3}} with one positional param per word. var params = "cure=" + header + "\n" + $.map(words, function (w) { return "|" + w; }).join("\n"); return section + "{{kol3|" + lang + "|" + params + "\n}}\n"; } }; } var steps = { lang: { id: "lang", required: true, name: "ziman", question_fmt: '"' + pageName + '" bi çi zimanî ye?', question_br: true, // Populated from [[MediaWiki:Gadget-start.js/data.json]] (langChoices). choices: [], output: function (values) { return "== {{ziman|" + values.lang + "}} ==\n"; } }, pron: { id: "pron", name: "bilêvkirin", question_fmt: '"' + pageName + '" çawa tê telafûzkirin?', // pronTpls populated from data.json pronTpls: [], visible: function (values) { if (!values.lang) return false; // In addLangMode, only skip pron when this langcode's section // already exists in the page — if it's a new language, show it. if (addLangMode) { var existing = $("#wpTextbox1").val() || ""; var header = "== {{ziman|" + values.lang + "}} =="; return existing.indexOf(header) === -1; } return true; }, /** Fills (or refills) the insert-dropdown from the current pronTpls array, filtering by language. */ refreshTplSelect: function () { var sel = $("#wiktku-start-pron .wiktku-tpl-insert-select"); if (!sel.length) return; var lang = getValues().lang || ""; sel.find("option[value!='']").remove(); $.each(steps.pron.pronTpls, function (_, tpl) { // Filter: if tpl.langs exists, only show if lang is in that list; otherwise show always var allowed = !tpl.langs || tpl.langs.indexOf(lang) !== -1; if (allowed) { sel.append($("<option></option>") .val(tpl.snippet) .text(tpl.name + " — " + tpl.desc) .attr("data-nolang", tpl.noLang ? "1" : "")); } }); // Notify Chosen that the option list has changed (no-op on mobile). if (!isMobile) sel.trigger("chosen:updated"); }, build: function (stepDiv) { if (stepDiv.find(".wiktku-pron-wrap").length) return null; var wrap = $("<div class='wiktku-pron-wrap'></div>"); var ta = $("<textarea></textarea>") .attr("name", "wiktku-pron-" + $.now()) .attr("class", "wiktku-start-step-field wiktku-pron-text") .attr("rows", 4) .attr("placeholder", "Nimûne: {{IPA|ku|/pɛɪ̯n/}} yan {{kîte|ku|he|ce|ki|rin}}"); // Template insert dropdown — filtered by language. var sel = $("<select class='wiktku-tpl-insert-select'></select>"); sel.append($("<option value=''>— şablonek lê zêde bike —</option>")); var lang = getValues().lang || ""; $.each(steps.pron.pronTpls, function (_, tpl) { // Filter: if tpl.langs exists, only show if lang is in that list; otherwise show always var allowed = !tpl.langs || tpl.langs.indexOf(lang) !== -1; if (allowed) { sel.append($("<option></option>") .val(tpl.snippet) .text(tpl.name + " — " + tpl.desc) .attr("data-nolang", tpl.noLang ? "1" : "")); } }); sel.on("change", function () { var snippet = $(this).val(); if (!snippet) return; var lang = getValues().lang || ""; // Check if the selected option has noLang flag var selectedOption = sel.find("option:selected"); var hasNoLang = selectedOption.attr("data-nolang") === "1"; if (!hasNoLang) { snippet = snippet.replace(/CODE/g, lang).replace(/SOURCELANG/g, "?"); } insertAtCursor(ta[0], snippet); $(this).val(""); ta.focus(); }); wrap.append(sel).append($("<br>")).append(ta); stepDiv.append(wrap); return ta; }, output: function () { var text = $.trim($("#wiktku-start-pron .wiktku-pron-text").val()); if (!text) return ""; var lines = text.split("\n"); var out = $.map(lines, function (line) { line = $.trim(line); if (!line) return undefined; return line.charAt(0) === "*" ? line : "* " + line; }).join("\n"); return "\n=== Bilêvkirin ===\n" + out + "\n"; } }, pos: { id: "pos", required: true, name: "Cureyê rêzimanî", question_fmt: 'Cureyê rêzimanî yê "' + pageName + '" çi ye?', visible: function (values) { return values.lang; }, question_br: true, // Populated from [[MediaWiki:Gadget-start.js/data.json]] (posChoices). choices: [], output: function (values) { var pos = values.pos || ""; var cinsiyet = values.cinsiyet || ""; // from the cinsiyet step var lekTur = values.lektur || ""; // from the lêker transitivity step var capitalizedPos = capitalize(pos); var outputString = "\n=== " + capitalizedPos + " ===\n"; // Add ku-tewîn-nav for single-word navdêr/serenav with known gender. if (!pageName.includes(" ") && cinsiyet && GENDER_BASE_LABELS[cinsiyet] && (pos === "navdêr" || pos === "serenav") && values.lang === "ku") { outputString += "{{ku-tewîn-nav|" + pageName + "|" + GENDER_BASE_LABELS[cinsiyet]; if (pos === "serenav") outputString += "|y"; outputString += "}}\n"; } outputString += "{{" + pos + "|" + values.lang; if (pos === "navdêr" || pos === "serenav") { if (cinsiyet) { outputString += "|c=" + cinsiyet; } else if (values.lang === "ku") { // Unknown gender — prompt editor to fill it in. outputString += "|c=?"; } } else if (/^lêker/.test(pos) && lekTur) { outputString += "|c=" + lekTur; } if (values.tr) { outputString += "|tr=" + values.tr; } outputString += "}}\n"; return outputString; } }, /** * cinsiyet (grammatical gender) — only shown for navdêr/serenav, û * tenê ger metadata ji bo zimanê hilbijartî lîsteyeke "g" (cinsiyet) * were dayîn. Opsiyonên vê gavê ne sabît in — ji metadata[values.lang].g * têne çêkirin, ji ber ku di hemû zimanan de cinsiyet tine. */ cinsiyet: { id: "cinsiyet", name: "cinsiyet", question_fmt: 'Cinsiyeta "' + pageName + '" çi ye?', question_br: true, visible: function (values) { var meta = metadata[values.lang]; return !!(values.lang && (values.pos === "navdêr" || values.pos === "serenav") && meta && meta.g && meta.g.length); }, build: function (stepDiv, values) { var select = stepDiv.find("select.wiktku-start-step-field"); if (!select.length) { select = $(mw.html.element("select", { "class": "wiktku-start-step-field", id: "wiktku-start-cinsiyet-field" })); stepDiv.append(select); } if (!values) return select; var meta = metadata[values.lang]; var codes = (meta && meta.g) || []; var prevVal = select.val(); var choices = $.map(codes, function (code) { return [[code, genderLabel(code)]]; }); populateMenus(select, choices); if ($.grep(choices, function (c) { return c[0] === prevVal; }).length) { select.val(prevVal); } if (!isMobile) select.trigger("chosen:updated"); return select; }, output: function () { return ""; } // consumed by pos.output }, /** * Lêker transitivity — only shown for any lêker variant. */ lektur: { id: "lektur", name: "Cureyê lêkerê (fiîlê)", question_fmt: "Cureyê lêkerê (fiîlê) çi ye?", question_br: true, visible: function (values) { return values.lang && values.pos && /^lêker/.test(values.pos); }, // Dictionary: value → display label. Add new types here. choices: [ ["gh", "gerguhêz"], ['x-gh', 'xwerû-gerguhêz'], ['p-gh', 'pêkhatî-gerguhêz'], ['h-gh', 'hevedudanî-gerguhêz'], ['b-gh', 'biwêjî-gerguhêz'], ["ngh", "negerguhêz"], ['x-ngh', 'xwerû-negerguhêz'], ['p-ngh', 'pêkhatî-negerguhêz'], ['h-ngh', 'hevedudanî-negerguhêz'], ['b-ngh', 'biwêjî-negerguhêz'] ], output: function () { return ""; } // consumed by pos.output }, tr: { id: "tr", name: "transkrîpsiyon", question_fmt: "Transkrîpsiyona kelîmeyê", multiple: false, narrow: true, visible: function (values) { return values.lang && values.pos && needsTransliteration(values.lang); } }, dfn: { id: "dfn", // required: true, ger mane tinebe [[Şablon:mane?]] bi kar bîne name: "Mane", question_fmt: "Maneya kelîmeyê binivîse. Mane otomatîk tê lînkkirin! Ji bo tercimeyan beşa 'Werger' bi kar bîne!", multiple: true, ordered: true, rows: 3, visible: function (values) { return values.lang && values.pos; }, example: function (values) { // posExamples loaded from [[MediaWiki:Gadget-start.js/data.json]]. var examples = steps.dfn.posExamples || {}; var full = values.pos || ""; return examples[full] || ""; }, /** * Builds one sense block (<li>) inside the ordered list. * Each block contains: * - a textarea for the definition * - an expandable nimûne list * - single-row sub-lists for formên alternatîv, hevmane, dijmane */ buildSenseBlock: function (stepDiv) { var block = $("<li class='wiktku-dfn-sense'></li>"); // — Mane textarea (declared first so the template handler can reference it) — var dfnArea = $("<textarea></textarea>") .attr("name", "wiktku-dfn-mane-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("class", "wiktku-start-step-field wiktku-dfn-mane") .attr("rows", 6) .attr("placeholder", "Mane…"); dfnArea.on("input", function () { steps.dfn.onDfnInput(stepDiv, block, this); }); // — Template selector (optional — replaces mane when chosen) — // Template definitions loaded from [[MediaWiki:Gadget-start.js/data.json]]. var tplDefs = steps.dfn.tplDefs || []; // Cache of all non-placeholder option elements — used by updateTplOptions // to remove/re-add options (the only approach compatible with Chosen.js). var _allTplOptions = []; var tplSelect = $(mw.html.element("select", { "class": "wiktku-dfn-tpl-select" })); tplSelect.append($("<option value=''>— yan jî şablonek hilbijêre —</option>")); $.each(tplDefs, function (_, tpl) { var opt = $("<option></option>") .val(tpl.name) .text(tpl.name) .attr("data-langs", tpl.langs ? tpl.langs.join(",") : "") .attr("data-nolang", tpl.noLang ? "1" : ""); tplSelect.append(opt); _allTplOptions.push(opt[0]); }); function updateTplOptions() { var lang = getValues().lang || ""; var currentVal = tplSelect.val(); var currentStillValid = false; // Detach all non-placeholder options, then re-attach only the visible ones. // This is the only approach that works correctly with both native <select> // and Chosen.js on desktop. tplSelect.find("option[value!='']").detach(); $.each(_allTplOptions, function (_, opt) { var allowed = $(opt).attr("data-langs"); var visible = !allowed || allowed.split(",").indexOf(lang) !== -1; if (visible) { tplSelect.append(opt); if ($(opt).val() === currentVal) currentStillValid = true; } }); if (!isMobile) tplSelect.trigger("chosen:updated"); if (currentVal && !currentStillValid) { tplSelect.val(""); dfnArea.show(); tplTitleInput.hide().val(""); } } // Store updater on the element so refresh() can call it for all blocks. tplSelect.data("updateOptions", updateTplOptions); var tplTitleInput = $("<input type='text'>") .addClass("wiktku-dfn-tpl-title wiktku-start-narrow") .attr("placeholder", "Navê rûpelê…") .hide(); // Grow the sense list when the title field of the last block gets content, // mirroring what onDfnInput does for the plain mane textarea. tplTitleInput.on("input", function () { steps.dfn.onDfnInput(stepDiv, block, this); }); /** * When a şablon sense is chosen, formên alternatîv/hevmane/dijmane/ * termên koordîne/jornav/jêrnav don't apply (there's no plain gloss * to hang them off), so hide those subgroups. Etîket, Nimûne and * Jêgirtin stay visible and still usable for a şablon sense. */ function updateFieldVisibility() { var isTpl = !!tplSelect.val(); $.each(HIDDEN_ON_TPL_GROUPS, function (_, cls) { block.find("." + cls + "-group").toggle(!isTpl); }); } // Store on the block so restoreDfn() can re-sync visibility // after programmatically setting tplSelect's value. block.data("updateFieldVisibility", updateFieldVisibility); tplSelect.on("change", function () { var chosen = $(this).val(); if (chosen) { dfnArea.hide(); tplTitleInput.show().focus(); } else { dfnArea.show(); tplTitleInput.hide().val(""); } updateFieldVisibility(); // Re-run refresh so the Werger step visibility updates. refresh(); }); var tplRow = $("<div></div>").addClass("wiktku-dfn-tpl-row") .append(tplSelect).append(" ").append(tplTitleInput); block.append(tplRow); block.append(dfnArea); // Apply lang filter on initial build. updateTplOptions(); // — Sub-field groups — // All groups are always visible with a placeholder textarea. // Nimûne is last in the DOM and last in the output. var allGroups = [ { cls: "wiktku-dfn-etiket", label: "Etîket", rows: 1, narrow: true, izah: "xisûsen, Mêrdîn, anatomî, Badînî" }, { cls: "wiktku-dfn-alternativ", label: "Formên alternatîv", rows: 1, narrow: true, izah: "Varyantên vê kelîmeyê" }, { cls: "wiktku-dfn-hevmane", label: "Hevmane", rows: 1, narrow: true, izah: "Spehî hevmaneya Bedew e." }, { cls: "wiktku-dfn-dijmane", label: "Dijmane", rows: 1, narrow: true, izah: "Zengîn dijmaneya feqîr e." }, { cls: "wiktku-dfn-koordine", label: "Termên koordîne", rows: 1, narrow: true, izah: "Pisîk û kûçik termên koordîne ne çunkî Jornavên wan gelek in" }, { cls: "wiktku-dfn-jornav", label: "Jornav", rows: 1, narrow: true, izah: "Heywan jornavê guhandar e" }, { cls: "wiktku-dfn-jernav", label: "Jêrnav", rows: 1, narrow: true, izah: "Guhandar jêrnavê heywan e" }, { cls: "wiktku-dfn-nimune", label: "Nimûne", rows: 2, narrow: false } ]; $.each(allGroups, function (_, g) { var groupDiv = $("<div></div>").addClass("wiktku-dfn-subgroup " + g.cls + "-group"); function buildNimuneLi() { var lang = getValues().lang || ""; var li = $("<li></li>").addClass("wiktku-dfn-nimune-li"); var mainTa = $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-text-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", g.rows) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-text") .attr("placeholder", "Nimûneya emilandina kelîmeyê tu bi xwe binivîse…"); mainTa.on("input", function () { var val = $.trim($(this).val()); var isLast = li.is(list.children("li:last-child")); if (val && isLast) { list.append(buildNimuneLi()); } }); li.append(mainTa); var subWrap = $("<div></div>").addClass("wiktku-dfn-nimune-sub"); if (needsTransliteration(lang)) { subWrap.append( $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-tr-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 5) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-tr") .attr("placeholder", "Transkrîpsiyona bi alfabeya latînî") ); } if (lang && lang !== "ku") { subWrap.append( $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-t-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 5) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-t") .attr("placeholder", "Tercimeya kurmancî") ); } if (subWrap.children().length) li.append(subWrap); return li; } if (g.cls === "wiktku-dfn-nimune") { // Nimûne — compound widget with tr/t sub-fields. var lbl = $("<span></span>").addClass("wiktku-dfn-sublabel").text(g.label + ": "); var list = $("<ol></ol>").addClass("wiktku-dfn-sublist " + g.cls + "-list"); groupDiv.data("buildNimuneLi", buildNimuneLi); list.append(buildNimuneLi()); groupDiv.append(lbl).append(list); block.append(groupDiv); } else { // Regular always-visible group — label + growing textarea list. var lbl = $("<span></span>").addClass("wiktku-dfn-sublabel").text(g.label + ": " + g.izah); var list = $("<ol></ol>").addClass("wiktku-dfn-sublist " + g.cls + "-list"); var firstInput = $("<textarea></textarea>") .attr("name", g.cls + "-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", g.rows) .attr("class", "wiktku-dfn-subfield" + (g.narrow ? " wiktku-start-narrow" : "")) .attr("placeholder", g.label + "…"); firstInput.on("input", function () { steps.dfn.onSubInput(list, this, g.rows, g.narrow); }); list.append($("<li></li>").append(firstInput)); groupDiv.append(lbl).append(list); block.append(groupDiv); } }); // — Jêder (quote / citation) group — a growing list, sibling to Nimûne — // Structured the same way as Nimûne (ol.wiktku-dfn-sublist > li) so it // lines up at the same indentation, and so that typing into the last // citation's Jêgirtin box automatically opens a fresh empty one below it. (function () { var jederGroupDiv = $("<div></div>").addClass("wiktku-dfn-subgroup wiktku-dfn-jeder-group"); var jederLbl = $("<span></span>").addClass("wiktku-dfn-sublabel").text("Jêgirtin: "); var jederList = $("<ol></ol>").addClass("wiktku-dfn-sublist wiktku-dfn-jeder-list"); function buildJederLi() { var lang = getValues().lang || ""; var li = $("<li></li>").addClass("wiktku-dfn-jeder-li"); var dragHandle = $("<span></span>") .addClass("wiktku-jeder-drag-handle") .attr("title", "Bişkûne û bikişîne da ku rêzê biguhezîne"); // Quote text textarea var quoteTa = $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-quote-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 2) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-quote") .attr("placeholder", "Nimûneya emilandinê ji kitêb an çavkaniyeke din binivîse"); quoteTa.on("input", function () { var val = $.trim($(this).val()); var isLast = li.is(jederList.children("li:last-child")); if (val && isLast) { jederList.append(buildJederLi()); } }); li.append(dragHandle).append(quoteTa); // tr/t sub-fields for the quote — shown as needed for the language. var quoteSubWrap = $("<div></div>").addClass("wiktku-dfn-quote-sub"); if (needsTransliteration(lang)) { quoteSubWrap.append( $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-quote-tr-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 2) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-quote-tr") .attr("placeholder", "Transkrîpsiyona jêgirtinê…") ); } if (lang && lang !== "ku") { quoteSubWrap.append( $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-quote-t-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 2) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-quote-t") .attr("placeholder", "Tercimeya jêgirtinê bi kurmancî") ); } if (quoteSubWrap.children().length) li.append(quoteSubWrap); // Citoid auto-fill: fetch citation data from a URL, DOI or ISBN and // prefill the source şablon + fields below (see Gadget-citoid-helper.js). var citoidWrap = $("<div></div>").addClass("wiktku-dfn-quote-citoid"); var citoidInput = $("<input type='text'>") .addClass("wiktku-dfn-quote-citoid-input wiktku-start-narrow") .attr("placeholder", "URL, DOI an ISBN binivîse ku otomatîk were tijekirin…"); var citoidBtn = new OO.ui.ButtonWidget({ label: "Bi Citoid bîne", classes: [ "wiktku-dfn-quote-citoid-btn" ] }); var citoidStatus = $("<span></span>").addClass("wiktku-dfn-quote-citoid-status"); /** * Fetches citation data from Citoid and applies it to this * citation's şablon selector + fields. Mirrors the logic in * Form.prototype._fillFromCitoid (Gadget-wikt.add-examples.js): * - only (re)selects the şablon when it actually differs from * what's already chosen, so a repeat fetch doesn't wipe out * a template the user already picked; * - only fills fields that are currently empty, so it never * overwrites something the user typed by hand; * - falls back to the freeform "bi destê xwe binivîsim" source * only when nothing was typed there yet. */ function runCitoidFetch() { var query = $.trim(citoidInput.val()); if (!query) { mw.notify("Ji kerema xwe re pêşî URL, DOI an ISBNyekê binivîse."); return; } citoidBtn.setDisabled(true); citoidStatus.text("Tê anîn…"); wikt.citoidHelper.ensure().then(function () { return wikt.citoid.fetchJederFields(query); }).then(function (result) { var jederKey = result.jederKey; var hasTpl = !!jederKey && srcSel.find("option[value='" + jederKey + "']").length > 0; var targetVal = hasTpl ? jederKey : "__manual__"; // Only (re)select — and thus rebuild — the field rows if // we're switching to a different şablon than what's // already chosen, so a second fetch doesn't clear fields // the user already filled in by hand. if (srcSel.val() !== targetVal) { srcSel.val(targetVal).trigger("change"); srcSel.trigger("chosen:updated"); } if (hasTpl) { // Tenê qadên vala tijî bike. $.each(result.fields, function (key, val) { var input = srcFields.find("[data-field-key='" + key + "']"); if (input.length && !$.trim(input.val())) { input.val(val); } }); } else { // Şablonek nehat naskirin ji bo vê itemType — rêzikeke // çavkaniyê ya bi destan a ji qadên Citoid tê çêkirin, // lê tenê ger qada destan vala be. var manualField = srcFields.find(".wiktku-dfn-quote-src-manual"); if (!$.trim(manualField.val())) { var parts = []; $.each(["nivîskar", "sernav", "websîte", "kovar", "weşanxane", "sal", "url"], function (_, k) { if (result.fields[k]) parts.push(result.fields[k]); }); manualField.val(parts.join(", ")); } } citoidStatus.text(""); }, function (errorMsg) { citoidStatus.text(typeof errorMsg === "string" ? errorMsg : "Nehat dîtin. Kontrol bike ka URL/DOI/ISBN rast e."); }).always(function () { citoidBtn.setDisabled(false); }); } citoidBtn.on("click", runCitoidFetch); citoidInput.on("keydown", function (e) { if (e.which === 13) { // Enter e.preventDefault(); runCitoidFetch(); } }); citoidWrap.append(citoidInput).append(citoidBtn.$element).append(citoidStatus); // Source template selector, specific to this citation. var srcSel = $("<select></select>").addClass("wiktku-dfn-quote-src-sel"); srcSel.append($("<option value=''>— Çavkaniyê hilbijêre —</option>")); srcSel.append($("<option></option>").val("__manual__").text("Bi destê xwe binivîsim")); var jederDefs = steps.dfn.jederDefs || {}; $.each(jederDefs, function (tplName, def) { srcSel.append($("<option></option>").val(tplName).text(def.label)); }); // Dynamic source fields container. var srcFields = $("<div></div>").addClass("wiktku-dfn-quote-src-fields"); srcSel.on("change", function () { srcFields.empty(); var chosen = $(this).val(); if (!chosen) return; if (chosen === "__manual__") { // Freeform source, written by the user — becomes the 2nd // positional param of {{jêder|lang|…}} instead of çavkanî?. srcFields.append( $("<textarea></textarea>") .attr("rows", 4) .addClass("wiktku-dfn-subfield wiktku-dfn-quote-src-manual") .attr("placeholder", "Çavkaniyê bi destê xwe binivîse…") ); return; } var def = (steps.dfn.jederDefs || {})[chosen]; if (!def) return; $.each(def.fields, function (_, f) { var row = $("<div></div>").addClass("wiktku-dfn-quote-src-row"); var fieldLbl = $("<label></label>").text(f.label + ": "); var inp = $("<textarea></textarea>") .attr("rows", 2) .addClass("wiktku-dfn-quote-src-input wiktku-start-narrow") .attr("data-field-key", f.key) .attr("placeholder", f.label + "…"); row.append(fieldLbl).append(inp); srcFields.append(row); }); }); li.append(citoidWrap).append(srcSel).append(srcFields); return li; } jederGroupDiv.data("buildJederLi", buildJederLi); jederList.append(buildJederLi()); // Make citation rows sortable (drag to reorder). // The last row is always the empty trailing row — cancel its drag. mw.loader.using("jquery.ui.sortable", function () { jederList.sortable({ handle: ".wiktku-jeder-drag-handle", axis: "y", items: "li:not(:last-child)", tolerance: "pointer" }); }); jederGroupDiv.append(jederLbl).append(jederList); block.append(jederGroupDiv); }()); // Apply the initial hide/show state for the sub-groups (matches // tplSelect's starting value, which is normally empty). updateFieldVisibility(); return block; }, /** Grows the sense list when the last mane textarea gets content. */ onDfnInput: function (stepDiv, block, textarea) { var val = $.trim($(textarea).val()); var list = stepDiv.find("ol.wiktku-dfn-list"); var isLast = block.is(list.children("li:last-child")); if (val && isLast) { var newBlock = steps.dfn.buildSenseBlock(stepDiv); list.append(newBlock); // Apply Chosen to the new block's template selector on desktop. if (!isMobile) newBlock.find("select.wiktku-dfn-tpl-select").chosen(chosenOptions); } refresh(); }, /** Grows a sub-list (nimûne/formên alternatîv/hevmane/dijmane/termên koordîne) on input. */ onSubInput: function (list, input, rows, narrow) { var val = $.trim($(input).val()); var item = $(input).parent(); var isLast = item.is(list.children("li:last-child")); if (val && isLast) { var next = $("<textarea></textarea>") .attr("name", "wiktku-dfn-sub-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", rows) .attr("class", "wiktku-dfn-subfield" + (narrow ? " wiktku-start-narrow" : "")); next.on("input", function () { steps.dfn.onSubInput(list, this, rows, narrow); }); list.append($("<li></li>").append(next)); } }, // Populated from [[MediaWiki:Gadget-start.js/data.json]] (tplDefs, posExamples, jederDefs). tplDefs: [], posExamples: {}, jederDefs: {}, build: function (stepDiv) { if (stepDiv.find("ol.wiktku-dfn-list").length) return null; var list = $("<ol class='wiktku-dfn-list'></ol>"); list.append(steps.dfn.buildSenseBlock(stepDiv)); stepDiv.append(list); return null; }, /** Reads all sense blocks from the DOM and returns an array of sense objects. */ getSenses: function (stepDiv) { var senses = []; stepDiv.find("li.wiktku-dfn-sense").each(function () { var block = $(this); var tplSel = block.find("select.wiktku-dfn-tpl-select"); var tpl = tplSel.val() || ""; // noLang: template already encodes the language — don't add |lang| param. var tplNoLang = tpl ? tplSel.find("option[value='" + tpl + "']").attr("data-nolang") === "1" : false; var tplTitle = $.trim(block.find("input.wiktku-dfn-tpl-title").val()); var mane = $.trim(block.find("textarea.wiktku-dfn-mane").val()); var etiket = (function () { var vals = []; block.find(".wiktku-dfn-etiket-list textarea").each(function () { var v = $.trim($(this).val()); if (v) vals.push(v); }); return vals; }()); function readList(cls) { var vals = []; block.find("." + cls + "-list textarea").each(function () { var v = $.trim($(this).val()); if (v) vals.push(v); }); return vals; } // Nimûne items are compound: { text, tr?, t? } function readNimuneList() { var items = []; block.find(".wiktku-dfn-nimune-list li.wiktku-dfn-nimune-li").each(function () { var text = $.trim($(this).find(".wiktku-dfn-nimune-text").val()); if (!text) return; var obj = { text: text }; var tr = $.trim($(this).find(".wiktku-dfn-nimune-tr").val()); var t = $.trim($(this).find(".wiktku-dfn-nimune-t").val()); if (tr) obj.tr = tr; if (t) obj.t = t; items.push(obj); }); return items; } // Jêder is a growing list of citations, one per li — mirrors readNimuneList(). function readJederList() { var items = []; block.find(".wiktku-dfn-jeder-list li.wiktku-dfn-jeder-li").each(function () { var li = $(this); var quote = $.trim(li.find(".wiktku-dfn-nimune-quote").val()); if (!quote) return; var obj = { quote: quote }; var qtr = $.trim(li.find(".wiktku-dfn-nimune-quote-tr").val()); var qt = $.trim(li.find(".wiktku-dfn-nimune-quote-t").val()); if (qtr) obj.quoteTr = qtr; if (qt) obj.quoteT = qt; var tplName = li.find(".wiktku-dfn-quote-src-sel").val(); if (tplName === "__manual__") { var manual = $.trim(li.find(".wiktku-dfn-quote-src-manual").val()); if (manual) obj.jederManual = manual; } else if (tplName) { obj.jederTpl = tplName; var fields = {}; li.find(".wiktku-dfn-quote-src-input").each(function () { var k = $(this).attr("data-field-key"); var v = $.trim($(this).val()); if (k && v) fields[k] = v; }); obj.jêderFields = fields; } items.push(obj); }); return items; } senses.push({ tpl: tpl, tplNoLang: tplNoLang, tplTitle: tplTitle, mane: mane, etiket: etiket, nimune: readNimuneList(), jeder: readJederList(), alternativ: readList("wiktku-dfn-alternativ"), hevmane: readList("wiktku-dfn-hevmane"), dijmane: readList("wiktku-dfn-dijmane"), koordine: readList("wiktku-dfn-koordine"), jornav: readList("wiktku-dfn-jornav"), jernav: readList("wiktku-dfn-jernav") }); }); return senses; }, getOutput: function (values, callback) { var stepDiv = $("#wiktku-start-dfn"); var senses = steps.dfn.getSenses(stepDiv); var lang = values.lang; // A sense counts as "filled" if it has a mane, a chosen template + title, // or any other content (etîket/hevmane/nimûne/jêder…) worth keeping. var hasMane = senses.some(function (s) { return s.mane !== "" || (s.tpl && s.tplTitle) || senseHasExtraContent(s); }); // True only when at least one sense has a regular mane (needs linkify). var hasRegularMane = senses.some(function (s) { return !s.tpl && s.mane !== ""; }); // nimûne and jêder lines must never pass through linkify — only // the plain mane text should be linkified. We build two parallel // arrays: defLines (sent to linkify) and citeLines (kept aside). // Each entry in citeLines corresponds 1-to-1 with a defLines entry; // a template token {{wiktku-cite-N}} is embedded in defLines so // that after linkify runs we know exactly where to splice them back. // Template-call syntax is guaranteed safe: linkifiers leave {{ }} // tokens completely untouched. var defLines = []; // one entry per kept sense (goes to linkify) var citeLines = []; // parallel — nimûne+jêder for that same sense $.each(senses, function (_, sense) { // — Template sense (e.g. {{guharto|ku|somepage}}) — if (sense.tpl) { if (!sense.tplTitle) return; // skip empty template senses var tplLabelTpl = ""; if (sense.etiket && sense.etiket.length) { var tplLabelParts = sense.etiket.map(function (part) { return $.trim(part); }).filter(function (part) { return part !== ""; }); if (tplLabelParts.length) { tplLabelTpl = " {{e|" + lang + "|" + tplLabelParts.join("|") + "}} "; } } var tplCall = sense.tplNoLang ? "{{" + sense.tpl + "|" + sense.tplTitle + "}}" : "{{" + sense.tpl + "|" + lang + "|" + sense.tplTitle + "}}"; var tplHasJeder = sense.jeder && $.grep(sense.jeder, function (j) { return j && j.quote; }).length > 0; var idx = defLines.length; var cite = formatNimune(sense.nimune, lang, tplHasJeder) + formatJeder(sense.jeder, lang); defLines.push("#" + (tplLabelTpl ? tplLabelTpl : " ") + tplCall + (cite ? "{{wiktku-cite-" + idx + "}}" : "")); citeLines.push(cite); return; } // — Normal mane sense — var dfn = sense.mane; if (!dfn && !senseHasExtraContent(sense)) return; // truly empty if (dfn) { dfn = stripWikilinks(dfn); if (dfn[0] !== dfn[0].toUpperCase()) dfn = capitalize(dfn); if (!dfn.match(/[.…?!)\]]$/)) dfn += "."; } else { dfn = "{{mane?|" + lang + "}}"; } var labelTpl = ""; if (sense.etiket && sense.etiket.length) { var labelParts = sense.etiket.map(function (part) { return $.trim(part); }).filter(function (part) { return part !== ""; }); if (labelParts.length) { labelTpl = " {{e|" + lang + "|" + labelParts.join("|") + "}} "; } } var out = "#" + (labelTpl ? labelTpl : " ") + dfn; function wordLine(tpl, words) { if (!words.length) return ""; return "\n#: {{" + tpl + "|" + lang + "|" + words.join("|") + "}}"; } out += wordLine("alt-r", sense.alternativ); out += wordLine("hevmane", sense.hevmane); out += wordLine("dijmane", sense.dijmane); out += wordLine("koordîne", sense.koordine); out += wordLine("jornav", sense.jornav); out += wordLine("jêrnav", sense.jernav); var hasJeder = sense.jeder && $.grep(sense.jeder, function (j) { return j && j.quote; }).length > 0; var cite = formatNimune(sense.nimune, lang, hasJeder) + formatJeder(sense.jeder, lang); var idx = defLines.length; defLines.push(out + (cite ? "{{wiktku-cite-" + idx + "}}" : "")); citeLines.push(cite); }); // Splice citeLines back into a linkified string, replacing each // {{wiktku-cite-N}} token with its stored nimûne/jêder block. function restoreCites(t) { return t.replace(/\{\{wiktku-cite-(\d+)\}\}/g, function (_, n) { return citeLines[parseInt(n, 10)] || ""; }); } var text = defLines.join("\n") + "\n"; if (!hasMane) { // No definitions entered — emit {{mane?}} with bênimûne. text = "# {{mane?|" + lang + "}}\n#* {{bênimûne|" + lang + "}}\n"; callback(text); return; } if (!hasRegularMane) { // All filled senses are template senses — no linkify needed. callback(restoreCites(text)); return; } var didTryToLoad = function () { if (typeof $.wiktviLinkify === "function") { $.wiktviLinkify(text, function (linked) { callback(restoreCites(linked)); }); } else { callback(restoreCites(text)); } }; mw.loader.using("ext.gadget.linkify", didTryToLoad, didTryToLoad); } }, je: makeWordListStep("je", "jê", "Kelîmeyên jê çêbûyî binivîse", "Jê", "g"), tekildar: makeWordListStep("tekildar", "têkildar", "Kelîmeyên ji aliyê etîmolojiyê ve têkildarî vê kelîmeyê binivîse", "Têkildar", "g"), binereherwiha: makeWordListStep("binereherwiha", "binêre herwiha", "Kelîmeyên din ên eleqedar binivîse", "Binêre herwiha", "g"), etym: { id: "etym", name: "etîmolojî", question_fmt: "Etîmolojiya kelîmeyê binivîse", // etymTpls populated from data.json etymTpls: [], visible: function (values) { return values.lang && values.pos; }, /** Fills (or refills) the insert-dropdown from the current etymTpls array. */ refreshTplSelect: function () { var sel = $("#wiktku-start-etym .wiktku-tpl-insert-select"); if (!sel.length) return; sel.find("option[value!='']").remove(); $.each(steps.etym.etymTpls, function (_, tpl) { sel.append($("<option></option>").val(tpl.snippet).text(tpl.name + " — " + tpl.desc)); }); // Notify Chosen that the option list has changed (no-op on mobile). if (!isMobile) sel.trigger("chosen:updated"); }, build: function (stepDiv) { if (stepDiv.find(".wiktku-etym-wrap").length) return null; var wrap = $("<div class='wiktku-etym-wrap'></div>"); var ta = $("<textarea></textarea>") .attr("name", "wiktku-etym-" + $.now()) .attr("class", "wiktku-start-step-field wiktku-etym-text") .attr("rows", 4) .attr("placeholder", "Nimûne: Ji {{ji|en|ku|apple}}. yan rasterast binivîse…"); // Template insert dropdown — options also refreshed after data.json loads. var sel = $("<select class='wiktku-tpl-insert-select'></select>"); sel.append($("<option value=''>— şablonek lê zêde bike —</option>")); $.each(steps.etym.etymTpls, function (_, tpl) { sel.append($("<option></option>").val(tpl.snippet).text(tpl.name + " — " + tpl.desc)); }); sel.on("change", function () { var snippet = $(this).val(); if (!snippet) return; var lang = getValues().lang || ""; snippet = snippet.replace(/CODE/g, lang).replace(/SOURCELANG/g, "?"); insertAtCursor(ta[0], snippet); $(this).val(""); ta.focus(); }); wrap.append(sel).append($("<br>")).append(ta); stepDiv.append(wrap); return ta; }, output: function (values) { var text = $.trim($("#wiktku-start-etym .wiktku-etym-text").val()); if (text) { return "\n==== Etîmolojî ====\n" + text + "\n"; } // No etymology entered — emit {{ji?|lang}} as a placeholder, // but only when the entry has at least one regular (non-şablon) // sense with content — either real mane text, or an empty mane // with other fields filled in (which dfn.getOutput() renders as // {{mane?|lang}} with those fields attached). A şablon sense // like {{guharto|…}} never counts, filled in or not. var dfnSenses = steps.dfn.getSenses($("#wiktku-start-dfn")); var hasRegularMane = dfnSenses.some(function (s) { return !s.tpl && (s.mane !== "" || senseHasExtraContent(s)); }); if (!hasRegularMane) return ""; return "\n==== Etîmolojî ====\n{{ji?|" + values.lang + "}}\n"; } }, dunde: { id: "dunde", name: "dûnde", question_fmt: "Eger ev kelîme ji vî zimanî ketibe zimanekî din, vî zimanî û kelîmeya wî binivîse", visible: function (values) { return !!values.pos; }, disabledKeys: { "navz": true}, /** * Builds one row: a language dropdown + a growing list of word * inputs. When the dropdown gets a value the next empty row is * appended automatically. Mirrors steps.trans's row widget, but * flat (one shared list — dûnde isn't tied to individual senses). */ buildRow: function (stepDiv) { var row = $("<li class='wiktku-dunde-row wiktku-lang-row'></li>"); // Language selector — chosen is applied after insertion into DOM. var langSel = $(mw.html.element("select", { "class": "wiktku-start-step-keyfield wiktku-start-narrow" })); langSel.attr("data-placeholder", "Zimanekî lê bigere"); populateMenus(langSel, steps.dunde.keys || [], steps.dunde.disabledKeys); // When a language is chosen, ensure a next empty row exists. langSel.on("change", function () { steps.dunde.onLangChange(stepDiv, row); }); // Word list for this language. var wordList = $("<ul class='wiktku-dunde-words wiktku-lang-row-words'></ul>"); var firstWord = steps.dunde.makeWordInput(); wordList.append($("<li></li>").append(firstWord)); if (isMobile) { row.append(wrapNativeSelect(langSel)).append(wordList); } else { row.append(langSel).append(wordList); } return row; }, makeWordInput: function () { var input = $("<textarea></textarea>") .attr("name", "wiktku-dunde-word-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 1) .attr("class", "wiktku-dfn-subfield wiktku-start-narrow") .attr("placeholder", "Kelîme…"); input.on("input", function () { var list = $(this).closest("ul.wiktku-dunde-words"); var item = $(this).parent(); var val = $.trim($(this).val()); if (val && item.is(list.children("li:last-child"))) { var next = steps.dunde.makeWordInput(); list.append($("<li></li>").append(next)); } }); return input; }, onLangChange: function (stepDiv, row) { var list = stepDiv.find("ul.wiktku-dunde-list"); var isLast = row.is(list.children("li.wiktku-dunde-row:last-child")); if (isLast) { var newRow = steps.dunde.buildRow(stepDiv); list.append(newRow); // Init chosen after the new row is in the DOM (desktop only). if (!isMobile) newRow.find("select").chosen(chosenOptions); } // Keep disabled keys in sync across all lang selectors. steps.dunde.syncDisabledKeys(stepDiv); }, /** Disables already-selected languages in all other dropdowns. */ syncDisabledKeys: function (stepDiv) { var taken = $.extend({}, steps.dunde.disabledKeys); stepDiv.find("li.wiktku-dunde-row select").each(function () { var v = $(this).val(); if (v) taken[v] = true; }); stepDiv.find("li.wiktku-dunde-row select").each(function () { var self = $(this); var own = self.val(); self.find("option").each(function () { var code = $(this).val(); if (!code) return; $(this).prop("disabled", taken[code] && code !== own); }); self.trigger("chosen:updated"); }); }, build: function (stepDiv) { if (stepDiv.find("ul.wiktku-dunde-list").length) return null; var list = $("<ul class='wiktku-dunde-list wiktku-lang-row-list'></ul>"); list.append(steps.dunde.buildRow(stepDiv)); stepDiv.append(list); // Init chosen after the select is in the DOM (desktop only). if (!isMobile) list.find("select").chosen(chosenOptions); return null; }, /** Reads all [langcode, words[]] rows from the DOM. */ getRows: function (stepDiv) { var result = []; stepDiv.find("li.wiktku-dunde-row").each(function () { var lang = $(this).find("select").val(); if (!lang) return; var words = []; $(this).find("ul.wiktku-dunde-words textarea").each(function () { var v = $.trim($(this).val()); if (v) words.push(v); }); if (words.length) result.push([lang, words]); }); return result; }, output: function () { var stepDiv = $("#wiktku-start-dunde"); var rows = steps.dunde.getRows(stepDiv); if (!rows.length) return ""; var lines = $.map(rows, function (row) { var lang = row[0], words = row[1]; return "* {{dû|" + lang + "|" + words.join("|") + "}}"; }); return "\n==== Dûnde ====\n" + lines.join("\n") + "\n"; } }, zarava: { id: "zarava", name: "bi zaravayên din", visible: function (values) { return steps.trans.visible(values); }, disabledKeys: { "navz": true }, buildRow: function (group) { var row = $("<li class='wiktku-zarava-row wiktku-lang-row'></li>"); var langSel = $(mw.html.element("select", { "class": "wiktku-start-step-keyfield wiktku-start-narrow" })); populateMenus(langSel, steps.zarava.keys || [], steps.zarava.disabledKeys); langSel.on("change", function () { steps.zarava.onLangChange(group, row); }); var wordList = $("<ul class='wiktku-zarava-words wiktku-lang-row-words'></ul>"); var firstWord = steps.zarava.makeWordInput(); wordList.append($("<li></li>").append(firstWord)); row.append(langSel).append(wordList); return row; }, makeWordInput: function () { var input = $("<textarea></textarea>") .attr("name", "wiktku-zarava-word-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 1) .attr("class", "wiktku-dfn-subfield wiktku-start-narrow") .attr("placeholder", "Tercime…"); input.on("input", function () { var list = $(this).closest("ul.wiktku-zarava-words"); var item = $(this).parent(); var val = $.trim($(this).val()); if (val && item.is(list.children("li:last-child"))) { var next = steps.zarava.makeWordInput(); list.append($("<li></li>").append(next)); } }); return input; }, onLangChange: function (group, row) { var list = group.find("ul.wiktku-zarava-list"); var isLast = row.is(list.children("li.wiktku-zarava-row:last-child")); if (isLast) { var newRow = steps.zarava.buildRow(group); list.append(newRow); } steps.zarava.syncDisabledKeys(group); }, /** Disables already-selected dialects in all other dropdowns within one group. */ syncDisabledKeys: function (group) { var taken = $.extend({}, steps.zarava.disabledKeys); group.find("li.wiktku-zarava-row select").each(function () { var v = $(this).val(); if (v) taken[v] = true; }); group.find("li.wiktku-zarava-row select").each(function () { var self = $(this); var own = self.val(); self.find("option").each(function () { var code = $(this).val(); if (!code) return; $(this).prop("disabled", taken[code] && code !== own); }); }); }, /** Builds (or fetches) the .wiktku-zarava-group for one gloss. */ buildGroup: function (stepDiv, gi) { var group = $("<div class='wiktku-zarava-group'></div>").attr("data-gloss-pos", gi); var list = $("<ul class='wiktku-zarava-list wiktku-lang-row-list'></ul>"); list.append(steps.zarava.buildRow(group)); group.append(list); stepDiv.append(group); return group; }, /** Syncs one .wiktku-zarava-group per current gloss (same logic as steps.trans.build). */ build: function (stepDiv) { var glosses = steps.trans.glossList(); if (!glosses.length) { stepDiv.find(".wiktku-zarava-group").remove(); return null; } var existingGroups = stepDiv.find(".wiktku-zarava-group"); if (existingGroups.length > glosses.length) { existingGroups.slice(glosses.length).remove(); } $.each(glosses, function (gi, gloss) { var group = stepDiv.find(".wiktku-zarava-group[data-gloss-pos='" + gi + "']"); if (!group.length) group = steps.zarava.buildGroup(stepDiv, gi); var label = group.find(".wiktku-zarava-group-label"); if (glosses.length > 1) { if (!label.length) { label = $("<div class='wiktku-zarava-group-label'></div>"); group.prepend(label); } label.text(gloss.index + " " + gloss.text); } else if (label.length) { label.remove(); } }); return null; }, /** Reads the dialect rows for a single gloss group. */ getGroupTranslations: function (group) { var result = []; group.find("li.wiktku-zarava-row").each(function () { var lang = $(this).find("select").val(); if (!lang) return; var words = []; $(this).find("ul.wiktku-zarava-words textarea").each(function () { var v = $.trim($(this).val()); if (v) words.push(v); }); if (words.length) result.push([lang, words]); }); return result; }, /** Reads all rows from the DOM, grouped by gloss position. */ getTranslations: function (stepDiv) { var result = []; stepDiv.find(".wiktku-zarava-group").each(function () { result.push(steps.zarava.getGroupTranslations($(this))); }); return result; }, output: function (values) { if (values.lang !== "ku") return ""; var stepDiv = $("#wiktku-start-zarava"); var glosses = steps.trans.glossList(); if (!glosses.length) return ""; var blocks = $.map(glosses, function (gloss, gi) { var group = stepDiv.find(".wiktku-zarava-group[data-gloss-pos='" + gi + "']"); var rows = group.length ? steps.zarava.getGroupTranslations(group) : []; if (!gloss.text && !rows.length) return undefined; if (rows.length) { rows.sort(function (a, b) { var aLang = langsByCode[a[0]] || []; var bLang = langsByCode[b[0]] || []; return (aLang[2] || "").localeCompare(bLang[2] || "", "ku"); }); } var wordLines = $.map(rows, function (row) { var lang = row[0]; var words = row[1]; var wikiWords = words.map(function (w) { return "{{W|" + lang + "|" + w + "}}"; }).join(", "); return "* {{Z|" + lang + "}}: " + wikiWords; }).join("\n"); if (!wordLines) return undefined; var block = "{{werger-ser|" + (gloss.text || "?") + "|" + gloss.index + "}}"; block += "\n" + wordLines; block += "\n{{werger-bin}}"; return block; }); if (!blocks.length) return ""; return "\n==== Bi zaravayên din ====\n" + blocks.join("\n") + "\n"; } }, trans: { id: "trans", name: "werger", visible: function (values) { if (!(values.lang === "ku" && values.pos)) return false; // Hide Werger only when EVERY sense is a template sense (Guharto etc.) // with a title filled in — i.e. there is real content but no plain // gloss to attach a translation table to. A mix of real + template // senses still shows Werger; the template senses are simply skipped // in output(). // // "Real" here means a non-şablon sense with either mane text or // other filled-in fields (etîket/hevmane/nimûne/jêder…), since // dfn.getOutput() renders the latter too, as {{mane?|lang}} plus // whatever else was filled in. // // When nothing has been filled in at all, output() will emit // {{mane?|lang}} instead of a gloss — but Werger should still show, // since the user may want to add translations before they've // settled on a gloss. var dfnSenses = steps.dfn.getSenses($("#wiktku-start-dfn")); var hasRealSense = dfnSenses.some(function (s) { return !s.tpl && (s.mane !== "" || senseHasExtraContent(s)); }); var hasFilledTplSense = dfnSenses.some(function (s) { return s.tpl && s.tplTitle; }); return hasRealSense || !hasFilledTplSense; }, disabledKeys: { "navz": true, "ku": true, "ckb": true, "sdh": true, "lki": true, "hac": true, "zza": true }, /** * Builds one translation row: a language dropdown + a growing list * of word inputs. When the dropdown gets a value the next empty row * is appended automatically. * * @param group the specific .wiktku-trans-group this row belongs to * (each gloss has its own group and its own list of rows, so the * lookups below must stay scoped to that group rather than the * whole step — the step now holds one list per gloss). */ buildRow: function (group) { var row = $("<li class='wiktku-trans-row wiktku-lang-row'></li>"); // Language selector — chosen is applied after insertion into DOM. var langSel = $(mw.html.element("select", { "class": "wiktku-start-step-keyfield wiktku-start-narrow" })); langSel.attr("data-placeholder", "Zimanekî lê bigere"); populateMenus(langSel, steps.trans.keys || [], steps.trans.disabledKeys); // When a language is chosen, ensure a next empty row exists. langSel.on("change", function () { steps.trans.onLangChange(group, row); }); // Word list for this language. var wordList = $("<ul class='wiktku-trans-words wiktku-lang-row-words'></ul>"); var firstWord = steps.trans.makeWordInput(); wordList.append($("<li></li>").append(firstWord)); if (isMobile) { row.append(wrapNativeSelect(langSel)).append(wordList); } else { row.append(langSel).append(wordList); } return row; }, makeWordInput: function () { var input = $("<textarea></textarea>") .attr("name", "wiktku-trans-word-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 1) .attr("class", "wiktku-dfn-subfield wiktku-start-narrow") .attr("placeholder", "Tercime…"); input.on("input", function () { var list = $(this).closest("ul.wiktku-trans-words"); var item = $(this).parent(); var val = $.trim($(this).val()); if (val && item.is(list.children("li:last-child"))) { var next = steps.trans.makeWordInput(); list.append($("<li></li>").append(next)); } }); return input; }, onLangChange: function (group, row) { var list = group.find("ul.wiktku-trans-list"); var isLast = row.is(list.children("li.wiktku-trans-row:last-child")); if (isLast) { var newRow = steps.trans.buildRow(group); list.append(newRow); // Init chosen after the new row is in the DOM (desktop only). if (!isMobile) newRow.find("select").chosen(chosenOptions); } // Keep disabled keys in sync across this gloss's lang selectors // only — the same language can be used for different senses. steps.trans.syncDisabledKeys(group); }, /** Disables already-selected languages in all other dropdowns within one group. */ syncDisabledKeys: function (group) { var taken = $.extend({}, steps.trans.disabledKeys); group.find("li.wiktku-trans-row select").each(function () { var v = $(this).val(); if (v) taken[v] = true; }); group.find("li.wiktku-trans-row select").each(function () { var self = $(this); var own = self.val(); self.find("option").each(function () { var code = $(this).val(); if (!code) return; $(this).prop("disabled", taken[code] && code !== own); }); self.trigger("chosen:updated"); }); }, /** * Builds (or fetches) the .wiktku-trans-group for one gloss, with * its own label and its own list of translation rows. */ buildGroup: function (stepDiv, gi) { var group = $("<div class='wiktku-trans-group'></div>").attr("data-gloss-pos", gi); var list = $("<ul class='wiktku-trans-list wiktku-lang-row-list'></ul>"); list.append(steps.trans.buildRow(group)); group.append(list); stepDiv.append(group); // Init chosen after the select is in the DOM (desktop only). if (!isMobile) list.find("select").chosen(chosenOptions); return group; }, /** * Syncs one .wiktku-trans-group per current gloss, adding new * groups and removing stale ones as senses are added or removed, * while leaving existing groups (and whatever translations the * user has already typed into them) untouched. Groups are keyed * to their gloss's position in glossList() via data-gloss-pos, so * a group always matches the same sense across rebuilds as long * as senses aren't reordered relative to each other. */ build: function (stepDiv) { var glosses = steps.trans.glossList(); if (!glosses.length) { stepDiv.find(".wiktku-trans-group").remove(); return null; } // Drop groups for glosses that no longer exist (always from the // tail — groups are only ever appended in gloss order below). var existingGroups = stepDiv.find(".wiktku-trans-group"); if (existingGroups.length > glosses.length) { existingGroups.slice(glosses.length).remove(); } $.each(glosses, function (gi, gloss) { var group = stepDiv.find(".wiktku-trans-group[data-gloss-pos='" + gi + "']"); if (!group.length) group = steps.trans.buildGroup(stepDiv, gi); // Only label groups when there's more than one gloss to // distinguish between — a single gloss needs no caption. var label = group.find(".wiktku-trans-group-label"); if (glosses.length > 1) { if (!label.length) { label = $("<div class='wiktku-trans-group-label'></div>"); group.prepend(label); } label.text(gloss.index + " " + gloss.text); } else if (label.length) { label.remove(); } }); return null; }, /** Reads the translation rows for a single gloss group. */ getGroupTranslations: function (group) { var result = []; group.find("li.wiktku-trans-row").each(function () { var lang = $(this).find("select").val(); if (!lang) return; var words = []; $(this).find("ul.wiktku-trans-words textarea").each(function () { var v = $.trim($(this).val()); if (v) words.push(v); }); if (words.length) result.push([lang, words]); }); return result; }, /** * Reads all translation rows from the DOM, grouped by gloss * position — one array of [lang, words] rows per gloss group, in * the same order as the .wiktku-trans-group elements. */ getTranslations: function (stepDiv) { var result = []; stepDiv.find(".wiktku-trans-group").each(function () { result.push(steps.trans.getGroupTranslations($(this))); }); return result; }, /** * Builds the numbered "{ index, gloss }" list — one entry per dfn * sense that has a real mane (skips template senses like Guharto, * which have nothing to caption a translation table with). The * index matches the sense's actual position in the numbered "#" * definition list (1-based), including template senses in the count, * so the number printed next to {{werger-ser}} lines up with the * gloss the reader sees in the entry. * * When nothing has been filled in at all (dfn.getOutput() will emit * {{mane?|lang}} as sense 1), this returns a single placeholder * entry with empty text instead of an empty array, so Werger still * has one group to attach translations to before a gloss exists. * When every filled sense is a template sense instead, this stays * empty — that mirrors trans.visible()'s hidden case, where there's * no group in the DOM for a placeholder to attach to anyway. */ glossList: function () { var dfnSenses = steps.dfn.getSenses($("#wiktku-start-dfn")); var glosses = []; var hasFilledTplSense = false; $.each(dfnSenses, function (i, s) { if (s.tpl) { if (s.tplTitle) hasFilledTplSense = true; return; // template sense — no gloss to caption with } var dfn = s.mane; if (!dfn) { // No mane text, but other fields (etîket/hevmane/nimûne/ // jêder…) are filled — dfn.getOutput() still emits this // sense as a numbered line using {{mane?|lang}}, so it // needs its own gloss group too, just with no caption text. if (senseHasExtraContent(s)) glosses.push({ index: i + 1, text: "" }); return; } if (dfn[0] !== dfn[0].toLowerCase()) dfn = decapitalize(dfn); dfn = stripWikilinks(dfn).replace(/[.…?!)\]،؟]+$/, ""); glosses.push({ index: i + 1, text: dfn }); }); if (!glosses.length && !hasFilledTplSense) { glosses.push({ index: 1, text: "" }); } return glosses; }, output: function (values) { if (values.lang !== "ku") return ""; var stepDiv = $("#wiktku-start-trans"); var glosses = steps.trans.glossList(); // Every sense is a template sense — there's no real gloss // anywhere and no group in the DOM either (glossList() only // returns empty in that case), so skip the section entirely. if (!glosses.length) return ""; // Each gloss now has its own group of translation rows — // attach every gloss's own words under its own werger-ser/-bin // pair instead of dumping everything under the first one. var blocks = $.map(glosses, function (gloss, gi) { var group = stepDiv.find(".wiktku-trans-group[data-gloss-pos='" + gi + "']"); var rows = group.length ? steps.trans.getGroupTranslations(group) : []; // Placeholder gloss (no real mane entered yet) with nothing // translated into it — nothing to output, and gloss.text is // empty so there's no caption to give {{werger-ser}} anyway. if (!gloss.text && !rows.length) return undefined; if (rows.length) { // Sort by Kurdish sort key. rows.sort(function (a, b) { var aLang = langsByCode[a[0]] || []; var bLang = langsByCode[b[0]] || []; return (aLang[2] || "").localeCompare(bLang[2] || "", "ku"); }); } var wordLines = $.map(rows, function (row) { var lang = row[0]; var words = row[1]; var wikiWords = words.map(function (w) { return "{{W|" + lang + "|" + w + "}}"; }).join(", "); return "* {{Z|" + lang + "}}: " + wikiWords; }).join("\n"); var block = "{{werger-ser|" + (gloss.text || "?") + "|" + gloss.index + "}}"; if (wordLines) block += "\n" + wordLines; block += "\n{{werger-bin}}"; return block; }); if (!blocks.length) return ""; return "\n==== Werger ====\n" + blocks.join("\n") + "\n"; } }, }; steps.trans.keys = steps.lang.choices; steps.dunde.keys = steps.lang.choices; steps.zarava.keys = getZaravaKeys(steps.lang.choices); var ordered_steps = [ steps.lang, steps.pron, steps.pos, steps.cinsiyet, steps.lektur, steps.tr, steps.dfn, steps.je, steps.tekildar, steps.etym, steps.dunde, steps.binereherwiha, steps.zarava, steps.trans]; // Step ids that belong to each section (not shared across sections). var PER_SECTION_STEP_IDS = [ "pos", "cinsiyet", "lektur", "tr", "dfn", "je", "tekildar", "etym", "dunde", "binereherwiha", "zarava", "trans" ]; // ── Multi-section state ────────────────────────────────────────────────── // Each entry is a plain snapshot: { pos, cinsiyet, lektur, tr, dfn (senses[]), // je, tekildar, binereherwiha, trans (rows[]) }. var sections = [{}]; // section 0 starts empty (DOM is the truth) var activeSection = 0; function snapshotDfn() { return steps.dfn.getSenses($("#wiktku-start-dfn")); } /** * Rebuild the dfn DOM from a previously snapshotted senses array. */ function restoreDfn(senses) { var stepDiv = $("#wiktku-start-dfn"); // Tear down the existing list so build() recreates it cleanly. stepDiv.find("ol.wiktku-dfn-list").remove(); steps.dfn.build(stepDiv); var list = stepDiv.find("ol.wiktku-dfn-list"); $.each(senses, function (i, sense) { // Ensure enough blocks exist (build() seeds one). var blocks = list.find("li.wiktku-dfn-sense"); var block = blocks.eq(i); if (!block.length) { var nb = steps.dfn.buildSenseBlock(stepDiv); list.append(nb); block = list.find("li.wiktku-dfn-sense").last(); } // Template selector. block.find("select.wiktku-dfn-tpl-select").val(sense.tpl || ""); if (sense.tpl) { block.find("textarea.wiktku-dfn-mane").hide(); block.find("input.wiktku-dfn-tpl-title").val(sense.tplTitle || "").show(); } else { block.find("textarea.wiktku-dfn-mane").val(sense.mane || "").show(); block.find("input.wiktku-dfn-tpl-title").hide().val(""); } // Re-sync the formên alternatîv/hevmane/… hide state now that // tplSelect's value was set programmatically (its own "change" // handler doesn't fire from .val(), so this doesn't happen otherwise). var updateVis = block.data("updateFieldVisibility"); if (updateVis) updateVis(); // Restore a sub-list (etiket, formên alternatîv, hevmane …) from a values array. function restoreSubList(cls, values) { if (!values || !values.length) return; var groupDiv = block.find("." + cls + "-group"); var subList = groupDiv.find("ol, ul").first(); if (!subList.length) return; // group not found // Fill existing items, append new ones as needed. $.each(values, function (j, val) { var items = subList.find("li"); if (j < items.length) { items.eq(j).find("textarea").val(val); } else { var ta = $("<textarea></textarea>") .attr("name", "wiktku-dfn-restore-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 1) .attr("class", "wiktku-dfn-subfield wiktku-start-narrow") .val(val); ta.on("input", function () { steps.dfn.onSubInput(subList, this, 1, true); }); subList.append($("<li></li>").append(ta)); } }); } // Reveal and populate lazy groups that have data. var lazyMap = { "wiktku-dfn-etiket": sense.etiket, "wiktku-dfn-alternativ": sense.alternativ, "wiktku-dfn-hevmane": sense.hevmane, "wiktku-dfn-dijmane": sense.dijmane, "wiktku-dfn-koordine": sense.koordine, "wiktku-dfn-jornav": sense.jornav, "wiktku-dfn-jernav": sense.jernav }; $.each(lazyMap, function (cls, vals) { if (vals && vals.length) restoreSubList(cls, vals); }); // Nimûne items are objects { text, tr?, t? } — restore using the builder. if (sense.nimune && sense.nimune.length) { var nimuneGroupDiv = block.find(".wiktku-dfn-nimune-group"); var nimuneList = nimuneGroupDiv.find("ol.wiktku-dfn-nimune-list"); var buildFn = nimuneGroupDiv.data("buildNimuneLi"); nimuneList.empty(); $.each(sense.nimune, function (_, n) { var text = typeof n === "object" ? (n.text || "") : n; if (!text) return; var li = buildFn ? buildFn() : $("<li class='wiktku-dfn-nimune-li'></li>"); li.find(".wiktku-dfn-nimune-text").val(text); if (n.tr) li.find(".wiktku-dfn-nimune-tr").val(n.tr); if (n.t) li.find(".wiktku-dfn-nimune-t").val(n.t); nimuneList.append(li); }); // Always leave a blank trailing item. if (buildFn) nimuneList.append(buildFn()); } // Restore jêder (quote/citation) entries — a growing list, restored using the // builder just like Nimûne. Accepts either the current array shape or a // single legacy object (from older saved sections) for backwards compatibility. var jederArr = $.isArray(sense.jeder) ? sense.jeder : (sense.jeder ? [sense.jeder] : []); if (jederArr.length) { var jederGroupDiv = block.find(".wiktku-dfn-jeder-group"); var jederList = jederGroupDiv.find("ol.wiktku-dfn-jeder-list"); var buildJederFn = jederGroupDiv.data("buildJederLi"); jederList.empty(); $.each(jederArr, function (_, j) { if (!j || !j.quote) return; var li = buildJederFn ? buildJederFn() : $("<li class='wiktku-dfn-jeder-li'></li>"); li.find(".wiktku-dfn-nimune-quote").val(j.quote); if (j.quoteTr) li.find(".wiktku-dfn-nimune-quote-tr").val(j.quoteTr); if (j.quoteT) li.find(".wiktku-dfn-nimune-quote-t").val(j.quoteT); if (j.jederManual) { var manualSel = li.find(".wiktku-dfn-quote-src-sel"); manualSel.val("__manual__").trigger("change"); li.find(".wiktku-dfn-quote-src-manual").val(j.jederManual); } else if (j.jederTpl) { var srcSel = li.find(".wiktku-dfn-quote-src-sel"); srcSel.val(j.jederTpl).trigger("change"); if (j.jêderFields) { $.each(j.jêderFields, function (key, val) { li.find(".wiktku-dfn-quote-src-input[data-field-key='" + key + "']").val(val); }); } } jederList.append(li); }); // Always leave a blank trailing item, same as Nimûne. if (buildJederFn) jederList.append(buildJederFn()); } }); } /** * Snapshot simple (non-dfn) per-section steps from current DOM into obj. */ function saveCurrentSection() { var snap = {}; $.each(PER_SECTION_STEP_IDS, function (_, id) { if (id === "dfn") { snap.dfn = snapshotDfn(); return; } if (id === "etym") { snap.etym = $.trim($("#wiktku-start-etym .wiktku-etym-text").val()); return; } var step = steps[id]; if (!step) return; var stepDiv = $("#wiktku-start-" + id); if (id === "trans") { snap.trans = steps.trans.getTranslations(stepDiv); return; } if (id === "zarava") { snap.zarava = steps.zarava.getTranslations(stepDiv); return; } if (id === "dunde") { snap.dunde = steps.dunde.getRows(stepDiv); return; } // Generic: read all step fields. var fields = stepDiv.find(".wiktku-start-step-field"); if (step.multiple) { snap[id] = fields.map(function () { return $(this).val(); }).get(); } else { snap[id] = fields.val(); } }); sections[activeSection] = snap; } /** * Restore a previously saved snapshot into the form DOM. */ function restoreSection(snap) { $.each(PER_SECTION_STEP_IDS, function (_, id) { if (id === "dfn") { restoreDfn(snap.dfn || []); return; } if (id === "etym") { $("#wiktku-start-etym .wiktku-etym-wrap").remove(); steps.etym.build($("#wiktku-start-etym")); $("#wiktku-start-etym .wiktku-etym-text").val(snap.etym || ""); return; } if (id === "trans") { // Rebuild trans groups (dfn must already be restored by this // point in the $.each loop, so glossList() reflects it). var transDiv = $("#wiktku-start-trans"); transDiv.find(".wiktku-trans-group").remove(); steps.trans.build(transDiv); var groupsSnap = snap.trans || []; $.each(groupsSnap, function (gi, rows) { var group = transDiv.find(".wiktku-trans-group[data-gloss-pos='" + gi + "']"); if (!group.length) return; // gloss no longer exists — drop its rows var list = group.find("ul.wiktku-trans-list"); $.each(rows, function (j, row) { var lang = row[0], words = row[1]; var lastRow = list.find("li.wiktku-trans-row").last(); lastRow.find("select").val(lang).trigger("change"); var wordList = lastRow.find("ul.wiktku-trans-words"); $.each(words, function (k, word) { var wordItems = wordList.find("li"); if (k < wordItems.length) { wordItems.eq(k).find("textarea").val(word); } else { // .val() below doesn't fire "input", so the normal // auto-grow never runs — append a matching item // ourselves instead of silently dropping the word. var extraInput = steps.trans.makeWordInput(); wordList.append($("<li></li>").append(extraInput)); extraInput.val(word); } }); // Leave one trailing empty field so the row can still grow // when the user types, matching a freshly-built row. if ($.trim(wordList.children("li").last().find("textarea").val())) { wordList.append($("<li></li>").append(steps.trans.makeWordInput())); } }); }); return; } if (id === "zarava") { // Rebuild zarava groups (dfn must already be restored by this // point in the $.each loop, so glossList() reflects it). var zaravaDiv = $("#wiktku-start-zarava"); zaravaDiv.find(".wiktku-zarava-group").remove(); steps.zarava.build(zaravaDiv); var zaravaGroupsSnap = snap.zarava || []; $.each(zaravaGroupsSnap, function (gi, rows) { var group = zaravaDiv.find(".wiktku-zarava-group[data-gloss-pos='" + gi + "']"); if (!group.length) return; // gloss no longer exists — drop its rows var list = group.find("ul.wiktku-zarava-list"); $.each(rows, function (j, row) { var lang = row[0], words = row[1]; var lastRow = list.find("li.wiktku-zarava-row").last(); lastRow.find("select").val(lang).trigger("change"); var wordList = lastRow.find("ul.wiktku-zarava-words"); $.each(words, function (k, word) { var wordItems = wordList.find("li"); if (k < wordItems.length) { wordItems.eq(k).find("textarea").val(word); } else { var extraInput = steps.zarava.makeWordInput(); wordList.append($("<li></li>").append(extraInput)); extraInput.val(word); } }); if ($.trim(wordList.children("li").last().find("textarea").val())) { wordList.append($("<li></li>").append(steps.zarava.makeWordInput())); } }); }); return; } if (id === "dunde") { // Rebuild dunde rows. var dundeDiv = $("#wiktku-start-dunde"); dundeDiv.find("ul.wiktku-dunde-list").remove(); steps.dunde.build(dundeDiv); var dundeRows = snap.dunde || []; $.each(dundeRows, function (i, row) { var lang = row[0], words = row[1]; var list = dundeDiv.find("ul.wiktku-dunde-list"); var lastRow = list.find("li.wiktku-dunde-row").last(); lastRow.find("select").val(lang).trigger("change"); var wordList = lastRow.find("ul.wiktku-dunde-words"); $.each(words, function (j, word) { var wordItems = wordList.find("li"); if (j < wordItems.length) { wordItems.eq(j).find("textarea").val(word); } else { // .val() below doesn't fire "input", so the normal // auto-grow never runs — append a matching item // ourselves instead of silently dropping the word. var extraInput = steps.dunde.makeWordInput(); wordList.append($("<li></li>").append(extraInput)); extraInput.val(word); } }); // Leave one trailing empty field so the row can still grow // when the user types, matching a freshly-built row. if ($.trim(wordList.children("li").last().find("textarea").val())) { wordList.append($("<li></li>").append(steps.dunde.makeWordInput())); } }); return; } var step = steps[id]; if (!step) return; var stepDiv = $("#wiktku-start-" + id); var fields = stepDiv.find(".wiktku-start-step-field"); var val = snap[id]; if (val === undefined || val === null) return; if (step.multiple) { var arr = val; fields.each(function (i) { if (i < arr.length) $(this).val(arr[i]); }); } else { fields.val(val); } // Notify chosen widgets of the programmatic value change. if (!isMobile) fields.filter("select").trigger("chosen:updated"); }); } function getWikitextForCurrentSection(callback) { var values = getValues(); var entry = steps.pos.output(values); steps.dfn.getOutput(values, function (output) { entry += output; entry += steps.je.output(values); entry += steps.tekildar.output(values); entry += steps.etym.output(values); entry += steps.dunde.output(values); entry += steps.binereherwiha.output(values); entry += steps.zarava.output(values); entry += steps.trans.output(values); callback(entry, values); }); } function getWikitextAllSections(callback) { saveCurrentSection(); var results = new Array(sections.length); var sharedValues = getValues(); // lang/pron are shared function processSection(i) { if (i >= sections.length) { // All done — restore original active section. restoreSection(sections[activeSection]); refresh(); callback(results, sharedValues); return; } restoreSection(sections[i]); refresh(); getWikitextForCurrentSection(function (sectionText) { results[i] = sectionText; processSection(i + 1); }); } processSection(0); } /** * Assembles wikitext for all sections plus the shared lang/pron header. */ function getWikitext(callback) { getWikitextAllSections(function (sectionTexts, sharedValues) { var entry = steps.lang.output(sharedValues); entry += steps.pron.output(sharedValues); entry += sectionTexts.join("\n"); // Edit summary uses section 0's values. Read from the saved snapshot // (not the live DOM) so it doesn't mix section 0's pos with whichever // section happens to be active/restored at this point. var dfnSenses = (sections[0] && sections[0].dfn) || []; var dfnSummary = dfnSenses.map(function (s) { return s.mane; }).filter(Boolean).join("; "); var summaryLabel = addLangMode ? "WF:Ziman lê zêde" : "WF:Nû"; var summary = "([[Mediawiki:Gadget-start.js|" + summaryLabel + "]] v.2.0) +" + sharedValues.lang + ":" + sections[0].pos + ":" + dfnSummary; var summaryField = document.getElementById("wpSummary"); if (addLangMode && summaryField.value) { summary = summaryField.value + " " + summary; } summaryField.value = summary; callback(entry); }); } var continueBtn; function getValuesForStep(stepId) { var fields = $("#wiktku-start-" + stepId + " .wiktku-start-step-field"); var step = steps[stepId]; if (step.keys) { var values = {}; fields.each(function (i, field) { var key = $(field).prevAll(".wiktku-start-step-keyfield").val(); if (key) values[key] = $(field).val(); }); return values; } else if (step.multiple) { return fields.map(function () { return $(this).val(); }).get(); } return fields.val(); } function getValues() { var values = {}; $.each(steps, function (stepId) { values[stepId] = getValuesForStep(stepId); }); return values; } function populateMenus(inputs, choices, disabledValues) { if (!disabledValues) disabledValues = {}; var vals = inputs.map(function (i, input) { return $(input).val(); }); inputs.empty(); inputs.append($("<option></option>")); $.each(choices, function (j, choice) { // Append the language code in parentheses so that typing a code // (e.g. "ku") in the search box still finds the language name. var displayText = capitalize(choice[1]); if (choice[2] !== undefined) { // This is a language choice [code, name, sortKey] — show code. displayText = capitalize(choice[1]) + " (" + choice[0] + ")"; } var option = $(mw.html.element("option", { value: choice[0] }, displayText)); if (disabledValues[choice[0]]) option.prop("disabled", true); inputs.append(option); }); inputs.val(function (i) { return vals[i]; }); } /** * Returns a bitmap containing the keys that should be disabled for a key * menu in the given step because they are disabled or already taken by * another key menu. */ function getDisabledKeys(step) { var occupiedKeys = {}; $("#wiktku-start-" + step.id + " .wiktku-start-step-keyfield").each(function () { occupiedKeys[$(this).val()] = true; }); if (step.disabledKeys) $.extend(occupiedKeys, step.disabledKeys); return occupiedKeys; } function buildKeyInput(step) { if (!step.keys) return undefined; var input = $(mw.html.element("select", { "class": "wiktku-start-step-keyfield wiktku-start-narrow" })); input.attr("data-placeholder", "Hilbijêre " + step.keyName); if (isMobile) { populateMenus(input, step.keys, getDisabledKeys(step)); // On mobile return the wrapper; the select is inside it. // Change events still fire on the inner select. return wrapNativeSelect(input); } input.on("chosen:showing_dropdown", function () { $(this).data("wiktku-defaultValue", $(this).val()); }); input.change(function (_, context) { var inputs = $("#wiktku-start-" + step.id + " .wiktku-start-step-keyfield").not(this); var oldValue = $(this).data("wiktku-defaultValue"); var newValue = context.selected; inputs.find("option[value='" + oldValue + "']").prop('disabled', false); inputs.find("option[value='" + newValue + "']").prop('disabled', true); inputs.trigger("chosen:updated"); }); populateMenus(input, step.keys, getDisabledKeys(step)); return input; } /** * If the current text field has text and there are no more text fields after * the current text field in the list, add another text field to the list. */ function refreshForTextField(currentInput, step) { currentInput = $(currentInput); var value = currentInput.val(); var item = currentInput.parent(); if (value && !item.next("li").length) { var nextInput = $("<textarea></textarea>") .attr("name", "wiktku-field-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("class", currentInput.attr("class")) .attr("rows", currentInput.attr("rows") || 1); nextInput.on("input", function (evt) { refreshForTextField(evt.target, step); }); var nextKeyInput = buildKeyInput(step); var nextItem = $("<li></li>").append(nextKeyInput).append(nextInput); item.parent().append(nextItem); if (nextKeyInput) nextKeyInput.chosen(chosenOptions); } var canContinue = !continueBtn.isDisabled(); if ((value && !canContinue) || (!value && canContinue)) { refresh(step); } } function prepareInput(input, step) { if (!input) return; if (step.required) input.prop('required', true); input.change(step, refresh); } /** * Shows and hides all the steps based on whether their prerequisites are met, * and updates placeholders where applicable. */ function refresh(evt) { var values = getValues(); var changedStep = evt && evt.data; var didFocus = false; var canContinue = true; // Re-filter template options in every sense block whenever lang changes. $("#wiktku-start-dfn .wiktku-dfn-tpl-select").each(function () { var fn = $(this).data("updateOptions"); if (typeof fn === "function") fn(); }); // Re-filter pronunciation and etymology template dropdowns when language changes. steps.pron.refreshTplSelect(); steps.etym.refreshTplSelect(); // Sync tr/t sub-fields in every nimûne item to the current language. // tr shown when language needs transliteration; t shown when lang !== "ku". (function () { var lang = values.lang || ""; var showTr = needsTransliteration(lang); var showT = lang && lang !== "ku"; $("#wiktku-start-dfn .wiktku-dfn-nimune-list li.wiktku-dfn-nimune-li").each(function () { var li = $(this); // Ensure the sub-wrapper exists when we need it. var subWrap = li.find(".wiktku-dfn-nimune-sub"); // tr field var trTa = li.find(".wiktku-dfn-nimune-tr"); if (showTr && !trTa.length) { if (!subWrap.length) { subWrap = $("<div></div>").addClass("wiktku-dfn-nimune-sub"); li.append(subWrap); } trTa = $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-tr-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 5) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-tr") .attr("placeholder", "Transkrîpsiyon…"); subWrap.prepend(trTa); } else if (!showTr && trTa.length) { trTa.remove(); } // t field var tTa = li.find(".wiktku-dfn-nimune-t"); if (showT && !tTa.length) { if (!subWrap.length) { subWrap = $("<div></div>").addClass("wiktku-dfn-nimune-sub"); li.append(subWrap); } tTa = $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-t-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 5) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-t") .attr("placeholder", "Tercimeya nimûneyê kurmancî…"); subWrap.append(tTa); } else if (!showT && tTa.length) { tTa.remove(); } // Remove the wrapper if it ended up empty. subWrap = li.find(".wiktku-dfn-nimune-sub"); if (subWrap.length && !subWrap.children().length) subWrap.remove(); }); }()); // Sync tr/t sub-fields in every jêder citation to the current language. // tr shown when language needs transliteration; t shown when lang !== "ku". (function () { var lang = values.lang || ""; var showTr = needsTransliteration(lang); var showT = lang && lang !== "ku"; $("#wiktku-start-dfn .wiktku-dfn-jeder-list li.wiktku-dfn-jeder-li").each(function () { var li = $(this); // Ensure the sub-wrapper exists when we need it. It must sit right // after the quote textarea and before the source selector. var subWrap = li.find(".wiktku-dfn-quote-sub"); // tr field var trTa = li.find(".wiktku-dfn-nimune-quote-tr"); if (showTr && !trTa.length) { if (!subWrap.length) { subWrap = $("<div></div>").addClass("wiktku-dfn-quote-sub"); li.find(".wiktku-dfn-nimune-quote").after(subWrap); } trTa = $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-quote-tr-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 2) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-quote-tr") .attr("placeholder", "Transkrîpsiyona jêgirtinê…"); subWrap.prepend(trTa); } else if (!showTr && trTa.length) { trTa.remove(); } // t field var tTa = li.find(".wiktku-dfn-nimune-quote-t"); if (showT && !tTa.length) { if (!subWrap.length) { subWrap = $("<div></div>").addClass("wiktku-dfn-quote-sub"); li.find(".wiktku-dfn-nimune-quote").after(subWrap); } tTa = $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-quote-t-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 2) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-quote-t") .attr("placeholder", "Tercimeya jêgirtinê ya kurmancî…"); subWrap.append(tTa); } else if (!showT && tTa.length) { tTa.remove(); } // Remove the wrapper if it ended up empty. subWrap = li.find(".wiktku-dfn-quote-sub"); if (subWrap.length && !subWrap.children().length) subWrap.remove(); }); }()); $.each(steps, function (stepId, step) { if (typeof(step.visible) === "function" && !step.visible(values)) { $("#wiktku-start-" + stepId).slideUp(); } else { var stepDiv = $("#wiktku-start-" + stepId); if (changedStep !== step && typeof(step.build) === "function") { prepareInput(step.build(stepDiv, values), step); } var input = stepDiv.find(".wiktku-start-step-field"); if (typeof(step.example) === "function") { // .find() above already reaches nested fields (e.g. the dfn // step's mane textareas inside each sense block), so one // assignment covers every step; dfn keeps its own fallback. var exampleText = step.example(values) || (step.id === "dfn" ? "Mane…" : ""); input.attr("placeholder", exampleText); } var didSlideDown; if (!didFocus && stepDiv.css("display") === "none" && step.required) { didSlideDown = function (evt) { input.focus(); }; didFocus = true; } stepDiv.slideDown(didSlideDown); } if (step.required && (values[stepId] === "" || (step.multiple && values[stepId].join("") === ""))) { canContinue = false; } }); continueBtn.setDisabled(!canContinue); } function destroy() { $("#wiktku-start-form, .noafterwizard").slideUp(function () { $(this).remove(); }); $(".noarticletext .nowizard, #editform").slideDown(); $("#ca-edit").removeClass("selected"); $("#ca-wiktku-nowizard").addClass("selected"); } // Priority order for Kurdish dialects and the navz pseudo-code. // Codes listed here come before all other languages; unlisted codes // are sorted alphabetically by their display name via localeCompare. var LANG_PRIORITY = ["navz", "ku", "hac", "sdh", "lki", "ckb", "zza"]; /** * Inserts a new == {{ziman|code}} == section into existing page wikitext * at the correct sorted position: * 1. Any content before the first language section is preserved at the top. * 2. navz is always first, then ku/hac/sdh/lki/ckb/zza in that order, * then all other languages sorted by display name (localeCompare). */ function insertNewLangSection(existing, wikitext) { var newCodeMatch = wikitext.match(/^== \{\{ziman\|([^}]+)\}\} ==/); var newCode = newCodeMatch ? newCodeMatch[1] : ""; var sections = []; var preamble = ""; var firstMatch = existing.match(/(?:^|\n)== \{\{ziman\|/); if (!firstMatch) { // No existing lang sections at all — just append. var sep = existing && !/\n\s*$/.test(existing) ? "\n\n" : ""; return existing + sep + wikitext; } // Everything before the first == {{ziman|...}} == is the preamble. var firstSectionStart = existing.indexOf("== {{ziman|"); // Walk back to the start of that line. var lineStart = existing.lastIndexOf("\n", firstSectionStart - 1); var preambleEnd = lineStart !== -1 ? lineStart + 1 : 0; preamble = existing.slice(0, preambleEnd); // Parse each language section: header line + everything until the next header. var body = existing.slice(preambleEnd); // NOTE: with the /m flag, a bare "$" matches end-of-*line*, not just // end-of-string — that previously made the non-greedy content group // stop at the section's first line break instead of running to the // next language header (or the real end of the text), silently // dropping the rest of that section's wikitext. (?![\s\S]) matches // only the true end of the string, /m flag or not. var langSectionRe = /^(== \{\{ziman\|([^}]+)\}\} ==\n?)([\s\S]*?)(?=\n== \{\{ziman\||(?![\s\S]))/gm; var m; while ((m = langSectionRe.exec(body)) !== null) { sections.push({ code: m[2], content: m[0] // full text of this section including header }); } // Determine sort rank: priority list first (by index), then alphabetical. function getLangName(code) { var entry = langsByCode[code]; return entry ? entry[1] : code; } function sortRank(code) { var idx = LANG_PRIORITY.indexOf(code); return idx !== -1 ? idx : LANG_PRIORITY.length; } function compareLangs(a, b) { var ra = sortRank(a), rb = sortRank(b); if (ra !== rb) return ra - rb; // Both are outside priority list — sort by display name. return getLangName(a).localeCompare(getLangName(b), userLang); } // Insert the new section into the sorted list. var newSection = { code: newCode, content: wikitext }; var inserted = false; for (var i = 0; i < sections.length; i++) { if (compareLangs(newCode, sections[i].code) < 0) { sections.splice(i, 0, newSection); inserted = true; break; } } if (!inserted) sections.push(newSection); // Re-join: preamble + sections separated by newlines. var joined = sections.map(function (s) { // Ensure each section ends with exactly one newline before the next. return s.content.replace(/\n+$/, ""); }).join("\n"); return preamble + joined + "\n"; } function build() { $(".nowizard, .nowizard .noafterwizard").hide(); var callToAction = $("#wiktku-calltoaction"); var origCallToActionText = callToAction.text(); $(mw.util.addPortletLink("p-views", "#", "Edîtora çavkaniyê veke", "ca-wiktku-nowizard", "Vê rûpelê bi edîtora çavkaniyê çêke", undefined, "#ca-watch")).click(function (evt) { evt.preventDefault(); callToAction.text(origCallToActionText); destroy(); }); if (callToAction.length) { callToAction.text(origCallToActionText + " Forma li jêr ji bo çêkirina madeyeke nû bi kar bîne."); } var startForm = $("<form id='wiktku-start-form'></form>"); if (addLangMode) { startForm.append($("<p class='wiktku-addlang-notice'></p>").html( "Bi vê formê tu yê beşeke nû li rûpelê îlaw bikî. Eger ev zimanê ku tu îlawe dikî jixwe di rûpelê de hebe, beşa nû li dawiya vî zimanî dê were îlawekirin. " + "Ji kerema xwe netîceya dawî kontrol bikin, eger problemek derkeve, li <a href='" + mw.util.getUrl('Mediawiki talk:Gadget-start.js') + "'>nîqaşa vê amûrê</a> problemê ragihîne." )); } var spinner; // Tab bar for switching between POS sections. var sectionTabsDiv = $("<div id='wiktku-section-tabs'></div>"); startForm.submit(function (evt) { evt.preventDefault(); continueBtn.setDisabled(true); spinner.show(); getWikitext(function (wikitext) { if (addLangMode) { var textbox = $("#wpTextbox1"); var existing = textbox.val() || ""; // Check whether the generated lang header already exists in the page. // wikitext always starts with "== {{ziman|CODE}} ==\n" (from steps.lang.output). // If that exact section heading is already present in the existing content, // strip it from the new output and insert the remaining content at the end // of that lang section (just before the next == level-2 heading, or at the // very end of the page if there is no following section). var langHeaderMatch = wikitext.match(/^(== \{\{ziman\|[^}]+\}\} ==\n)/); if (langHeaderMatch) { var langHeader = langHeaderMatch[1]; // e.g. "== {{ziman|ku}} ==\n" // Escape for use in RegExp. var escapedHeader = langHeader.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); if (new RegExp(escapedHeader).test(existing)) { // Strip the header from the new output. var newContent = wikitext.slice(langHeader.length); // Find the insertion point: end of the existing lang section. // A new L2 heading marks the start of the next language block. var afterHeader = existing.indexOf(langHeader); var searchFrom = afterHeader + langHeader.length; // Find the next == … == heading after this section's start. var nextL2 = existing.indexOf("\n== ", searchFrom); var insertAt = nextL2 !== -1 ? nextL2 : existing.length; // Ensure there's a blank line before the inserted block. var before = existing.slice(0, insertAt); var after = existing.slice(insertAt); var sep = /\n\s*$/.test(before) ? "" : "\n"; textbox.val(before + sep + newContent + after); } else { // New language — insert at the correct sorted position. textbox.val(insertNewLangSection(existing, wikitext)); } } else { // Unexpected format — insert at sorted position anyway. textbox.val(insertNewLangSection(existing, wikitext)); } } else { $("#wpTextbox1").val(wikitext); } $("html, body").animate({scrollTop: 0}); callToAction.text("Hindik ma!"); $("#wiktku-preview-container").remove(); destroy(); }); }); $.each(ordered_steps, function (i, step) { var stepDiv = $(mw.html.element("div", { "class": "wiktku-start-step", id: "wiktku-start-" + step.id })); var name = capitalize(step.name); stepDiv.append($(mw.html.element("h3", { "class": "wiktku-start-step-name" }, new mw.html.Raw(mw.html.element("label", { "for": "wiktku-start-" + step.id + "-field" }, name))))); if (step.question_fmt) { stepDiv.append($(mw.html.element("label", { "class": "wiktku-start-step-question", "for": "wiktku-start-" + step.id + "-field" }, step.question_fmt))); if (step.question_br) stepDiv.append($("<br>")); } var input; if (step.choices) { input = $(mw.html.element("select", { "class": "wiktku-start-step-field", id: "wiktku-start-" + step.id + "-field" })); input.attr("data-placeholder", capitalize(step.name) + " hilbijêre "); populateMenus(input, step.choices); if (step.multiple) input.attr("multiple", true); if (isMobile) { stepDiv.append(wrapNativeSelect(input)); } else { stepDiv.append(input); } } else if (typeof(step.build) === "function") { input = step.build(stepDiv); } else { input = $("<textarea></textarea>") .attr("class", "wiktku-start-step-field") .attr("id", "wiktku-start-" + step.id + "-field") .attr("rows", step.rows || 2); if (step.narrow) input.addClass("wiktku-start-narrow"); if (step.multiple) { input.on("input", function (evt) { refreshForTextField(evt.target, step); }); var keyInput = buildKeyInput(step); var list = $(step.ordered ? "<ol></ol>" : "<ul></ul>") .append($("<li></li>").append(keyInput).append(input)); stepDiv.append(list); } else stepDiv.append(input); } prepareInput(input, step); stepDiv.hide(); // Insert tab bar just before the first per-section step. if (step.id === "pos") startForm.append(sectionTabsDiv); startForm.append(stepDiv); }); // ── Section tab helpers ────────────────────────────────────────────── // ── Add-section button — lives in the tab bar, disabled until pos chosen ── var addSectionBtn = new OO.ui.ButtonWidget({ label: "+ Beş zêde bike", disabled: true }); addSectionBtn.on("click", function () { saveCurrentSection(); sections.push({}); activeSection = sections.length - 1; $.each(PER_SECTION_STEP_IDS, function (_, id) { if (id === "dfn") { var stepDiv = $("#wiktku-start-dfn"); stepDiv.find("ol.wiktku-dfn-list").remove(); steps.dfn.build(stepDiv); return; } if (id === "etym") { $("#wiktku-start-etym .wiktku-etym-wrap").remove(); steps.etym.build($("#wiktku-start-etym")); return; } if (id === "trans") { var transDiv = $("#wiktku-start-trans"); transDiv.find(".wiktku-trans-group").remove(); return; } if (id === "zarava") { var zaravaDiv = $("#wiktku-start-zarava"); zaravaDiv.find(".wiktku-zarava-group").remove(); return; } if (id === "dunde") { var dundeDiv = $("#wiktku-start-dunde"); dundeDiv.find("ul.wiktku-dunde-list").remove(); return; } var stepDiv = $("#wiktku-start-" + id); stepDiv.find(".wiktku-start-step-field").val(""); if (!isMobile) stepDiv.find("select.wiktku-start-step-field").trigger("chosen:updated"); }); renderSectionTabs(); refresh(); $("html, body").animate({ scrollTop: sectionTabsDiv.offset().top - 20 }, 300); }); /** Re-render the tab bar to reflect current sections[] and activeSection. */ function renderSectionTabs() { // Detach (not remove) the button first: .empty() strips bound // event data from any children left inside it, which would // silently kill addSectionBtn's click handler on every re-render. addSectionBtn.$element.detach(); sectionTabsDiv.empty(); var lang = getValues().lang || ""; if (!lang) { sectionTabsDiv.hide(); return; } sectionTabsDiv.show(); $.each(sections, function (i) { var posVal = sections[i].pos || ""; var tabLabel = posVal ? capitalize(posVal) : ("Beş " + (i + 1)); var tab = $("<span></span>") .addClass("wiktku-section-tab") .text(tabLabel) .toggleClass("wiktku-tab-active", i === activeSection); (function (idx) { tab.on("click", function () { if (idx === activeSection) return; saveCurrentSection(); activeSection = idx; restoreSection(sections[activeSection]); refresh(); renderSectionTabs(); }); }(i)); sectionTabsDiv.append(tab); }); // Enable "Beş zêde bike" only when the active section has a pos chosen. var activePos = sections[activeSection] && sections[activeSection].pos ? sections[activeSection].pos : getValues().pos; addSectionBtn.setDisabled(!activePos); sectionTabsDiv.append(addSectionBtn.$element); } renderSectionTabs(); // Update the active tab's label whenever pos changes. startForm.on("change", "#wiktku-start-pos-field", function () { renderSectionTabs(); }); // Show the tab bar as soon as a language is selected. startForm.on("change", "#wiktku-start-lang-field", function () { renderSectionTabs(); }); var footer = $("<div id='wiktku-start-footer'></div>"); spinner = $(mw.html.element("img", { id: "wiktku-start-spinner", src: "//upload.wikimedia.org/wikipedia/commons/d/de/Ajax-loader.gif", alt: "Tê barkirin…", title: "Tê barkirin…" })); footer.append(spinner.hide()); continueBtn = new OO.ui.ButtonWidget({ id: "wiktku-unhide-editform", label: "Bişîne", flags: [ "primary", "progressive" ] }); continueBtn.on("click", function () { mw.notify("Tê şandin…", { type: "info", tag: "wiktku-submit" }); startForm.trigger("submit"); }); footer.append(continueBtn.$element); // "Edîtora çavkaniyê veke" button — inline fallback for the portlet link // which is invisible on mobile and easy to miss on desktop. var sourceEditorBtn = new OO.ui.ButtonWidget({ label: "Edîtora çavkaniyê veke", framed: false }); sourceEditorBtn.on("click", function () { destroy(); }); footer.append(sourceEditorBtn.$element); // ── Preview checkboxes ─────────────────────────────────────────────── // Wikitext preview (raw text panel) var previewCheck = $("<input type='checkbox' id='wiktku-preview-toggle'>"); var previewLabel = $("<label for='wiktku-preview-toggle'></label>") .text(" Pêşdîtina wîkîtekstê"); var previewPanel = $("<pre id='wiktku-preview-panel'></pre>").hide(); // Live rendered preview (parsed HTML panel, same logic as AjaxEdit). // Not available on mobile — API polling causes too many problems on small screens. var livePreviewCheck = null; var livePreviewPanel = null; if (!isMobile) { livePreviewCheck = $("<input type='checkbox' id='wiktku-live-preview-toggle'>"); livePreviewPanel = $("<div id='wiktku-live-preview-panel'></div>").hide(); } // Container that holds both panels and switches between stacked / side-by-side. var previewContainer = $("<div id='wiktku-preview-container'></div>"); previewContainer.append(previewPanel); if (!isMobile) previewContainer.append(livePreviewPanel); var previewTimer = null; var livePreviewIntervalId = -1; var livePreviewActive = false; // guards in-flight fetches after uncheck /** Rebuilds wikitext preview if its checkbox is checked. */ function schedulePreview() { if (!previewCheck.prop("checked")) return; clearTimeout(previewTimer); // Debounce: wait 400 ms after the last keystroke before rebuilding. previewTimer = setTimeout(function () { getWikitext(function (wikitext) { previewPanel.text(wikitext).show(); updatePanelLayout(); }); }, 400); } /** Fetches parsed HTML and populates the live preview panel. */ function loadLivePreview() { getWikitext(function (wikitext) { new mw.Api().parse(wikitext, { title: mw.config.get("wgPageName") }).done(function (html) { // Discard result if the user unchecked while the fetch was in flight. if (!livePreviewActive) return; livePreviewPanel.html(html).show(); updatePanelLayout(); }); }); } /** Adjusts panel widths depending on which previews are visible. */ function updatePanelLayout() { var wikitextVisible = previewCheck.prop("checked"); var liveVisible = livePreviewCheck && livePreviewCheck.prop("checked"); if (wikitextVisible && liveVisible) { // Side by side — each panel takes roughly half the available width. previewPanel.css({ "flex": "1 1 45%", "min-width": "280px" }); livePreviewPanel.css({ "flex": "1 1 45%", "min-width": "280px" }); } else { // Full width for whichever is visible — only touch panels that are // actually shown so that setting flex doesn't override display:none. if (wikitextVisible) previewPanel.css({ "flex": "1 1 100%", "min-width": "" }); if (liveVisible && livePreviewPanel) livePreviewPanel.css({ "flex": "1 1 100%", "min-width": "" }); } } previewCheck.on("change", function () { if ($(this).prop("checked")) { schedulePreview(); } else { clearTimeout(previewTimer); previewPanel.hide(); updatePanelLayout(); } }); if (!isMobile) { livePreviewCheck.on("change", function () { if ($(this).prop("checked")) { livePreviewActive = true; livePreviewPanel.show(); loadLivePreview(); livePreviewIntervalId = setInterval(loadLivePreview, 500); } else { livePreviewActive = false; clearInterval(livePreviewIntervalId); livePreviewIntervalId = -1; livePreviewPanel.hide().empty(); updatePanelLayout(); } }); } // Listen on all input/change events on the form and update both previews. startForm.on("input change", function () { schedulePreview(); }); footer.append($("<span style='margin-left:1em'></span>") .append(previewCheck).append(previewLabel)); if (!isMobile) { var livePreviewLabel = $("<label for='wiktku-live-preview-toggle'></label>") .text(" Pêşdîtina zindî"); footer.append($("<span style='margin-left:1em'></span>") .append(livePreviewCheck).append(livePreviewLabel)); } startForm.append(footer); $("#editform").hide().before(startForm); // Insert preview container (holds both panels) after the form. startForm.after(previewContainer); if (!isMobile) startForm.find("select").chosen(chosenOptions); refresh(); // Zimanan ji MediaWiki:Gadget-translation_editor.js/ziman.json bar bike. // Kodên ku bi "-pro" diqedin û navên ku "zimanê destan" tê de heye // tên derxistin. Zimanên xardkirî li serî dimînin, yên din // bi alfabeyê li dû wan tên. // Pinned choices come from MediaWiki:Gadget-start.js/data.json (langChoices), // already loaded into steps.lang.choices before build() runs. var pinnedChoices = steps.lang.choices.slice(); var pinnedCodes = $.map(pinnedChoices, function (choice) { return choice[0]; }); new mw.Api().get({ action: "query", prop: "revisions", titles: "MediaWiki:Gadget-translation_editor.js/ziman.json", rvprop: "content", rvslots: "main", formatversion: 2 }).then(function (data) { var page = data.query.pages[0]; var content = page && page.revisions && page.revisions[0].slots.main.content; var zimanData; try { zimanData = JSON.parse(content); } catch (e) { zimanData = {}; } var extraChoices = []; $.each(zimanData, function (code, name) { // Filter: skip proto-language codes and legendary/reconstructed langs. if (/-pro$/i.test(code)) return; if (/ziman[eê]\s+destan/i.test(name)) return; // Skip codes already in the pinned list (they are handled above). if (pinnedCodes.indexOf(code) !== -1) return; // sortKey: bare name without leading "zimanê " for sorting. var sortKey = name.replace(/^ziman[eê]\s+/i, ""); var choice = [code, name, sortKey]; extraChoices.push(choice); langsByCode[code] = choice; }); // Populate langsByCode for pinned choices too. $.each(pinnedChoices, function (i, choice) { // Ensure pinned choices have a sortKey (index 2). if (choice.length < 3) choice[2] = choice[1]; langsByCode[choice[0]] = choice; }); // Sort the extra choices alphabetically by sort key. extraChoices.sort(function (a, b) { return a[2].localeCompare(b[2], userLang); }); // Final list: pinned first, then the rest. var allChoices = pinnedChoices.concat(extraChoices); steps.lang.choices = allChoices; steps.trans.keys = allChoices; steps.dunde.keys = allChoices; steps.zarava.keys = getZaravaKeys(allChoices); var langMenu = $("#wiktku-start-lang-field"); populateMenus(langMenu, steps.lang.choices); langMenu.trigger("chosen:updated"); var transMenus = $("#wiktku-start-trans .wiktku-start-step-keyfield"); populateMenus(transMenus, steps.trans.keys, getDisabledKeys(steps.trans)); transMenus.trigger("chosen:updated"); var dundeMenus = $("#wiktku-start-dunde .wiktku-start-step-keyfield"); populateMenus(dundeMenus, steps.dunde.keys, getDisabledKeys(steps.dunde)); dundeMenus.trigger("chosen:updated"); var zaravaMenus = $("#wiktku-start-zarava .wiktku-start-step-keyfield"); populateMenus(zaravaMenus, steps.zarava.keys, getDisabledKeys(steps.zarava)); }); } mw.loader.using(["jquery.chosen", "mediawiki.api", "oojs-ui-core"], function () { if (!isMobile) { mw.notify( "Amûr dest pê dike, hinek bisekinin. Not: jkx Sentaks (sentaks highlighter) neaktîv bikin", { type: "info", tag: "wiktku-start-notice", autoHide: true, autoHideSeconds: 10 } ); } // Load metadata, langChoices, posChoices and tplDefs from the companion // data page so they can be updated without touching this script. new mw.Api().get({ action: "query", prop: "revisions", titles: "MediaWiki:Gadget-start.js/data.json", rvprop: "content", rvslots: "main", formatversion: 2 }).then(function (data) { var page = data.query.pages[0]; var content = page && page.revisions && page.revisions[0].slots.main.content; var d; try { d = JSON.parse(content); } catch (e) { d = {}; } // Populate metadata. if (d.metadata) $.extend(metadata, d.metadata); // Populate gender labels. if (d.genderLabels) $.extend(GENDER_BASE_LABELS, d.genderLabels); // Populate lang choices (pinned list used by build() → ziman.json loader). if (d.langChoices) steps.lang.choices = d.langChoices; // Populate POS choices. if (d.posChoices) steps.pos.choices = d.posChoices; // Populate template definitions for the dfn sense-block builder. if (d.tplDefs) steps.dfn.tplDefs = d.tplDefs; // Populate pos placeholder examples. if (d.posExamples) steps.dfn.posExamples = d.posExamples; // Populate citation template definitions for the quote widget. if (d.jederDefs) steps.dfn.jederDefs = d.jederDefs; // Populate pronunciation and etymology template insert lists. if (d.pronTpls) { steps.pron.pronTpls = d.pronTpls; steps.pron.refreshTplSelect(); } if (d.etymTpls) { steps.etym.etymTpls = d.etymTpls; steps.etym.refreshTplSelect(); } // Sync trans/dunde/zarava keys with the (now populated) lang choices. steps.trans.keys = steps.lang.choices; steps.dunde.keys = steps.lang.choices; steps.zarava.keys = getZaravaKeys(steps.lang.choices); }).always(build); }); }); //</nowiki> 3teo9xrl4emgy4qm7e94lynnka9nphe 6265573 6265572 2026-07-19T14:10:46Z Wikihez 7344 6265573 javascript text/javascript // Li ser [[vi:MediaWiki:Gadget-start.js]] hatiye refaktorkirin. //<nowiki> $(function () { if (window.location.href.includes("editintro=User:Wikihez/creation/intro")) { return; // Do not run the script wextê WF:Bilez dişuxile } var ns = mw.config.get("wgNamespaceNumber"); if (ns && !(ns === 2 && mw.config.get("wgPageName").match(/\/ceribandin$|\/test$/))) { return; } var action = mw.config.get("wgAction"); var pageExists = !!mw.config.get("wgArticleId"); // "Zimanek lê zêde bike" mode: triggered from the portlet link below. var addLangMode = pageExists && mw.util.getParamValue("wiktkuaddlang") === "1"; // On a normal page view of an existing page, add the portlet link if (action === "view" && pageExists) { var targetContainer; var skin = mw.config.get('skin'); if (skin === 'vector-2022') { targetContainer = 'p-cactions'; } else if (skin === 'vector') { targetContainer = 'p-tb'; } else { targetContainer = 'p-views'; } mw.util.addPortletLink(targetContainer, mw.util.getUrl(mw.config.get("wgPageName"), { action: "submit", wiktkuaddlang: "1" }), "+Ziman/beşeke din", "ca-wiktku-addlang", "Ji vê rûpelê re ziman an jî beşeke nû zêde bike"); return; } if (!(action === "edit" || action === "submit")) { return; } if (!addLangMode && !$(".mw-newarticletext, .mw-newarticletextanon").length) { return; } function capitalize(str) { if (!str) return str; return str[0].toUpperCase() + str.substr(1); } function decapitalize(str) { if (!str) return str; return str[0].toLowerCase() + str.substr(1); } function escapeRegExp(str) { return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); } function stripWikilinks(str) { return str.replace(/\[\[([^\]|]+)(?:\|([^\]]+))?\]\]/g, function (m, target, display) { return display || target; }); } function insertAtCursor(el, text) { var start = el.selectionStart; var end = el.selectionEnd; var val = el.value; el.value = val.slice(0, start) + text + val.slice(end); var pos = start + text.length; el.selectionStart = el.selectionEnd = pos; } var pageName = mw.config.get("wgPageName").replaceAll(/_/g, " "); if (ns) pageName = pageName.replace(/.*\//, ""); var pageNameRe = escapeRegExp(pageName); var userLang = mw.config.get("wgUserLanguage"); // Mobile detection: MobileFrontend sets wgMFMode, or fall back to touch check. var isMobile = !!mw.config.get("wgMFMode") || window.matchMedia("(pointer: coarse)").matches; var chosenOptions = { width: "20em", disable_search_threshold: 0, placeholder_text_single: "Yekî hilbijêre", placeholder_text_multiple: "Hilbijêre", no_results_text: "Nehat dîtin", enable_split_word_search: true, search_contains: true }; function wrapNativeSelect(select) { var placeholder = select.attr("data-placeholder") || "Lê bigere…"; // Hide the native select — we drive it programmatically. select.hide(); var wrapper = $("<span class='wiktku-native-select-wrap'></span>"); var textInput = $("<input type='search' autocomplete='off'>") .attr("placeholder", placeholder) .addClass("wiktku-start-narrow wiktku-ac-input"); var resultsList = $("<ul class='wiktku-ac-results'></ul>").hide(); // Full option cache — rebuilt when chosen:updated fires. var allOptions = []; function cacheOptions() { allOptions = []; select.find("option").each(function () { var v = $(this).val(); if (!v) return; // skip the empty placeholder option allOptions.push({ value: v, text: $(this).text(), disabled: $(this).prop("disabled") }); }); } cacheOptions(); function showResults(query) { var q = query.trim().toLowerCase(); resultsList.empty(); var matched; if (q) { matched = []; $.each(allOptions, function (_, o) { if (o.disabled) return; var codeMatch = o.value.toLowerCase().indexOf(q) !== -1; var nameMatch = o.text.toLowerCase().indexOf(q) !== -1; if (codeMatch || nameMatch) { matched.push({ opt: o, codeMatch: codeMatch }); } }); // Code matches (especially prefix matches) come first. matched.sort(function (a, b) { var aCode = a.opt.value.toLowerCase(); var bCode = b.opt.value.toLowerCase(); var aPrefix = aCode.indexOf(q) === 0; var bPrefix = bCode.indexOf(q) === 0; if (aPrefix !== bPrefix) return aPrefix ? -1 : 1; if (a.codeMatch !== b.codeMatch) return a.codeMatch ? -1 : 1; return 0; }); matched = matched.map(function (item) { return item.opt; }); } else { matched = allOptions.filter(function (o) { return !o.disabled; }); } if (!matched.length) { resultsList.hide(); return; } $.each(matched.slice(0, 50), function (_, opt) { var li = $("<li></li>").text(opt.text).attr("data-value", opt.value); // Use touchend instead of touchstart so that a scroll gesture does // not accidentally select an item. We track whether the finger moved // between touchstart and touchend — if it did, it was a scroll. var touchMoved = false; li.on("touchstart", function () { touchMoved = false; }); li.on("touchmove", function () { touchMoved = true; }); li.on("touchend", function (e) { if (touchMoved) return; // was a scroll, not a tap e.preventDefault(); selectOption(opt.value, opt.text); }); // Keep mousedown for desktop fallback. li.on("mousedown", function (e) { e.preventDefault(); selectOption(opt.value, opt.text); }); resultsList.append(li); }); // Position the list above or below depending on available viewport space. var inputRect = textInput[0].getBoundingClientRect(); var viewportH = window.innerHeight; var spaceBelow = viewportH - inputRect.bottom - 8; var spaceAbove = inputRect.top - 8; var maxH = Math.min(224, Math.max(spaceBelow, spaceAbove)); // 224px ≈ 14em resultsList.css({ "max-height": maxH + "px", "top": spaceBelow >= spaceAbove ? "100%" : "auto", "bottom": spaceBelow >= spaceAbove ? "auto" : "100%" }); resultsList.show(); } function selectOption(value, text) { textInput.val(text); select.val(value); resultsList.hide(); select.trigger("change"); } textInput.on("input focus", function () { showResults($(this).val()); }); textInput.on("blur", function () { // Short delay so a touchstart on a result item fires first. setTimeout(function () { resultsList.hide(); }, 200); }); // chosen:updated → re-cache (called after ziman.json loads). select.on("chosen:updated", function () { cacheOptions(); // If a value is already selected, keep the display text in sync. var cur = select.val(); if (cur) { var match = $.grep(allOptions, function (o) { return o.value === cur; })[0]; if (match) textInput.val(match.text); } }); // No-op .chosen() so desktop call-sites don't need guarding. select.chosen = function () { return select; }; wrapper.append(textInput).append(resultsList).append(select); return wrapper; } var langsByCode = {}; // Populated from [[MediaWiki:Gadget-start.js/data.json]] at runtime. var metadata = {}; // Zaravayên kurdî yên ku di beşa "Bi zaravayên din" de tên pêşkêşkirin — // ev kod ji beşa Werger têne derxistin daku heman zimên du caran neyê xwendin. var ZARAVA_LANG_CODES = ["ckb", "sdh", "lki", "hac", "zza"]; function getZaravaKeys(choices) { var byCode = {}; $.each(choices || [], function (_, c) { byCode[c[0]] = c; }); var result = []; $.each(ZARAVA_LANG_CODES, function (_, code) { if (byCode[code]) result.push(byCode[code]); }); return result; } function needsTransliteration(langCode) { var meta = metadata[langCode]; if (!meta || !meta.sc) return false; var scripts = Array.isArray(meta.sc) ? meta.sc : [meta.sc]; return scripts.length > 0 && scripts[0] !== "Latn"; } // Kodên cinsiyetê yên di metadata.g de — ji data.json tê dagirtin var GENDER_BASE_LABELS = {}; // Sub-lists that only make sense for a plain (non-şablon) sense — hidden // when a şablon (e.g. {{guharto|…}}) is chosen for that sense, since a // template-based sense has no "own" gloss for alternate forms, synonyms, // antonyms, coordinate terms, hypernyms or hyponyms to attach to. Etîket, // Nimûne and Jêgirtin stay visible either way. var HIDDEN_ON_TPL_GROUPS = [ "wiktku-dfn-alternativ", "wiktku-dfn-hevmane", "wiktku-dfn-dijmane", "wiktku-dfn-koordine", "wiktku-dfn-jornav", "wiktku-dfn-jernav" ]; function genderLabel(code) { if (code === "p") return "Pirjimar"; var pluralMatch = code.match(/^(.+)-p$/); if (pluralMatch && GENDER_BASE_LABELS[pluralMatch[1]]) { return GENDER_BASE_LABELS[pluralMatch[1]] + " (pirjimar)"; } return GENDER_BASE_LABELS[code] || code; } /** * True if a sense has any content worth keeping besides its mane text — * etîket, hevmane/dijmane/koordîne/etc. word lists, nimûne, or jêder * (quote). Used so a sense with an empty mane but filled-in extra * fields still gets emitted (with {{mane?}} standing in for the gloss) * instead of being silently dropped. */ function senseHasExtraContent(s) { if (s.etiket && $.grep(s.etiket, function (e) { return $.trim(e) !== ""; }).length) return true; if (s.alternativ.length || s.hevmane.length || s.dijmane.length || s.koordine.length || s.jornav.length || s.jernav.length) return true; if (s.nimune && $.grep(s.nimune, function (n) { return (typeof n === "object" ? n.text : n) !== ""; }).length > 0) return true; if (s.jeder && $.grep(s.jeder, function (j) { return j && j.quote; }).length > 0) return true; return false; } /** * formatNimune: each nimûne item can be { text, tr, t }: * text — example text * tr — transliteration (only when the language needs it) * t — Kurdish translation (third positional param, no key) */ function formatNimune(nimunes, lang, hasJeder) { var hasNimune = nimunes && $.grep(nimunes, function (n) { return (typeof n === "object" ? n.text : n) !== ""; }).length > 0; if (!hasNimune) { return hasJeder ? "" : "\n#* {{bênimûne|" + lang + "}}"; } return $.map(nimunes, function (n) { var text = typeof n === "object" ? n.text : n; if (!text) return undefined; var bolded = text.replace( new RegExp("(" + pageNameRe + "([^( |,|;|\\?|\\.|\\!)]+)?)", "ig"), "'''$1'''"); var tpl = "\n#: {{nm|" + lang + "|" + bolded; if (typeof n === "object") { if (n.tr) tpl += "|tr=" + n.tr; // Translation as third positional param (no key needed). if (n.t) tpl += "|" + n.t; } // Short examples fit on one line together with their translation. // rêz=1 is not used for ku — definitions are shown on separate lines there. if (text.length < 200 && lang !== "ku") tpl += "|rêz=1"; tpl += "}}"; return tpl; }).join(""); } /** * Formats a list of jêder (quote/citation) objects into wikitext lines. * Each entry that has no quote text is skipped. Returns "" when the list * is empty or every entry is blank. * * #* {{jêder-…|lang|jêgirtin=…|tr=…|tercime=…|…fields…}} * * When no template is chosen, the generic {{jêder|…}} template is used * instead. Its 2nd positional param is the user's freeform "bi destê xwe * binivîsim" source text when supplied, or the çavkanî? placeholder otherwise. * If that text contains "=" it is passed as |2=… instead of a bare * positional param, since MediaWiki would otherwise misparse it as its * own key=value pair and break the template: * #* {{jêder|lang|jêgirtin=…|tr=…|tercime=…|<manual source or çavkanî?>}} */ function formatJeder(jederList, lang) { if (!jederList || !jederList.length) return ""; return $.map(jederList, function (jeder) { if (!jeder || !jeder.quote) return undefined; if (jeder.jederTpl) { var cite = "\n#* {{" + jeder.jederTpl + "|" + lang; cite += "|jêgirtin=" + jeder.quote; if (jeder.quoteTr) cite += "|tr=" + jeder.quoteTr; if (jeder.quoteT) cite += "|tercime=" + jeder.quoteT; $.each(jeder.jêderFields || {}, function (key, val) { if (val) cite += "|" + key + "=" + val; }); cite += "}}"; return cite; } var out = "\n#* {{jêder|" + lang + "|jêgirtin=" + jeder.quote; if (jeder.quoteTr) out += "|tr=" + jeder.quoteTr; if (jeder.quoteT) out += "|tercime=" + jeder.quoteT; var srcParam = jeder.jederManual ? jeder.jederManual : "çavkanî?"; // A positional param containing "=" gets parsed as its own key=value // pair by MediaWiki and breaks the template, so force it to be // explicitly named (|2=) whenever that's the case. out += (srcParam.indexOf("=") !== -1 ? "|2=" : "|") + srcParam; out += "}}"; return out; }).join(""); } function makeWordListStep(id, name, question_fmt, header, templateName) { return { id: id, name: name, question_fmt: question_fmt, multiple: true, narrow: true, visible: function (values) { return values.lang && values.pos; }, output: function (values) { var words = $.grep(values[id] || [], function (w) { return !!w; }); if (!words.length) return ""; var lang = values.lang; var section = "\n==== " + header + " ====\n"; if (words.length === 1) { // Single word — keep the simple inline template. return section + "* {{" + templateName + "|" + lang + "|" + words[0] + "}}\n"; } // Multiple words — use {{kol3}} with one positional param per word. var params = "cure=" + header + "\n" + $.map(words, function (w) { return "|" + w; }).join("\n"); return section + "{{kol3|" + lang + "|" + params + "\n}}\n"; } }; } var steps = { lang: { id: "lang", required: true, name: "ziman", question_fmt: '"' + pageName + '" bi çi zimanî ye?', question_br: true, // Populated from [[MediaWiki:Gadget-start.js/data.json]] (langChoices). choices: [], output: function (values) { return "== {{ziman|" + values.lang + "}} ==\n"; } }, pron: { id: "pron", name: "bilêvkirin", question_fmt: '"' + pageName + '" çawa tê telafûzkirin?', // pronTpls populated from data.json pronTpls: [], visible: function (values) { if (!values.lang) return false; // In addLangMode, only skip pron when this langcode's section // already exists in the page — if it's a new language, show it. if (addLangMode) { var existing = $("#wpTextbox1").val() || ""; var header = "== {{ziman|" + values.lang + "}} =="; return existing.indexOf(header) === -1; } return true; }, /** Fills (or refills) the insert-dropdown from the current pronTpls array, filtering by language. */ refreshTplSelect: function () { var sel = $("#wiktku-start-pron .wiktku-tpl-insert-select"); if (!sel.length) return; var lang = getValues().lang || ""; sel.find("option[value!='']").remove(); $.each(steps.pron.pronTpls, function (_, tpl) { // Filter: if tpl.langs exists, only show if lang is in that list; otherwise show always var allowed = !tpl.langs || tpl.langs.indexOf(lang) !== -1; if (allowed) { sel.append($("<option></option>") .val(tpl.snippet) .text(tpl.name + " — " + tpl.desc) .attr("data-nolang", tpl.noLang ? "1" : "")); } }); // Notify Chosen that the option list has changed (no-op on mobile). if (!isMobile) sel.trigger("chosen:updated"); }, build: function (stepDiv) { if (stepDiv.find(".wiktku-pron-wrap").length) return null; var wrap = $("<div class='wiktku-pron-wrap'></div>"); var ta = $("<textarea></textarea>") .attr("name", "wiktku-pron-" + $.now()) .attr("class", "wiktku-start-step-field wiktku-pron-text") .attr("rows", 4) .attr("placeholder", "Nimûne: {{IPA|ku|/pɛɪ̯n/}} yan {{kîte|ku|he|ce|ki|rin}}"); // Template insert dropdown — filtered by language. var sel = $("<select class='wiktku-tpl-insert-select'></select>"); sel.append($("<option value=''>— şablonek lê zêde bike —</option>")); var lang = getValues().lang || ""; $.each(steps.pron.pronTpls, function (_, tpl) { // Filter: if tpl.langs exists, only show if lang is in that list; otherwise show always var allowed = !tpl.langs || tpl.langs.indexOf(lang) !== -1; if (allowed) { sel.append($("<option></option>") .val(tpl.snippet) .text(tpl.name + " — " + tpl.desc) .attr("data-nolang", tpl.noLang ? "1" : "")); } }); sel.on("change", function () { var snippet = $(this).val(); if (!snippet) return; var lang = getValues().lang || ""; // Check if the selected option has noLang flag var selectedOption = sel.find("option:selected"); var hasNoLang = selectedOption.attr("data-nolang") === "1"; if (!hasNoLang) { snippet = snippet.replace(/CODE/g, lang).replace(/SOURCELANG/g, "?"); } insertAtCursor(ta[0], snippet); $(this).val(""); ta.focus(); }); wrap.append(sel).append($("<br>")).append(ta); stepDiv.append(wrap); return ta; }, output: function () { var text = $.trim($("#wiktku-start-pron .wiktku-pron-text").val()); if (!text) return ""; var lines = text.split("\n"); var out = $.map(lines, function (line) { line = $.trim(line); if (!line) return undefined; return line.charAt(0) === "*" ? line : "* " + line; }).join("\n"); return "\n=== Bilêvkirin ===\n" + out + "\n"; } }, pos: { id: "pos", required: true, name: "Cureyê rêzimanî", question_fmt: 'Cureyê rêzimanî yê "' + pageName + '" çi ye?', visible: function (values) { return values.lang; }, question_br: true, // Populated from [[MediaWiki:Gadget-start.js/data.json]] (posChoices). choices: [], output: function (values) { var pos = values.pos || ""; var cinsiyet = values.cinsiyet || ""; // from the cinsiyet step var lekTur = values.lektur || ""; // from the lêker transitivity step var capitalizedPos = capitalize(pos); var outputString = "\n=== " + capitalizedPos + " ===\n"; // Add ku-tewîn-nav for single-word navdêr/serenav with known gender. if (!pageName.includes(" ") && cinsiyet && GENDER_BASE_LABELS[cinsiyet] && (pos === "navdêr" || pos === "serenav") && values.lang === "ku") { outputString += "{{ku-tewîn-nav|" + pageName + "|" + GENDER_BASE_LABELS[cinsiyet]; if (pos === "serenav") outputString += "|y"; outputString += "}}\n"; } outputString += "{{" + pos + "|" + values.lang; if (pos === "navdêr" || pos === "serenav") { if (cinsiyet) { outputString += "|c=" + cinsiyet; } else if (values.lang === "ku") { // Unknown gender — prompt editor to fill it in. outputString += "|c=?"; } } else if (/^lêker/.test(pos) && lekTur) { outputString += "|c=" + lekTur; } if (values.tr) { outputString += "|tr=" + values.tr; } outputString += "}}\n"; return outputString; } }, /** * cinsiyet (grammatical gender) — only shown for navdêr/serenav, û * tenê ger metadata ji bo zimanê hilbijartî lîsteyeke "g" (cinsiyet) * were dayîn. Opsiyonên vê gavê ne sabît in — ji metadata[values.lang].g * têne çêkirin, ji ber ku di hemû zimanan de cinsiyet tine. */ cinsiyet: { id: "cinsiyet", name: "cinsiyet", question_fmt: 'Cinsiyeta "' + pageName + '" çi ye?', question_br: true, visible: function (values) { var meta = metadata[values.lang]; return !!(values.lang && (values.pos === "navdêr" || values.pos === "serenav") && meta && meta.g && meta.g.length); }, build: function (stepDiv, values) { var select = stepDiv.find("select.wiktku-start-step-field"); if (!select.length) { select = $(mw.html.element("select", { "class": "wiktku-start-step-field", id: "wiktku-start-cinsiyet-field" })); stepDiv.append(select); } if (!values) return select; var meta = metadata[values.lang]; var codes = (meta && meta.g) || []; var prevVal = select.val(); var choices = $.map(codes, function (code) { return [[code, genderLabel(code)]]; }); populateMenus(select, choices); if ($.grep(choices, function (c) { return c[0] === prevVal; }).length) { select.val(prevVal); } if (!isMobile) select.trigger("chosen:updated"); return select; }, output: function () { return ""; } // consumed by pos.output }, /** * Lêker transitivity — only shown for any lêker variant. */ lektur: { id: "lektur", name: "Cureyê lêkerê (fiîlê)", question_fmt: "Cureyê lêkerê (fiîlê) çi ye?", question_br: true, visible: function (values) { return values.lang && values.pos && /^lêker/.test(values.pos); }, // Dictionary: value → display label. Add new types here. choices: [ ["gh", "gerguhêz"], ['x-gh', 'xwerû-gerguhêz'], ['p-gh', 'pêkhatî-gerguhêz'], ['h-gh', 'hevedudanî-gerguhêz'], ['b-gh', 'biwêjî-gerguhêz'], ["ngh", "negerguhêz"], ['x-ngh', 'xwerû-negerguhêz'], ['p-ngh', 'pêkhatî-negerguhêz'], ['h-ngh', 'hevedudanî-negerguhêz'], ['b-ngh', 'biwêjî-negerguhêz'] ], output: function () { return ""; } // consumed by pos.output }, tr: { id: "tr", name: "transkrîpsiyon", question_fmt: "Transkrîpsiyona kelîmeyê", multiple: false, narrow: true, visible: function (values) { return values.lang && values.pos && needsTransliteration(values.lang); } }, dfn: { id: "dfn", // required: true, ger mane tinebe [[Şablon:mane?]] bi kar bîne name: "Mane", question_fmt: "Maneya kelîmeyê binivîse. Mane otomatîk tê lînkkirin! Ji bo tercimeyan beşa 'Werger' bi kar bîne!", multiple: true, ordered: true, rows: 3, visible: function (values) { return values.lang && values.pos; }, example: function (values) { // posExamples loaded from [[MediaWiki:Gadget-start.js/data.json]]. var examples = steps.dfn.posExamples || {}; var full = values.pos || ""; return examples[full] || ""; }, /** * Builds one sense block (<li>) inside the ordered list. * Each block contains: * - a textarea for the definition * - an expandable nimûne list * - single-row sub-lists for formên alternatîv, hevmane, dijmane */ buildSenseBlock: function (stepDiv) { var block = $("<li class='wiktku-dfn-sense'></li>"); // — Mane textarea (declared first so the template handler can reference it) — var dfnArea = $("<textarea></textarea>") .attr("name", "wiktku-dfn-mane-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("class", "wiktku-start-step-field wiktku-dfn-mane") .attr("rows", 6) .attr("placeholder", "Mane…"); dfnArea.on("input", function () { steps.dfn.onDfnInput(stepDiv, block, this); }); // — Template selector (optional — replaces mane when chosen) — // Template definitions loaded from [[MediaWiki:Gadget-start.js/data.json]]. var tplDefs = steps.dfn.tplDefs || []; // Cache of all non-placeholder option elements — used by updateTplOptions // to remove/re-add options (the only approach compatible with Chosen.js). var _allTplOptions = []; var tplSelect = $(mw.html.element("select", { "class": "wiktku-dfn-tpl-select" })); tplSelect.append($("<option value=''>— yan jî şablonek hilbijêre —</option>")); $.each(tplDefs, function (_, tpl) { var opt = $("<option></option>") .val(tpl.name) .text(tpl.name) .attr("data-langs", tpl.langs ? tpl.langs.join(",") : "") .attr("data-nolang", tpl.noLang ? "1" : ""); tplSelect.append(opt); _allTplOptions.push(opt[0]); }); function updateTplOptions() { var lang = getValues().lang || ""; var currentVal = tplSelect.val(); var currentStillValid = false; // Detach all non-placeholder options, then re-attach only the visible ones. // This is the only approach that works correctly with both native <select> // and Chosen.js on desktop. tplSelect.find("option[value!='']").detach(); $.each(_allTplOptions, function (_, opt) { var allowed = $(opt).attr("data-langs"); var visible = !allowed || allowed.split(",").indexOf(lang) !== -1; if (visible) { tplSelect.append(opt); if ($(opt).val() === currentVal) currentStillValid = true; } }); if (!isMobile) tplSelect.trigger("chosen:updated"); if (currentVal && !currentStillValid) { tplSelect.val(""); dfnArea.show(); tplTitleInput.hide().val(""); } } // Store updater on the element so refresh() can call it for all blocks. tplSelect.data("updateOptions", updateTplOptions); var tplTitleInput = $("<input type='text'>") .addClass("wiktku-dfn-tpl-title wiktku-start-narrow") .attr("placeholder", "Navê rûpelê…") .hide(); // Grow the sense list when the title field of the last block gets content, // mirroring what onDfnInput does for the plain mane textarea. tplTitleInput.on("input", function () { steps.dfn.onDfnInput(stepDiv, block, this); }); /** * When a şablon sense is chosen, formên alternatîv/hevmane/dijmane/ * termên koordîne/jornav/jêrnav don't apply (there's no plain gloss * to hang them off), so hide those subgroups. Etîket, Nimûne and * Jêgirtin stay visible and still usable for a şablon sense. */ function updateFieldVisibility() { var isTpl = !!tplSelect.val(); $.each(HIDDEN_ON_TPL_GROUPS, function (_, cls) { block.find("." + cls + "-group").toggle(!isTpl); }); } // Store on the block so restoreDfn() can re-sync visibility // after programmatically setting tplSelect's value. block.data("updateFieldVisibility", updateFieldVisibility); tplSelect.on("change", function () { var chosen = $(this).val(); if (chosen) { dfnArea.hide(); tplTitleInput.show().focus(); } else { dfnArea.show(); tplTitleInput.hide().val(""); } updateFieldVisibility(); // Re-run refresh so the Werger step visibility updates. refresh(); }); var tplRow = $("<div></div>").addClass("wiktku-dfn-tpl-row") .append(tplSelect).append(" ").append(tplTitleInput); block.append(tplRow); block.append(dfnArea); // Apply lang filter on initial build. updateTplOptions(); // — Sub-field groups — // All groups are always visible with a placeholder textarea. // Nimûne is last in the DOM and last in the output. var allGroups = [ { cls: "wiktku-dfn-etiket", label: "Etîket", rows: 1, narrow: true, izah: "xisûsen, Mêrdîn, anatomî, Badînî" }, { cls: "wiktku-dfn-alternativ", label: "Formên alternatîv", rows: 1, narrow: true, izah: "Varyantên vê kelîmeyê" }, { cls: "wiktku-dfn-hevmane", label: "Hevmane", rows: 1, narrow: true, izah: "Spehî hevmaneya Bedew e." }, { cls: "wiktku-dfn-dijmane", label: "Dijmane", rows: 1, narrow: true, izah: "Zengîn dijmaneya feqîr e." }, { cls: "wiktku-dfn-koordine", label: "Termên koordîne", rows: 1, narrow: true, izah: "Pisîk û kûçik termên koordîne ne çunkî Jornavên wan gelek in" }, { cls: "wiktku-dfn-jornav", label: "Jornav", rows: 1, narrow: true, izah: "Heywan jornavê guhandar e" }, { cls: "wiktku-dfn-jernav", label: "Jêrnav", rows: 1, narrow: true, izah: "Guhandar jêrnavê heywan e" }, { cls: "wiktku-dfn-nimune", label: "Nimûne", rows: 2, narrow: false } ]; $.each(allGroups, function (_, g) { var groupDiv = $("<div></div>").addClass("wiktku-dfn-subgroup " + g.cls + "-group"); function buildNimuneLi() { var lang = getValues().lang || ""; var li = $("<li></li>").addClass("wiktku-dfn-nimune-li"); var mainTa = $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-text-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", g.rows) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-text") .attr("placeholder", "Nimûneya emilandina kelîmeyê tu bi xwe binivîse…"); mainTa.on("input", function () { var val = $.trim($(this).val()); var isLast = li.is(list.children("li:last-child")); if (val && isLast) { list.append(buildNimuneLi()); } }); li.append(mainTa); var subWrap = $("<div></div>").addClass("wiktku-dfn-nimune-sub"); if (needsTransliteration(lang)) { subWrap.append( $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-tr-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 5) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-tr") .attr("placeholder", "Transkrîpsiyona bi alfabeya latînî") ); } if (lang && lang !== "ku") { subWrap.append( $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-t-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 5) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-t") .attr("placeholder", "Tercimeya kurmancî") ); } if (subWrap.children().length) li.append(subWrap); return li; } if (g.cls === "wiktku-dfn-nimune") { // Nimûne — compound widget with tr/t sub-fields. var lbl = $("<span></span>").addClass("wiktku-dfn-sublabel").text(g.label + ": "); var list = $("<ol></ol>").addClass("wiktku-dfn-sublist " + g.cls + "-list"); groupDiv.data("buildNimuneLi", buildNimuneLi); list.append(buildNimuneLi()); groupDiv.append(lbl).append(list); block.append(groupDiv); } else { // Regular always-visible group — label + growing textarea list. var lbl = $("<span></span>").addClass("wiktku-dfn-sublabel").text(g.label + ": " + g.izah); var list = $("<ol></ol>").addClass("wiktku-dfn-sublist " + g.cls + "-list"); var firstInput = $("<textarea></textarea>") .attr("name", g.cls + "-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", g.rows) .attr("class", "wiktku-dfn-subfield" + (g.narrow ? " wiktku-start-narrow" : "")) .attr("placeholder", g.label + "…"); firstInput.on("input", function () { steps.dfn.onSubInput(list, this, g.rows, g.narrow); }); list.append($("<li></li>").append(firstInput)); groupDiv.append(lbl).append(list); block.append(groupDiv); } }); // — Jêder (quote / citation) group — a growing list, sibling to Nimûne — // Structured the same way as Nimûne (ol.wiktku-dfn-sublist > li) so it // lines up at the same indentation, and so that typing into the last // citation's Jêgirtin box automatically opens a fresh empty one below it. (function () { var jederGroupDiv = $("<div></div>").addClass("wiktku-dfn-subgroup wiktku-dfn-jeder-group"); var jederLbl = $("<span></span>").addClass("wiktku-dfn-sublabel").text("Jêgirtin: "); var jederList = $("<ol></ol>").addClass("wiktku-dfn-sublist wiktku-dfn-jeder-list"); function buildJederLi() { var lang = getValues().lang || ""; var li = $("<li></li>").addClass("wiktku-dfn-jeder-li"); var dragHandle = $("<span></span>") .addClass("wiktku-jeder-drag-handle") .attr("title", "Bişkûne û bikişîne da ku rêzê biguhezîne"); // Quote text textarea var quoteTa = $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-quote-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 2) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-quote") .attr("placeholder", "Nimûneya emilandinê ji kitêb an çavkaniyeke din binivîse"); quoteTa.on("input", function () { var val = $.trim($(this).val()); var isLast = li.is(jederList.children("li:last-child")); if (val && isLast) { jederList.append(buildJederLi()); } }); li.append(dragHandle).append(quoteTa); // tr/t sub-fields for the quote — shown as needed for the language. var quoteSubWrap = $("<div></div>").addClass("wiktku-dfn-quote-sub"); if (needsTransliteration(lang)) { quoteSubWrap.append( $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-quote-tr-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 2) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-quote-tr") .attr("placeholder", "Transkrîpsiyona jêgirtinê…") ); } if (lang && lang !== "ku") { quoteSubWrap.append( $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-quote-t-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 2) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-quote-t") .attr("placeholder", "Tercimeya jêgirtinê bi kurmancî") ); } if (quoteSubWrap.children().length) li.append(quoteSubWrap); // Citoid auto-fill: fetch citation data from a URL, DOI or ISBN and // prefill the source şablon + fields below (see Gadget-citoid-helper.js). var citoidWrap = $("<div></div>").addClass("wiktku-dfn-quote-citoid"); var citoidInput = $("<input type='text'>") .addClass("wiktku-dfn-quote-citoid-input wiktku-start-narrow") .attr("placeholder", "URL, DOI an ISBN binivîse ku otomatîk were tijekirin…"); var citoidBtn = new OO.ui.ButtonWidget({ label: "Bi Citoid bîne", classes: [ "wiktku-dfn-quote-citoid-btn" ] }); var citoidStatus = $("<span></span>").addClass("wiktku-dfn-quote-citoid-status"); /** * Fetches citation data from Citoid and applies it to this * citation's şablon selector + fields. Mirrors the logic in * Form.prototype._fillFromCitoid (Gadget-wikt.add-examples.js): * - only (re)selects the şablon when it actually differs from * what's already chosen, so a repeat fetch doesn't wipe out * a template the user already picked; * - only fills fields that are currently empty, so it never * overwrites something the user typed by hand; * - falls back to the freeform "bi destê xwe binivîsim" source * only when nothing was typed there yet. */ function runCitoidFetch() { var query = $.trim(citoidInput.val()); if (!query) { mw.notify("Ji kerema xwe re pêşî URL, DOI an ISBNyekê binivîse."); return; } citoidBtn.setDisabled(true); citoidStatus.text("Tê anîn…"); wikt.citoidHelper.ensure().then(function () { return wikt.citoid.fetchJederFields(query); }).then(function (result) { var jederKey = result.jederKey; var hasTpl = !!jederKey && srcSel.find("option[value='" + jederKey + "']").length > 0; var targetVal = hasTpl ? jederKey : "__manual__"; // Only (re)select — and thus rebuild — the field rows if // we're switching to a different şablon than what's // already chosen, so a second fetch doesn't clear fields // the user already filled in by hand. if (srcSel.val() !== targetVal) { srcSel.val(targetVal).trigger("change"); srcSel.trigger("chosen:updated"); } if (hasTpl) { // Tenê qadên vala tijî bike. $.each(result.fields, function (key, val) { var input = srcFields.find("[data-field-key='" + key + "']"); if (input.length && !$.trim(input.val())) { input.val(val); } }); } else { // Şablonek nehat naskirin ji bo vê itemType — rêzikeke // çavkaniyê ya bi destan a ji qadên Citoid tê çêkirin, // lê tenê ger qada destan vala be. var manualField = srcFields.find(".wiktku-dfn-quote-src-manual"); if (!$.trim(manualField.val())) { var parts = []; $.each(["nivîskar", "sernav", "websîte", "kovar", "weşanxane", "sal", "url"], function (_, k) { if (result.fields[k]) parts.push(result.fields[k]); }); manualField.val(parts.join(", ")); } } citoidStatus.text(""); }, function (errorMsg) { citoidStatus.text(typeof errorMsg === "string" ? errorMsg : "Nehat dîtin. Kontrol bike ka URL/DOI/ISBN rast e."); }).always(function () { citoidBtn.setDisabled(false); }); } citoidBtn.on("click", runCitoidFetch); citoidInput.on("keydown", function (e) { if (e.which === 13) { // Enter e.preventDefault(); runCitoidFetch(); } }); citoidWrap.append(citoidInput).append(citoidBtn.$element).append(citoidStatus); // Source template selector, specific to this citation. var srcSel = $("<select></select>").addClass("wiktku-dfn-quote-src-sel"); srcSel.append($("<option value=''>— Çavkaniyê hilbijêre —</option>")); srcSel.append($("<option></option>").val("__manual__").text("Bi destê xwe binivîsim")); var jederDefs = steps.dfn.jederDefs || {}; $.each(jederDefs, function (tplName, def) { srcSel.append($("<option></option>").val(tplName).text(def.label)); }); // Dynamic source fields container. var srcFields = $("<div></div>").addClass("wiktku-dfn-quote-src-fields"); srcSel.on("change", function () { srcFields.empty(); var chosen = $(this).val(); if (!chosen) return; if (chosen === "__manual__") { // Freeform source, written by the user — becomes the 2nd // positional param of {{jêder|lang|…}} instead of çavkanî?. srcFields.append( $("<textarea></textarea>") .attr("rows", 4) .addClass("wiktku-dfn-subfield wiktku-dfn-quote-src-manual") .attr("placeholder", "Çavkaniyê bi destê xwe binivîse…") ); return; } var def = (steps.dfn.jederDefs || {})[chosen]; if (!def) return; $.each(def.fields, function (_, f) { var row = $("<div></div>").addClass("wiktku-dfn-quote-src-row"); var fieldLbl = $("<label></label>").text(f.label + ": "); var inp = $("<textarea></textarea>") .attr("rows", 2) .addClass("wiktku-dfn-quote-src-input wiktku-start-narrow") .attr("data-field-key", f.key) .attr("placeholder", f.label + "…"); row.append(fieldLbl).append(inp); srcFields.append(row); }); }); li.append(citoidWrap).append(srcSel).append(srcFields); return li; } jederGroupDiv.data("buildJederLi", buildJederLi); jederList.append(buildJederLi()); // Make citation rows sortable (drag to reorder). // The last row is always the empty trailing row — cancel its drag. mw.loader.using("jquery.ui.sortable", function () { jederList.sortable({ handle: ".wiktku-jeder-drag-handle", axis: "y", items: "li:not(:last-child)", tolerance: "pointer" }); }); jederGroupDiv.append(jederLbl).append(jederList); block.append(jederGroupDiv); }()); // Apply the initial hide/show state for the sub-groups (matches // tplSelect's starting value, which is normally empty). updateFieldVisibility(); return block; }, /** Grows the sense list when the last mane textarea gets content. */ onDfnInput: function (stepDiv, block, textarea) { var val = $.trim($(textarea).val()); var list = stepDiv.find("ol.wiktku-dfn-list"); var isLast = block.is(list.children("li:last-child")); if (val && isLast) { var newBlock = steps.dfn.buildSenseBlock(stepDiv); list.append(newBlock); // Apply Chosen to the new block's template selector on desktop. if (!isMobile) newBlock.find("select.wiktku-dfn-tpl-select").chosen(chosenOptions); } refresh(); }, /** Grows a sub-list (nimûne/formên alternatîv/hevmane/dijmane/termên koordîne) on input. */ onSubInput: function (list, input, rows, narrow) { var val = $.trim($(input).val()); var item = $(input).parent(); var isLast = item.is(list.children("li:last-child")); if (val && isLast) { var next = $("<textarea></textarea>") .attr("name", "wiktku-dfn-sub-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", rows) .attr("class", "wiktku-dfn-subfield" + (narrow ? " wiktku-start-narrow" : "")); next.on("input", function () { steps.dfn.onSubInput(list, this, rows, narrow); }); list.append($("<li></li>").append(next)); } }, // Populated from [[MediaWiki:Gadget-start.js/data.json]] (tplDefs, posExamples, jederDefs). tplDefs: [], posExamples: {}, jederDefs: {}, build: function (stepDiv) { if (stepDiv.find("ol.wiktku-dfn-list").length) return null; var list = $("<ol class='wiktku-dfn-list'></ol>"); list.append(steps.dfn.buildSenseBlock(stepDiv)); stepDiv.append(list); return null; }, /** Reads all sense blocks from the DOM and returns an array of sense objects. */ getSenses: function (stepDiv) { var senses = []; stepDiv.find("li.wiktku-dfn-sense").each(function () { var block = $(this); var tplSel = block.find("select.wiktku-dfn-tpl-select"); var tpl = tplSel.val() || ""; // noLang: template already encodes the language — don't add |lang| param. var tplNoLang = tpl ? tplSel.find("option[value='" + tpl + "']").attr("data-nolang") === "1" : false; var tplTitle = $.trim(block.find("input.wiktku-dfn-tpl-title").val()); var mane = $.trim(block.find("textarea.wiktku-dfn-mane").val()); var etiket = (function () { var vals = []; block.find(".wiktku-dfn-etiket-list textarea").each(function () { var v = $.trim($(this).val()); if (v) vals.push(v); }); return vals; }()); function readList(cls) { var vals = []; block.find("." + cls + "-list textarea").each(function () { var v = $.trim($(this).val()); if (v) vals.push(v); }); return vals; } // Nimûne items are compound: { text, tr?, t? } function readNimuneList() { var items = []; block.find(".wiktku-dfn-nimune-list li.wiktku-dfn-nimune-li").each(function () { var text = $.trim($(this).find(".wiktku-dfn-nimune-text").val()); if (!text) return; var obj = { text: text }; var tr = $.trim($(this).find(".wiktku-dfn-nimune-tr").val()); var t = $.trim($(this).find(".wiktku-dfn-nimune-t").val()); if (tr) obj.tr = tr; if (t) obj.t = t; items.push(obj); }); return items; } // Jêder is a growing list of citations, one per li — mirrors readNimuneList(). function readJederList() { var items = []; block.find(".wiktku-dfn-jeder-list li.wiktku-dfn-jeder-li").each(function () { var li = $(this); var quote = $.trim(li.find(".wiktku-dfn-nimune-quote").val()); if (!quote) return; var obj = { quote: quote }; var qtr = $.trim(li.find(".wiktku-dfn-nimune-quote-tr").val()); var qt = $.trim(li.find(".wiktku-dfn-nimune-quote-t").val()); if (qtr) obj.quoteTr = qtr; if (qt) obj.quoteT = qt; var tplName = li.find(".wiktku-dfn-quote-src-sel").val(); if (tplName === "__manual__") { var manual = $.trim(li.find(".wiktku-dfn-quote-src-manual").val()); if (manual) obj.jederManual = manual; } else if (tplName) { obj.jederTpl = tplName; var fields = {}; li.find(".wiktku-dfn-quote-src-input").each(function () { var k = $(this).attr("data-field-key"); var v = $.trim($(this).val()); if (k && v) fields[k] = v; }); obj.jêderFields = fields; } items.push(obj); }); return items; } senses.push({ tpl: tpl, tplNoLang: tplNoLang, tplTitle: tplTitle, mane: mane, etiket: etiket, nimune: readNimuneList(), jeder: readJederList(), alternativ: readList("wiktku-dfn-alternativ"), hevmane: readList("wiktku-dfn-hevmane"), dijmane: readList("wiktku-dfn-dijmane"), koordine: readList("wiktku-dfn-koordine"), jornav: readList("wiktku-dfn-jornav"), jernav: readList("wiktku-dfn-jernav") }); }); return senses; }, getOutput: function (values, callback) { var stepDiv = $("#wiktku-start-dfn"); var senses = steps.dfn.getSenses(stepDiv); var lang = values.lang; // A sense counts as "filled" if it has a mane, a chosen template + title, // or any other content (etîket/hevmane/nimûne/jêder…) worth keeping. var hasMane = senses.some(function (s) { return s.mane !== "" || (s.tpl && s.tplTitle) || senseHasExtraContent(s); }); // True only when at least one sense has a regular mane (needs linkify). var hasRegularMane = senses.some(function (s) { return !s.tpl && s.mane !== ""; }); // nimûne and jêder lines must never pass through linkify — only // the plain mane text should be linkified. We build two parallel // arrays: defLines (sent to linkify) and citeLines (kept aside). // Each entry in citeLines corresponds 1-to-1 with a defLines entry; // a template token {{wiktku-cite-N}} is embedded in defLines so // that after linkify runs we know exactly where to splice them back. // Template-call syntax is guaranteed safe: linkifiers leave {{ }} // tokens completely untouched. var defLines = []; // one entry per kept sense (goes to linkify) var citeLines = []; // parallel — nimûne+jêder for that same sense $.each(senses, function (_, sense) { // — Template sense (e.g. {{guharto|ku|somepage}}) — if (sense.tpl) { if (!sense.tplTitle) return; // skip empty template senses var tplLabelTpl = ""; if (sense.etiket && sense.etiket.length) { var tplLabelParts = sense.etiket.map(function (part) { return $.trim(part); }).filter(function (part) { return part !== ""; }); if (tplLabelParts.length) { tplLabelTpl = " {{e|" + lang + "|" + tplLabelParts.join("|") + "}} "; } } var tplCall = sense.tplNoLang ? "{{" + sense.tpl + "|" + sense.tplTitle + "}}" : "{{" + sense.tpl + "|" + lang + "|" + sense.tplTitle + "}}"; var tplHasJeder = sense.jeder && $.grep(sense.jeder, function (j) { return j && j.quote; }).length > 0; var idx = defLines.length; var cite = formatNimune(sense.nimune, lang, tplHasJeder) + formatJeder(sense.jeder, lang); defLines.push("#" + (tplLabelTpl ? tplLabelTpl : " ") + tplCall + (cite ? "{{wiktku-cite-" + idx + "}}" : "")); citeLines.push(cite); return; } // — Normal mane sense — var dfn = sense.mane; if (!dfn && !senseHasExtraContent(sense)) return; // truly empty if (dfn) { dfn = stripWikilinks(dfn); if (dfn[0] !== dfn[0].toUpperCase()) dfn = capitalize(dfn); if (!dfn.match(/[.…?!)\]]$/)) dfn += "."; } else { dfn = "{{mane?|" + lang + "}}"; } var labelTpl = ""; if (sense.etiket && sense.etiket.length) { var labelParts = sense.etiket.map(function (part) { return $.trim(part); }).filter(function (part) { return part !== ""; }); if (labelParts.length) { labelTpl = " {{e|" + lang + "|" + labelParts.join("|") + "}} "; } } var out = "#" + (labelTpl ? labelTpl : " ") + dfn; function wordLine(tpl, words) { if (!words.length) return ""; return "\n#: {{" + tpl + "|" + lang + "|" + words.join("|") + "}}"; } out += wordLine("alt-r", sense.alternativ); out += wordLine("hevmane", sense.hevmane); out += wordLine("dijmane", sense.dijmane); out += wordLine("koordîne", sense.koordine); out += wordLine("jornav", sense.jornav); out += wordLine("jêrnav", sense.jernav); var hasJeder = sense.jeder && $.grep(sense.jeder, function (j) { return j && j.quote; }).length > 0; var cite = formatNimune(sense.nimune, lang, hasJeder) + formatJeder(sense.jeder, lang); var idx = defLines.length; defLines.push(out + (cite ? "{{wiktku-cite-" + idx + "}}" : "")); citeLines.push(cite); }); // Splice citeLines back into a linkified string, replacing each // {{wiktku-cite-N}} token with its stored nimûne/jêder block. function restoreCites(t) { return t.replace(/\{\{wiktku-cite-(\d+)\}\}/g, function (_, n) { return citeLines[parseInt(n, 10)] || ""; }); } var text = defLines.join("\n") + "\n"; if (!hasMane) { // No definitions entered — emit {{mane?}} with bênimûne. text = "# {{mane?|" + lang + "}}\n#* {{bênimûne|" + lang + "}}\n"; callback(text); return; } if (!hasRegularMane) { // All filled senses are template senses — no linkify needed. callback(restoreCites(text)); return; } var didTryToLoad = function () { if (typeof $.wiktviLinkify === "function") { $.wiktviLinkify(text, function (linked) { callback(restoreCites(linked)); }); } else { callback(restoreCites(text)); } }; mw.loader.using("ext.gadget.linkify", didTryToLoad, didTryToLoad); } }, je: makeWordListStep("je", "jê", "Kelîmeyên jê çêbûyî binivîse", "Jê", "g"), tekildar: makeWordListStep("tekildar", "têkildar", "Kelîmeyên ji aliyê etîmolojiyê ve têkildarî vê kelîmeyê binivîse", "Têkildar", "g"), binereherwiha: makeWordListStep("binereherwiha", "binêre herwiha", "Kelîmeyên din ên eleqedar binivîse", "Binêre herwiha", "g"), etym: { id: "etym", name: "etîmolojî", question_fmt: "Etîmolojiya kelîmeyê binivîse", // etymTpls populated from data.json etymTpls: [], visible: function (values) { return values.lang && values.pos; }, /** Fills (or refills) the insert-dropdown from the current etymTpls array. */ refreshTplSelect: function () { var sel = $("#wiktku-start-etym .wiktku-tpl-insert-select"); if (!sel.length) return; sel.find("option[value!='']").remove(); $.each(steps.etym.etymTpls, function (_, tpl) { sel.append($("<option></option>").val(tpl.snippet).text(tpl.name + " — " + tpl.desc)); }); // Notify Chosen that the option list has changed (no-op on mobile). if (!isMobile) sel.trigger("chosen:updated"); }, build: function (stepDiv) { if (stepDiv.find(".wiktku-etym-wrap").length) return null; var wrap = $("<div class='wiktku-etym-wrap'></div>"); var ta = $("<textarea></textarea>") .attr("name", "wiktku-etym-" + $.now()) .attr("class", "wiktku-start-step-field wiktku-etym-text") .attr("rows", 4) .attr("placeholder", "Nimûne: Ji {{ji|en|ku|apple}}. yan rasterast binivîse…"); // Template insert dropdown — options also refreshed after data.json loads. var sel = $("<select class='wiktku-tpl-insert-select'></select>"); sel.append($("<option value=''>— şablonek lê zêde bike —</option>")); $.each(steps.etym.etymTpls, function (_, tpl) { sel.append($("<option></option>").val(tpl.snippet).text(tpl.name + " — " + tpl.desc)); }); sel.on("change", function () { var snippet = $(this).val(); if (!snippet) return; var lang = getValues().lang || ""; snippet = snippet.replace(/CODE/g, lang).replace(/SOURCELANG/g, "?"); insertAtCursor(ta[0], snippet); $(this).val(""); ta.focus(); }); wrap.append(sel).append($("<br>")).append(ta); stepDiv.append(wrap); return ta; }, output: function (values) { var text = $.trim($("#wiktku-start-etym .wiktku-etym-text").val()); if (text) { return "\n==== Etîmolojî ====\n" + text + "\n"; } // No etymology entered — emit {{ji?|lang}} as a placeholder, // but only when the entry has at least one regular (non-şablon) // sense with content — either real mane text, or an empty mane // with other fields filled in (which dfn.getOutput() renders as // {{mane?|lang}} with those fields attached). A şablon sense // like {{guharto|…}} never counts, filled in or not. var dfnSenses = steps.dfn.getSenses($("#wiktku-start-dfn")); var hasRegularMane = dfnSenses.some(function (s) { return !s.tpl && (s.mane !== "" || senseHasExtraContent(s)); }); if (!hasRegularMane) return ""; return "\n==== Etîmolojî ====\n{{ji?|" + values.lang + "}}\n"; } }, dunde: { id: "dunde", name: "dûnde", question_fmt: "Eger ev kelîme ji vî zimanî ketibe zimanekî din, vî zimanî û kelîmeya wî binivîse", visible: function (values) { return !!values.pos; }, disabledKeys: { "navz": true}, /** * Builds one row: a language dropdown + a growing list of word * inputs. When the dropdown gets a value the next empty row is * appended automatically. Mirrors steps.trans's row widget, but * flat (one shared list — dûnde isn't tied to individual senses). */ buildRow: function (stepDiv) { var row = $("<li class='wiktku-dunde-row wiktku-lang-row'></li>"); // Language selector — chosen is applied after insertion into DOM. var langSel = $(mw.html.element("select", { "class": "wiktku-start-step-keyfield wiktku-start-narrow" })); langSel.attr("data-placeholder", "Zimanekî lê bigere"); populateMenus(langSel, steps.dunde.keys || [], steps.dunde.disabledKeys); // When a language is chosen, ensure a next empty row exists. langSel.on("change", function () { steps.dunde.onLangChange(stepDiv, row); }); // Word list for this language. var wordList = $("<ul class='wiktku-dunde-words wiktku-lang-row-words'></ul>"); var firstWord = steps.dunde.makeWordInput(); wordList.append($("<li></li>").append(firstWord)); if (isMobile) { row.append(wrapNativeSelect(langSel)).append(wordList); } else { row.append(langSel).append(wordList); } return row; }, makeWordInput: function () { var input = $("<textarea></textarea>") .attr("name", "wiktku-dunde-word-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 1) .attr("class", "wiktku-dfn-subfield wiktku-start-narrow") .attr("placeholder", "Kelîme…"); input.on("input", function () { var list = $(this).closest("ul.wiktku-dunde-words"); var item = $(this).parent(); var val = $.trim($(this).val()); if (val && item.is(list.children("li:last-child"))) { var next = steps.dunde.makeWordInput(); list.append($("<li></li>").append(next)); } }); return input; }, onLangChange: function (stepDiv, row) { var list = stepDiv.find("ul.wiktku-dunde-list"); var isLast = row.is(list.children("li.wiktku-dunde-row:last-child")); if (isLast) { var newRow = steps.dunde.buildRow(stepDiv); list.append(newRow); // Init chosen after the new row is in the DOM (desktop only). if (!isMobile) newRow.find("select").chosen(chosenOptions); } // Keep disabled keys in sync across all lang selectors. steps.dunde.syncDisabledKeys(stepDiv); }, /** Disables already-selected languages in all other dropdowns. */ syncDisabledKeys: function (stepDiv) { var taken = $.extend({}, steps.dunde.disabledKeys); stepDiv.find("li.wiktku-dunde-row select").each(function () { var v = $(this).val(); if (v) taken[v] = true; }); stepDiv.find("li.wiktku-dunde-row select").each(function () { var self = $(this); var own = self.val(); self.find("option").each(function () { var code = $(this).val(); if (!code) return; $(this).prop("disabled", taken[code] && code !== own); }); self.trigger("chosen:updated"); }); }, build: function (stepDiv) { if (stepDiv.find("ul.wiktku-dunde-list").length) return null; var list = $("<ul class='wiktku-dunde-list wiktku-lang-row-list'></ul>"); list.append(steps.dunde.buildRow(stepDiv)); stepDiv.append(list); // Init chosen after the select is in the DOM (desktop only). if (!isMobile) list.find("select").chosen(chosenOptions); return null; }, /** Reads all [langcode, words[]] rows from the DOM. */ getRows: function (stepDiv) { var result = []; stepDiv.find("li.wiktku-dunde-row").each(function () { var lang = $(this).find("select").val(); if (!lang) return; var words = []; $(this).find("ul.wiktku-dunde-words textarea").each(function () { var v = $.trim($(this).val()); if (v) words.push(v); }); if (words.length) result.push([lang, words]); }); return result; }, output: function () { var stepDiv = $("#wiktku-start-dunde"); var rows = steps.dunde.getRows(stepDiv); if (!rows.length) return ""; var lines = $.map(rows, function (row) { var lang = row[0], words = row[1]; return "* {{dû|" + lang + "|" + words.join("|") + "}}"; }); return "\n==== Dûnde ====\n" + lines.join("\n") + "\n"; } }, zarava: { id: "zarava", name: "bi zaravayên din", visible: function (values) { return steps.trans.visible(values); }, disabledKeys: { "navz": true }, buildRow: function (group) { var row = $("<li class='wiktku-zarava-row wiktku-lang-row'></li>"); var langSel = $(mw.html.element("select", { "class": "wiktku-start-step-keyfield wiktku-start-narrow" })); populateMenus(langSel, steps.zarava.keys || [], steps.zarava.disabledKeys); langSel.on("change", function () { steps.zarava.onLangChange(group, row); }); var wordList = $("<ul class='wiktku-zarava-words wiktku-lang-row-words'></ul>"); var firstWord = steps.zarava.makeWordInput(); wordList.append($("<li></li>").append(firstWord)); row.append(langSel).append(wordList); return row; }, makeWordInput: function () { var input = $("<textarea></textarea>") .attr("name", "wiktku-zarava-word-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 1) .attr("class", "wiktku-dfn-subfield wiktku-start-narrow") .attr("placeholder", "Tercime…"); input.on("input", function () { var list = $(this).closest("ul.wiktku-zarava-words"); var item = $(this).parent(); var val = $.trim($(this).val()); if (val && item.is(list.children("li:last-child"))) { var next = steps.zarava.makeWordInput(); list.append($("<li></li>").append(next)); } }); return input; }, onLangChange: function (group, row) { var list = group.find("ul.wiktku-zarava-list"); var isLast = row.is(list.children("li.wiktku-zarava-row:last-child")); if (isLast) { var newRow = steps.zarava.buildRow(group); list.append(newRow); } steps.zarava.syncDisabledKeys(group); }, /** Disables already-selected dialects in all other dropdowns within one group. */ syncDisabledKeys: function (group) { var taken = $.extend({}, steps.zarava.disabledKeys); group.find("li.wiktku-zarava-row select").each(function () { var v = $(this).val(); if (v) taken[v] = true; }); group.find("li.wiktku-zarava-row select").each(function () { var self = $(this); var own = self.val(); self.find("option").each(function () { var code = $(this).val(); if (!code) return; $(this).prop("disabled", taken[code] && code !== own); }); }); }, /** Builds (or fetches) the .wiktku-zarava-group for one gloss. */ buildGroup: function (stepDiv, gi) { var group = $("<div class='wiktku-zarava-group'></div>").attr("data-gloss-pos", gi); var list = $("<ul class='wiktku-zarava-list wiktku-lang-row-list'></ul>"); list.append(steps.zarava.buildRow(group)); group.append(list); stepDiv.append(group); return group; }, /** Syncs one .wiktku-zarava-group per current gloss (same logic as steps.trans.build). */ build: function (stepDiv) { var glosses = steps.trans.glossList(); if (!glosses.length) { stepDiv.find(".wiktku-zarava-group").remove(); return null; } var existingGroups = stepDiv.find(".wiktku-zarava-group"); if (existingGroups.length > glosses.length) { existingGroups.slice(glosses.length).remove(); } $.each(glosses, function (gi, gloss) { var group = stepDiv.find(".wiktku-zarava-group[data-gloss-pos='" + gi + "']"); if (!group.length) group = steps.zarava.buildGroup(stepDiv, gi); var label = group.find(".wiktku-zarava-group-label"); if (glosses.length > 1) { if (!label.length) { label = $("<div class='wiktku-zarava-group-label'></div>"); group.prepend(label); } label.text(gloss.index + " " + gloss.text); } else if (label.length) { label.remove(); } }); return null; }, /** Reads the dialect rows for a single gloss group. */ getGroupTranslations: function (group) { var result = []; group.find("li.wiktku-zarava-row").each(function () { var lang = $(this).find("select").val(); if (!lang) return; var words = []; $(this).find("ul.wiktku-zarava-words textarea").each(function () { var v = $.trim($(this).val()); if (v) words.push(v); }); if (words.length) result.push([lang, words]); }); return result; }, /** Reads all rows from the DOM, grouped by gloss position. */ getTranslations: function (stepDiv) { var result = []; stepDiv.find(".wiktku-zarava-group").each(function () { result.push(steps.zarava.getGroupTranslations($(this))); }); return result; }, output: function (values) { if (values.lang !== "ku") return ""; var stepDiv = $("#wiktku-start-zarava"); var glosses = steps.trans.glossList(); if (!glosses.length) return ""; var blocks = $.map(glosses, function (gloss, gi) { var group = stepDiv.find(".wiktku-zarava-group[data-gloss-pos='" + gi + "']"); var rows = group.length ? steps.zarava.getGroupTranslations(group) : []; if (!gloss.text && !rows.length) return undefined; if (rows.length) { rows.sort(function (a, b) { var aLang = langsByCode[a[0]] || []; var bLang = langsByCode[b[0]] || []; return (aLang[2] || "").localeCompare(bLang[2] || "", "ku"); }); } var wordLines = $.map(rows, function (row) { var lang = row[0]; var words = row[1]; var wikiWords = words.map(function (w) { return "{{W|" + lang + "|" + w + "}}"; }).join(", "); return "* {{Z|" + lang + "}}: " + wikiWords; }).join("\n"); if (!wordLines) return undefined; var block = "{{werger-ser|" + (gloss.text || "?") + "|" + gloss.index + "}}"; block += "\n" + wordLines; block += "\n{{werger-bin}}"; return block; }); if (!blocks.length) return ""; return "\n==== Bi zaravayên din ====\n" + blocks.join("\n") + "\n"; } }, trans: { id: "trans", name: "werger", visible: function (values) { if (!(values.lang === "ku" && values.pos)) return false; // Hide Werger only when EVERY sense is a template sense (Guharto etc.) // with a title filled in — i.e. there is real content but no plain // gloss to attach a translation table to. A mix of real + template // senses still shows Werger; the template senses are simply skipped // in output(). // // "Real" here means a non-şablon sense with either mane text or // other filled-in fields (etîket/hevmane/nimûne/jêder…), since // dfn.getOutput() renders the latter too, as {{mane?|lang}} plus // whatever else was filled in. // // When nothing has been filled in at all, output() will emit // {{mane?|lang}} instead of a gloss — but Werger should still show, // since the user may want to add translations before they've // settled on a gloss. var dfnSenses = steps.dfn.getSenses($("#wiktku-start-dfn")); var hasRealSense = dfnSenses.some(function (s) { return !s.tpl && (s.mane !== "" || senseHasExtraContent(s)); }); var hasFilledTplSense = dfnSenses.some(function (s) { return s.tpl && s.tplTitle; }); return hasRealSense || !hasFilledTplSense; }, disabledKeys: { "navz": true, "ku": true, "ckb": true, "sdh": true, "lki": true, "hac": true, "zza": true }, /** * Builds one translation row: a language dropdown + a growing list * of word inputs. When the dropdown gets a value the next empty row * is appended automatically. * * @param group the specific .wiktku-trans-group this row belongs to * (each gloss has its own group and its own list of rows, so the * lookups below must stay scoped to that group rather than the * whole step — the step now holds one list per gloss). */ buildRow: function (group) { var row = $("<li class='wiktku-trans-row wiktku-lang-row'></li>"); // Language selector — chosen is applied after insertion into DOM. var langSel = $(mw.html.element("select", { "class": "wiktku-start-step-keyfield wiktku-start-narrow" })); langSel.attr("data-placeholder", "Zimanekî lê bigere"); populateMenus(langSel, steps.trans.keys || [], steps.trans.disabledKeys); // When a language is chosen, ensure a next empty row exists. langSel.on("change", function () { steps.trans.onLangChange(group, row); }); // Word list for this language. var wordList = $("<ul class='wiktku-trans-words wiktku-lang-row-words'></ul>"); var firstWord = steps.trans.makeWordInput(); wordList.append($("<li></li>").append(firstWord)); if (isMobile) { row.append(wrapNativeSelect(langSel)).append(wordList); } else { row.append(langSel).append(wordList); } return row; }, makeWordInput: function () { var input = $("<textarea></textarea>") .attr("name", "wiktku-trans-word-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 1) .attr("class", "wiktku-dfn-subfield wiktku-start-narrow") .attr("placeholder", "Tercime…"); input.on("input", function () { var list = $(this).closest("ul.wiktku-trans-words"); var item = $(this).parent(); var val = $.trim($(this).val()); if (val && item.is(list.children("li:last-child"))) { var next = steps.trans.makeWordInput(); list.append($("<li></li>").append(next)); } }); return input; }, onLangChange: function (group, row) { var list = group.find("ul.wiktku-trans-list"); var isLast = row.is(list.children("li.wiktku-trans-row:last-child")); if (isLast) { var newRow = steps.trans.buildRow(group); list.append(newRow); // Init chosen after the new row is in the DOM (desktop only). if (!isMobile) newRow.find("select").chosen(chosenOptions); } // Keep disabled keys in sync across this gloss's lang selectors // only — the same language can be used for different senses. steps.trans.syncDisabledKeys(group); }, /** Disables already-selected languages in all other dropdowns within one group. */ syncDisabledKeys: function (group) { var taken = $.extend({}, steps.trans.disabledKeys); group.find("li.wiktku-trans-row select").each(function () { var v = $(this).val(); if (v) taken[v] = true; }); group.find("li.wiktku-trans-row select").each(function () { var self = $(this); var own = self.val(); self.find("option").each(function () { var code = $(this).val(); if (!code) return; $(this).prop("disabled", taken[code] && code !== own); }); self.trigger("chosen:updated"); }); }, /** * Builds (or fetches) the .wiktku-trans-group for one gloss, with * its own label and its own list of translation rows. */ buildGroup: function (stepDiv, gi) { var group = $("<div class='wiktku-trans-group'></div>").attr("data-gloss-pos", gi); var list = $("<ul class='wiktku-trans-list wiktku-lang-row-list'></ul>"); list.append(steps.trans.buildRow(group)); group.append(list); stepDiv.append(group); // Init chosen after the select is in the DOM (desktop only). if (!isMobile) list.find("select").chosen(chosenOptions); return group; }, /** * Syncs one .wiktku-trans-group per current gloss, adding new * groups and removing stale ones as senses are added or removed, * while leaving existing groups (and whatever translations the * user has already typed into them) untouched. Groups are keyed * to their gloss's position in glossList() via data-gloss-pos, so * a group always matches the same sense across rebuilds as long * as senses aren't reordered relative to each other. */ build: function (stepDiv) { var glosses = steps.trans.glossList(); if (!glosses.length) { stepDiv.find(".wiktku-trans-group").remove(); return null; } // Drop groups for glosses that no longer exist (always from the // tail — groups are only ever appended in gloss order below). var existingGroups = stepDiv.find(".wiktku-trans-group"); if (existingGroups.length > glosses.length) { existingGroups.slice(glosses.length).remove(); } $.each(glosses, function (gi, gloss) { var group = stepDiv.find(".wiktku-trans-group[data-gloss-pos='" + gi + "']"); if (!group.length) group = steps.trans.buildGroup(stepDiv, gi); // Only label groups when there's more than one gloss to // distinguish between — a single gloss needs no caption. var label = group.find(".wiktku-trans-group-label"); if (glosses.length > 1) { if (!label.length) { label = $("<div class='wiktku-trans-group-label'></div>"); group.prepend(label); } label.text(gloss.index + " " + gloss.text); } else if (label.length) { label.remove(); } }); return null; }, /** Reads the translation rows for a single gloss group. */ getGroupTranslations: function (group) { var result = []; group.find("li.wiktku-trans-row").each(function () { var lang = $(this).find("select").val(); if (!lang) return; var words = []; $(this).find("ul.wiktku-trans-words textarea").each(function () { var v = $.trim($(this).val()); if (v) words.push(v); }); if (words.length) result.push([lang, words]); }); return result; }, /** * Reads all translation rows from the DOM, grouped by gloss * position — one array of [lang, words] rows per gloss group, in * the same order as the .wiktku-trans-group elements. */ getTranslations: function (stepDiv) { var result = []; stepDiv.find(".wiktku-trans-group").each(function () { result.push(steps.trans.getGroupTranslations($(this))); }); return result; }, /** * Builds the numbered "{ index, gloss }" list — one entry per dfn * sense that has a real mane (skips template senses like Guharto, * which have nothing to caption a translation table with). The * index matches the sense's actual position in the numbered "#" * definition list (1-based), including template senses in the count, * so the number printed next to {{werger-ser}} lines up with the * gloss the reader sees in the entry. * * When nothing has been filled in at all (dfn.getOutput() will emit * {{mane?|lang}} as sense 1), this returns a single placeholder * entry with empty text instead of an empty array, so Werger still * has one group to attach translations to before a gloss exists. * When every filled sense is a template sense instead, this stays * empty — that mirrors trans.visible()'s hidden case, where there's * no group in the DOM for a placeholder to attach to anyway. */ glossList: function () { var dfnSenses = steps.dfn.getSenses($("#wiktku-start-dfn")); var glosses = []; var hasFilledTplSense = false; $.each(dfnSenses, function (i, s) { if (s.tpl) { if (s.tplTitle) hasFilledTplSense = true; return; // template sense — no gloss to caption with } var dfn = s.mane; if (!dfn) { // No mane text, but other fields (etîket/hevmane/nimûne/ // jêder…) are filled — dfn.getOutput() still emits this // sense as a numbered line using {{mane?|lang}}, so it // needs its own gloss group too, just with no caption text. if (senseHasExtraContent(s)) glosses.push({ index: i + 1, text: "" }); return; } if (dfn[0] !== dfn[0].toLowerCase()) dfn = decapitalize(dfn); dfn = stripWikilinks(dfn).replace(/[.…?!)\]،؟]+$/, ""); glosses.push({ index: i + 1, text: dfn }); }); if (!glosses.length && !hasFilledTplSense) { glosses.push({ index: 1, text: "" }); } return glosses; }, output: function (values) { if (values.lang !== "ku") return ""; var stepDiv = $("#wiktku-start-trans"); var glosses = steps.trans.glossList(); // Every sense is a template sense — there's no real gloss // anywhere and no group in the DOM either (glossList() only // returns empty in that case), so skip the section entirely. if (!glosses.length) return ""; // Each gloss now has its own group of translation rows — // attach every gloss's own words under its own werger-ser/-bin // pair instead of dumping everything under the first one. var blocks = $.map(glosses, function (gloss, gi) { var group = stepDiv.find(".wiktku-trans-group[data-gloss-pos='" + gi + "']"); var rows = group.length ? steps.trans.getGroupTranslations(group) : []; // Placeholder gloss (no real mane entered yet) with nothing // translated into it — nothing to output, and gloss.text is // empty so there's no caption to give {{werger-ser}} anyway. if (!gloss.text && !rows.length) return undefined; if (rows.length) { // Sort by Kurdish sort key. rows.sort(function (a, b) { var aLang = langsByCode[a[0]] || []; var bLang = langsByCode[b[0]] || []; return (aLang[2] || "").localeCompare(bLang[2] || "", "ku"); }); } var wordLines = $.map(rows, function (row) { var lang = row[0]; var words = row[1]; var wikiWords = words.map(function (w) { return "{{W|" + lang + "|" + w + "}}"; }).join(", "); return "* {{Z|" + lang + "}}: " + wikiWords; }).join("\n"); var block = "{{werger-ser|" + (gloss.text || "?") + "|" + gloss.index + "}}"; if (wordLines) block += "\n" + wordLines; block += "\n{{werger-bin}}"; return block; }); if (!blocks.length) return ""; return "\n==== Werger ====\n" + blocks.join("\n") + "\n"; } }, }; steps.trans.keys = steps.lang.choices; steps.dunde.keys = steps.lang.choices; steps.zarava.keys = getZaravaKeys(steps.lang.choices); var ordered_steps = [ steps.lang, steps.pron, steps.pos, steps.cinsiyet, steps.lektur, steps.tr, steps.dfn, steps.je, steps.tekildar, steps.etym, steps.dunde, steps.binereherwiha, steps.zarava, steps.trans]; // Step ids that belong to each section (not shared across sections). var PER_SECTION_STEP_IDS = [ "pos", "cinsiyet", "lektur", "tr", "dfn", "je", "tekildar", "etym", "dunde", "binereherwiha", "zarava", "trans" ]; // ── Multi-section state ────────────────────────────────────────────────── // Each entry is a plain snapshot: { pos, cinsiyet, lektur, tr, dfn (senses[]), // je, tekildar, binereherwiha, trans (rows[]) }. var sections = [{}]; // section 0 starts empty (DOM is the truth) var activeSection = 0; function snapshotDfn() { return steps.dfn.getSenses($("#wiktku-start-dfn")); } /** * Rebuild the dfn DOM from a previously snapshotted senses array. */ function restoreDfn(senses) { var stepDiv = $("#wiktku-start-dfn"); // Tear down the existing list so build() recreates it cleanly. stepDiv.find("ol.wiktku-dfn-list").remove(); steps.dfn.build(stepDiv); var list = stepDiv.find("ol.wiktku-dfn-list"); $.each(senses, function (i, sense) { // Ensure enough blocks exist (build() seeds one). var blocks = list.find("li.wiktku-dfn-sense"); var block = blocks.eq(i); if (!block.length) { var nb = steps.dfn.buildSenseBlock(stepDiv); list.append(nb); block = list.find("li.wiktku-dfn-sense").last(); } // Template selector. block.find("select.wiktku-dfn-tpl-select").val(sense.tpl || ""); if (sense.tpl) { block.find("textarea.wiktku-dfn-mane").hide(); block.find("input.wiktku-dfn-tpl-title").val(sense.tplTitle || "").show(); } else { block.find("textarea.wiktku-dfn-mane").val(sense.mane || "").show(); block.find("input.wiktku-dfn-tpl-title").hide().val(""); } // Re-sync the formên alternatîv/hevmane/… hide state now that // tplSelect's value was set programmatically (its own "change" // handler doesn't fire from .val(), so this doesn't happen otherwise). var updateVis = block.data("updateFieldVisibility"); if (updateVis) updateVis(); // Restore a sub-list (etiket, formên alternatîv, hevmane …) from a values array. function restoreSubList(cls, values) { if (!values || !values.length) return; var groupDiv = block.find("." + cls + "-group"); var subList = groupDiv.find("ol, ul").first(); if (!subList.length) return; // group not found // Fill existing items, append new ones as needed. $.each(values, function (j, val) { var items = subList.find("li"); if (j < items.length) { items.eq(j).find("textarea").val(val); } else { var ta = $("<textarea></textarea>") .attr("name", "wiktku-dfn-restore-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 1) .attr("class", "wiktku-dfn-subfield wiktku-start-narrow") .val(val); ta.on("input", function () { steps.dfn.onSubInput(subList, this, 1, true); }); subList.append($("<li></li>").append(ta)); } }); } // Reveal and populate lazy groups that have data. var lazyMap = { "wiktku-dfn-etiket": sense.etiket, "wiktku-dfn-alternativ": sense.alternativ, "wiktku-dfn-hevmane": sense.hevmane, "wiktku-dfn-dijmane": sense.dijmane, "wiktku-dfn-koordine": sense.koordine, "wiktku-dfn-jornav": sense.jornav, "wiktku-dfn-jernav": sense.jernav }; $.each(lazyMap, function (cls, vals) { if (vals && vals.length) restoreSubList(cls, vals); }); // Nimûne items are objects { text, tr?, t? } — restore using the builder. if (sense.nimune && sense.nimune.length) { var nimuneGroupDiv = block.find(".wiktku-dfn-nimune-group"); var nimuneList = nimuneGroupDiv.find("ol.wiktku-dfn-nimune-list"); var buildFn = nimuneGroupDiv.data("buildNimuneLi"); nimuneList.empty(); $.each(sense.nimune, function (_, n) { var text = typeof n === "object" ? (n.text || "") : n; if (!text) return; var li = buildFn ? buildFn() : $("<li class='wiktku-dfn-nimune-li'></li>"); li.find(".wiktku-dfn-nimune-text").val(text); if (n.tr) li.find(".wiktku-dfn-nimune-tr").val(n.tr); if (n.t) li.find(".wiktku-dfn-nimune-t").val(n.t); nimuneList.append(li); }); // Always leave a blank trailing item. if (buildFn) nimuneList.append(buildFn()); } // Restore jêder (quote/citation) entries — a growing list, restored using the // builder just like Nimûne. Accepts either the current array shape or a // single legacy object (from older saved sections) for backwards compatibility. var jederArr = $.isArray(sense.jeder) ? sense.jeder : (sense.jeder ? [sense.jeder] : []); if (jederArr.length) { var jederGroupDiv = block.find(".wiktku-dfn-jeder-group"); var jederList = jederGroupDiv.find("ol.wiktku-dfn-jeder-list"); var buildJederFn = jederGroupDiv.data("buildJederLi"); jederList.empty(); $.each(jederArr, function (_, j) { if (!j || !j.quote) return; var li = buildJederFn ? buildJederFn() : $("<li class='wiktku-dfn-jeder-li'></li>"); li.find(".wiktku-dfn-nimune-quote").val(j.quote); if (j.quoteTr) li.find(".wiktku-dfn-nimune-quote-tr").val(j.quoteTr); if (j.quoteT) li.find(".wiktku-dfn-nimune-quote-t").val(j.quoteT); if (j.jederManual) { var manualSel = li.find(".wiktku-dfn-quote-src-sel"); manualSel.val("__manual__").trigger("change"); li.find(".wiktku-dfn-quote-src-manual").val(j.jederManual); } else if (j.jederTpl) { var srcSel = li.find(".wiktku-dfn-quote-src-sel"); srcSel.val(j.jederTpl).trigger("change"); if (j.jêderFields) { $.each(j.jêderFields, function (key, val) { li.find(".wiktku-dfn-quote-src-input[data-field-key='" + key + "']").val(val); }); } } jederList.append(li); }); // Always leave a blank trailing item, same as Nimûne. if (buildJederFn) jederList.append(buildJederFn()); } }); } /** * Snapshot simple (non-dfn) per-section steps from current DOM into obj. */ function saveCurrentSection() { var snap = {}; $.each(PER_SECTION_STEP_IDS, function (_, id) { if (id === "dfn") { snap.dfn = snapshotDfn(); return; } if (id === "etym") { snap.etym = $.trim($("#wiktku-start-etym .wiktku-etym-text").val()); return; } var step = steps[id]; if (!step) return; var stepDiv = $("#wiktku-start-" + id); if (id === "trans") { snap.trans = steps.trans.getTranslations(stepDiv); return; } if (id === "zarava") { snap.zarava = steps.zarava.getTranslations(stepDiv); return; } if (id === "dunde") { snap.dunde = steps.dunde.getRows(stepDiv); return; } // Generic: read all step fields. var fields = stepDiv.find(".wiktku-start-step-field"); if (step.multiple) { snap[id] = fields.map(function () { return $(this).val(); }).get(); } else { snap[id] = fields.val(); } }); sections[activeSection] = snap; } /** * Restore a previously saved snapshot into the form DOM. */ function restoreSection(snap) { $.each(PER_SECTION_STEP_IDS, function (_, id) { if (id === "dfn") { restoreDfn(snap.dfn || []); return; } if (id === "etym") { $("#wiktku-start-etym .wiktku-etym-wrap").remove(); steps.etym.build($("#wiktku-start-etym")); $("#wiktku-start-etym .wiktku-etym-text").val(snap.etym || ""); return; } if (id === "trans") { // Rebuild trans groups (dfn must already be restored by this // point in the $.each loop, so glossList() reflects it). var transDiv = $("#wiktku-start-trans"); transDiv.find(".wiktku-trans-group").remove(); steps.trans.build(transDiv); var groupsSnap = snap.trans || []; $.each(groupsSnap, function (gi, rows) { var group = transDiv.find(".wiktku-trans-group[data-gloss-pos='" + gi + "']"); if (!group.length) return; // gloss no longer exists — drop its rows var list = group.find("ul.wiktku-trans-list"); $.each(rows, function (j, row) { var lang = row[0], words = row[1]; var lastRow = list.find("li.wiktku-trans-row").last(); lastRow.find("select").val(lang).trigger("change"); var wordList = lastRow.find("ul.wiktku-trans-words"); $.each(words, function (k, word) { var wordItems = wordList.find("li"); if (k < wordItems.length) { wordItems.eq(k).find("textarea").val(word); } else { // .val() below doesn't fire "input", so the normal // auto-grow never runs — append a matching item // ourselves instead of silently dropping the word. var extraInput = steps.trans.makeWordInput(); wordList.append($("<li></li>").append(extraInput)); extraInput.val(word); } }); // Leave one trailing empty field so the row can still grow // when the user types, matching a freshly-built row. if ($.trim(wordList.children("li").last().find("textarea").val())) { wordList.append($("<li></li>").append(steps.trans.makeWordInput())); } }); }); return; } if (id === "zarava") { // Rebuild zarava groups (dfn must already be restored by this // point in the $.each loop, so glossList() reflects it). var zaravaDiv = $("#wiktku-start-zarava"); zaravaDiv.find(".wiktku-zarava-group").remove(); steps.zarava.build(zaravaDiv); var zaravaGroupsSnap = snap.zarava || []; $.each(zaravaGroupsSnap, function (gi, rows) { var group = zaravaDiv.find(".wiktku-zarava-group[data-gloss-pos='" + gi + "']"); if (!group.length) return; // gloss no longer exists — drop its rows var list = group.find("ul.wiktku-zarava-list"); $.each(rows, function (j, row) { var lang = row[0], words = row[1]; var lastRow = list.find("li.wiktku-zarava-row").last(); lastRow.find("select").val(lang).trigger("change"); var wordList = lastRow.find("ul.wiktku-zarava-words"); $.each(words, function (k, word) { var wordItems = wordList.find("li"); if (k < wordItems.length) { wordItems.eq(k).find("textarea").val(word); } else { var extraInput = steps.zarava.makeWordInput(); wordList.append($("<li></li>").append(extraInput)); extraInput.val(word); } }); if ($.trim(wordList.children("li").last().find("textarea").val())) { wordList.append($("<li></li>").append(steps.zarava.makeWordInput())); } }); }); return; } if (id === "dunde") { // Rebuild dunde rows. var dundeDiv = $("#wiktku-start-dunde"); dundeDiv.find("ul.wiktku-dunde-list").remove(); steps.dunde.build(dundeDiv); var dundeRows = snap.dunde || []; $.each(dundeRows, function (i, row) { var lang = row[0], words = row[1]; var list = dundeDiv.find("ul.wiktku-dunde-list"); var lastRow = list.find("li.wiktku-dunde-row").last(); lastRow.find("select").val(lang).trigger("change"); var wordList = lastRow.find("ul.wiktku-dunde-words"); $.each(words, function (j, word) { var wordItems = wordList.find("li"); if (j < wordItems.length) { wordItems.eq(j).find("textarea").val(word); } else { // .val() below doesn't fire "input", so the normal // auto-grow never runs — append a matching item // ourselves instead of silently dropping the word. var extraInput = steps.dunde.makeWordInput(); wordList.append($("<li></li>").append(extraInput)); extraInput.val(word); } }); // Leave one trailing empty field so the row can still grow // when the user types, matching a freshly-built row. if ($.trim(wordList.children("li").last().find("textarea").val())) { wordList.append($("<li></li>").append(steps.dunde.makeWordInput())); } }); return; } var step = steps[id]; if (!step) return; var stepDiv = $("#wiktku-start-" + id); var fields = stepDiv.find(".wiktku-start-step-field"); var val = snap[id]; if (val === undefined || val === null) return; if (step.multiple) { var arr = val; fields.each(function (i) { if (i < arr.length) $(this).val(arr[i]); }); } else { fields.val(val); } // Notify chosen widgets of the programmatic value change. if (!isMobile) fields.filter("select").trigger("chosen:updated"); }); } function getWikitextForCurrentSection(callback) { var values = getValues(); var entry = steps.pos.output(values); steps.dfn.getOutput(values, function (output) { entry += output; entry += steps.je.output(values); entry += steps.tekildar.output(values); entry += steps.etym.output(values); entry += steps.dunde.output(values); entry += steps.binereherwiha.output(values); entry += steps.zarava.output(values); entry += steps.trans.output(values); callback(entry, values); }); } function getWikitextAllSections(callback) { saveCurrentSection(); var results = new Array(sections.length); var sharedValues = getValues(); // lang/pron are shared function processSection(i) { if (i >= sections.length) { // All done — restore original active section. restoreSection(sections[activeSection]); refresh(); callback(results, sharedValues); return; } restoreSection(sections[i]); refresh(); getWikitextForCurrentSection(function (sectionText) { results[i] = sectionText; processSection(i + 1); }); } processSection(0); } /** * Assembles wikitext for all sections plus the shared lang/pron header. */ function getWikitext(callback) { getWikitextAllSections(function (sectionTexts, sharedValues) { var entry = steps.lang.output(sharedValues); entry += steps.pron.output(sharedValues); entry += sectionTexts.join("\n"); // Edit summary uses section 0's values. Read from the saved snapshot // (not the live DOM) so it doesn't mix section 0's pos with whichever // section happens to be active/restored at this point. var dfnSenses = (sections[0] && sections[0].dfn) || []; var dfnSummary = dfnSenses.map(function (s) { return s.mane; }).filter(Boolean).join("; "); var summaryLabel = addLangMode ? "WF:Ziman lê zêde" : "WF:Nû"; var summary = "([[Mediawiki:Gadget-start.js|" + summaryLabel + "]] v.2.0) +" + sharedValues.lang + ":" + sections[0].pos + ":" + dfnSummary; var summaryField = document.getElementById("wpSummary"); if (addLangMode && summaryField.value) { summary = summaryField.value + " " + summary; } summaryField.value = summary; callback(entry); }); } var continueBtn; function getValuesForStep(stepId) { var fields = $("#wiktku-start-" + stepId + " .wiktku-start-step-field"); var step = steps[stepId]; if (step.keys) { var values = {}; fields.each(function (i, field) { var key = $(field).prevAll(".wiktku-start-step-keyfield").val(); if (key) values[key] = $(field).val(); }); return values; } else if (step.multiple) { return fields.map(function () { return $(this).val(); }).get(); } return fields.val(); } function getValues() { var values = {}; $.each(steps, function (stepId) { values[stepId] = getValuesForStep(stepId); }); return values; } function populateMenus(inputs, choices, disabledValues) { if (!disabledValues) disabledValues = {}; var vals = inputs.map(function (i, input) { return $(input).val(); }); inputs.empty(); inputs.append($("<option></option>")); $.each(choices, function (j, choice) { // Append the language code in parentheses so that typing a code // (e.g. "ku") in the search box still finds the language name. var displayText = capitalize(choice[1]); if (choice[2] !== undefined) { // This is a language choice [code, name, sortKey] — show code. displayText = capitalize(choice[1]) + " (" + choice[0] + ")"; } var option = $(mw.html.element("option", { value: choice[0] }, displayText)); if (disabledValues[choice[0]]) option.prop("disabled", true); inputs.append(option); }); inputs.val(function (i) { return vals[i]; }); } /** * Returns a bitmap containing the keys that should be disabled for a key * menu in the given step because they are disabled or already taken by * another key menu. */ function getDisabledKeys(step) { var occupiedKeys = {}; $("#wiktku-start-" + step.id + " .wiktku-start-step-keyfield").each(function () { occupiedKeys[$(this).val()] = true; }); if (step.disabledKeys) $.extend(occupiedKeys, step.disabledKeys); return occupiedKeys; } function buildKeyInput(step) { if (!step.keys) return undefined; var input = $(mw.html.element("select", { "class": "wiktku-start-step-keyfield wiktku-start-narrow" })); input.attr("data-placeholder", "Hilbijêre " + step.keyName); if (isMobile) { populateMenus(input, step.keys, getDisabledKeys(step)); // On mobile return the wrapper; the select is inside it. // Change events still fire on the inner select. return wrapNativeSelect(input); } input.on("chosen:showing_dropdown", function () { $(this).data("wiktku-defaultValue", $(this).val()); }); input.change(function (_, context) { var inputs = $("#wiktku-start-" + step.id + " .wiktku-start-step-keyfield").not(this); var oldValue = $(this).data("wiktku-defaultValue"); var newValue = context.selected; inputs.find("option[value='" + oldValue + "']").prop('disabled', false); inputs.find("option[value='" + newValue + "']").prop('disabled', true); inputs.trigger("chosen:updated"); }); populateMenus(input, step.keys, getDisabledKeys(step)); return input; } /** * If the current text field has text and there are no more text fields after * the current text field in the list, add another text field to the list. */ function refreshForTextField(currentInput, step) { currentInput = $(currentInput); var value = currentInput.val(); var item = currentInput.parent(); if (value && !item.next("li").length) { var nextInput = $("<textarea></textarea>") .attr("name", "wiktku-field-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("class", currentInput.attr("class")) .attr("rows", currentInput.attr("rows") || 1); nextInput.on("input", function (evt) { refreshForTextField(evt.target, step); }); var nextKeyInput = buildKeyInput(step); var nextItem = $("<li></li>").append(nextKeyInput).append(nextInput); item.parent().append(nextItem); if (nextKeyInput) nextKeyInput.chosen(chosenOptions); } var canContinue = !continueBtn.isDisabled(); if ((value && !canContinue) || (!value && canContinue)) { refresh(step); } } function prepareInput(input, step) { if (!input) return; if (step.required) input.prop('required', true); input.change(step, refresh); } /** * Shows and hides all the steps based on whether their prerequisites are met, * and updates placeholders where applicable. */ function refresh(evt) { var values = getValues(); var changedStep = evt && evt.data; var didFocus = false; var canContinue = true; // Re-filter template options in every sense block whenever lang changes. $("#wiktku-start-dfn .wiktku-dfn-tpl-select").each(function () { var fn = $(this).data("updateOptions"); if (typeof fn === "function") fn(); }); // Re-filter pronunciation and etymology template dropdowns when language changes. steps.pron.refreshTplSelect(); steps.etym.refreshTplSelect(); // Sync tr/t sub-fields in every nimûne item to the current language. // tr shown when language needs transliteration; t shown when lang !== "ku". (function () { var lang = values.lang || ""; var showTr = needsTransliteration(lang); var showT = lang && lang !== "ku"; $("#wiktku-start-dfn .wiktku-dfn-nimune-list li.wiktku-dfn-nimune-li").each(function () { var li = $(this); // Ensure the sub-wrapper exists when we need it. var subWrap = li.find(".wiktku-dfn-nimune-sub"); // tr field var trTa = li.find(".wiktku-dfn-nimune-tr"); if (showTr && !trTa.length) { if (!subWrap.length) { subWrap = $("<div></div>").addClass("wiktku-dfn-nimune-sub"); li.append(subWrap); } trTa = $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-tr-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 5) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-tr") .attr("placeholder", "Transkrîpsiyon…"); subWrap.prepend(trTa); } else if (!showTr && trTa.length) { trTa.remove(); } // t field var tTa = li.find(".wiktku-dfn-nimune-t"); if (showT && !tTa.length) { if (!subWrap.length) { subWrap = $("<div></div>").addClass("wiktku-dfn-nimune-sub"); li.append(subWrap); } tTa = $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-t-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 5) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-t") .attr("placeholder", "Tercimeya nimûneyê kurmancî…"); subWrap.append(tTa); } else if (!showT && tTa.length) { tTa.remove(); } // Remove the wrapper if it ended up empty. subWrap = li.find(".wiktku-dfn-nimune-sub"); if (subWrap.length && !subWrap.children().length) subWrap.remove(); }); }()); // Sync tr/t sub-fields in every jêder citation to the current language. // tr shown when language needs transliteration; t shown when lang !== "ku". (function () { var lang = values.lang || ""; var showTr = needsTransliteration(lang); var showT = lang && lang !== "ku"; $("#wiktku-start-dfn .wiktku-dfn-jeder-list li.wiktku-dfn-jeder-li").each(function () { var li = $(this); // Ensure the sub-wrapper exists when we need it. It must sit right // after the quote textarea and before the source selector. var subWrap = li.find(".wiktku-dfn-quote-sub"); // tr field var trTa = li.find(".wiktku-dfn-nimune-quote-tr"); if (showTr && !trTa.length) { if (!subWrap.length) { subWrap = $("<div></div>").addClass("wiktku-dfn-quote-sub"); li.find(".wiktku-dfn-nimune-quote").after(subWrap); } trTa = $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-quote-tr-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 2) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-quote-tr") .attr("placeholder", "Transkrîpsiyona jêgirtinê…"); subWrap.prepend(trTa); } else if (!showTr && trTa.length) { trTa.remove(); } // t field var tTa = li.find(".wiktku-dfn-nimune-quote-t"); if (showT && !tTa.length) { if (!subWrap.length) { subWrap = $("<div></div>").addClass("wiktku-dfn-quote-sub"); li.find(".wiktku-dfn-nimune-quote").after(subWrap); } tTa = $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-quote-t-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 2) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-quote-t") .attr("placeholder", "Tercimeya jêgirtinê ya kurmancî…"); subWrap.append(tTa); } else if (!showT && tTa.length) { tTa.remove(); } // Remove the wrapper if it ended up empty. subWrap = li.find(".wiktku-dfn-quote-sub"); if (subWrap.length && !subWrap.children().length) subWrap.remove(); }); }()); $.each(steps, function (stepId, step) { if (typeof(step.visible) === "function" && !step.visible(values)) { $("#wiktku-start-" + stepId).slideUp(); } else { var stepDiv = $("#wiktku-start-" + stepId); if (changedStep !== step && typeof(step.build) === "function") { prepareInput(step.build(stepDiv, values), step); } var input = stepDiv.find(".wiktku-start-step-field"); if (typeof(step.example) === "function") { // .find() above already reaches nested fields (e.g. the dfn // step's mane textareas inside each sense block), so one // assignment covers every step; dfn keeps its own fallback. var exampleText = step.example(values) || (step.id === "dfn" ? "Mane…" : ""); input.attr("placeholder", exampleText); } var didSlideDown; if (!didFocus && stepDiv.css("display") === "none" && step.required) { didSlideDown = function (evt) { input.focus(); }; didFocus = true; } stepDiv.slideDown(didSlideDown); } if (step.required && (values[stepId] === "" || (step.multiple && values[stepId].join("") === ""))) { canContinue = false; } }); continueBtn.setDisabled(!canContinue); } function destroy() { $("#wiktku-start-form, .noafterwizard").slideUp(function () { $(this).remove(); }); $(".noarticletext .nowizard, #editform").slideDown(); $("#ca-edit").removeClass("selected"); $("#ca-wiktku-nowizard").addClass("selected"); } // Priority order for Kurdish dialects and the navz pseudo-code. // Codes listed here come before all other languages; unlisted codes // are sorted alphabetically by their display name via localeCompare. var LANG_PRIORITY = ["navz", "ku", "hac", "sdh", "lki", "ckb", "zza"]; /** * Inserts a new == {{ziman|code}} == section into existing page wikitext * at the correct sorted position: * 1. Any content before the first language section is preserved at the top. * 2. navz is always first, then ku/hac/sdh/lki/ckb/zza in that order, * then all other languages sorted by display name (localeCompare). */ function insertNewLangSection(existing, wikitext) { var newCodeMatch = wikitext.match(/^== \{\{ziman\|([^}]+)\}\} ==/); var newCode = newCodeMatch ? newCodeMatch[1] : ""; var sections = []; var preamble = ""; var firstMatch = existing.match(/(?:^|\n)== \{\{ziman\|/); if (!firstMatch) { // No existing lang sections at all — just append. var sep = existing && !/\n\s*$/.test(existing) ? "\n\n" : ""; return existing + sep + wikitext; } // Everything before the first == {{ziman|...}} == is the preamble. var firstSectionStart = existing.indexOf("== {{ziman|"); // Walk back to the start of that line. var lineStart = existing.lastIndexOf("\n", firstSectionStart - 1); var preambleEnd = lineStart !== -1 ? lineStart + 1 : 0; preamble = existing.slice(0, preambleEnd); // Parse each language section: header line + everything until the next header. var body = existing.slice(preambleEnd); // NOTE: with the /m flag, a bare "$" matches end-of-*line*, not just // end-of-string — that previously made the non-greedy content group // stop at the section's first line break instead of running to the // next language header (or the real end of the text), silently // dropping the rest of that section's wikitext. (?![\s\S]) matches // only the true end of the string, /m flag or not. var langSectionRe = /^(== \{\{ziman\|([^}]+)\}\} ==\n?)([\s\S]*?)(?=\n== \{\{ziman\||(?![\s\S]))/gm; var m; while ((m = langSectionRe.exec(body)) !== null) { sections.push({ code: m[2], content: m[0] // full text of this section including header }); } // Determine sort rank: priority list first (by index), then alphabetical. function getLangName(code) { var entry = langsByCode[code]; return entry ? entry[1] : code; } function sortRank(code) { var idx = LANG_PRIORITY.indexOf(code); return idx !== -1 ? idx : LANG_PRIORITY.length; } function compareLangs(a, b) { var ra = sortRank(a), rb = sortRank(b); if (ra !== rb) return ra - rb; // Both are outside priority list — sort by display name. return getLangName(a).localeCompare(getLangName(b), userLang); } // Insert the new section into the sorted list. var newSection = { code: newCode, content: wikitext }; var inserted = false; for (var i = 0; i < sections.length; i++) { if (compareLangs(newCode, sections[i].code) < 0) { sections.splice(i, 0, newSection); inserted = true; break; } } if (!inserted) sections.push(newSection); // Re-join: preamble + sections separated by newlines. var joined = sections.map(function (s) { // Ensure each section ends with exactly one newline before the next. return s.content.replace(/\n+$/, ""); }).join("\n"); return preamble + joined + "\n"; } function build() { $(".nowizard, .nowizard .noafterwizard").hide(); var callToAction = $("#wiktku-calltoaction"); var origCallToActionText = callToAction.text(); $(mw.util.addPortletLink("p-views", "#", "Edîtora çavkaniyê veke", "ca-wiktku-nowizard", "Vê rûpelê bi edîtora çavkaniyê çêke", undefined, "#ca-watch")).click(function (evt) { evt.preventDefault(); callToAction.text(origCallToActionText); destroy(); }); if (callToAction.length) { callToAction.text(origCallToActionText + " Forma li jêr ji bo çêkirina madeyeke nû bi kar bîne."); } var startForm = $("<form id='wiktku-start-form'></form>"); if (addLangMode) { startForm.append($("<p class='wiktku-addlang-notice'></p>").html( "Bi vê formê tu yê beşeke nû li rûpelê îlawe bikî. Eger ev zimanê ku tu îlawe dikî jixwe di rûpelê de hebe, beşa nû li dawiya vî zimanî dê were îlawekirin. " + "Ji kerema xwe netîceya dawî kontrol bikin, eger problemek derkeve, li <a href='" + mw.util.getUrl('Mediawiki talk:Gadget-start.js') + "'>nîqaşa vê amûrê</a> problemê ragihîne." )); } var spinner; // Tab bar for switching between POS sections. var sectionTabsDiv = $("<div id='wiktku-section-tabs'></div>"); startForm.submit(function (evt) { evt.preventDefault(); continueBtn.setDisabled(true); spinner.show(); getWikitext(function (wikitext) { if (addLangMode) { var textbox = $("#wpTextbox1"); var existing = textbox.val() || ""; // Check whether the generated lang header already exists in the page. // wikitext always starts with "== {{ziman|CODE}} ==\n" (from steps.lang.output). // If that exact section heading is already present in the existing content, // strip it from the new output and insert the remaining content at the end // of that lang section (just before the next == level-2 heading, or at the // very end of the page if there is no following section). var langHeaderMatch = wikitext.match(/^(== \{\{ziman\|[^}]+\}\} ==\n)/); if (langHeaderMatch) { var langHeader = langHeaderMatch[1]; // e.g. "== {{ziman|ku}} ==\n" // Escape for use in RegExp. var escapedHeader = langHeader.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); if (new RegExp(escapedHeader).test(existing)) { // Strip the header from the new output. var newContent = wikitext.slice(langHeader.length); // Find the insertion point: end of the existing lang section. // A new L2 heading marks the start of the next language block. var afterHeader = existing.indexOf(langHeader); var searchFrom = afterHeader + langHeader.length; // Find the next == … == heading after this section's start. var nextL2 = existing.indexOf("\n== ", searchFrom); var insertAt = nextL2 !== -1 ? nextL2 : existing.length; // Ensure there's a blank line before the inserted block. var before = existing.slice(0, insertAt); var after = existing.slice(insertAt); var sep = /\n\s*$/.test(before) ? "" : "\n"; textbox.val(before + sep + newContent + after); } else { // New language — insert at the correct sorted position. textbox.val(insertNewLangSection(existing, wikitext)); } } else { // Unexpected format — insert at sorted position anyway. textbox.val(insertNewLangSection(existing, wikitext)); } } else { $("#wpTextbox1").val(wikitext); } $("html, body").animate({scrollTop: 0}); callToAction.text("Hindik ma!"); $("#wiktku-preview-container").remove(); destroy(); }); }); $.each(ordered_steps, function (i, step) { var stepDiv = $(mw.html.element("div", { "class": "wiktku-start-step", id: "wiktku-start-" + step.id })); var name = capitalize(step.name); stepDiv.append($(mw.html.element("h3", { "class": "wiktku-start-step-name" }, new mw.html.Raw(mw.html.element("label", { "for": "wiktku-start-" + step.id + "-field" }, name))))); if (step.question_fmt) { stepDiv.append($(mw.html.element("label", { "class": "wiktku-start-step-question", "for": "wiktku-start-" + step.id + "-field" }, step.question_fmt))); if (step.question_br) stepDiv.append($("<br>")); } var input; if (step.choices) { input = $(mw.html.element("select", { "class": "wiktku-start-step-field", id: "wiktku-start-" + step.id + "-field" })); input.attr("data-placeholder", capitalize(step.name) + " hilbijêre "); populateMenus(input, step.choices); if (step.multiple) input.attr("multiple", true); if (isMobile) { stepDiv.append(wrapNativeSelect(input)); } else { stepDiv.append(input); } } else if (typeof(step.build) === "function") { input = step.build(stepDiv); } else { input = $("<textarea></textarea>") .attr("class", "wiktku-start-step-field") .attr("id", "wiktku-start-" + step.id + "-field") .attr("rows", step.rows || 2); if (step.narrow) input.addClass("wiktku-start-narrow"); if (step.multiple) { input.on("input", function (evt) { refreshForTextField(evt.target, step); }); var keyInput = buildKeyInput(step); var list = $(step.ordered ? "<ol></ol>" : "<ul></ul>") .append($("<li></li>").append(keyInput).append(input)); stepDiv.append(list); } else stepDiv.append(input); } prepareInput(input, step); stepDiv.hide(); // Insert tab bar just before the first per-section step. if (step.id === "pos") startForm.append(sectionTabsDiv); startForm.append(stepDiv); }); // ── Section tab helpers ────────────────────────────────────────────── // ── Add-section button — lives in the tab bar, disabled until pos chosen ── var addSectionBtn = new OO.ui.ButtonWidget({ label: "+ Beş zêde bike", disabled: true }); addSectionBtn.on("click", function () { saveCurrentSection(); sections.push({}); activeSection = sections.length - 1; $.each(PER_SECTION_STEP_IDS, function (_, id) { if (id === "dfn") { var stepDiv = $("#wiktku-start-dfn"); stepDiv.find("ol.wiktku-dfn-list").remove(); steps.dfn.build(stepDiv); return; } if (id === "etym") { $("#wiktku-start-etym .wiktku-etym-wrap").remove(); steps.etym.build($("#wiktku-start-etym")); return; } if (id === "trans") { var transDiv = $("#wiktku-start-trans"); transDiv.find(".wiktku-trans-group").remove(); return; } if (id === "zarava") { var zaravaDiv = $("#wiktku-start-zarava"); zaravaDiv.find(".wiktku-zarava-group").remove(); return; } if (id === "dunde") { var dundeDiv = $("#wiktku-start-dunde"); dundeDiv.find("ul.wiktku-dunde-list").remove(); return; } var stepDiv = $("#wiktku-start-" + id); stepDiv.find(".wiktku-start-step-field").val(""); if (!isMobile) stepDiv.find("select.wiktku-start-step-field").trigger("chosen:updated"); }); renderSectionTabs(); refresh(); $("html, body").animate({ scrollTop: sectionTabsDiv.offset().top - 20 }, 300); }); /** Re-render the tab bar to reflect current sections[] and activeSection. */ function renderSectionTabs() { // Detach (not remove) the button first: .empty() strips bound // event data from any children left inside it, which would // silently kill addSectionBtn's click handler on every re-render. addSectionBtn.$element.detach(); sectionTabsDiv.empty(); var lang = getValues().lang || ""; if (!lang) { sectionTabsDiv.hide(); return; } sectionTabsDiv.show(); $.each(sections, function (i) { var posVal = sections[i].pos || ""; var tabLabel = posVal ? capitalize(posVal) : ("Beş " + (i + 1)); var tab = $("<span></span>") .addClass("wiktku-section-tab") .text(tabLabel) .toggleClass("wiktku-tab-active", i === activeSection); (function (idx) { tab.on("click", function () { if (idx === activeSection) return; saveCurrentSection(); activeSection = idx; restoreSection(sections[activeSection]); refresh(); renderSectionTabs(); }); }(i)); sectionTabsDiv.append(tab); }); // Enable "Beş zêde bike" only when the active section has a pos chosen. var activePos = sections[activeSection] && sections[activeSection].pos ? sections[activeSection].pos : getValues().pos; addSectionBtn.setDisabled(!activePos); sectionTabsDiv.append(addSectionBtn.$element); } renderSectionTabs(); // Update the active tab's label whenever pos changes. startForm.on("change", "#wiktku-start-pos-field", function () { renderSectionTabs(); }); // Show the tab bar as soon as a language is selected. startForm.on("change", "#wiktku-start-lang-field", function () { renderSectionTabs(); }); var footer = $("<div id='wiktku-start-footer'></div>"); spinner = $(mw.html.element("img", { id: "wiktku-start-spinner", src: "//upload.wikimedia.org/wikipedia/commons/d/de/Ajax-loader.gif", alt: "Tê barkirin…", title: "Tê barkirin…" })); footer.append(spinner.hide()); continueBtn = new OO.ui.ButtonWidget({ id: "wiktku-unhide-editform", label: "Bişîne", flags: [ "primary", "progressive" ] }); continueBtn.on("click", function () { mw.notify("Tê şandin…", { type: "info", tag: "wiktku-submit" }); startForm.trigger("submit"); }); footer.append(continueBtn.$element); // "Edîtora çavkaniyê veke" button — inline fallback for the portlet link // which is invisible on mobile and easy to miss on desktop. var sourceEditorBtn = new OO.ui.ButtonWidget({ label: "Edîtora çavkaniyê veke", framed: false }); sourceEditorBtn.on("click", function () { destroy(); }); footer.append(sourceEditorBtn.$element); // ── Preview checkboxes ─────────────────────────────────────────────── // Wikitext preview (raw text panel) var previewCheck = $("<input type='checkbox' id='wiktku-preview-toggle'>"); var previewLabel = $("<label for='wiktku-preview-toggle'></label>") .text(" Pêşdîtina wîkîtekstê"); var previewPanel = $("<pre id='wiktku-preview-panel'></pre>").hide(); // Live rendered preview (parsed HTML panel, same logic as AjaxEdit). // Not available on mobile — API polling causes too many problems on small screens. var livePreviewCheck = null; var livePreviewPanel = null; if (!isMobile) { livePreviewCheck = $("<input type='checkbox' id='wiktku-live-preview-toggle'>"); livePreviewPanel = $("<div id='wiktku-live-preview-panel'></div>").hide(); } // Container that holds both panels and switches between stacked / side-by-side. var previewContainer = $("<div id='wiktku-preview-container'></div>"); previewContainer.append(previewPanel); if (!isMobile) previewContainer.append(livePreviewPanel); var previewTimer = null; var livePreviewIntervalId = -1; var livePreviewActive = false; // guards in-flight fetches after uncheck /** Rebuilds wikitext preview if its checkbox is checked. */ function schedulePreview() { if (!previewCheck.prop("checked")) return; clearTimeout(previewTimer); // Debounce: wait 400 ms after the last keystroke before rebuilding. previewTimer = setTimeout(function () { getWikitext(function (wikitext) { previewPanel.text(wikitext).show(); updatePanelLayout(); }); }, 400); } /** Fetches parsed HTML and populates the live preview panel. */ function loadLivePreview() { getWikitext(function (wikitext) { new mw.Api().parse(wikitext, { title: mw.config.get("wgPageName") }).done(function (html) { // Discard result if the user unchecked while the fetch was in flight. if (!livePreviewActive) return; livePreviewPanel.html(html).show(); updatePanelLayout(); }); }); } /** Adjusts panel widths depending on which previews are visible. */ function updatePanelLayout() { var wikitextVisible = previewCheck.prop("checked"); var liveVisible = livePreviewCheck && livePreviewCheck.prop("checked"); if (wikitextVisible && liveVisible) { // Side by side — each panel takes roughly half the available width. previewPanel.css({ "flex": "1 1 45%", "min-width": "280px" }); livePreviewPanel.css({ "flex": "1 1 45%", "min-width": "280px" }); } else { // Full width for whichever is visible — only touch panels that are // actually shown so that setting flex doesn't override display:none. if (wikitextVisible) previewPanel.css({ "flex": "1 1 100%", "min-width": "" }); if (liveVisible && livePreviewPanel) livePreviewPanel.css({ "flex": "1 1 100%", "min-width": "" }); } } previewCheck.on("change", function () { if ($(this).prop("checked")) { schedulePreview(); } else { clearTimeout(previewTimer); previewPanel.hide(); updatePanelLayout(); } }); if (!isMobile) { livePreviewCheck.on("change", function () { if ($(this).prop("checked")) { livePreviewActive = true; livePreviewPanel.show(); loadLivePreview(); livePreviewIntervalId = setInterval(loadLivePreview, 500); } else { livePreviewActive = false; clearInterval(livePreviewIntervalId); livePreviewIntervalId = -1; livePreviewPanel.hide().empty(); updatePanelLayout(); } }); } // Listen on all input/change events on the form and update both previews. startForm.on("input change", function () { schedulePreview(); }); footer.append($("<span style='margin-left:1em'></span>") .append(previewCheck).append(previewLabel)); if (!isMobile) { var livePreviewLabel = $("<label for='wiktku-live-preview-toggle'></label>") .text(" Pêşdîtina zindî"); footer.append($("<span style='margin-left:1em'></span>") .append(livePreviewCheck).append(livePreviewLabel)); } startForm.append(footer); $("#editform").hide().before(startForm); // Insert preview container (holds both panels) after the form. startForm.after(previewContainer); if (!isMobile) startForm.find("select").chosen(chosenOptions); refresh(); // Zimanan ji MediaWiki:Gadget-translation_editor.js/ziman.json bar bike. // Kodên ku bi "-pro" diqedin û navên ku "zimanê destan" tê de heye // tên derxistin. Zimanên xardkirî li serî dimînin, yên din // bi alfabeyê li dû wan tên. // Pinned choices come from MediaWiki:Gadget-start.js/data.json (langChoices), // already loaded into steps.lang.choices before build() runs. var pinnedChoices = steps.lang.choices.slice(); var pinnedCodes = $.map(pinnedChoices, function (choice) { return choice[0]; }); new mw.Api().get({ action: "query", prop: "revisions", titles: "MediaWiki:Gadget-translation_editor.js/ziman.json", rvprop: "content", rvslots: "main", formatversion: 2 }).then(function (data) { var page = data.query.pages[0]; var content = page && page.revisions && page.revisions[0].slots.main.content; var zimanData; try { zimanData = JSON.parse(content); } catch (e) { zimanData = {}; } var extraChoices = []; $.each(zimanData, function (code, name) { // Filter: skip proto-language codes and legendary/reconstructed langs. if (/-pro$/i.test(code)) return; if (/ziman[eê]\s+destan/i.test(name)) return; // Skip codes already in the pinned list (they are handled above). if (pinnedCodes.indexOf(code) !== -1) return; // sortKey: bare name without leading "zimanê " for sorting. var sortKey = name.replace(/^ziman[eê]\s+/i, ""); var choice = [code, name, sortKey]; extraChoices.push(choice); langsByCode[code] = choice; }); // Populate langsByCode for pinned choices too. $.each(pinnedChoices, function (i, choice) { // Ensure pinned choices have a sortKey (index 2). if (choice.length < 3) choice[2] = choice[1]; langsByCode[choice[0]] = choice; }); // Sort the extra choices alphabetically by sort key. extraChoices.sort(function (a, b) { return a[2].localeCompare(b[2], userLang); }); // Final list: pinned first, then the rest. var allChoices = pinnedChoices.concat(extraChoices); steps.lang.choices = allChoices; steps.trans.keys = allChoices; steps.dunde.keys = allChoices; steps.zarava.keys = getZaravaKeys(allChoices); var langMenu = $("#wiktku-start-lang-field"); populateMenus(langMenu, steps.lang.choices); langMenu.trigger("chosen:updated"); var transMenus = $("#wiktku-start-trans .wiktku-start-step-keyfield"); populateMenus(transMenus, steps.trans.keys, getDisabledKeys(steps.trans)); transMenus.trigger("chosen:updated"); var dundeMenus = $("#wiktku-start-dunde .wiktku-start-step-keyfield"); populateMenus(dundeMenus, steps.dunde.keys, getDisabledKeys(steps.dunde)); dundeMenus.trigger("chosen:updated"); var zaravaMenus = $("#wiktku-start-zarava .wiktku-start-step-keyfield"); populateMenus(zaravaMenus, steps.zarava.keys, getDisabledKeys(steps.zarava)); }); } mw.loader.using(["jquery.chosen", "mediawiki.api", "oojs-ui-core"], function () { if (!isMobile) { mw.notify( "Amûr dest pê dike, hinek bisekinin. Not: jkx Sentaks (sentaks highlighter) neaktîv bikin", { type: "info", tag: "wiktku-start-notice", autoHide: true, autoHideSeconds: 10 } ); } // Load metadata, langChoices, posChoices and tplDefs from the companion // data page so they can be updated without touching this script. new mw.Api().get({ action: "query", prop: "revisions", titles: "MediaWiki:Gadget-start.js/data.json", rvprop: "content", rvslots: "main", formatversion: 2 }).then(function (data) { var page = data.query.pages[0]; var content = page && page.revisions && page.revisions[0].slots.main.content; var d; try { d = JSON.parse(content); } catch (e) { d = {}; } // Populate metadata. if (d.metadata) $.extend(metadata, d.metadata); // Populate gender labels. if (d.genderLabels) $.extend(GENDER_BASE_LABELS, d.genderLabels); // Populate lang choices (pinned list used by build() → ziman.json loader). if (d.langChoices) steps.lang.choices = d.langChoices; // Populate POS choices. if (d.posChoices) steps.pos.choices = d.posChoices; // Populate template definitions for the dfn sense-block builder. if (d.tplDefs) steps.dfn.tplDefs = d.tplDefs; // Populate pos placeholder examples. if (d.posExamples) steps.dfn.posExamples = d.posExamples; // Populate citation template definitions for the quote widget. if (d.jederDefs) steps.dfn.jederDefs = d.jederDefs; // Populate pronunciation and etymology template insert lists. if (d.pronTpls) { steps.pron.pronTpls = d.pronTpls; steps.pron.refreshTplSelect(); } if (d.etymTpls) { steps.etym.etymTpls = d.etymTpls; steps.etym.refreshTplSelect(); } // Sync trans/dunde/zarava keys with the (now populated) lang choices. steps.trans.keys = steps.lang.choices; steps.dunde.keys = steps.lang.choices; steps.zarava.keys = getZaravaKeys(steps.lang.choices); }).always(build); }); }); //</nowiki> ltlun8s2gyg4zdhsg1dzpqhhkrj6dfp 6265575 6265573 2026-07-19T14:27:31Z Wikihez 7344 6265575 javascript text/javascript // Li ser [[vi:MediaWiki:Gadget-start.js]] hatiye refaktorkirin. //<nowiki> $(function () { if (window.location.href.includes("editintro=User:Wikihez/creation/intro")) { return; // Do not run the script wextê WF:Bilez dişuxile } var ns = mw.config.get("wgNamespaceNumber"); if (ns && !(ns === 2 && mw.config.get("wgPageName").match(/\/ceribandin$|\/test$/))) { return; } var action = mw.config.get("wgAction"); var pageExists = !!mw.config.get("wgArticleId"); // "Zimanek lê zêde bike" mode: triggered from the portlet link below. var addLangMode = pageExists && mw.util.getParamValue("wiktkuaddlang") === "1"; // On a normal page view of an existing page, add the portlet link if (action === "view" && pageExists) { var targetContainer; var skin = mw.config.get('skin'); if (skin === 'vector-2022') { targetContainer = 'p-cactions'; } else if (skin === 'vector') { targetContainer = 'p-tb'; } else { targetContainer = 'p-views'; } mw.util.addPortletLink(targetContainer, mw.util.getUrl(mw.config.get("wgPageName"), { action: "submit", wiktkuaddlang: "1" }), "+Ziman/beşeke din", "ca-wiktku-addlang", "Ji vê rûpelê re ziman an jî beşeke nû zêde bike"); return; } if (!(action === "edit" || action === "submit")) { return; } if (!addLangMode && !$(".mw-newarticletext, .mw-newarticletextanon").length) { return; } function capitalize(str) { if (!str) return str; return str[0].toUpperCase() + str.substr(1); } function decapitalize(str) { if (!str) return str; return str[0].toLowerCase() + str.substr(1); } function escapeRegExp(str) { return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); } function stripWikilinks(str) { return str.replace(/\[\[([^\]|]+)(?:\|([^\]]+))?\]\]/g, function (m, target, display) { return display || target; }); } function insertAtCursor(el, text) { var start = el.selectionStart; var end = el.selectionEnd; var val = el.value; el.value = val.slice(0, start) + text + val.slice(end); var pos = start + text.length; el.selectionStart = el.selectionEnd = pos; } var pageName = mw.config.get("wgPageName").replaceAll(/_/g, " "); if (ns) pageName = pageName.replace(/.*\//, ""); var pageNameRe = escapeRegExp(pageName); var userLang = mw.config.get("wgUserLanguage"); // Mobile detection: MobileFrontend sets wgMFMode, or fall back to touch check. var isMobile = !!mw.config.get("wgMFMode") || window.matchMedia("(pointer: coarse)").matches; var chosenOptions = { width: "20em", disable_search_threshold: 0, placeholder_text_single: "Yekî hilbijêre", placeholder_text_multiple: "Hilbijêre", no_results_text: "Nehat dîtin", enable_split_word_search: true, search_contains: true }; function wrapNativeSelect(select) { var placeholder = select.attr("data-placeholder") || "Lê bigere…"; // Hide the native select — we drive it programmatically. select.hide(); var wrapper = $("<span class='wiktku-native-select-wrap'></span>"); var textInput = $("<input type='search' autocomplete='off'>") .attr("placeholder", placeholder) .addClass("wiktku-start-narrow wiktku-ac-input"); var resultsList = $("<ul class='wiktku-ac-results'></ul>").hide(); // Full option cache — rebuilt when chosen:updated fires. var allOptions = []; function cacheOptions() { allOptions = []; select.find("option").each(function () { var v = $(this).val(); if (!v) return; // skip the empty placeholder option allOptions.push({ value: v, text: $(this).text(), disabled: $(this).prop("disabled") }); }); } cacheOptions(); function showResults(query) { var q = query.trim().toLowerCase(); resultsList.empty(); var matched; if (q) { matched = []; $.each(allOptions, function (_, o) { if (o.disabled) return; var codeMatch = o.value.toLowerCase().indexOf(q) !== -1; var nameMatch = o.text.toLowerCase().indexOf(q) !== -1; if (codeMatch || nameMatch) { matched.push({ opt: o, codeMatch: codeMatch }); } }); // Code matches (especially prefix matches) come first. matched.sort(function (a, b) { var aCode = a.opt.value.toLowerCase(); var bCode = b.opt.value.toLowerCase(); var aPrefix = aCode.indexOf(q) === 0; var bPrefix = bCode.indexOf(q) === 0; if (aPrefix !== bPrefix) return aPrefix ? -1 : 1; if (a.codeMatch !== b.codeMatch) return a.codeMatch ? -1 : 1; return 0; }); matched = matched.map(function (item) { return item.opt; }); } else { matched = allOptions.filter(function (o) { return !o.disabled; }); } if (!matched.length) { resultsList.hide(); return; } $.each(matched.slice(0, 50), function (_, opt) { var li = $("<li></li>").text(opt.text).attr("data-value", opt.value); // Use touchend instead of touchstart so that a scroll gesture does // not accidentally select an item. We track whether the finger moved // between touchstart and touchend — if it did, it was a scroll. var touchMoved = false; li.on("touchstart", function () { touchMoved = false; }); li.on("touchmove", function () { touchMoved = true; }); li.on("touchend", function (e) { if (touchMoved) return; // was a scroll, not a tap e.preventDefault(); selectOption(opt.value, opt.text); }); // Keep mousedown for desktop fallback. li.on("mousedown", function (e) { e.preventDefault(); selectOption(opt.value, opt.text); }); resultsList.append(li); }); // Position the list above or below depending on available viewport space. var inputRect = textInput[0].getBoundingClientRect(); var viewportH = window.innerHeight; var spaceBelow = viewportH - inputRect.bottom - 8; var spaceAbove = inputRect.top - 8; var maxH = Math.min(224, Math.max(spaceBelow, spaceAbove)); // 224px ≈ 14em resultsList.css({ "max-height": maxH + "px", "top": spaceBelow >= spaceAbove ? "100%" : "auto", "bottom": spaceBelow >= spaceAbove ? "auto" : "100%" }); resultsList.show(); } function selectOption(value, text) { textInput.val(text); select.val(value); resultsList.hide(); select.trigger("change"); } textInput.on("input focus", function () { showResults($(this).val()); }); textInput.on("blur", function () { // Short delay so a touchstart on a result item fires first. setTimeout(function () { resultsList.hide(); }, 200); }); // chosen:updated → re-cache (called after ziman.json loads). select.on("chosen:updated", function () { cacheOptions(); // If a value is already selected, keep the display text in sync. var cur = select.val(); if (cur) { var match = $.grep(allOptions, function (o) { return o.value === cur; })[0]; if (match) textInput.val(match.text); } }); // No-op .chosen() so desktop call-sites don't need guarding. select.chosen = function () { return select; }; wrapper.append(textInput).append(resultsList).append(select); return wrapper; } var langsByCode = {}; // Populated from [[MediaWiki:Gadget-start.js/data.json]] at runtime. var metadata = {}; // Zaravayên kurdî yên ku di beşa "Bi zaravayên din" de tên pêşkêşkirin — // ev kod ji beşa Werger têne derxistin daku heman zimên du caran neyê xwendin. var ZARAVA_LANG_CODES = ["ckb", "sdh", "lki", "hac", "zza"]; function getZaravaKeys(choices) { var byCode = {}; $.each(choices || [], function (_, c) { byCode[c[0]] = c; }); var result = []; $.each(ZARAVA_LANG_CODES, function (_, code) { if (byCode[code]) result.push(byCode[code]); }); return result; } function needsTransliteration(langCode) { var meta = metadata[langCode]; if (!meta || !meta.sc) return false; var scripts = Array.isArray(meta.sc) ? meta.sc : [meta.sc]; return scripts.length > 0 && scripts[0] !== "Latn"; } // Kodên cinsiyetê yên di metadata.g de — ji data.json tê dagirtin var GENDER_BASE_LABELS = {}; // Sub-lists that only make sense for a plain (non-şablon) sense — hidden // when a şablon (e.g. {{guharto|…}}) is chosen for that sense, since a // template-based sense has no "own" gloss for alternate forms, synonyms, // antonyms, coordinate terms, hypernyms or hyponyms to attach to. Etîket, // Nimûne and Jêgirtin stay visible either way. var HIDDEN_ON_TPL_GROUPS = [ "wiktku-dfn-alternativ", "wiktku-dfn-hevmane", "wiktku-dfn-dijmane", "wiktku-dfn-koordine", "wiktku-dfn-jornav", "wiktku-dfn-jernav" ]; function genderLabel(code) { if (code === "p") return "Pirjimar"; var pluralMatch = code.match(/^(.+)-p$/); if (pluralMatch && GENDER_BASE_LABELS[pluralMatch[1]]) { return GENDER_BASE_LABELS[pluralMatch[1]] + " (pirjimar)"; } return GENDER_BASE_LABELS[code] || code; } /** * True if a sense has any content worth keeping besides its mane text — * etîket, hevmane/dijmane/koordîne/etc. word lists, nimûne, or jêder * (quote). Used so a sense with an empty mane but filled-in extra * fields still gets emitted (with {{mane?}} standing in for the gloss) * instead of being silently dropped. */ function senseHasExtraContent(s) { if (s.etiket && $.grep(s.etiket, function (e) { return $.trim(e) !== ""; }).length) return true; if (s.kategorî && $.grep(s.kategorî, function (k) { return $.trim(k) !== ""; }).length) return true; if (s.alternativ.length || s.hevmane.length || s.dijmane.length || s.koordine.length || s.jornav.length || s.jernav.length) return true; if (s.nimune && $.grep(s.nimune, function (n) { return (typeof n === "object" ? n.text : n) !== ""; }).length > 0) return true; if (s.jeder && $.grep(s.jeder, function (j) { return j && j.quote; }).length > 0) return true; return false; } /** * formatNimune: each nimûne item can be { text, tr, t }: * text — example text * tr — transliteration (only when the language needs it) * t — Kurdish translation (third positional param, no key) */ function formatNimune(nimunes, lang, hasJeder) { var hasNimune = nimunes && $.grep(nimunes, function (n) { return (typeof n === "object" ? n.text : n) !== ""; }).length > 0; if (!hasNimune) { return hasJeder ? "" : "\n#* {{bênimûne|" + lang + "}}"; } return $.map(nimunes, function (n) { var text = typeof n === "object" ? n.text : n; if (!text) return undefined; var bolded = text.replace( new RegExp("(" + pageNameRe + "([^( |,|;|\\?|\\.|\\!)]+)?)", "ig"), "'''$1'''"); var tpl = "\n#: {{nm|" + lang + "|" + bolded; if (typeof n === "object") { if (n.tr) tpl += "|tr=" + n.tr; // Translation as third positional param (no key needed). if (n.t) tpl += "|" + n.t; } // Short examples fit on one line together with their translation. // rêz=1 is not used for ku — definitions are shown on separate lines there. if (text.length < 200 && lang !== "ku") tpl += "|rêz=1"; tpl += "}}"; return tpl; }).join(""); } /** * Formats a list of jêder (quote/citation) objects into wikitext lines. * Each entry that has no quote text is skipped. Returns "" when the list * is empty or every entry is blank. * * #* {{jêder-…|lang|jêgirtin=…|tr=…|tercime=…|…fields…}} * * When no template is chosen, the generic {{jêder|…}} template is used * instead. Its 2nd positional param is the user's freeform "bi destê xwe * binivîsim" source text when supplied, or the çavkanî? placeholder otherwise. * If that text contains "=" it is passed as |2=… instead of a bare * positional param, since MediaWiki would otherwise misparse it as its * own key=value pair and break the template: * #* {{jêder|lang|jêgirtin=…|tr=…|tercime=…|<manual source or çavkanî?>}} */ function formatJeder(jederList, lang) { if (!jederList || !jederList.length) return ""; return $.map(jederList, function (jeder) { if (!jeder || !jeder.quote) return undefined; if (jeder.jederTpl) { var cite = "\n#* {{" + jeder.jederTpl + "|" + lang; cite += "|jêgirtin=" + jeder.quote; if (jeder.quoteTr) cite += "|tr=" + jeder.quoteTr; if (jeder.quoteT) cite += "|tercime=" + jeder.quoteT; $.each(jeder.jêderFields || {}, function (key, val) { if (val) cite += "|" + key + "=" + val; }); cite += "}}"; return cite; } var out = "\n#* {{jêder|" + lang + "|jêgirtin=" + jeder.quote; if (jeder.quoteTr) out += "|tr=" + jeder.quoteTr; if (jeder.quoteT) out += "|tercime=" + jeder.quoteT; var srcParam = jeder.jederManual ? jeder.jederManual : "çavkanî?"; // A positional param containing "=" gets parsed as its own key=value // pair by MediaWiki and breaks the template, so force it to be // explicitly named (|2=) whenever that's the case. out += (srcParam.indexOf("=") !== -1 ? "|2=" : "|") + srcParam; out += "}}"; return out; }).join(""); } function makeWordListStep(id, name, question_fmt, header, templateName) { return { id: id, name: name, question_fmt: question_fmt, multiple: true, narrow: true, visible: function (values) { return values.lang && values.pos; }, output: function (values) { var words = $.grep(values[id] || [], function (w) { return !!w; }); if (!words.length) return ""; var lang = values.lang; var section = "\n==== " + header + " ====\n"; if (words.length === 1) { // Single word — keep the simple inline template. return section + "* {{" + templateName + "|" + lang + "|" + words[0] + "}}\n"; } // Multiple words — use {{kol3}} with one positional param per word. var params = "cure=" + header + "\n" + $.map(words, function (w) { return "|" + w; }).join("\n"); return section + "{{kol3|" + lang + "|" + params + "\n}}\n"; } }; } var steps = { lang: { id: "lang", required: true, name: "ziman", question_fmt: '"' + pageName + '" bi çi zimanî ye?', question_br: true, // Populated from [[MediaWiki:Gadget-start.js/data.json]] (langChoices). choices: [], output: function (values) { return "== {{ziman|" + values.lang + "}} ==\n"; } }, pron: { id: "pron", name: "bilêvkirin", question_fmt: '"' + pageName + '" çawa tê telafûzkirin?', // pronTpls populated from data.json pronTpls: [], visible: function (values) { if (!values.lang) return false; // In addLangMode, only skip pron when this langcode's section // already exists in the page — if it's a new language, show it. if (addLangMode) { var existing = $("#wpTextbox1").val() || ""; var header = "== {{ziman|" + values.lang + "}} =="; return existing.indexOf(header) === -1; } return true; }, /** Fills (or refills) the insert-dropdown from the current pronTpls array, filtering by language. */ refreshTplSelect: function () { var sel = $("#wiktku-start-pron .wiktku-tpl-insert-select"); if (!sel.length) return; var lang = getValues().lang || ""; sel.find("option[value!='']").remove(); $.each(steps.pron.pronTpls, function (_, tpl) { // Filter: if tpl.langs exists, only show if lang is in that list; otherwise show always var allowed = !tpl.langs || tpl.langs.indexOf(lang) !== -1; if (allowed) { sel.append($("<option></option>") .val(tpl.snippet) .text(tpl.name + " — " + tpl.desc) .attr("data-nolang", tpl.noLang ? "1" : "")); } }); // Notify Chosen that the option list has changed (no-op on mobile). if (!isMobile) sel.trigger("chosen:updated"); }, build: function (stepDiv) { if (stepDiv.find(".wiktku-pron-wrap").length) return null; var wrap = $("<div class='wiktku-pron-wrap'></div>"); var ta = $("<textarea></textarea>") .attr("name", "wiktku-pron-" + $.now()) .attr("class", "wiktku-start-step-field wiktku-pron-text") .attr("rows", 4) .attr("placeholder", "Nimûne: {{IPA|ku|/pɛɪ̯n/}} yan {{kîte|ku|he|ce|ki|rin}}"); // Template insert dropdown — filtered by language. var sel = $("<select class='wiktku-tpl-insert-select'></select>"); sel.append($("<option value=''>— şablonek lê zêde bike —</option>")); var lang = getValues().lang || ""; $.each(steps.pron.pronTpls, function (_, tpl) { // Filter: if tpl.langs exists, only show if lang is in that list; otherwise show always var allowed = !tpl.langs || tpl.langs.indexOf(lang) !== -1; if (allowed) { sel.append($("<option></option>") .val(tpl.snippet) .text(tpl.name + " — " + tpl.desc) .attr("data-nolang", tpl.noLang ? "1" : "")); } }); sel.on("change", function () { var snippet = $(this).val(); if (!snippet) return; var lang = getValues().lang || ""; // Check if the selected option has noLang flag var selectedOption = sel.find("option:selected"); var hasNoLang = selectedOption.attr("data-nolang") === "1"; if (!hasNoLang) { snippet = snippet.replace(/CODE/g, lang).replace(/SOURCELANG/g, "?"); } insertAtCursor(ta[0], snippet); $(this).val(""); ta.focus(); }); wrap.append(sel).append($("<br>")).append(ta); stepDiv.append(wrap); return ta; }, output: function () { var text = $.trim($("#wiktku-start-pron .wiktku-pron-text").val()); if (!text) return ""; var lines = text.split("\n"); var out = $.map(lines, function (line) { line = $.trim(line); if (!line) return undefined; return line.charAt(0) === "*" ? line : "* " + line; }).join("\n"); return "\n=== Bilêvkirin ===\n" + out + "\n"; } }, pos: { id: "pos", required: true, name: "Cureyê rêzimanî", question_fmt: 'Cureyê rêzimanî yê "' + pageName + '" çi ye?', visible: function (values) { return values.lang; }, question_br: true, // Populated from [[MediaWiki:Gadget-start.js/data.json]] (posChoices). choices: [], output: function (values) { var pos = values.pos || ""; var cinsiyet = values.cinsiyet || ""; // from the cinsiyet step var lekTur = values.lektur || ""; // from the lêker transitivity step var capitalizedPos = capitalize(pos); var outputString = "\n=== " + capitalizedPos + " ===\n"; // Add ku-tewîn-nav for single-word navdêr/serenav with known gender. if (!pageName.includes(" ") && cinsiyet && GENDER_BASE_LABELS[cinsiyet] && (pos === "navdêr" || pos === "serenav") && values.lang === "ku") { outputString += "{{ku-tewîn-nav|" + pageName + "|" + GENDER_BASE_LABELS[cinsiyet]; if (pos === "serenav") outputString += "|y"; outputString += "}}\n"; } outputString += "{{" + pos + "|" + values.lang; if (pos === "navdêr" || pos === "serenav") { if (cinsiyet) { outputString += "|c=" + cinsiyet; } else if (values.lang === "ku") { // Unknown gender — prompt editor to fill it in. outputString += "|c=?"; } } else if (/^lêker/.test(pos) && lekTur) { outputString += "|c=" + lekTur; } if (values.tr) { outputString += "|tr=" + values.tr; } outputString += "}}\n"; return outputString; } }, /** * cinsiyet (grammatical gender) — only shown for navdêr/serenav, û * tenê ger metadata ji bo zimanê hilbijartî lîsteyeke "g" (cinsiyet) * were dayîn. Opsiyonên vê gavê ne sabît in — ji metadata[values.lang].g * têne çêkirin, ji ber ku di hemû zimanan de cinsiyet tine. */ cinsiyet: { id: "cinsiyet", name: "cinsiyet", question_fmt: 'Cinsiyeta "' + pageName + '" çi ye?', question_br: true, visible: function (values) { var meta = metadata[values.lang]; return !!(values.lang && (values.pos === "navdêr" || values.pos === "serenav") && meta && meta.g && meta.g.length); }, build: function (stepDiv, values) { var select = stepDiv.find("select.wiktku-start-step-field"); if (!select.length) { select = $(mw.html.element("select", { "class": "wiktku-start-step-field", id: "wiktku-start-cinsiyet-field" })); stepDiv.append(select); } if (!values) return select; var meta = metadata[values.lang]; var codes = (meta && meta.g) || []; var prevVal = select.val(); var choices = $.map(codes, function (code) { return [[code, genderLabel(code)]]; }); populateMenus(select, choices); if ($.grep(choices, function (c) { return c[0] === prevVal; }).length) { select.val(prevVal); } if (!isMobile) select.trigger("chosen:updated"); return select; }, output: function () { return ""; } // consumed by pos.output }, /** * Lêker transitivity — only shown for any lêker variant. */ lektur: { id: "lektur", name: "Cureyê lêkerê (fiîlê)", question_fmt: "Cureyê lêkerê (fiîlê) çi ye?", question_br: true, visible: function (values) { return values.lang && values.pos && /^lêker/.test(values.pos); }, // Dictionary: value → display label. Add new types here. choices: [ ["gh", "gerguhêz"], ['x-gh', 'xwerû-gerguhêz'], ['p-gh', 'pêkhatî-gerguhêz'], ['h-gh', 'hevedudanî-gerguhêz'], ['b-gh', 'biwêjî-gerguhêz'], ["ngh", "negerguhêz"], ['x-ngh', 'xwerû-negerguhêz'], ['p-ngh', 'pêkhatî-negerguhêz'], ['h-ngh', 'hevedudanî-negerguhêz'], ['b-ngh', 'biwêjî-negerguhêz'] ], output: function () { return ""; } // consumed by pos.output }, tr: { id: "tr", name: "transkrîpsiyon", question_fmt: "Transkrîpsiyona kelîmeyê", multiple: false, narrow: true, visible: function (values) { return values.lang && values.pos && needsTransliteration(values.lang); } }, dfn: { id: "dfn", // required: true, ger mane tinebe [[Şablon:mane?]] bi kar bîne name: "Mane", question_fmt: "Maneya kelîmeyê binivîse. Mane otomatîk tê lînkkirin! Ji bo tercimeyan beşa 'Werger' bi kar bîne!", multiple: true, ordered: true, rows: 3, visible: function (values) { return values.lang && values.pos; }, example: function (values) { // posExamples loaded from [[MediaWiki:Gadget-start.js/data.json]]. var examples = steps.dfn.posExamples || {}; var full = values.pos || ""; return examples[full] || ""; }, /** * Builds one sense block (<li>) inside the ordered list. * Each block contains: * - a textarea for the definition * - an expandable nimûne list * - single-row sub-lists for formên alternatîv, hevmane, dijmane */ buildSenseBlock: function (stepDiv) { var block = $("<li class='wiktku-dfn-sense'></li>"); // — Mane textarea (declared first so the template handler can reference it) — var dfnArea = $("<textarea></textarea>") .attr("name", "wiktku-dfn-mane-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("class", "wiktku-start-step-field wiktku-dfn-mane") .attr("rows", 6) .attr("placeholder", "Mane…"); dfnArea.on("input", function () { steps.dfn.onDfnInput(stepDiv, block, this); }); // — Template selector (optional — replaces mane when chosen) — // Template definitions loaded from [[MediaWiki:Gadget-start.js/data.json]]. var tplDefs = steps.dfn.tplDefs || []; // Cache of all non-placeholder option elements — used by updateTplOptions // to remove/re-add options (the only approach compatible with Chosen.js). var _allTplOptions = []; var tplSelect = $(mw.html.element("select", { "class": "wiktku-dfn-tpl-select" })); tplSelect.append($("<option value=''>— yan jî şablonek hilbijêre —</option>")); $.each(tplDefs, function (_, tpl) { var opt = $("<option></option>") .val(tpl.name) .text(tpl.name) .attr("data-langs", tpl.langs ? tpl.langs.join(",") : "") .attr("data-nolang", tpl.noLang ? "1" : ""); tplSelect.append(opt); _allTplOptions.push(opt[0]); }); function updateTplOptions() { var lang = getValues().lang || ""; var currentVal = tplSelect.val(); var currentStillValid = false; // Detach all non-placeholder options, then re-attach only the visible ones. // This is the only approach that works correctly with both native <select> // and Chosen.js on desktop. tplSelect.find("option[value!='']").detach(); $.each(_allTplOptions, function (_, opt) { var allowed = $(opt).attr("data-langs"); var visible = !allowed || allowed.split(",").indexOf(lang) !== -1; if (visible) { tplSelect.append(opt); if ($(opt).val() === currentVal) currentStillValid = true; } }); if (!isMobile) tplSelect.trigger("chosen:updated"); if (currentVal && !currentStillValid) { tplSelect.val(""); dfnArea.show(); tplTitleInput.hide().val(""); } } // Store updater on the element so refresh() can call it for all blocks. tplSelect.data("updateOptions", updateTplOptions); var tplTitleInput = $("<input type='text'>") .addClass("wiktku-dfn-tpl-title wiktku-start-narrow") .attr("placeholder", "Navê rûpelê…") .hide(); // Grow the sense list when the title field of the last block gets content, // mirroring what onDfnInput does for the plain mane textarea. tplTitleInput.on("input", function () { steps.dfn.onDfnInput(stepDiv, block, this); }); /** * When a şablon sense is chosen, formên alternatîv/hevmane/dijmane/ * termên koordîne/jornav/jêrnav don't apply (there's no plain gloss * to hang them off), so hide those subgroups. Etîket, Nimûne and * Jêgirtin stay visible and still usable for a şablon sense. */ function updateFieldVisibility() { var isTpl = !!tplSelect.val(); $.each(HIDDEN_ON_TPL_GROUPS, function (_, cls) { block.find("." + cls + "-group").toggle(!isTpl); }); } // Store on the block so restoreDfn() can re-sync visibility // after programmatically setting tplSelect's value. block.data("updateFieldVisibility", updateFieldVisibility); tplSelect.on("change", function () { var chosen = $(this).val(); if (chosen) { dfnArea.hide(); tplTitleInput.show().focus(); } else { dfnArea.show(); tplTitleInput.hide().val(""); } updateFieldVisibility(); // Re-run refresh so the Werger step visibility updates. refresh(); }); var tplRow = $("<div></div>").addClass("wiktku-dfn-tpl-row") .append(tplSelect).append(" ").append(tplTitleInput); block.append(tplRow); block.append(dfnArea); // Apply lang filter on initial build. updateTplOptions(); // — Sub-field groups — // All groups are always visible with a placeholder textarea. // Nimûne is last in the DOM and last in the output. var allGroups = [ { cls: "wiktku-dfn-etiket", label: "Etîket", rows: 1, narrow: true, izah: "xisûsen, Mêrdîn, anatomî, Badînî" }, { cls: "wiktku-dfn-kategorî", label: "Kategorî", rows: 1, narrow: true, izah: "Kategoriya ku ev mane lê tê zêdekirin" }, { cls: "wiktku-dfn-alternativ", label: "Formên alternatîv", rows: 1, narrow: true, izah: "Varyantên vê kelîmeyê" }, { cls: "wiktku-dfn-hevmane", label: "Hevmane", rows: 1, narrow: true, izah: "Spehî hevmaneya Bedew e." }, { cls: "wiktku-dfn-dijmane", label: "Dijmane", rows: 1, narrow: true, izah: "Zengîn dijmaneya feqîr e." }, { cls: "wiktku-dfn-koordine", label: "Termên koordîne", rows: 1, narrow: true, izah: "Pisîk û kûçik termên koordîne ne çunkî Jornavên wan gelek in" }, { cls: "wiktku-dfn-jornav", label: "Jornav", rows: 1, narrow: true, izah: "Heywan jornavê guhandar e" }, { cls: "wiktku-dfn-jernav", label: "Jêrnav", rows: 1, narrow: true, izah: "Guhandar jêrnavê heywan e" }, { cls: "wiktku-dfn-nimune", label: "Nimûne", rows: 2, narrow: false } ]; $.each(allGroups, function (_, g) { var groupDiv = $("<div></div>").addClass("wiktku-dfn-subgroup " + g.cls + "-group"); function buildNimuneLi() { var lang = getValues().lang || ""; var li = $("<li></li>").addClass("wiktku-dfn-nimune-li"); var mainTa = $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-text-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", g.rows) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-text") .attr("placeholder", "Nimûneya emilandina kelîmeyê tu bi xwe binivîse…"); mainTa.on("input", function () { var val = $.trim($(this).val()); var isLast = li.is(list.children("li:last-child")); if (val && isLast) { list.append(buildNimuneLi()); } }); li.append(mainTa); var subWrap = $("<div></div>").addClass("wiktku-dfn-nimune-sub"); if (needsTransliteration(lang)) { subWrap.append( $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-tr-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 5) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-tr") .attr("placeholder", "Transkrîpsiyona bi alfabeya latînî") ); } if (lang && lang !== "ku") { subWrap.append( $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-t-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 5) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-t") .attr("placeholder", "Tercimeya kurmancî") ); } if (subWrap.children().length) li.append(subWrap); return li; } if (g.cls === "wiktku-dfn-nimune") { // Nimûne — compound widget with tr/t sub-fields. var lbl = $("<span></span>").addClass("wiktku-dfn-sublabel").text(g.label + ": "); var list = $("<ol></ol>").addClass("wiktku-dfn-sublist " + g.cls + "-list"); groupDiv.data("buildNimuneLi", buildNimuneLi); list.append(buildNimuneLi()); groupDiv.append(lbl).append(list); block.append(groupDiv); } else { // Regular always-visible group — label + growing textarea list. var lbl = $("<span></span>").addClass("wiktku-dfn-sublabel").text(g.label + ": " + g.izah); var list = $("<ol></ol>").addClass("wiktku-dfn-sublist " + g.cls + "-list"); var firstInput = $("<textarea></textarea>") .attr("name", g.cls + "-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", g.rows) .attr("class", "wiktku-dfn-subfield" + (g.narrow ? " wiktku-start-narrow" : "")) .attr("placeholder", g.label + "…"); firstInput.on("input", function () { steps.dfn.onSubInput(list, this, g.rows, g.narrow); }); list.append($("<li></li>").append(firstInput)); groupDiv.append(lbl).append(list); block.append(groupDiv); } }); // — Jêder (quote / citation) group — a growing list, sibling to Nimûne — // Structured the same way as Nimûne (ol.wiktku-dfn-sublist > li) so it // lines up at the same indentation, and so that typing into the last // citation's Jêgirtin box automatically opens a fresh empty one below it. (function () { var jederGroupDiv = $("<div></div>").addClass("wiktku-dfn-subgroup wiktku-dfn-jeder-group"); var jederLbl = $("<span></span>").addClass("wiktku-dfn-sublabel").text("Jêgirtin: "); var jederList = $("<ol></ol>").addClass("wiktku-dfn-sublist wiktku-dfn-jeder-list"); function buildJederLi() { var lang = getValues().lang || ""; var li = $("<li></li>").addClass("wiktku-dfn-jeder-li"); var dragHandle = $("<span></span>") .addClass("wiktku-jeder-drag-handle") .attr("title", "Bişkûne û bikişîne da ku rêzê biguhezîne"); // Quote text textarea var quoteTa = $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-quote-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 2) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-quote") .attr("placeholder", "Nimûneya emilandinê ji kitêb an çavkaniyeke din binivîse"); quoteTa.on("input", function () { var val = $.trim($(this).val()); var isLast = li.is(jederList.children("li:last-child")); if (val && isLast) { jederList.append(buildJederLi()); } }); li.append(dragHandle).append(quoteTa); // tr/t sub-fields for the quote — shown as needed for the language. var quoteSubWrap = $("<div></div>").addClass("wiktku-dfn-quote-sub"); if (needsTransliteration(lang)) { quoteSubWrap.append( $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-quote-tr-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 2) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-quote-tr") .attr("placeholder", "Transkrîpsiyona jêgirtinê…") ); } if (lang && lang !== "ku") { quoteSubWrap.append( $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-quote-t-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 2) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-quote-t") .attr("placeholder", "Tercimeya jêgirtinê bi kurmancî") ); } if (quoteSubWrap.children().length) li.append(quoteSubWrap); // Citoid auto-fill: fetch citation data from a URL, DOI or ISBN and // prefill the source şablon + fields below (see Gadget-citoid-helper.js). var citoidWrap = $("<div></div>").addClass("wiktku-dfn-quote-citoid"); var citoidInput = $("<input type='text'>") .addClass("wiktku-dfn-quote-citoid-input wiktku-start-narrow") .attr("placeholder", "URL, DOI an ISBN binivîse ku otomatîk were tijekirin…"); var citoidBtn = new OO.ui.ButtonWidget({ label: "Bi Citoid bîne", classes: [ "wiktku-dfn-quote-citoid-btn" ] }); var citoidStatus = $("<span></span>").addClass("wiktku-dfn-quote-citoid-status"); /** * Fetches citation data from Citoid and applies it to this * citation's şablon selector + fields. Mirrors the logic in * Form.prototype._fillFromCitoid (Gadget-wikt.add-examples.js): * - only (re)selects the şablon when it actually differs from * what's already chosen, so a repeat fetch doesn't wipe out * a template the user already picked; * - only fills fields that are currently empty, so it never * overwrites something the user typed by hand; * - falls back to the freeform "bi destê xwe binivîsim" source * only when nothing was typed there yet. */ function runCitoidFetch() { var query = $.trim(citoidInput.val()); if (!query) { mw.notify("Ji kerema xwe re pêşî URL, DOI an ISBNyekê binivîse."); return; } citoidBtn.setDisabled(true); citoidStatus.text("Tê anîn…"); wikt.citoidHelper.ensure().then(function () { return wikt.citoid.fetchJederFields(query); }).then(function (result) { var jederKey = result.jederKey; var hasTpl = !!jederKey && srcSel.find("option[value='" + jederKey + "']").length > 0; var targetVal = hasTpl ? jederKey : "__manual__"; // Only (re)select — and thus rebuild — the field rows if // we're switching to a different şablon than what's // already chosen, so a second fetch doesn't clear fields // the user already filled in by hand. if (srcSel.val() !== targetVal) { srcSel.val(targetVal).trigger("change"); srcSel.trigger("chosen:updated"); } if (hasTpl) { // Tenê qadên vala tijî bike. $.each(result.fields, function (key, val) { var input = srcFields.find("[data-field-key='" + key + "']"); if (input.length && !$.trim(input.val())) { input.val(val); } }); } else { // Şablonek nehat naskirin ji bo vê itemType — rêzikeke // çavkaniyê ya bi destan a ji qadên Citoid tê çêkirin, // lê tenê ger qada destan vala be. var manualField = srcFields.find(".wiktku-dfn-quote-src-manual"); if (!$.trim(manualField.val())) { var parts = []; $.each(["nivîskar", "sernav", "websîte", "kovar", "weşanxane", "sal", "url"], function (_, k) { if (result.fields[k]) parts.push(result.fields[k]); }); manualField.val(parts.join(", ")); } } citoidStatus.text(""); }, function (errorMsg) { citoidStatus.text(typeof errorMsg === "string" ? errorMsg : "Nehat dîtin. Kontrol bike ka URL/DOI/ISBN rast e."); }).always(function () { citoidBtn.setDisabled(false); }); } citoidBtn.on("click", runCitoidFetch); citoidInput.on("keydown", function (e) { if (e.which === 13) { // Enter e.preventDefault(); runCitoidFetch(); } }); citoidWrap.append(citoidInput).append(citoidBtn.$element).append(citoidStatus); // Source template selector, specific to this citation. var srcSel = $("<select></select>").addClass("wiktku-dfn-quote-src-sel"); srcSel.append($("<option value=''>— Çavkaniyê hilbijêre —</option>")); srcSel.append($("<option></option>").val("__manual__").text("Bi destê xwe binivîsim")); var jederDefs = steps.dfn.jederDefs || {}; $.each(jederDefs, function (tplName, def) { srcSel.append($("<option></option>").val(tplName).text(def.label)); }); // Dynamic source fields container. var srcFields = $("<div></div>").addClass("wiktku-dfn-quote-src-fields"); srcSel.on("change", function () { srcFields.empty(); var chosen = $(this).val(); if (!chosen) return; if (chosen === "__manual__") { // Freeform source, written by the user — becomes the 2nd // positional param of {{jêder|lang|…}} instead of çavkanî?. srcFields.append( $("<textarea></textarea>") .attr("rows", 4) .addClass("wiktku-dfn-subfield wiktku-dfn-quote-src-manual") .attr("placeholder", "Çavkaniyê bi destê xwe binivîse…") ); return; } var def = (steps.dfn.jederDefs || {})[chosen]; if (!def) return; $.each(def.fields, function (_, f) { var row = $("<div></div>").addClass("wiktku-dfn-quote-src-row"); var fieldLbl = $("<label></label>").text(f.label + ": "); var inp = $("<textarea></textarea>") .attr("rows", 2) .addClass("wiktku-dfn-quote-src-input wiktku-start-narrow") .attr("data-field-key", f.key) .attr("placeholder", f.label + "…"); row.append(fieldLbl).append(inp); srcFields.append(row); }); }); li.append(citoidWrap).append(srcSel).append(srcFields); return li; } jederGroupDiv.data("buildJederLi", buildJederLi); jederList.append(buildJederLi()); // Make citation rows sortable (drag to reorder). // The last row is always the empty trailing row — cancel its drag. mw.loader.using("jquery.ui.sortable", function () { jederList.sortable({ handle: ".wiktku-jeder-drag-handle", axis: "y", items: "li:not(:last-child)", tolerance: "pointer" }); }); jederGroupDiv.append(jederLbl).append(jederList); block.append(jederGroupDiv); }()); // Apply the initial hide/show state for the sub-groups (matches // tplSelect's starting value, which is normally empty). updateFieldVisibility(); return block; }, /** Grows the sense list when the last mane textarea gets content. */ onDfnInput: function (stepDiv, block, textarea) { var val = $.trim($(textarea).val()); var list = stepDiv.find("ol.wiktku-dfn-list"); var isLast = block.is(list.children("li:last-child")); if (val && isLast) { var newBlock = steps.dfn.buildSenseBlock(stepDiv); list.append(newBlock); // Apply Chosen to the new block's template selector on desktop. if (!isMobile) newBlock.find("select.wiktku-dfn-tpl-select").chosen(chosenOptions); } refresh(); }, /** Grows a sub-list (nimûne/formên alternatîv/hevmane/dijmane/termên koordîne) on input. */ onSubInput: function (list, input, rows, narrow) { var val = $.trim($(input).val()); var item = $(input).parent(); var isLast = item.is(list.children("li:last-child")); if (val && isLast) { var next = $("<textarea></textarea>") .attr("name", "wiktku-dfn-sub-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", rows) .attr("class", "wiktku-dfn-subfield" + (narrow ? " wiktku-start-narrow" : "")); next.on("input", function () { steps.dfn.onSubInput(list, this, rows, narrow); }); list.append($("<li></li>").append(next)); } }, // Populated from [[MediaWiki:Gadget-start.js/data.json]] (tplDefs, posExamples, jederDefs). tplDefs: [], posExamples: {}, jederDefs: {}, build: function (stepDiv) { if (stepDiv.find("ol.wiktku-dfn-list").length) return null; var list = $("<ol class='wiktku-dfn-list'></ol>"); list.append(steps.dfn.buildSenseBlock(stepDiv)); stepDiv.append(list); return null; }, /** Reads all sense blocks from the DOM and returns an array of sense objects. */ getSenses: function (stepDiv) { var senses = []; stepDiv.find("li.wiktku-dfn-sense").each(function () { var block = $(this); var tplSel = block.find("select.wiktku-dfn-tpl-select"); var tpl = tplSel.val() || ""; // noLang: template already encodes the language — don't add |lang| param. var tplNoLang = tpl ? tplSel.find("option[value='" + tpl + "']").attr("data-nolang") === "1" : false; var tplTitle = $.trim(block.find("input.wiktku-dfn-tpl-title").val()); var mane = $.trim(block.find("textarea.wiktku-dfn-mane").val()); var etiket = (function () { var vals = []; block.find(".wiktku-dfn-etiket-list textarea").each(function () { var v = $.trim($(this).val()); if (v) vals.push(v); }); return vals; }()); var kategorî = (function () { var vals = []; block.find(".wiktku-dfn-kategorî-list textarea").each(function () { var v = $.trim($(this).val()); if (v) vals.push(v); }); return vals; }()); function readList(cls) { var vals = []; block.find("." + cls + "-list textarea").each(function () { var v = $.trim($(this).val()); if (v) vals.push(v); }); return vals; } // Nimûne items are compound: { text, tr?, t? } function readNimuneList() { var items = []; block.find(".wiktku-dfn-nimune-list li.wiktku-dfn-nimune-li").each(function () { var text = $.trim($(this).find(".wiktku-dfn-nimune-text").val()); if (!text) return; var obj = { text: text }; var tr = $.trim($(this).find(".wiktku-dfn-nimune-tr").val()); var t = $.trim($(this).find(".wiktku-dfn-nimune-t").val()); if (tr) obj.tr = tr; if (t) obj.t = t; items.push(obj); }); return items; } // Jêder is a growing list of citations, one per li — mirrors readNimuneList(). function readJederList() { var items = []; block.find(".wiktku-dfn-jeder-list li.wiktku-dfn-jeder-li").each(function () { var li = $(this); var quote = $.trim(li.find(".wiktku-dfn-nimune-quote").val()); if (!quote) return; var obj = { quote: quote }; var qtr = $.trim(li.find(".wiktku-dfn-nimune-quote-tr").val()); var qt = $.trim(li.find(".wiktku-dfn-nimune-quote-t").val()); if (qtr) obj.quoteTr = qtr; if (qt) obj.quoteT = qt; var tplName = li.find(".wiktku-dfn-quote-src-sel").val(); if (tplName === "__manual__") { var manual = $.trim(li.find(".wiktku-dfn-quote-src-manual").val()); if (manual) obj.jederManual = manual; } else if (tplName) { obj.jederTpl = tplName; var fields = {}; li.find(".wiktku-dfn-quote-src-input").each(function () { var k = $(this).attr("data-field-key"); var v = $.trim($(this).val()); if (k && v) fields[k] = v; }); obj.jêderFields = fields; } items.push(obj); }); return items; } senses.push({ tpl: tpl, tplNoLang: tplNoLang, tplTitle: tplTitle, mane: mane, etiket: etiket, kategorî: kategorî, nimune: readNimuneList(), jeder: readJederList(), alternativ: readList("wiktku-dfn-alternativ"), hevmane: readList("wiktku-dfn-hevmane"), dijmane: readList("wiktku-dfn-dijmane"), koordine: readList("wiktku-dfn-koordine"), jornav: readList("wiktku-dfn-jornav"), jernav: readList("wiktku-dfn-jernav") }); }); return senses; }, getOutput: function (values, callback) { var stepDiv = $("#wiktku-start-dfn"); var senses = steps.dfn.getSenses(stepDiv); var lang = values.lang; // A sense counts as "filled" if it has a mane, a chosen template + title, // or any other content (etîket/hevmane/nimûne/jêder…) worth keeping. var hasMane = senses.some(function (s) { return s.mane !== "" || (s.tpl && s.tplTitle) || senseHasExtraContent(s); }); // True only when at least one sense has a regular mane (needs linkify). var hasRegularMane = senses.some(function (s) { return !s.tpl && s.mane !== ""; }); // nimûne and jêder lines must never pass through linkify — only // the plain mane text should be linkified. We build two parallel // arrays: defLines (sent to linkify) and citeLines (kept aside). // Each entry in citeLines corresponds 1-to-1 with a defLines entry; // a template token {{wiktku-cite-N}} is embedded in defLines so // that after linkify runs we know exactly where to splice them back. // Template-call syntax is guaranteed safe: linkifiers leave {{ }} // tokens completely untouched. var defLines = []; // one entry per kept sense (goes to linkify) var citeLines = []; // parallel — nimûne+jêder for that same sense $.each(senses, function (_, sense) { // — Template sense (e.g. {{guharto|ku|somepage}}) — if (sense.tpl) { if (!sense.tplTitle) return; // skip empty template senses var tplKatTpl = ""; if (sense.kategorî && sense.kategorî.length) { var tplKatParts = sense.kategorî.map(function (k) { return $.trim(k); }) .filter(function (k) { return k !== ""; }); if (tplKatParts.length) { tplKatTpl = "\n#: {{K|" + lang + "|" + tplKatParts.join("|") + "}}"; } } var tplLabelTpl = ""; if (sense.etiket && sense.etiket.length) { var tplLabelParts = sense.etiket.map(function (part) { return $.trim(part); }).filter(function (part) { return part !== ""; }); if (tplLabelParts.length) { tplLabelTpl = " {{e|" + lang + "|" + tplLabelParts.join("|") + "}} "; } } var tplCall = sense.tplNoLang ? "{{" + sense.tpl + "|" + sense.tplTitle + "}}" : "{{" + sense.tpl + "|" + lang + "|" + sense.tplTitle + "}}"; var tplHasJeder = sense.jeder && $.grep(sense.jeder, function (j) { return j && j.quote; }).length > 0; var idx = defLines.length; var cite = formatNimune(sense.nimune, lang, tplHasJeder) + formatJeder(sense.jeder, lang); defLines.push("#" + (tplLabelTpl ? tplLabelTpl : " ") + tplCall + tplKatTpl + (cite ? "{{wiktku-cite-" + idx + "}}" : "")); citeLines.push(cite); return; } // — Normal mane sense — var dfn = sense.mane; if (!dfn && !senseHasExtraContent(sense)) return; // truly empty if (dfn) { dfn = stripWikilinks(dfn); if (dfn[0] !== dfn[0].toUpperCase()) dfn = capitalize(dfn); if (!dfn.match(/[.…?!)\]]$/)) dfn += "."; } else { dfn = "{{mane?|" + lang + "}}"; } var katTpl = ""; if (sense.kategorî && sense.kategorî.length) { var katParts = sense.kategorî.map(function (k) { return $.trim(k); }) .filter(function (k) { return k !== ""; }); if (katParts.length) { katTpl = "\n#: {{K|" + lang + "|" + katParts.join("|") + "}}"; } } var labelTpl = ""; if (sense.etiket && sense.etiket.length) { var labelParts = sense.etiket.map(function (part) { return $.trim(part); }).filter(function (part) { return part !== ""; }); if (labelParts.length) { labelTpl = " {{e|" + lang + "|" + labelParts.join("|") + "}} "; } } var out = "#" + (labelTpl ? labelTpl : " ") + dfn; out += katTpl; function wordLine(tpl, words) { if (!words.length) return ""; return "\n#: {{" + tpl + "|" + lang + "|" + words.join("|") + "}}"; } out += wordLine("alt-r", sense.alternativ); out += wordLine("hevmane", sense.hevmane); out += wordLine("dijmane", sense.dijmane); out += wordLine("koordîne", sense.koordine); out += wordLine("jornav", sense.jornav); out += wordLine("jêrnav", sense.jernav); var hasJeder = sense.jeder && $.grep(sense.jeder, function (j) { return j && j.quote; }).length > 0; var cite = formatNimune(sense.nimune, lang, hasJeder) + formatJeder(sense.jeder, lang); var idx = defLines.length; defLines.push(out + (cite ? "{{wiktku-cite-" + idx + "}}" : "")); citeLines.push(cite); }); // Splice citeLines back into a linkified string, replacing each // {{wiktku-cite-N}} token with its stored nimûne/jêder block. function restoreCites(t) { return t.replace(/\{\{wiktku-cite-(\d+)\}\}/g, function (_, n) { return citeLines[parseInt(n, 10)] || ""; }); } var text = defLines.join("\n") + "\n"; if (!hasMane) { // No definitions entered — emit {{mane?}} with bênimûne. text = "# {{mane?|" + lang + "}}\n#* {{bênimûne|" + lang + "}}\n"; callback(text); return; } if (!hasRegularMane) { // All filled senses are template senses — no linkify needed. callback(restoreCites(text)); return; } var didTryToLoad = function () { if (typeof $.wiktviLinkify === "function") { $.wiktviLinkify(text, function (linked) { callback(restoreCites(linked)); }); } else { callback(restoreCites(text)); } }; mw.loader.using("ext.gadget.linkify", didTryToLoad, didTryToLoad); } }, je: makeWordListStep("je", "jê", "Kelîmeyên jê çêbûyî binivîse", "Jê", "g"), tekildar: makeWordListStep("tekildar", "têkildar", "Kelîmeyên ji aliyê etîmolojiyê ve têkildarî vê kelîmeyê binivîse", "Têkildar", "g"), binereherwiha: makeWordListStep("binereherwiha", "binêre herwiha", "Kelîmeyên din ên eleqedar binivîse", "Binêre herwiha", "g"), etym: { id: "etym", name: "etîmolojî", question_fmt: "Etîmolojiya kelîmeyê binivîse", // etymTpls populated from data.json etymTpls: [], visible: function (values) { return values.lang && values.pos; }, /** Fills (or refills) the insert-dropdown from the current etymTpls array. */ refreshTplSelect: function () { var sel = $("#wiktku-start-etym .wiktku-tpl-insert-select"); if (!sel.length) return; sel.find("option[value!='']").remove(); $.each(steps.etym.etymTpls, function (_, tpl) { sel.append($("<option></option>").val(tpl.snippet).text(tpl.name + " — " + tpl.desc)); }); // Notify Chosen that the option list has changed (no-op on mobile). if (!isMobile) sel.trigger("chosen:updated"); }, build: function (stepDiv) { if (stepDiv.find(".wiktku-etym-wrap").length) return null; var wrap = $("<div class='wiktku-etym-wrap'></div>"); var ta = $("<textarea></textarea>") .attr("name", "wiktku-etym-" + $.now()) .attr("class", "wiktku-start-step-field wiktku-etym-text") .attr("rows", 4) .attr("placeholder", "Nimûne: Ji {{ji|en|ku|apple}}. yan rasterast binivîse…"); // Template insert dropdown — options also refreshed after data.json loads. var sel = $("<select class='wiktku-tpl-insert-select'></select>"); sel.append($("<option value=''>— şablonek lê zêde bike —</option>")); $.each(steps.etym.etymTpls, function (_, tpl) { sel.append($("<option></option>").val(tpl.snippet).text(tpl.name + " — " + tpl.desc)); }); sel.on("change", function () { var snippet = $(this).val(); if (!snippet) return; var lang = getValues().lang || ""; snippet = snippet.replace(/CODE/g, lang).replace(/SOURCELANG/g, "?"); insertAtCursor(ta[0], snippet); $(this).val(""); ta.focus(); }); wrap.append(sel).append($("<br>")).append(ta); stepDiv.append(wrap); return ta; }, output: function (values) { var text = $.trim($("#wiktku-start-etym .wiktku-etym-text").val()); if (text) { return "\n==== Etîmolojî ====\n" + text + "\n"; } // No etymology entered — emit {{ji?|lang}} as a placeholder, // but only when the entry has at least one regular (non-şablon) // sense with content — either real mane text, or an empty mane // with other fields filled in (which dfn.getOutput() renders as // {{mane?|lang}} with those fields attached). A şablon sense // like {{guharto|…}} never counts, filled in or not. var dfnSenses = steps.dfn.getSenses($("#wiktku-start-dfn")); var hasRegularMane = dfnSenses.some(function (s) { return !s.tpl && (s.mane !== "" || senseHasExtraContent(s)); }); if (!hasRegularMane) return ""; return "\n==== Etîmolojî ====\n{{ji?|" + values.lang + "}}\n"; } }, dunde: { id: "dunde", name: "dûnde", question_fmt: "Eger ev kelîme ji vî zimanî ketibe zimanekî din, vî zimanî û kelîmeya wî binivîse", visible: function (values) { return !!values.pos; }, disabledKeys: { "navz": true}, /** * Builds one row: a language dropdown + a growing list of word * inputs. When the dropdown gets a value the next empty row is * appended automatically. Mirrors steps.trans's row widget, but * flat (one shared list — dûnde isn't tied to individual senses). */ buildRow: function (stepDiv) { var row = $("<li class='wiktku-dunde-row wiktku-lang-row'></li>"); // Language selector — chosen is applied after insertion into DOM. var langSel = $(mw.html.element("select", { "class": "wiktku-start-step-keyfield wiktku-start-narrow" })); langSel.attr("data-placeholder", "Zimanekî lê bigere"); populateMenus(langSel, steps.dunde.keys || [], steps.dunde.disabledKeys); // When a language is chosen, ensure a next empty row exists. langSel.on("change", function () { steps.dunde.onLangChange(stepDiv, row); }); // Word list for this language. var wordList = $("<ul class='wiktku-dunde-words wiktku-lang-row-words'></ul>"); var firstWord = steps.dunde.makeWordInput(); wordList.append($("<li></li>").append(firstWord)); if (isMobile) { row.append(wrapNativeSelect(langSel)).append(wordList); } else { row.append(langSel).append(wordList); } return row; }, makeWordInput: function () { var input = $("<textarea></textarea>") .attr("name", "wiktku-dunde-word-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 1) .attr("class", "wiktku-dfn-subfield wiktku-start-narrow") .attr("placeholder", "Kelîme…"); input.on("input", function () { var list = $(this).closest("ul.wiktku-dunde-words"); var item = $(this).parent(); var val = $.trim($(this).val()); if (val && item.is(list.children("li:last-child"))) { var next = steps.dunde.makeWordInput(); list.append($("<li></li>").append(next)); } }); return input; }, onLangChange: function (stepDiv, row) { var list = stepDiv.find("ul.wiktku-dunde-list"); var isLast = row.is(list.children("li.wiktku-dunde-row:last-child")); if (isLast) { var newRow = steps.dunde.buildRow(stepDiv); list.append(newRow); // Init chosen after the new row is in the DOM (desktop only). if (!isMobile) newRow.find("select").chosen(chosenOptions); } // Keep disabled keys in sync across all lang selectors. steps.dunde.syncDisabledKeys(stepDiv); }, /** Disables already-selected languages in all other dropdowns. */ syncDisabledKeys: function (stepDiv) { var taken = $.extend({}, steps.dunde.disabledKeys); stepDiv.find("li.wiktku-dunde-row select").each(function () { var v = $(this).val(); if (v) taken[v] = true; }); stepDiv.find("li.wiktku-dunde-row select").each(function () { var self = $(this); var own = self.val(); self.find("option").each(function () { var code = $(this).val(); if (!code) return; $(this).prop("disabled", taken[code] && code !== own); }); self.trigger("chosen:updated"); }); }, build: function (stepDiv) { if (stepDiv.find("ul.wiktku-dunde-list").length) return null; var list = $("<ul class='wiktku-dunde-list wiktku-lang-row-list'></ul>"); list.append(steps.dunde.buildRow(stepDiv)); stepDiv.append(list); // Init chosen after the select is in the DOM (desktop only). if (!isMobile) list.find("select").chosen(chosenOptions); return null; }, /** Reads all [langcode, words[]] rows from the DOM. */ getRows: function (stepDiv) { var result = []; stepDiv.find("li.wiktku-dunde-row").each(function () { var lang = $(this).find("select").val(); if (!lang) return; var words = []; $(this).find("ul.wiktku-dunde-words textarea").each(function () { var v = $.trim($(this).val()); if (v) words.push(v); }); if (words.length) result.push([lang, words]); }); return result; }, output: function () { var stepDiv = $("#wiktku-start-dunde"); var rows = steps.dunde.getRows(stepDiv); if (!rows.length) return ""; var lines = $.map(rows, function (row) { var lang = row[0], words = row[1]; return "* {{dû|" + lang + "|" + words.join("|") + "}}"; }); return "\n==== Dûnde ====\n" + lines.join("\n") + "\n"; } }, zarava: { id: "zarava", name: "bi zaravayên din", visible: function (values) { return steps.trans.visible(values); }, disabledKeys: { "navz": true }, buildRow: function (group) { var row = $("<li class='wiktku-zarava-row wiktku-lang-row'></li>"); var langSel = $(mw.html.element("select", { "class": "wiktku-start-step-keyfield wiktku-start-narrow" })); populateMenus(langSel, steps.zarava.keys || [], steps.zarava.disabledKeys); langSel.on("change", function () { steps.zarava.onLangChange(group, row); }); var wordList = $("<ul class='wiktku-zarava-words wiktku-lang-row-words'></ul>"); var firstWord = steps.zarava.makeWordInput(); wordList.append($("<li></li>").append(firstWord)); row.append(langSel).append(wordList); return row; }, makeWordInput: function () { var input = $("<textarea></textarea>") .attr("name", "wiktku-zarava-word-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 1) .attr("class", "wiktku-dfn-subfield wiktku-start-narrow") .attr("placeholder", "Tercime…"); input.on("input", function () { var list = $(this).closest("ul.wiktku-zarava-words"); var item = $(this).parent(); var val = $.trim($(this).val()); if (val && item.is(list.children("li:last-child"))) { var next = steps.zarava.makeWordInput(); list.append($("<li></li>").append(next)); } }); return input; }, onLangChange: function (group, row) { var list = group.find("ul.wiktku-zarava-list"); var isLast = row.is(list.children("li.wiktku-zarava-row:last-child")); if (isLast) { var newRow = steps.zarava.buildRow(group); list.append(newRow); } steps.zarava.syncDisabledKeys(group); }, /** Disables already-selected dialects in all other dropdowns within one group. */ syncDisabledKeys: function (group) { var taken = $.extend({}, steps.zarava.disabledKeys); group.find("li.wiktku-zarava-row select").each(function () { var v = $(this).val(); if (v) taken[v] = true; }); group.find("li.wiktku-zarava-row select").each(function () { var self = $(this); var own = self.val(); self.find("option").each(function () { var code = $(this).val(); if (!code) return; $(this).prop("disabled", taken[code] && code !== own); }); }); }, /** Builds (or fetches) the .wiktku-zarava-group for one gloss. */ buildGroup: function (stepDiv, gi) { var group = $("<div class='wiktku-zarava-group'></div>").attr("data-gloss-pos", gi); var list = $("<ul class='wiktku-zarava-list wiktku-lang-row-list'></ul>"); list.append(steps.zarava.buildRow(group)); group.append(list); stepDiv.append(group); return group; }, /** Syncs one .wiktku-zarava-group per current gloss (same logic as steps.trans.build). */ build: function (stepDiv) { var glosses = steps.trans.glossList(); if (!glosses.length) { stepDiv.find(".wiktku-zarava-group").remove(); return null; } var existingGroups = stepDiv.find(".wiktku-zarava-group"); if (existingGroups.length > glosses.length) { existingGroups.slice(glosses.length).remove(); } $.each(glosses, function (gi, gloss) { var group = stepDiv.find(".wiktku-zarava-group[data-gloss-pos='" + gi + "']"); if (!group.length) group = steps.zarava.buildGroup(stepDiv, gi); var label = group.find(".wiktku-zarava-group-label"); if (glosses.length > 1) { if (!label.length) { label = $("<div class='wiktku-zarava-group-label'></div>"); group.prepend(label); } label.text(gloss.index + " " + gloss.text); } else if (label.length) { label.remove(); } }); return null; }, /** Reads the dialect rows for a single gloss group. */ getGroupTranslations: function (group) { var result = []; group.find("li.wiktku-zarava-row").each(function () { var lang = $(this).find("select").val(); if (!lang) return; var words = []; $(this).find("ul.wiktku-zarava-words textarea").each(function () { var v = $.trim($(this).val()); if (v) words.push(v); }); if (words.length) result.push([lang, words]); }); return result; }, /** Reads all rows from the DOM, grouped by gloss position. */ getTranslations: function (stepDiv) { var result = []; stepDiv.find(".wiktku-zarava-group").each(function () { result.push(steps.zarava.getGroupTranslations($(this))); }); return result; }, output: function (values) { if (values.lang !== "ku") return ""; var stepDiv = $("#wiktku-start-zarava"); var glosses = steps.trans.glossList(); if (!glosses.length) return ""; var blocks = $.map(glosses, function (gloss, gi) { var group = stepDiv.find(".wiktku-zarava-group[data-gloss-pos='" + gi + "']"); var rows = group.length ? steps.zarava.getGroupTranslations(group) : []; if (!gloss.text && !rows.length) return undefined; if (rows.length) { rows.sort(function (a, b) { var aLang = langsByCode[a[0]] || []; var bLang = langsByCode[b[0]] || []; return (aLang[2] || "").localeCompare(bLang[2] || "", "ku"); }); } var wordLines = $.map(rows, function (row) { var lang = row[0]; var words = row[1]; var wikiWords = words.map(function (w) { return "{{W|" + lang + "|" + w + "}}"; }).join(", "); return "* {{Z|" + lang + "}}: " + wikiWords; }).join("\n"); if (!wordLines) return undefined; var block = "{{werger-ser|" + (gloss.text || "?") + "|" + gloss.index + "}}"; block += "\n" + wordLines; block += "\n{{werger-bin}}"; return block; }); if (!blocks.length) return ""; return "\n==== Bi zaravayên din ====\n" + blocks.join("\n") + "\n"; } }, trans: { id: "trans", name: "werger", visible: function (values) { if (!(values.lang === "ku" && values.pos)) return false; // Hide Werger only when EVERY sense is a template sense (Guharto etc.) // with a title filled in — i.e. there is real content but no plain // gloss to attach a translation table to. A mix of real + template // senses still shows Werger; the template senses are simply skipped // in output(). // // "Real" here means a non-şablon sense with either mane text or // other filled-in fields (etîket/hevmane/nimûne/jêder…), since // dfn.getOutput() renders the latter too, as {{mane?|lang}} plus // whatever else was filled in. // // When nothing has been filled in at all, output() will emit // {{mane?|lang}} instead of a gloss — but Werger should still show, // since the user may want to add translations before they've // settled on a gloss. var dfnSenses = steps.dfn.getSenses($("#wiktku-start-dfn")); var hasRealSense = dfnSenses.some(function (s) { return !s.tpl && (s.mane !== "" || senseHasExtraContent(s)); }); var hasFilledTplSense = dfnSenses.some(function (s) { return s.tpl && s.tplTitle; }); return hasRealSense || !hasFilledTplSense; }, disabledKeys: { "navz": true, "ku": true, "ckb": true, "sdh": true, "lki": true, "hac": true, "zza": true }, /** * Builds one translation row: a language dropdown + a growing list * of word inputs. When the dropdown gets a value the next empty row * is appended automatically. * * @param group the specific .wiktku-trans-group this row belongs to * (each gloss has its own group and its own list of rows, so the * lookups below must stay scoped to that group rather than the * whole step — the step now holds one list per gloss). */ buildRow: function (group) { var row = $("<li class='wiktku-trans-row wiktku-lang-row'></li>"); // Language selector — chosen is applied after insertion into DOM. var langSel = $(mw.html.element("select", { "class": "wiktku-start-step-keyfield wiktku-start-narrow" })); langSel.attr("data-placeholder", "Zimanekî lê bigere"); populateMenus(langSel, steps.trans.keys || [], steps.trans.disabledKeys); // When a language is chosen, ensure a next empty row exists. langSel.on("change", function () { steps.trans.onLangChange(group, row); }); // Word list for this language. var wordList = $("<ul class='wiktku-trans-words wiktku-lang-row-words'></ul>"); var firstWord = steps.trans.makeWordInput(); wordList.append($("<li></li>").append(firstWord)); if (isMobile) { row.append(wrapNativeSelect(langSel)).append(wordList); } else { row.append(langSel).append(wordList); } return row; }, makeWordInput: function () { var input = $("<textarea></textarea>") .attr("name", "wiktku-trans-word-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 1) .attr("class", "wiktku-dfn-subfield wiktku-start-narrow") .attr("placeholder", "Tercime…"); input.on("input", function () { var list = $(this).closest("ul.wiktku-trans-words"); var item = $(this).parent(); var val = $.trim($(this).val()); if (val && item.is(list.children("li:last-child"))) { var next = steps.trans.makeWordInput(); list.append($("<li></li>").append(next)); } }); return input; }, onLangChange: function (group, row) { var list = group.find("ul.wiktku-trans-list"); var isLast = row.is(list.children("li.wiktku-trans-row:last-child")); if (isLast) { var newRow = steps.trans.buildRow(group); list.append(newRow); // Init chosen after the new row is in the DOM (desktop only). if (!isMobile) newRow.find("select").chosen(chosenOptions); } // Keep disabled keys in sync across this gloss's lang selectors // only — the same language can be used for different senses. steps.trans.syncDisabledKeys(group); }, /** Disables already-selected languages in all other dropdowns within one group. */ syncDisabledKeys: function (group) { var taken = $.extend({}, steps.trans.disabledKeys); group.find("li.wiktku-trans-row select").each(function () { var v = $(this).val(); if (v) taken[v] = true; }); group.find("li.wiktku-trans-row select").each(function () { var self = $(this); var own = self.val(); self.find("option").each(function () { var code = $(this).val(); if (!code) return; $(this).prop("disabled", taken[code] && code !== own); }); self.trigger("chosen:updated"); }); }, /** * Builds (or fetches) the .wiktku-trans-group for one gloss, with * its own label and its own list of translation rows. */ buildGroup: function (stepDiv, gi) { var group = $("<div class='wiktku-trans-group'></div>").attr("data-gloss-pos", gi); var list = $("<ul class='wiktku-trans-list wiktku-lang-row-list'></ul>"); list.append(steps.trans.buildRow(group)); group.append(list); stepDiv.append(group); // Init chosen after the select is in the DOM (desktop only). if (!isMobile) list.find("select").chosen(chosenOptions); return group; }, /** * Syncs one .wiktku-trans-group per current gloss, adding new * groups and removing stale ones as senses are added or removed, * while leaving existing groups (and whatever translations the * user has already typed into them) untouched. Groups are keyed * to their gloss's position in glossList() via data-gloss-pos, so * a group always matches the same sense across rebuilds as long * as senses aren't reordered relative to each other. */ build: function (stepDiv) { var glosses = steps.trans.glossList(); if (!glosses.length) { stepDiv.find(".wiktku-trans-group").remove(); return null; } // Drop groups for glosses that no longer exist (always from the // tail — groups are only ever appended in gloss order below). var existingGroups = stepDiv.find(".wiktku-trans-group"); if (existingGroups.length > glosses.length) { existingGroups.slice(glosses.length).remove(); } $.each(glosses, function (gi, gloss) { var group = stepDiv.find(".wiktku-trans-group[data-gloss-pos='" + gi + "']"); if (!group.length) group = steps.trans.buildGroup(stepDiv, gi); // Only label groups when there's more than one gloss to // distinguish between — a single gloss needs no caption. var label = group.find(".wiktku-trans-group-label"); if (glosses.length > 1) { if (!label.length) { label = $("<div class='wiktku-trans-group-label'></div>"); group.prepend(label); } label.text(gloss.index + " " + gloss.text); } else if (label.length) { label.remove(); } }); return null; }, /** Reads the translation rows for a single gloss group. */ getGroupTranslations: function (group) { var result = []; group.find("li.wiktku-trans-row").each(function () { var lang = $(this).find("select").val(); if (!lang) return; var words = []; $(this).find("ul.wiktku-trans-words textarea").each(function () { var v = $.trim($(this).val()); if (v) words.push(v); }); if (words.length) result.push([lang, words]); }); return result; }, /** * Reads all translation rows from the DOM, grouped by gloss * position — one array of [lang, words] rows per gloss group, in * the same order as the .wiktku-trans-group elements. */ getTranslations: function (stepDiv) { var result = []; stepDiv.find(".wiktku-trans-group").each(function () { result.push(steps.trans.getGroupTranslations($(this))); }); return result; }, /** * Builds the numbered "{ index, gloss }" list — one entry per dfn * sense that has a real mane (skips template senses like Guharto, * which have nothing to caption a translation table with). The * index matches the sense's actual position in the numbered "#" * definition list (1-based), including template senses in the count, * so the number printed next to {{werger-ser}} lines up with the * gloss the reader sees in the entry. * * When nothing has been filled in at all (dfn.getOutput() will emit * {{mane?|lang}} as sense 1), this returns a single placeholder * entry with empty text instead of an empty array, so Werger still * has one group to attach translations to before a gloss exists. * When every filled sense is a template sense instead, this stays * empty — that mirrors trans.visible()'s hidden case, where there's * no group in the DOM for a placeholder to attach to anyway. */ glossList: function () { var dfnSenses = steps.dfn.getSenses($("#wiktku-start-dfn")); var glosses = []; var hasFilledTplSense = false; $.each(dfnSenses, function (i, s) { if (s.tpl) { if (s.tplTitle) hasFilledTplSense = true; return; // template sense — no gloss to caption with } var dfn = s.mane; if (!dfn) { // No mane text, but other fields (etîket/hevmane/nimûne/ // jêder…) are filled — dfn.getOutput() still emits this // sense as a numbered line using {{mane?|lang}}, so it // needs its own gloss group too, just with no caption text. if (senseHasExtraContent(s)) glosses.push({ index: i + 1, text: "" }); return; } if (dfn[0] !== dfn[0].toLowerCase()) dfn = decapitalize(dfn); dfn = stripWikilinks(dfn).replace(/[.…?!)\]،؟]+$/, ""); glosses.push({ index: i + 1, text: dfn }); }); if (!glosses.length && !hasFilledTplSense) { glosses.push({ index: 1, text: "" }); } return glosses; }, output: function (values) { if (values.lang !== "ku") return ""; var stepDiv = $("#wiktku-start-trans"); var glosses = steps.trans.glossList(); // Every sense is a template sense — there's no real gloss // anywhere and no group in the DOM either (glossList() only // returns empty in that case), so skip the section entirely. if (!glosses.length) return ""; // Each gloss now has its own group of translation rows — // attach every gloss's own words under its own werger-ser/-bin // pair instead of dumping everything under the first one. var blocks = $.map(glosses, function (gloss, gi) { var group = stepDiv.find(".wiktku-trans-group[data-gloss-pos='" + gi + "']"); var rows = group.length ? steps.trans.getGroupTranslations(group) : []; // Placeholder gloss (no real mane entered yet) with nothing // translated into it — nothing to output, and gloss.text is // empty so there's no caption to give {{werger-ser}} anyway. if (!gloss.text && !rows.length) return undefined; if (rows.length) { // Sort by Kurdish sort key. rows.sort(function (a, b) { var aLang = langsByCode[a[0]] || []; var bLang = langsByCode[b[0]] || []; return (aLang[2] || "").localeCompare(bLang[2] || "", "ku"); }); } var wordLines = $.map(rows, function (row) { var lang = row[0]; var words = row[1]; var wikiWords = words.map(function (w) { return "{{W|" + lang + "|" + w + "}}"; }).join(", "); return "* {{Z|" + lang + "}}: " + wikiWords; }).join("\n"); var block = "{{werger-ser|" + (gloss.text || "?") + "|" + gloss.index + "}}"; if (wordLines) block += "\n" + wordLines; block += "\n{{werger-bin}}"; return block; }); if (!blocks.length) return ""; return "\n==== Werger ====\n" + blocks.join("\n") + "\n"; } }, }; steps.trans.keys = steps.lang.choices; steps.dunde.keys = steps.lang.choices; steps.zarava.keys = getZaravaKeys(steps.lang.choices); var ordered_steps = [ steps.lang, steps.pron, steps.pos, steps.cinsiyet, steps.lektur, steps.tr, steps.dfn, steps.je, steps.tekildar, steps.etym, steps.dunde, steps.binereherwiha, steps.zarava, steps.trans]; // Step ids that belong to each section (not shared across sections). var PER_SECTION_STEP_IDS = [ "pos", "cinsiyet", "lektur", "tr", "dfn", "je", "tekildar", "etym", "dunde", "binereherwiha", "zarava", "trans" ]; // ── Multi-section state ────────────────────────────────────────────────── // Each entry is a plain snapshot: { pos, cinsiyet, lektur, tr, dfn (senses[]), // je, tekildar, binereherwiha, trans (rows[]) }. var sections = [{}]; // section 0 starts empty (DOM is the truth) var activeSection = 0; function snapshotDfn() { return steps.dfn.getSenses($("#wiktku-start-dfn")); } /** * Rebuild the dfn DOM from a previously snapshotted senses array. */ function restoreDfn(senses) { var stepDiv = $("#wiktku-start-dfn"); // Tear down the existing list so build() recreates it cleanly. stepDiv.find("ol.wiktku-dfn-list").remove(); steps.dfn.build(stepDiv); var list = stepDiv.find("ol.wiktku-dfn-list"); $.each(senses, function (i, sense) { // Ensure enough blocks exist (build() seeds one). var blocks = list.find("li.wiktku-dfn-sense"); var block = blocks.eq(i); if (!block.length) { var nb = steps.dfn.buildSenseBlock(stepDiv); list.append(nb); block = list.find("li.wiktku-dfn-sense").last(); } // Template selector. block.find("select.wiktku-dfn-tpl-select").val(sense.tpl || ""); if (sense.tpl) { block.find("textarea.wiktku-dfn-mane").hide(); block.find("input.wiktku-dfn-tpl-title").val(sense.tplTitle || "").show(); } else { block.find("textarea.wiktku-dfn-mane").val(sense.mane || "").show(); block.find("input.wiktku-dfn-tpl-title").hide().val(""); } // Re-sync the formên alternatîv/hevmane/… hide state now that // tplSelect's value was set programmatically (its own "change" // handler doesn't fire from .val(), so this doesn't happen otherwise). var updateVis = block.data("updateFieldVisibility"); if (updateVis) updateVis(); // Restore a sub-list (etiket, formên alternatîv, hevmane …) from a values array. function restoreSubList(cls, values) { if (!values || !values.length) return; var groupDiv = block.find("." + cls + "-group"); var subList = groupDiv.find("ol, ul").first(); if (!subList.length) return; // group not found // Fill existing items, append new ones as needed. $.each(values, function (j, val) { var items = subList.find("li"); if (j < items.length) { items.eq(j).find("textarea").val(val); } else { var ta = $("<textarea></textarea>") .attr("name", "wiktku-dfn-restore-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 1) .attr("class", "wiktku-dfn-subfield wiktku-start-narrow") .val(val); ta.on("input", function () { steps.dfn.onSubInput(subList, this, 1, true); }); subList.append($("<li></li>").append(ta)); } }); } // Reveal and populate lazy groups that have data. var lazyMap = { "wiktku-dfn-etiket": sense.etiket, "wiktku-dfn-kategorî": sense.kategorî, "wiktku-dfn-alternativ": sense.alternativ, "wiktku-dfn-hevmane": sense.hevmane, "wiktku-dfn-dijmane": sense.dijmane, "wiktku-dfn-koordine": sense.koordine, "wiktku-dfn-jornav": sense.jornav, "wiktku-dfn-jernav": sense.jernav }; $.each(lazyMap, function (cls, vals) { if (vals && vals.length) restoreSubList(cls, vals); }); // Nimûne items are objects { text, tr?, t? } — restore using the builder. if (sense.nimune && sense.nimune.length) { var nimuneGroupDiv = block.find(".wiktku-dfn-nimune-group"); var nimuneList = nimuneGroupDiv.find("ol.wiktku-dfn-nimune-list"); var buildFn = nimuneGroupDiv.data("buildNimuneLi"); nimuneList.empty(); $.each(sense.nimune, function (_, n) { var text = typeof n === "object" ? (n.text || "") : n; if (!text) return; var li = buildFn ? buildFn() : $("<li class='wiktku-dfn-nimune-li'></li>"); li.find(".wiktku-dfn-nimune-text").val(text); if (n.tr) li.find(".wiktku-dfn-nimune-tr").val(n.tr); if (n.t) li.find(".wiktku-dfn-nimune-t").val(n.t); nimuneList.append(li); }); // Always leave a blank trailing item. if (buildFn) nimuneList.append(buildFn()); } // Restore jêder (quote/citation) entries — a growing list, restored using the // builder just like Nimûne. Accepts either the current array shape or a // single legacy object (from older saved sections) for backwards compatibility. var jederArr = $.isArray(sense.jeder) ? sense.jeder : (sense.jeder ? [sense.jeder] : []); if (jederArr.length) { var jederGroupDiv = block.find(".wiktku-dfn-jeder-group"); var jederList = jederGroupDiv.find("ol.wiktku-dfn-jeder-list"); var buildJederFn = jederGroupDiv.data("buildJederLi"); jederList.empty(); $.each(jederArr, function (_, j) { if (!j || !j.quote) return; var li = buildJederFn ? buildJederFn() : $("<li class='wiktku-dfn-jeder-li'></li>"); li.find(".wiktku-dfn-nimune-quote").val(j.quote); if (j.quoteTr) li.find(".wiktku-dfn-nimune-quote-tr").val(j.quoteTr); if (j.quoteT) li.find(".wiktku-dfn-nimune-quote-t").val(j.quoteT); if (j.jederManual) { var manualSel = li.find(".wiktku-dfn-quote-src-sel"); manualSel.val("__manual__").trigger("change"); li.find(".wiktku-dfn-quote-src-manual").val(j.jederManual); } else if (j.jederTpl) { var srcSel = li.find(".wiktku-dfn-quote-src-sel"); srcSel.val(j.jederTpl).trigger("change"); if (j.jêderFields) { $.each(j.jêderFields, function (key, val) { li.find(".wiktku-dfn-quote-src-input[data-field-key='" + key + "']").val(val); }); } } jederList.append(li); }); // Always leave a blank trailing item, same as Nimûne. if (buildJederFn) jederList.append(buildJederFn()); } }); } /** * Snapshot simple (non-dfn) per-section steps from current DOM into obj. */ function saveCurrentSection() { var snap = {}; $.each(PER_SECTION_STEP_IDS, function (_, id) { if (id === "dfn") { snap.dfn = snapshotDfn(); return; } if (id === "etym") { snap.etym = $.trim($("#wiktku-start-etym .wiktku-etym-text").val()); return; } var step = steps[id]; if (!step) return; var stepDiv = $("#wiktku-start-" + id); if (id === "trans") { snap.trans = steps.trans.getTranslations(stepDiv); return; } if (id === "zarava") { snap.zarava = steps.zarava.getTranslations(stepDiv); return; } if (id === "dunde") { snap.dunde = steps.dunde.getRows(stepDiv); return; } // Generic: read all step fields. var fields = stepDiv.find(".wiktku-start-step-field"); if (step.multiple) { snap[id] = fields.map(function () { return $(this).val(); }).get(); } else { snap[id] = fields.val(); } }); sections[activeSection] = snap; } /** * Restore a previously saved snapshot into the form DOM. */ function restoreSection(snap) { $.each(PER_SECTION_STEP_IDS, function (_, id) { if (id === "dfn") { restoreDfn(snap.dfn || []); return; } if (id === "etym") { $("#wiktku-start-etym .wiktku-etym-wrap").remove(); steps.etym.build($("#wiktku-start-etym")); $("#wiktku-start-etym .wiktku-etym-text").val(snap.etym || ""); return; } if (id === "trans") { // Rebuild trans groups (dfn must already be restored by this // point in the $.each loop, so glossList() reflects it). var transDiv = $("#wiktku-start-trans"); transDiv.find(".wiktku-trans-group").remove(); steps.trans.build(transDiv); var groupsSnap = snap.trans || []; $.each(groupsSnap, function (gi, rows) { var group = transDiv.find(".wiktku-trans-group[data-gloss-pos='" + gi + "']"); if (!group.length) return; // gloss no longer exists — drop its rows var list = group.find("ul.wiktku-trans-list"); $.each(rows, function (j, row) { var lang = row[0], words = row[1]; var lastRow = list.find("li.wiktku-trans-row").last(); lastRow.find("select").val(lang).trigger("change"); var wordList = lastRow.find("ul.wiktku-trans-words"); $.each(words, function (k, word) { var wordItems = wordList.find("li"); if (k < wordItems.length) { wordItems.eq(k).find("textarea").val(word); } else { // .val() below doesn't fire "input", so the normal // auto-grow never runs — append a matching item // ourselves instead of silently dropping the word. var extraInput = steps.trans.makeWordInput(); wordList.append($("<li></li>").append(extraInput)); extraInput.val(word); } }); // Leave one trailing empty field so the row can still grow // when the user types, matching a freshly-built row. if ($.trim(wordList.children("li").last().find("textarea").val())) { wordList.append($("<li></li>").append(steps.trans.makeWordInput())); } }); }); return; } if (id === "zarava") { // Rebuild zarava groups (dfn must already be restored by this // point in the $.each loop, so glossList() reflects it). var zaravaDiv = $("#wiktku-start-zarava"); zaravaDiv.find(".wiktku-zarava-group").remove(); steps.zarava.build(zaravaDiv); var zaravaGroupsSnap = snap.zarava || []; $.each(zaravaGroupsSnap, function (gi, rows) { var group = zaravaDiv.find(".wiktku-zarava-group[data-gloss-pos='" + gi + "']"); if (!group.length) return; // gloss no longer exists — drop its rows var list = group.find("ul.wiktku-zarava-list"); $.each(rows, function (j, row) { var lang = row[0], words = row[1]; var lastRow = list.find("li.wiktku-zarava-row").last(); lastRow.find("select").val(lang).trigger("change"); var wordList = lastRow.find("ul.wiktku-zarava-words"); $.each(words, function (k, word) { var wordItems = wordList.find("li"); if (k < wordItems.length) { wordItems.eq(k).find("textarea").val(word); } else { var extraInput = steps.zarava.makeWordInput(); wordList.append($("<li></li>").append(extraInput)); extraInput.val(word); } }); if ($.trim(wordList.children("li").last().find("textarea").val())) { wordList.append($("<li></li>").append(steps.zarava.makeWordInput())); } }); }); return; } if (id === "dunde") { // Rebuild dunde rows. var dundeDiv = $("#wiktku-start-dunde"); dundeDiv.find("ul.wiktku-dunde-list").remove(); steps.dunde.build(dundeDiv); var dundeRows = snap.dunde || []; $.each(dundeRows, function (i, row) { var lang = row[0], words = row[1]; var list = dundeDiv.find("ul.wiktku-dunde-list"); var lastRow = list.find("li.wiktku-dunde-row").last(); lastRow.find("select").val(lang).trigger("change"); var wordList = lastRow.find("ul.wiktku-dunde-words"); $.each(words, function (j, word) { var wordItems = wordList.find("li"); if (j < wordItems.length) { wordItems.eq(j).find("textarea").val(word); } else { // .val() below doesn't fire "input", so the normal // auto-grow never runs — append a matching item // ourselves instead of silently dropping the word. var extraInput = steps.dunde.makeWordInput(); wordList.append($("<li></li>").append(extraInput)); extraInput.val(word); } }); // Leave one trailing empty field so the row can still grow // when the user types, matching a freshly-built row. if ($.trim(wordList.children("li").last().find("textarea").val())) { wordList.append($("<li></li>").append(steps.dunde.makeWordInput())); } }); return; } var step = steps[id]; if (!step) return; var stepDiv = $("#wiktku-start-" + id); var fields = stepDiv.find(".wiktku-start-step-field"); var val = snap[id]; if (val === undefined || val === null) return; if (step.multiple) { var arr = val; fields.each(function (i) { if (i < arr.length) $(this).val(arr[i]); }); } else { fields.val(val); } // Notify chosen widgets of the programmatic value change. if (!isMobile) fields.filter("select").trigger("chosen:updated"); }); } function getWikitextForCurrentSection(callback) { var values = getValues(); var entry = steps.pos.output(values); steps.dfn.getOutput(values, function (output) { entry += output; entry += steps.je.output(values); entry += steps.tekildar.output(values); entry += steps.etym.output(values); entry += steps.dunde.output(values); entry += steps.binereherwiha.output(values); entry += steps.zarava.output(values); entry += steps.trans.output(values); callback(entry, values); }); } function getWikitextAllSections(callback) { saveCurrentSection(); var results = new Array(sections.length); var sharedValues = getValues(); // lang/pron are shared function processSection(i) { if (i >= sections.length) { // All done — restore original active section. restoreSection(sections[activeSection]); refresh(); callback(results, sharedValues); return; } restoreSection(sections[i]); refresh(); getWikitextForCurrentSection(function (sectionText) { results[i] = sectionText; processSection(i + 1); }); } processSection(0); } /** * Assembles wikitext for all sections plus the shared lang/pron header. */ function getWikitext(callback) { getWikitextAllSections(function (sectionTexts, sharedValues) { var entry = steps.lang.output(sharedValues); entry += steps.pron.output(sharedValues); entry += sectionTexts.join("\n"); // Edit summary uses section 0's values. Read from the saved snapshot // (not the live DOM) so it doesn't mix section 0's pos with whichever // section happens to be active/restored at this point. var dfnSenses = (sections[0] && sections[0].dfn) || []; var dfnSummary = dfnSenses.map(function (s) { return s.mane; }).filter(Boolean).join("; "); var summaryLabel = addLangMode ? "WF:Ziman lê zêde" : "WF:Nû"; var summary = "([[Mediawiki:Gadget-start.js|" + summaryLabel + "]] v.2.0) +" + sharedValues.lang + ":" + sections[0].pos + ":" + dfnSummary; var summaryField = document.getElementById("wpSummary"); if (addLangMode && summaryField.value) { summary = summaryField.value + " " + summary; } summaryField.value = summary; callback(entry); }); } var continueBtn; function getValuesForStep(stepId) { var fields = $("#wiktku-start-" + stepId + " .wiktku-start-step-field"); var step = steps[stepId]; if (step.keys) { var values = {}; fields.each(function (i, field) { var key = $(field).prevAll(".wiktku-start-step-keyfield").val(); if (key) values[key] = $(field).val(); }); return values; } else if (step.multiple) { return fields.map(function () { return $(this).val(); }).get(); } return fields.val(); } function getValues() { var values = {}; $.each(steps, function (stepId) { values[stepId] = getValuesForStep(stepId); }); return values; } function populateMenus(inputs, choices, disabledValues) { if (!disabledValues) disabledValues = {}; var vals = inputs.map(function (i, input) { return $(input).val(); }); inputs.empty(); inputs.append($("<option></option>")); $.each(choices, function (j, choice) { // Append the language code in parentheses so that typing a code // (e.g. "ku") in the search box still finds the language name. var displayText = capitalize(choice[1]); if (choice[2] !== undefined) { // This is a language choice [code, name, sortKey] — show code. displayText = capitalize(choice[1]) + " (" + choice[0] + ")"; } var option = $(mw.html.element("option", { value: choice[0] }, displayText)); if (disabledValues[choice[0]]) option.prop("disabled", true); inputs.append(option); }); inputs.val(function (i) { return vals[i]; }); } /** * Returns a bitmap containing the keys that should be disabled for a key * menu in the given step because they are disabled or already taken by * another key menu. */ function getDisabledKeys(step) { var occupiedKeys = {}; $("#wiktku-start-" + step.id + " .wiktku-start-step-keyfield").each(function () { occupiedKeys[$(this).val()] = true; }); if (step.disabledKeys) $.extend(occupiedKeys, step.disabledKeys); return occupiedKeys; } function buildKeyInput(step) { if (!step.keys) return undefined; var input = $(mw.html.element("select", { "class": "wiktku-start-step-keyfield wiktku-start-narrow" })); input.attr("data-placeholder", "Hilbijêre " + step.keyName); if (isMobile) { populateMenus(input, step.keys, getDisabledKeys(step)); // On mobile return the wrapper; the select is inside it. // Change events still fire on the inner select. return wrapNativeSelect(input); } input.on("chosen:showing_dropdown", function () { $(this).data("wiktku-defaultValue", $(this).val()); }); input.change(function (_, context) { var inputs = $("#wiktku-start-" + step.id + " .wiktku-start-step-keyfield").not(this); var oldValue = $(this).data("wiktku-defaultValue"); var newValue = context.selected; inputs.find("option[value='" + oldValue + "']").prop('disabled', false); inputs.find("option[value='" + newValue + "']").prop('disabled', true); inputs.trigger("chosen:updated"); }); populateMenus(input, step.keys, getDisabledKeys(step)); return input; } /** * If the current text field has text and there are no more text fields after * the current text field in the list, add another text field to the list. */ function refreshForTextField(currentInput, step) { currentInput = $(currentInput); var value = currentInput.val(); var item = currentInput.parent(); if (value && !item.next("li").length) { var nextInput = $("<textarea></textarea>") .attr("name", "wiktku-field-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("class", currentInput.attr("class")) .attr("rows", currentInput.attr("rows") || 1); nextInput.on("input", function (evt) { refreshForTextField(evt.target, step); }); var nextKeyInput = buildKeyInput(step); var nextItem = $("<li></li>").append(nextKeyInput).append(nextInput); item.parent().append(nextItem); if (nextKeyInput) nextKeyInput.chosen(chosenOptions); } var canContinue = !continueBtn.isDisabled(); if ((value && !canContinue) || (!value && canContinue)) { refresh(step); } } function prepareInput(input, step) { if (!input) return; if (step.required) input.prop('required', true); input.change(step, refresh); } /** * Shows and hides all the steps based on whether their prerequisites are met, * and updates placeholders where applicable. */ function refresh(evt) { var values = getValues(); var changedStep = evt && evt.data; var didFocus = false; var canContinue = true; // Re-filter template options in every sense block whenever lang changes. $("#wiktku-start-dfn .wiktku-dfn-tpl-select").each(function () { var fn = $(this).data("updateOptions"); if (typeof fn === "function") fn(); }); // Re-filter pronunciation and etymology template dropdowns when language changes. steps.pron.refreshTplSelect(); steps.etym.refreshTplSelect(); // Sync tr/t sub-fields in every nimûne item to the current language. // tr shown when language needs transliteration; t shown when lang !== "ku". (function () { var lang = values.lang || ""; var showTr = needsTransliteration(lang); var showT = lang && lang !== "ku"; $("#wiktku-start-dfn .wiktku-dfn-nimune-list li.wiktku-dfn-nimune-li").each(function () { var li = $(this); // Ensure the sub-wrapper exists when we need it. var subWrap = li.find(".wiktku-dfn-nimune-sub"); // tr field var trTa = li.find(".wiktku-dfn-nimune-tr"); if (showTr && !trTa.length) { if (!subWrap.length) { subWrap = $("<div></div>").addClass("wiktku-dfn-nimune-sub"); li.append(subWrap); } trTa = $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-tr-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 5) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-tr") .attr("placeholder", "Transkrîpsiyon…"); subWrap.prepend(trTa); } else if (!showTr && trTa.length) { trTa.remove(); } // t field var tTa = li.find(".wiktku-dfn-nimune-t"); if (showT && !tTa.length) { if (!subWrap.length) { subWrap = $("<div></div>").addClass("wiktku-dfn-nimune-sub"); li.append(subWrap); } tTa = $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-t-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 5) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-t") .attr("placeholder", "Tercimeya nimûneyê kurmancî…"); subWrap.append(tTa); } else if (!showT && tTa.length) { tTa.remove(); } // Remove the wrapper if it ended up empty. subWrap = li.find(".wiktku-dfn-nimune-sub"); if (subWrap.length && !subWrap.children().length) subWrap.remove(); }); }()); // Sync tr/t sub-fields in every jêder citation to the current language. // tr shown when language needs transliteration; t shown when lang !== "ku". (function () { var lang = values.lang || ""; var showTr = needsTransliteration(lang); var showT = lang && lang !== "ku"; $("#wiktku-start-dfn .wiktku-dfn-jeder-list li.wiktku-dfn-jeder-li").each(function () { var li = $(this); // Ensure the sub-wrapper exists when we need it. It must sit right // after the quote textarea and before the source selector. var subWrap = li.find(".wiktku-dfn-quote-sub"); // tr field var trTa = li.find(".wiktku-dfn-nimune-quote-tr"); if (showTr && !trTa.length) { if (!subWrap.length) { subWrap = $("<div></div>").addClass("wiktku-dfn-quote-sub"); li.find(".wiktku-dfn-nimune-quote").after(subWrap); } trTa = $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-quote-tr-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 2) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-quote-tr") .attr("placeholder", "Transkrîpsiyona jêgirtinê…"); subWrap.prepend(trTa); } else if (!showTr && trTa.length) { trTa.remove(); } // t field var tTa = li.find(".wiktku-dfn-nimune-quote-t"); if (showT && !tTa.length) { if (!subWrap.length) { subWrap = $("<div></div>").addClass("wiktku-dfn-quote-sub"); li.find(".wiktku-dfn-nimune-quote").after(subWrap); } tTa = $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-quote-t-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 2) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-quote-t") .attr("placeholder", "Tercimeya jêgirtinê ya kurmancî…"); subWrap.append(tTa); } else if (!showT && tTa.length) { tTa.remove(); } // Remove the wrapper if it ended up empty. subWrap = li.find(".wiktku-dfn-quote-sub"); if (subWrap.length && !subWrap.children().length) subWrap.remove(); }); }()); $.each(steps, function (stepId, step) { if (typeof(step.visible) === "function" && !step.visible(values)) { $("#wiktku-start-" + stepId).slideUp(); } else { var stepDiv = $("#wiktku-start-" + stepId); if (changedStep !== step && typeof(step.build) === "function") { prepareInput(step.build(stepDiv, values), step); } var input = stepDiv.find(".wiktku-start-step-field"); if (typeof(step.example) === "function") { // .find() above already reaches nested fields (e.g. the dfn // step's mane textareas inside each sense block), so one // assignment covers every step; dfn keeps its own fallback. var exampleText = step.example(values) || (step.id === "dfn" ? "Mane…" : ""); input.attr("placeholder", exampleText); } var didSlideDown; if (!didFocus && stepDiv.css("display") === "none" && step.required) { didSlideDown = function (evt) { input.focus(); }; didFocus = true; } stepDiv.slideDown(didSlideDown); } if (step.required && (values[stepId] === "" || (step.multiple && values[stepId].join("") === ""))) { canContinue = false; } }); continueBtn.setDisabled(!canContinue); } function destroy() { $("#wiktku-start-form, .noafterwizard").slideUp(function () { $(this).remove(); }); $(".noarticletext .nowizard, #editform").slideDown(); $("#ca-edit").removeClass("selected"); $("#ca-wiktku-nowizard").addClass("selected"); } // Priority order for Kurdish dialects and the navz pseudo-code. // Codes listed here come before all other languages; unlisted codes // are sorted alphabetically by their display name via localeCompare. var LANG_PRIORITY = ["navz", "ku", "hac", "sdh", "lki", "ckb", "zza"]; /** * Inserts a new == {{ziman|code}} == section into existing page wikitext * at the correct sorted position: * 1. Any content before the first language section is preserved at the top. * 2. navz is always first, then ku/hac/sdh/lki/ckb/zza in that order, * then all other languages sorted by display name (localeCompare). */ function insertNewLangSection(existing, wikitext) { var newCodeMatch = wikitext.match(/^== \{\{ziman\|([^}]+)\}\} ==/); var newCode = newCodeMatch ? newCodeMatch[1] : ""; var sections = []; var preamble = ""; var firstMatch = existing.match(/(?:^|\n)== \{\{ziman\|/); if (!firstMatch) { // No existing lang sections at all — just append. var sep = existing && !/\n\s*$/.test(existing) ? "\n\n" : ""; return existing + sep + wikitext; } // Everything before the first == {{ziman|...}} == is the preamble. var firstSectionStart = existing.indexOf("== {{ziman|"); // Walk back to the start of that line. var lineStart = existing.lastIndexOf("\n", firstSectionStart - 1); var preambleEnd = lineStart !== -1 ? lineStart + 1 : 0; preamble = existing.slice(0, preambleEnd); // Parse each language section: header line + everything until the next header. var body = existing.slice(preambleEnd); // NOTE: with the /m flag, a bare "$" matches end-of-*line*, not just // end-of-string — that previously made the non-greedy content group // stop at the section's first line break instead of running to the // next language header (or the real end of the text), silently // dropping the rest of that section's wikitext. (?![\s\S]) matches // only the true end of the string, /m flag or not. var langSectionRe = /^(== \{\{ziman\|([^}]+)\}\} ==\n?)([\s\S]*?)(?=\n== \{\{ziman\||(?![\s\S]))/gm; var m; while ((m = langSectionRe.exec(body)) !== null) { sections.push({ code: m[2], content: m[0] // full text of this section including header }); } // Determine sort rank: priority list first (by index), then alphabetical. function getLangName(code) { var entry = langsByCode[code]; return entry ? entry[1] : code; } function sortRank(code) { var idx = LANG_PRIORITY.indexOf(code); return idx !== -1 ? idx : LANG_PRIORITY.length; } function compareLangs(a, b) { var ra = sortRank(a), rb = sortRank(b); if (ra !== rb) return ra - rb; // Both are outside priority list — sort by display name. return getLangName(a).localeCompare(getLangName(b), userLang); } // Insert the new section into the sorted list. var newSection = { code: newCode, content: wikitext }; var inserted = false; for (var i = 0; i < sections.length; i++) { if (compareLangs(newCode, sections[i].code) < 0) { sections.splice(i, 0, newSection); inserted = true; break; } } if (!inserted) sections.push(newSection); // Re-join: preamble + sections separated by newlines. var joined = sections.map(function (s) { // Ensure each section ends with exactly one newline before the next. return s.content.replace(/\n+$/, ""); }).join("\n"); return preamble + joined + "\n"; } function build() { $(".nowizard, .nowizard .noafterwizard").hide(); var callToAction = $("#wiktku-calltoaction"); var origCallToActionText = callToAction.text(); $(mw.util.addPortletLink("p-views", "#", "Edîtora çavkaniyê veke", "ca-wiktku-nowizard", "Vê rûpelê bi edîtora çavkaniyê çêke", undefined, "#ca-watch")).click(function (evt) { evt.preventDefault(); callToAction.text(origCallToActionText); destroy(); }); if (callToAction.length) { callToAction.text(origCallToActionText + " Forma li jêr ji bo çêkirina madeyeke nû bi kar bîne."); } var startForm = $("<form id='wiktku-start-form'></form>"); var clearPageCheck = null; if (addLangMode) { startForm.append($("<p class='wiktku-addlang-notice'></p>").html( "Bi vê formê tu yê beşeke nû li rûpelê îlawe bikî. Eger ev zimanê ku tu îlawe dikî jixwe di rûpelê de hebe, beşa nû li dawiya vî zimanî dê were îlawekirin. " + "Ji kerema xwe netîceya dawî kontrol bikin, eger problemek derkeve, li <a href='" + mw.util.getUrl('Mediawiki talk:Gadget-start.js') + "'>nîqaşa vê amûrê</a> problemê ragihîne." )); clearPageCheck = $("<input type='checkbox' id='wiktku-clear-page-check'>"); var clearPageLabel = $("<label for='wiktku-clear-page-check'></label>") .text(" Naveroka rûpelê paqij bike (rûpelê ji nû ve binivîse)"); startForm.append( $("<p class='wiktku-addlang-notice'></p>") .append(clearPageCheck) .append(clearPageLabel) ); } var spinner; // Tab bar for switching between POS sections. var sectionTabsDiv = $("<div id='wiktku-section-tabs'></div>"); startForm.submit(function (evt) { evt.preventDefault(); continueBtn.setDisabled(true); spinner.show(); getWikitext(function (wikitext) { if (addLangMode) { var textbox = $("#wpTextbox1"); var existing = textbox.val() || ""; // Check whether the generated lang header already exists in the page. // wikitext always starts with "== {{ziman|CODE}} ==\n" (from steps.lang.output). // If that exact section heading is already present in the existing content, // strip it from the new output and insert the remaining content at the end // of that lang section (just before the next == level-2 heading, or at the // very end of the page if there is no following section). var langHeaderMatch = wikitext.match(/^(== \{\{ziman\|[^}]+\}\} ==\n)/); if (langHeaderMatch) { var langHeader = langHeaderMatch[1]; // e.g. "== {{ziman|ku}} ==\n" // Escape for use in RegExp. var escapedHeader = langHeader.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); if (new RegExp(escapedHeader).test(existing)) { // Strip the header from the new output. var newContent = wikitext.slice(langHeader.length); // Find the insertion point: end of the existing lang section. // A new L2 heading marks the start of the next language block. var afterHeader = existing.indexOf(langHeader); var searchFrom = afterHeader + langHeader.length; // Find the next == … == heading after this section's start. var nextL2 = existing.indexOf("\n== ", searchFrom); var insertAt = nextL2 !== -1 ? nextL2 : existing.length; // Ensure there's a blank line before the inserted block. var before = existing.slice(0, insertAt); var after = existing.slice(insertAt); var sep = /\n\s*$/.test(before) ? "" : "\n"; textbox.val(before + sep + newContent + after); } else { // New language — insert at the correct sorted position. textbox.val(insertNewLangSection(existing, wikitext)); } } else { // Unexpected format — insert at sorted position anyway. textbox.val(insertNewLangSection(existing, wikitext)); } } else { $("#wpTextbox1").val(wikitext); } $("html, body").animate({scrollTop: 0}); callToAction.text("Hindik ma!"); $("#wiktku-preview-container").remove(); destroy(); }); }); $.each(ordered_steps, function (i, step) { var stepDiv = $(mw.html.element("div", { "class": "wiktku-start-step", id: "wiktku-start-" + step.id })); var name = capitalize(step.name); stepDiv.append($(mw.html.element("h3", { "class": "wiktku-start-step-name" }, new mw.html.Raw(mw.html.element("label", { "for": "wiktku-start-" + step.id + "-field" }, name))))); if (step.question_fmt) { stepDiv.append($(mw.html.element("label", { "class": "wiktku-start-step-question", "for": "wiktku-start-" + step.id + "-field" }, step.question_fmt))); if (step.question_br) stepDiv.append($("<br>")); } var input; if (step.choices) { input = $(mw.html.element("select", { "class": "wiktku-start-step-field", id: "wiktku-start-" + step.id + "-field" })); input.attr("data-placeholder", capitalize(step.name) + " hilbijêre "); populateMenus(input, step.choices); if (step.multiple) input.attr("multiple", true); if (isMobile) { stepDiv.append(wrapNativeSelect(input)); } else { stepDiv.append(input); } } else if (typeof(step.build) === "function") { input = step.build(stepDiv); } else { input = $("<textarea></textarea>") .attr("class", "wiktku-start-step-field") .attr("id", "wiktku-start-" + step.id + "-field") .attr("rows", step.rows || 2); if (step.narrow) input.addClass("wiktku-start-narrow"); if (step.multiple) { input.on("input", function (evt) { refreshForTextField(evt.target, step); }); var keyInput = buildKeyInput(step); var list = $(step.ordered ? "<ol></ol>" : "<ul></ul>") .append($("<li></li>").append(keyInput).append(input)); stepDiv.append(list); } else stepDiv.append(input); } prepareInput(input, step); stepDiv.hide(); // Insert tab bar just before the first per-section step. if (step.id === "pos") startForm.append(sectionTabsDiv); startForm.append(stepDiv); }); // ── Section tab helpers ────────────────────────────────────────────── // ── Add-section button — lives in the tab bar, disabled until pos chosen ── var addSectionBtn = new OO.ui.ButtonWidget({ label: "+ Beş zêde bike", disabled: true }); addSectionBtn.on("click", function () { saveCurrentSection(); sections.push({}); activeSection = sections.length - 1; $.each(PER_SECTION_STEP_IDS, function (_, id) { if (id === "dfn") { var stepDiv = $("#wiktku-start-dfn"); stepDiv.find("ol.wiktku-dfn-list").remove(); steps.dfn.build(stepDiv); return; } if (id === "etym") { $("#wiktku-start-etym .wiktku-etym-wrap").remove(); steps.etym.build($("#wiktku-start-etym")); return; } if (id === "trans") { var transDiv = $("#wiktku-start-trans"); transDiv.find(".wiktku-trans-group").remove(); return; } if (id === "zarava") { var zaravaDiv = $("#wiktku-start-zarava"); zaravaDiv.find(".wiktku-zarava-group").remove(); return; } if (id === "dunde") { var dundeDiv = $("#wiktku-start-dunde"); dundeDiv.find("ul.wiktku-dunde-list").remove(); return; } var stepDiv = $("#wiktku-start-" + id); stepDiv.find(".wiktku-start-step-field").val(""); if (!isMobile) stepDiv.find("select.wiktku-start-step-field").trigger("chosen:updated"); }); renderSectionTabs(); refresh(); $("html, body").animate({ scrollTop: sectionTabsDiv.offset().top - 20 }, 300); }); /** Re-render the tab bar to reflect current sections[] and activeSection. */ function renderSectionTabs() { // Detach (not remove) the button first: .empty() strips bound // event data from any children left inside it, which would // silently kill addSectionBtn's click handler on every re-render. addSectionBtn.$element.detach(); sectionTabsDiv.empty(); var lang = getValues().lang || ""; if (!lang) { sectionTabsDiv.hide(); return; } sectionTabsDiv.show(); $.each(sections, function (i) { var posVal = sections[i].pos || ""; var tabLabel = posVal ? capitalize(posVal) : ("Beş " + (i + 1)); var tab = $("<span></span>") .addClass("wiktku-section-tab") .text(tabLabel) .toggleClass("wiktku-tab-active", i === activeSection); (function (idx) { tab.on("click", function () { if (idx === activeSection) return; saveCurrentSection(); activeSection = idx; restoreSection(sections[activeSection]); refresh(); renderSectionTabs(); }); }(i)); sectionTabsDiv.append(tab); }); // Enable "Beş zêde bike" only when the active section has a pos chosen. var activePos = sections[activeSection] && sections[activeSection].pos ? sections[activeSection].pos : getValues().pos; addSectionBtn.setDisabled(!activePos); sectionTabsDiv.append(addSectionBtn.$element); } renderSectionTabs(); // Update the active tab's label whenever pos changes. startForm.on("change", "#wiktku-start-pos-field", function () { renderSectionTabs(); }); // Show the tab bar as soon as a language is selected. startForm.on("change", "#wiktku-start-lang-field", function () { renderSectionTabs(); }); var footer = $("<div id='wiktku-start-footer'></div>"); spinner = $(mw.html.element("img", { id: "wiktku-start-spinner", src: "//upload.wikimedia.org/wikipedia/commons/d/de/Ajax-loader.gif", alt: "Tê barkirin…", title: "Tê barkirin…" })); footer.append(spinner.hide()); continueBtn = new OO.ui.ButtonWidget({ id: "wiktku-unhide-editform", label: "Bişîne", flags: [ "primary", "progressive" ] }); continueBtn.on("click", function () { mw.notify("Tê şandin…", { type: "info", tag: "wiktku-submit" }); startForm.trigger("submit"); }); footer.append(continueBtn.$element); // "Edîtora çavkaniyê veke" button — inline fallback for the portlet link // which is invisible on mobile and easy to miss on desktop. var sourceEditorBtn = new OO.ui.ButtonWidget({ label: "Edîtora çavkaniyê veke", framed: false }); sourceEditorBtn.on("click", function () { destroy(); }); footer.append(sourceEditorBtn.$element); // ── Preview checkboxes ─────────────────────────────────────────────── // Wikitext preview (raw text panel) var previewCheck = $("<input type='checkbox' id='wiktku-preview-toggle'>"); var previewLabel = $("<label for='wiktku-preview-toggle'></label>") .text(" Pêşdîtina wîkîtekstê"); var previewPanel = $("<pre id='wiktku-preview-panel'></pre>").hide(); // Live rendered preview (parsed HTML panel, same logic as AjaxEdit). // Not available on mobile — API polling causes too many problems on small screens. var livePreviewCheck = null; var livePreviewPanel = null; if (!isMobile) { livePreviewCheck = $("<input type='checkbox' id='wiktku-live-preview-toggle'>"); livePreviewPanel = $("<div id='wiktku-live-preview-panel'></div>").hide(); } // Container that holds both panels and switches between stacked / side-by-side. var previewContainer = $("<div id='wiktku-preview-container'></div>"); previewContainer.append(previewPanel); if (!isMobile) previewContainer.append(livePreviewPanel); var previewTimer = null; var livePreviewIntervalId = -1; var livePreviewActive = false; // guards in-flight fetches after uncheck /** Rebuilds wikitext preview if its checkbox is checked. */ function schedulePreview() { if (!previewCheck.prop("checked")) return; clearTimeout(previewTimer); // Debounce: wait 400 ms after the last keystroke before rebuilding. previewTimer = setTimeout(function () { getWikitext(function (wikitext) { previewPanel.text(wikitext).show(); updatePanelLayout(); }); }, 400); } /** Fetches parsed HTML and populates the live preview panel. */ function loadLivePreview() { getWikitext(function (wikitext) { new mw.Api().parse(wikitext, { title: mw.config.get("wgPageName") }).done(function (html) { // Discard result if the user unchecked while the fetch was in flight. if (!livePreviewActive) return; livePreviewPanel.html(html).show(); updatePanelLayout(); }); }); } /** Adjusts panel widths depending on which previews are visible. */ function updatePanelLayout() { var wikitextVisible = previewCheck.prop("checked"); var liveVisible = livePreviewCheck && livePreviewCheck.prop("checked"); if (wikitextVisible && liveVisible) { // Side by side — each panel takes roughly half the available width. previewPanel.css({ "flex": "1 1 45%", "min-width": "280px" }); livePreviewPanel.css({ "flex": "1 1 45%", "min-width": "280px" }); } else { // Full width for whichever is visible — only touch panels that are // actually shown so that setting flex doesn't override display:none. if (wikitextVisible) previewPanel.css({ "flex": "1 1 100%", "min-width": "" }); if (liveVisible && livePreviewPanel) livePreviewPanel.css({ "flex": "1 1 100%", "min-width": "" }); } } previewCheck.on("change", function () { if ($(this).prop("checked")) { schedulePreview(); } else { clearTimeout(previewTimer); previewPanel.hide(); updatePanelLayout(); } }); if (!isMobile) { livePreviewCheck.on("change", function () { if ($(this).prop("checked")) { livePreviewActive = true; livePreviewPanel.show(); loadLivePreview(); livePreviewIntervalId = setInterval(loadLivePreview, 500); } else { livePreviewActive = false; clearInterval(livePreviewIntervalId); livePreviewIntervalId = -1; livePreviewPanel.hide().empty(); updatePanelLayout(); } }); } // Listen on all input/change events on the form and update both previews. startForm.on("input change", function () { schedulePreview(); }); footer.append($("<span style='margin-left:1em'></span>") .append(previewCheck).append(previewLabel)); if (!isMobile) { var livePreviewLabel = $("<label for='wiktku-live-preview-toggle'></label>") .text(" Pêşdîtina zindî"); footer.append($("<span style='margin-left:1em'></span>") .append(livePreviewCheck).append(livePreviewLabel)); } startForm.append(footer); $("#editform").hide().before(startForm); // Insert preview container (holds both panels) after the form. startForm.after(previewContainer); if (!isMobile) startForm.find("select").chosen(chosenOptions); refresh(); // Zimanan ji MediaWiki:Gadget-translation_editor.js/ziman.json bar bike. // Kodên ku bi "-pro" diqedin û navên ku "zimanê destan" tê de heye // tên derxistin. Zimanên xardkirî li serî dimînin, yên din // bi alfabeyê li dû wan tên. // Pinned choices come from MediaWiki:Gadget-start.js/data.json (langChoices), // already loaded into steps.lang.choices before build() runs. var pinnedChoices = steps.lang.choices.slice(); var pinnedCodes = $.map(pinnedChoices, function (choice) { return choice[0]; }); new mw.Api().get({ action: "query", prop: "revisions", titles: "MediaWiki:Gadget-translation_editor.js/ziman.json", rvprop: "content", rvslots: "main", formatversion: 2 }).then(function (data) { var page = data.query.pages[0]; var content = page && page.revisions && page.revisions[0].slots.main.content; var zimanData; try { zimanData = JSON.parse(content); } catch (e) { zimanData = {}; } var extraChoices = []; $.each(zimanData, function (code, name) { // Filter: skip proto-language codes and legendary/reconstructed langs. if (/-pro$/i.test(code)) return; if (/ziman[eê]\s+destan/i.test(name)) return; // Skip codes already in the pinned list (they are handled above). if (pinnedCodes.indexOf(code) !== -1) return; // sortKey: bare name without leading "zimanê " for sorting. var sortKey = name.replace(/^ziman[eê]\s+/i, ""); var choice = [code, name, sortKey]; extraChoices.push(choice); langsByCode[code] = choice; }); // Populate langsByCode for pinned choices too. $.each(pinnedChoices, function (i, choice) { // Ensure pinned choices have a sortKey (index 2). if (choice.length < 3) choice[2] = choice[1]; langsByCode[choice[0]] = choice; }); // Sort the extra choices alphabetically by sort key. extraChoices.sort(function (a, b) { return a[2].localeCompare(b[2], userLang); }); // Final list: pinned first, then the rest. var allChoices = pinnedChoices.concat(extraChoices); steps.lang.choices = allChoices; steps.trans.keys = allChoices; steps.dunde.keys = allChoices; steps.zarava.keys = getZaravaKeys(allChoices); var langMenu = $("#wiktku-start-lang-field"); populateMenus(langMenu, steps.lang.choices); langMenu.trigger("chosen:updated"); var transMenus = $("#wiktku-start-trans .wiktku-start-step-keyfield"); populateMenus(transMenus, steps.trans.keys, getDisabledKeys(steps.trans)); transMenus.trigger("chosen:updated"); var dundeMenus = $("#wiktku-start-dunde .wiktku-start-step-keyfield"); populateMenus(dundeMenus, steps.dunde.keys, getDisabledKeys(steps.dunde)); dundeMenus.trigger("chosen:updated"); var zaravaMenus = $("#wiktku-start-zarava .wiktku-start-step-keyfield"); populateMenus(zaravaMenus, steps.zarava.keys, getDisabledKeys(steps.zarava)); }); } mw.loader.using(["jquery.chosen", "mediawiki.api", "oojs-ui-core"], function () { if (!isMobile) { mw.notify( "Amûr dest pê dike, hinek bisekinin. Not: jkx Sentaks (sentaks highlighter) neaktîv bikin", { type: "info", tag: "wiktku-start-notice", autoHide: true, autoHideSeconds: 10 } ); } // Load metadata, langChoices, posChoices and tplDefs from the companion // data page so they can be updated without touching this script. new mw.Api().get({ action: "query", prop: "revisions", titles: "MediaWiki:Gadget-start.js/data.json", rvprop: "content", rvslots: "main", formatversion: 2 }).then(function (data) { var page = data.query.pages[0]; var content = page && page.revisions && page.revisions[0].slots.main.content; var d; try { d = JSON.parse(content); } catch (e) { d = {}; } // Populate metadata. if (d.metadata) $.extend(metadata, d.metadata); // Populate gender labels. if (d.genderLabels) $.extend(GENDER_BASE_LABELS, d.genderLabels); // Populate lang choices (pinned list used by build() → ziman.json loader). if (d.langChoices) steps.lang.choices = d.langChoices; // Populate POS choices. if (d.posChoices) steps.pos.choices = d.posChoices; // Populate template definitions for the dfn sense-block builder. if (d.tplDefs) steps.dfn.tplDefs = d.tplDefs; // Populate pos placeholder examples. if (d.posExamples) steps.dfn.posExamples = d.posExamples; // Populate citation template definitions for the quote widget. if (d.jederDefs) steps.dfn.jederDefs = d.jederDefs; // Populate pronunciation and etymology template insert lists. if (d.pronTpls) { steps.pron.pronTpls = d.pronTpls; steps.pron.refreshTplSelect(); } if (d.etymTpls) { steps.etym.etymTpls = d.etymTpls; steps.etym.refreshTplSelect(); } // Sync trans/dunde/zarava keys with the (now populated) lang choices. steps.trans.keys = steps.lang.choices; steps.dunde.keys = steps.lang.choices; steps.zarava.keys = getZaravaKeys(steps.lang.choices); }).always(build); }); }); //</nowiki> kvggoyhrf08x5ou2auhzp3me1a9u9qv 6265576 6265575 2026-07-19T14:31:04Z Wikihez 7344 6265576 javascript text/javascript // Li ser [[vi:MediaWiki:Gadget-start.js]] hatiye refaktorkirin. //<nowiki> $(function () { if (window.location.href.includes("editintro=User:Wikihez/creation/intro")) { return; // Do not run the script wextê WF:Bilez dişuxile } var ns = mw.config.get("wgNamespaceNumber"); if (ns && !(ns === 2 && mw.config.get("wgPageName").match(/\/ceribandin$|\/test$/))) { return; } var action = mw.config.get("wgAction"); var pageExists = !!mw.config.get("wgArticleId"); // "Zimanek lê zêde bike" mode: triggered from the portlet link below. var addLangMode = pageExists && mw.util.getParamValue("wiktkuaddlang") === "1"; // On a normal page view of an existing page, add the portlet link if (action === "view" && pageExists) { var targetContainer; var skin = mw.config.get('skin'); if (skin === 'vector-2022') { targetContainer = 'p-cactions'; } else if (skin === 'vector') { targetContainer = 'p-tb'; } else { targetContainer = 'p-views'; } mw.util.addPortletLink(targetContainer, mw.util.getUrl(mw.config.get("wgPageName"), { action: "submit", wiktkuaddlang: "1" }), "+Ziman/beşeke din", "ca-wiktku-addlang", "Ji vê rûpelê re ziman an jî beşeke nû zêde bike"); return; } if (!(action === "edit" || action === "submit")) { return; } if (!addLangMode && !$(".mw-newarticletext, .mw-newarticletextanon").length) { return; } function capitalize(str) { if (!str) return str; return str[0].toUpperCase() + str.substr(1); } function decapitalize(str) { if (!str) return str; return str[0].toLowerCase() + str.substr(1); } function escapeRegExp(str) { return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); } function stripWikilinks(str) { return str.replace(/\[\[([^\]|]+)(?:\|([^\]]+))?\]\]/g, function (m, target, display) { return display || target; }); } function insertAtCursor(el, text) { var start = el.selectionStart; var end = el.selectionEnd; var val = el.value; el.value = val.slice(0, start) + text + val.slice(end); var pos = start + text.length; el.selectionStart = el.selectionEnd = pos; } var pageName = mw.config.get("wgPageName").replaceAll(/_/g, " "); if (ns) pageName = pageName.replace(/.*\//, ""); var pageNameRe = escapeRegExp(pageName); var userLang = mw.config.get("wgUserLanguage"); // Mobile detection: MobileFrontend sets wgMFMode, or fall back to touch check. var isMobile = !!mw.config.get("wgMFMode") || window.matchMedia("(pointer: coarse)").matches; var chosenOptions = { width: "20em", disable_search_threshold: 0, placeholder_text_single: "Yekî hilbijêre", placeholder_text_multiple: "Hilbijêre", no_results_text: "Nehat dîtin", enable_split_word_search: true, search_contains: true }; function wrapNativeSelect(select) { var placeholder = select.attr("data-placeholder") || "Lê bigere…"; // Hide the native select — we drive it programmatically. select.hide(); var wrapper = $("<span class='wiktku-native-select-wrap'></span>"); var textInput = $("<input type='search' autocomplete='off'>") .attr("placeholder", placeholder) .addClass("wiktku-start-narrow wiktku-ac-input"); var resultsList = $("<ul class='wiktku-ac-results'></ul>").hide(); // Full option cache — rebuilt when chosen:updated fires. var allOptions = []; function cacheOptions() { allOptions = []; select.find("option").each(function () { var v = $(this).val(); if (!v) return; // skip the empty placeholder option allOptions.push({ value: v, text: $(this).text(), disabled: $(this).prop("disabled") }); }); } cacheOptions(); function showResults(query) { var q = query.trim().toLowerCase(); resultsList.empty(); var matched; if (q) { matched = []; $.each(allOptions, function (_, o) { if (o.disabled) return; var codeMatch = o.value.toLowerCase().indexOf(q) !== -1; var nameMatch = o.text.toLowerCase().indexOf(q) !== -1; if (codeMatch || nameMatch) { matched.push({ opt: o, codeMatch: codeMatch }); } }); // Code matches (especially prefix matches) come first. matched.sort(function (a, b) { var aCode = a.opt.value.toLowerCase(); var bCode = b.opt.value.toLowerCase(); var aPrefix = aCode.indexOf(q) === 0; var bPrefix = bCode.indexOf(q) === 0; if (aPrefix !== bPrefix) return aPrefix ? -1 : 1; if (a.codeMatch !== b.codeMatch) return a.codeMatch ? -1 : 1; return 0; }); matched = matched.map(function (item) { return item.opt; }); } else { matched = allOptions.filter(function (o) { return !o.disabled; }); } if (!matched.length) { resultsList.hide(); return; } $.each(matched.slice(0, 50), function (_, opt) { var li = $("<li></li>").text(opt.text).attr("data-value", opt.value); // Use touchend instead of touchstart so that a scroll gesture does // not accidentally select an item. We track whether the finger moved // between touchstart and touchend — if it did, it was a scroll. var touchMoved = false; li.on("touchstart", function () { touchMoved = false; }); li.on("touchmove", function () { touchMoved = true; }); li.on("touchend", function (e) { if (touchMoved) return; // was a scroll, not a tap e.preventDefault(); selectOption(opt.value, opt.text); }); // Keep mousedown for desktop fallback. li.on("mousedown", function (e) { e.preventDefault(); selectOption(opt.value, opt.text); }); resultsList.append(li); }); // Position the list above or below depending on available viewport space. var inputRect = textInput[0].getBoundingClientRect(); var viewportH = window.innerHeight; var spaceBelow = viewportH - inputRect.bottom - 8; var spaceAbove = inputRect.top - 8; var maxH = Math.min(224, Math.max(spaceBelow, spaceAbove)); // 224px ≈ 14em resultsList.css({ "max-height": maxH + "px", "top": spaceBelow >= spaceAbove ? "100%" : "auto", "bottom": spaceBelow >= spaceAbove ? "auto" : "100%" }); resultsList.show(); } function selectOption(value, text) { textInput.val(text); select.val(value); resultsList.hide(); select.trigger("change"); } textInput.on("input focus", function () { showResults($(this).val()); }); textInput.on("blur", function () { // Short delay so a touchstart on a result item fires first. setTimeout(function () { resultsList.hide(); }, 200); }); // chosen:updated → re-cache (called after ziman.json loads). select.on("chosen:updated", function () { cacheOptions(); // If a value is already selected, keep the display text in sync. var cur = select.val(); if (cur) { var match = $.grep(allOptions, function (o) { return o.value === cur; })[0]; if (match) textInput.val(match.text); } }); // No-op .chosen() so desktop call-sites don't need guarding. select.chosen = function () { return select; }; wrapper.append(textInput).append(resultsList).append(select); return wrapper; } var langsByCode = {}; // Populated from [[MediaWiki:Gadget-start.js/data.json]] at runtime. var metadata = {}; // Zaravayên kurdî yên ku di beşa "Bi zaravayên din" de tên pêşkêşkirin — // ev kod ji beşa Werger têne derxistin daku heman zimên du caran neyê xwendin. var ZARAVA_LANG_CODES = ["ckb", "sdh", "lki", "hac", "zza"]; function getZaravaKeys(choices) { var byCode = {}; $.each(choices || [], function (_, c) { byCode[c[0]] = c; }); var result = []; $.each(ZARAVA_LANG_CODES, function (_, code) { if (byCode[code]) result.push(byCode[code]); }); return result; } function needsTransliteration(langCode) { var meta = metadata[langCode]; if (!meta || !meta.sc) return false; var scripts = Array.isArray(meta.sc) ? meta.sc : [meta.sc]; return scripts.length > 0 && scripts[0] !== "Latn"; } // Kodên cinsiyetê yên di metadata.g de — ji data.json tê dagirtin var GENDER_BASE_LABELS = {}; // Sub-lists that only make sense for a plain (non-şablon) sense — hidden // when a şablon (e.g. {{guharto|…}}) is chosen for that sense, since a // template-based sense has no "own" gloss for alternate forms, synonyms, // antonyms, coordinate terms, hypernyms or hyponyms to attach to. Etîket, // Nimûne and Jêgirtin stay visible either way. var HIDDEN_ON_TPL_GROUPS = [ "wiktku-dfn-alternativ", "wiktku-dfn-hevmane", "wiktku-dfn-dijmane", "wiktku-dfn-koordine", "wiktku-dfn-jornav", "wiktku-dfn-jernav" ]; function genderLabel(code) { if (code === "p") return "Pirjimar"; var pluralMatch = code.match(/^(.+)-p$/); if (pluralMatch && GENDER_BASE_LABELS[pluralMatch[1]]) { return GENDER_BASE_LABELS[pluralMatch[1]] + " (pirjimar)"; } return GENDER_BASE_LABELS[code] || code; } /** * True if a sense has any content worth keeping besides its mane text — * etîket, hevmane/dijmane/koordîne/etc. word lists, nimûne, or jêder * (quote). Used so a sense with an empty mane but filled-in extra * fields still gets emitted (with {{mane?}} standing in for the gloss) * instead of being silently dropped. */ function senseHasExtraContent(s) { if (s.etiket && $.grep(s.etiket, function (e) { return $.trim(e) !== ""; }).length) return true; if (s.kategori && $.grep(s.kategori, function (k) { return $.trim(k) !== ""; }).length) return true; if (s.alternativ.length || s.hevmane.length || s.dijmane.length || s.koordine.length || s.jornav.length || s.jernav.length) return true; if (s.nimune && $.grep(s.nimune, function (n) { return (typeof n === "object" ? n.text : n) !== ""; }).length > 0) return true; if (s.jeder && $.grep(s.jeder, function (j) { return j && j.quote; }).length > 0) return true; return false; } /** * formatNimune: each nimûne item can be { text, tr, t }: * text — example text * tr — transliteration (only when the language needs it) * t — Kurdish translation (third positional param, no key) */ function formatNimune(nimunes, lang, hasJeder) { var hasNimune = nimunes && $.grep(nimunes, function (n) { return (typeof n === "object" ? n.text : n) !== ""; }).length > 0; if (!hasNimune) { return hasJeder ? "" : "\n#* {{bênimûne|" + lang + "}}"; } return $.map(nimunes, function (n) { var text = typeof n === "object" ? n.text : n; if (!text) return undefined; var bolded = text.replace( new RegExp("(" + pageNameRe + "([^( |,|;|\\?|\\.|\\!)]+)?)", "ig"), "'''$1'''"); var tpl = "\n#: {{nm|" + lang + "|" + bolded; if (typeof n === "object") { if (n.tr) tpl += "|tr=" + n.tr; // Translation as third positional param (no key needed). if (n.t) tpl += "|" + n.t; } // Short examples fit on one line together with their translation. // rêz=1 is not used for ku — definitions are shown on separate lines there. if (text.length < 200 && lang !== "ku") tpl += "|rêz=1"; tpl += "}}"; return tpl; }).join(""); } /** * Formats a list of jêder (quote/citation) objects into wikitext lines. * Each entry that has no quote text is skipped. Returns "" when the list * is empty or every entry is blank. * * #* {{jêder-…|lang|jêgirtin=…|tr=…|tercime=…|…fields…}} * * When no template is chosen, the generic {{jêder|…}} template is used * instead. Its 2nd positional param is the user's freeform "bi destê xwe * binivîsim" source text when supplied, or the çavkanî? placeholder otherwise. * If that text contains "=" it is passed as |2=… instead of a bare * positional param, since MediaWiki would otherwise misparse it as its * own key=value pair and break the template: * #* {{jêder|lang|jêgirtin=…|tr=…|tercime=…|<manual source or çavkanî?>}} */ function formatJeder(jederList, lang) { if (!jederList || !jederList.length) return ""; return $.map(jederList, function (jeder) { if (!jeder || !jeder.quote) return undefined; if (jeder.jederTpl) { var cite = "\n#* {{" + jeder.jederTpl + "|" + lang; cite += "|jêgirtin=" + jeder.quote; if (jeder.quoteTr) cite += "|tr=" + jeder.quoteTr; if (jeder.quoteT) cite += "|tercime=" + jeder.quoteT; $.each(jeder.jêderFields || {}, function (key, val) { if (val) cite += "|" + key + "=" + val; }); cite += "}}"; return cite; } var out = "\n#* {{jêder|" + lang + "|jêgirtin=" + jeder.quote; if (jeder.quoteTr) out += "|tr=" + jeder.quoteTr; if (jeder.quoteT) out += "|tercime=" + jeder.quoteT; var srcParam = jeder.jederManual ? jeder.jederManual : "çavkanî?"; // A positional param containing "=" gets parsed as its own key=value // pair by MediaWiki and breaks the template, so force it to be // explicitly named (|2=) whenever that's the case. out += (srcParam.indexOf("=") !== -1 ? "|2=" : "|") + srcParam; out += "}}"; return out; }).join(""); } function makeWordListStep(id, name, question_fmt, header, templateName) { return { id: id, name: name, question_fmt: question_fmt, multiple: true, narrow: true, visible: function (values) { return values.lang && values.pos; }, output: function (values) { var words = $.grep(values[id] || [], function (w) { return !!w; }); if (!words.length) return ""; var lang = values.lang; var section = "\n==== " + header + " ====\n"; if (words.length === 1) { // Single word — keep the simple inline template. return section + "* {{" + templateName + "|" + lang + "|" + words[0] + "}}\n"; } // Multiple words — use {{kol3}} with one positional param per word. var params = "cure=" + header + "\n" + $.map(words, function (w) { return "|" + w; }).join("\n"); return section + "{{kol3|" + lang + "|" + params + "\n}}\n"; } }; } var steps = { lang: { id: "lang", required: true, name: "ziman", question_fmt: '"' + pageName + '" bi çi zimanî ye?', question_br: true, // Populated from [[MediaWiki:Gadget-start.js/data.json]] (langChoices). choices: [], output: function (values) { return "== {{ziman|" + values.lang + "}} ==\n"; } }, pron: { id: "pron", name: "bilêvkirin", question_fmt: '"' + pageName + '" çawa tê telafûzkirin?', // pronTpls populated from data.json pronTpls: [], visible: function (values) { if (!values.lang) return false; // In addLangMode, only skip pron when this langcode's section // already exists in the page — if it's a new language, show it. if (addLangMode) { var existing = $("#wpTextbox1").val() || ""; var header = "== {{ziman|" + values.lang + "}} =="; return existing.indexOf(header) === -1; } return true; }, /** Fills (or refills) the insert-dropdown from the current pronTpls array, filtering by language. */ refreshTplSelect: function () { var sel = $("#wiktku-start-pron .wiktku-tpl-insert-select"); if (!sel.length) return; var lang = getValues().lang || ""; sel.find("option[value!='']").remove(); $.each(steps.pron.pronTpls, function (_, tpl) { // Filter: if tpl.langs exists, only show if lang is in that list; otherwise show always var allowed = !tpl.langs || tpl.langs.indexOf(lang) !== -1; if (allowed) { sel.append($("<option></option>") .val(tpl.snippet) .text(tpl.name + " — " + tpl.desc) .attr("data-nolang", tpl.noLang ? "1" : "")); } }); // Notify Chosen that the option list has changed (no-op on mobile). if (!isMobile) sel.trigger("chosen:updated"); }, build: function (stepDiv) { if (stepDiv.find(".wiktku-pron-wrap").length) return null; var wrap = $("<div class='wiktku-pron-wrap'></div>"); var ta = $("<textarea></textarea>") .attr("name", "wiktku-pron-" + $.now()) .attr("class", "wiktku-start-step-field wiktku-pron-text") .attr("rows", 4) .attr("placeholder", "Nimûne: {{IPA|ku|/pɛɪ̯n/}} yan {{kîte|ku|he|ce|ki|rin}}"); // Template insert dropdown — filtered by language. var sel = $("<select class='wiktku-tpl-insert-select'></select>"); sel.append($("<option value=''>— şablonek lê zêde bike —</option>")); var lang = getValues().lang || ""; $.each(steps.pron.pronTpls, function (_, tpl) { // Filter: if tpl.langs exists, only show if lang is in that list; otherwise show always var allowed = !tpl.langs || tpl.langs.indexOf(lang) !== -1; if (allowed) { sel.append($("<option></option>") .val(tpl.snippet) .text(tpl.name + " — " + tpl.desc) .attr("data-nolang", tpl.noLang ? "1" : "")); } }); sel.on("change", function () { var snippet = $(this).val(); if (!snippet) return; var lang = getValues().lang || ""; // Check if the selected option has noLang flag var selectedOption = sel.find("option:selected"); var hasNoLang = selectedOption.attr("data-nolang") === "1"; if (!hasNoLang) { snippet = snippet.replace(/CODE/g, lang).replace(/SOURCELANG/g, "?"); } insertAtCursor(ta[0], snippet); $(this).val(""); ta.focus(); }); wrap.append(sel).append($("<br>")).append(ta); stepDiv.append(wrap); return ta; }, output: function () { var text = $.trim($("#wiktku-start-pron .wiktku-pron-text").val()); if (!text) return ""; var lines = text.split("\n"); var out = $.map(lines, function (line) { line = $.trim(line); if (!line) return undefined; return line.charAt(0) === "*" ? line : "* " + line; }).join("\n"); return "\n=== Bilêvkirin ===\n" + out + "\n"; } }, pos: { id: "pos", required: true, name: "Cureyê rêzimanî", question_fmt: 'Cureyê rêzimanî yê "' + pageName + '" çi ye?', visible: function (values) { return values.lang; }, question_br: true, // Populated from [[MediaWiki:Gadget-start.js/data.json]] (posChoices). choices: [], output: function (values) { var pos = values.pos || ""; var cinsiyet = values.cinsiyet || ""; // from the cinsiyet step var lekTur = values.lektur || ""; // from the lêker transitivity step var capitalizedPos = capitalize(pos); var outputString = "\n=== " + capitalizedPos + " ===\n"; // Add ku-tewîn-nav for single-word navdêr/serenav with known gender. if (!pageName.includes(" ") && cinsiyet && GENDER_BASE_LABELS[cinsiyet] && (pos === "navdêr" || pos === "serenav") && values.lang === "ku") { outputString += "{{ku-tewîn-nav|" + pageName + "|" + GENDER_BASE_LABELS[cinsiyet]; if (pos === "serenav") outputString += "|y"; outputString += "}}\n"; } outputString += "{{" + pos + "|" + values.lang; if (pos === "navdêr" || pos === "serenav") { if (cinsiyet) { outputString += "|c=" + cinsiyet; } else if (values.lang === "ku") { // Unknown gender — prompt editor to fill it in. outputString += "|c=?"; } } else if (/^lêker/.test(pos) && lekTur) { outputString += "|c=" + lekTur; } if (values.tr) { outputString += "|tr=" + values.tr; } outputString += "}}\n"; return outputString; } }, /** * cinsiyet (grammatical gender) — only shown for navdêr/serenav, û * tenê ger metadata ji bo zimanê hilbijartî lîsteyeke "g" (cinsiyet) * were dayîn. Opsiyonên vê gavê ne sabît in — ji metadata[values.lang].g * têne çêkirin, ji ber ku di hemû zimanan de cinsiyet tine. */ cinsiyet: { id: "cinsiyet", name: "cinsiyet", question_fmt: 'Cinsiyeta "' + pageName + '" çi ye?', question_br: true, visible: function (values) { var meta = metadata[values.lang]; return !!(values.lang && (values.pos === "navdêr" || values.pos === "serenav") && meta && meta.g && meta.g.length); }, build: function (stepDiv, values) { var select = stepDiv.find("select.wiktku-start-step-field"); if (!select.length) { select = $(mw.html.element("select", { "class": "wiktku-start-step-field", id: "wiktku-start-cinsiyet-field" })); stepDiv.append(select); } if (!values) return select; var meta = metadata[values.lang]; var codes = (meta && meta.g) || []; var prevVal = select.val(); var choices = $.map(codes, function (code) { return [[code, genderLabel(code)]]; }); populateMenus(select, choices); if ($.grep(choices, function (c) { return c[0] === prevVal; }).length) { select.val(prevVal); } if (!isMobile) select.trigger("chosen:updated"); return select; }, output: function () { return ""; } // consumed by pos.output }, /** * Lêker transitivity — only shown for any lêker variant. */ lektur: { id: "lektur", name: "Cureyê lêkerê (fiîlê)", question_fmt: "Cureyê lêkerê (fiîlê) çi ye?", question_br: true, visible: function (values) { return values.lang && values.pos && /^lêker/.test(values.pos); }, // Dictionary: value → display label. Add new types here. choices: [ ["gh", "gerguhêz"], ['x-gh', 'xwerû-gerguhêz'], ['p-gh', 'pêkhatî-gerguhêz'], ['h-gh', 'hevedudanî-gerguhêz'], ['b-gh', 'biwêjî-gerguhêz'], ["ngh", "negerguhêz"], ['x-ngh', 'xwerû-negerguhêz'], ['p-ngh', 'pêkhatî-negerguhêz'], ['h-ngh', 'hevedudanî-negerguhêz'], ['b-ngh', 'biwêjî-negerguhêz'] ], output: function () { return ""; } // consumed by pos.output }, tr: { id: "tr", name: "transkrîpsiyon", question_fmt: "Transkrîpsiyona kelîmeyê", multiple: false, narrow: true, visible: function (values) { return values.lang && values.pos && needsTransliteration(values.lang); } }, dfn: { id: "dfn", // required: true, ger mane tinebe [[Şablon:mane?]] bi kar bîne name: "Mane", question_fmt: "Maneya kelîmeyê binivîse. Mane otomatîk tê lînkkirin! Ji bo tercimeyan beşa 'Werger' bi kar bîne!", multiple: true, ordered: true, rows: 3, visible: function (values) { return values.lang && values.pos; }, example: function (values) { // posExamples loaded from [[MediaWiki:Gadget-start.js/data.json]]. var examples = steps.dfn.posExamples || {}; var full = values.pos || ""; return examples[full] || ""; }, /** * Builds one sense block (<li>) inside the ordered list. * Each block contains: * - a textarea for the definition * - an expandable nimûne list * - single-row sub-lists for formên alternatîv, hevmane, dijmane */ buildSenseBlock: function (stepDiv) { var block = $("<li class='wiktku-dfn-sense'></li>"); // — Mane textarea (declared first so the template handler can reference it) — var dfnArea = $("<textarea></textarea>") .attr("name", "wiktku-dfn-mane-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("class", "wiktku-start-step-field wiktku-dfn-mane") .attr("rows", 6) .attr("placeholder", "Mane…"); dfnArea.on("input", function () { steps.dfn.onDfnInput(stepDiv, block, this); }); // — Template selector (optional — replaces mane when chosen) — // Template definitions loaded from [[MediaWiki:Gadget-start.js/data.json]]. var tplDefs = steps.dfn.tplDefs || []; // Cache of all non-placeholder option elements — used by updateTplOptions // to remove/re-add options (the only approach compatible with Chosen.js). var _allTplOptions = []; var tplSelect = $(mw.html.element("select", { "class": "wiktku-dfn-tpl-select" })); tplSelect.append($("<option value=''>— yan jî şablonek hilbijêre —</option>")); $.each(tplDefs, function (_, tpl) { var opt = $("<option></option>") .val(tpl.name) .text(tpl.name) .attr("data-langs", tpl.langs ? tpl.langs.join(",") : "") .attr("data-nolang", tpl.noLang ? "1" : ""); tplSelect.append(opt); _allTplOptions.push(opt[0]); }); function updateTplOptions() { var lang = getValues().lang || ""; var currentVal = tplSelect.val(); var currentStillValid = false; // Detach all non-placeholder options, then re-attach only the visible ones. // This is the only approach that works correctly with both native <select> // and Chosen.js on desktop. tplSelect.find("option[value!='']").detach(); $.each(_allTplOptions, function (_, opt) { var allowed = $(opt).attr("data-langs"); var visible = !allowed || allowed.split(",").indexOf(lang) !== -1; if (visible) { tplSelect.append(opt); if ($(opt).val() === currentVal) currentStillValid = true; } }); if (!isMobile) tplSelect.trigger("chosen:updated"); if (currentVal && !currentStillValid) { tplSelect.val(""); dfnArea.show(); tplTitleInput.hide().val(""); } } // Store updater on the element so refresh() can call it for all blocks. tplSelect.data("updateOptions", updateTplOptions); var tplTitleInput = $("<input type='text'>") .addClass("wiktku-dfn-tpl-title wiktku-start-narrow") .attr("placeholder", "Navê rûpelê…") .hide(); // Grow the sense list when the title field of the last block gets content, // mirroring what onDfnInput does for the plain mane textarea. tplTitleInput.on("input", function () { steps.dfn.onDfnInput(stepDiv, block, this); }); /** * When a şablon sense is chosen, formên alternatîv/hevmane/dijmane/ * termên koordîne/jornav/jêrnav don't apply (there's no plain gloss * to hang them off), so hide those subgroups. Etîket, Nimûne and * Jêgirtin stay visible and still usable for a şablon sense. */ function updateFieldVisibility() { var isTpl = !!tplSelect.val(); $.each(HIDDEN_ON_TPL_GROUPS, function (_, cls) { block.find("." + cls + "-group").toggle(!isTpl); }); } // Store on the block so restoreDfn() can re-sync visibility // after programmatically setting tplSelect's value. block.data("updateFieldVisibility", updateFieldVisibility); tplSelect.on("change", function () { var chosen = $(this).val(); if (chosen) { dfnArea.hide(); tplTitleInput.show().focus(); } else { dfnArea.show(); tplTitleInput.hide().val(""); } updateFieldVisibility(); // Re-run refresh so the Werger step visibility updates. refresh(); }); var tplRow = $("<div></div>").addClass("wiktku-dfn-tpl-row") .append(tplSelect).append(" ").append(tplTitleInput); block.append(tplRow); block.append(dfnArea); // Apply lang filter on initial build. updateTplOptions(); // — Sub-field groups — // All groups are always visible with a placeholder textarea. // Nimûne is last in the DOM and last in the output. var allGroups = [ { cls: "wiktku-dfn-etiket", label: "Etîket", rows: 1, narrow: true, izah: "xisûsen, Mêrdîn, anatomî, Badînî" }, { cls: "wiktku-dfn-kategori", label: "Kategorî", rows: 1, narrow: true, izah: "Kategoriya ku ev mane lê tê zêdekirin" }, { cls: "wiktku-dfn-alternativ", label: "Formên alternatîv", rows: 1, narrow: true, izah: "Varyantên vê kelîmeyê" }, { cls: "wiktku-dfn-hevmane", label: "Hevmane", rows: 1, narrow: true, izah: "Spehî hevmaneya Bedew e." }, { cls: "wiktku-dfn-dijmane", label: "Dijmane", rows: 1, narrow: true, izah: "Zengîn dijmaneya feqîr e." }, { cls: "wiktku-dfn-koordine", label: "Termên koordîne", rows: 1, narrow: true, izah: "Pisîk û kûçik termên koordîne ne çunkî Jornavên wan gelek in" }, { cls: "wiktku-dfn-jornav", label: "Jornav", rows: 1, narrow: true, izah: "Heywan jornavê guhandar e" }, { cls: "wiktku-dfn-jernav", label: "Jêrnav", rows: 1, narrow: true, izah: "Guhandar jêrnavê heywan e" }, { cls: "wiktku-dfn-nimune", label: "Nimûne", rows: 2, narrow: false } ]; $.each(allGroups, function (_, g) { var groupDiv = $("<div></div>").addClass("wiktku-dfn-subgroup " + g.cls + "-group"); function buildNimuneLi() { var lang = getValues().lang || ""; var li = $("<li></li>").addClass("wiktku-dfn-nimune-li"); var mainTa = $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-text-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", g.rows) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-text") .attr("placeholder", "Nimûneya emilandina kelîmeyê tu bi xwe binivîse…"); mainTa.on("input", function () { var val = $.trim($(this).val()); var isLast = li.is(list.children("li:last-child")); if (val && isLast) { list.append(buildNimuneLi()); } }); li.append(mainTa); var subWrap = $("<div></div>").addClass("wiktku-dfn-nimune-sub"); if (needsTransliteration(lang)) { subWrap.append( $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-tr-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 5) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-tr") .attr("placeholder", "Transkrîpsiyona bi alfabeya latînî") ); } if (lang && lang !== "ku") { subWrap.append( $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-t-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 5) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-t") .attr("placeholder", "Tercimeya kurmancî") ); } if (subWrap.children().length) li.append(subWrap); return li; } if (g.cls === "wiktku-dfn-nimune") { // Nimûne — compound widget with tr/t sub-fields. var lbl = $("<span></span>").addClass("wiktku-dfn-sublabel").text(g.label + ": "); var list = $("<ol></ol>").addClass("wiktku-dfn-sublist " + g.cls + "-list"); groupDiv.data("buildNimuneLi", buildNimuneLi); list.append(buildNimuneLi()); groupDiv.append(lbl).append(list); block.append(groupDiv); } else { // Regular always-visible group — label + growing textarea list. var lbl = $("<span></span>").addClass("wiktku-dfn-sublabel").text(g.label + ": " + g.izah); var list = $("<ol></ol>").addClass("wiktku-dfn-sublist " + g.cls + "-list"); var firstInput = $("<textarea></textarea>") .attr("name", g.cls + "-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", g.rows) .attr("class", "wiktku-dfn-subfield" + (g.narrow ? " wiktku-start-narrow" : "")) .attr("placeholder", g.label + "…"); firstInput.on("input", function () { steps.dfn.onSubInput(list, this, g.rows, g.narrow); }); list.append($("<li></li>").append(firstInput)); groupDiv.append(lbl).append(list); block.append(groupDiv); } }); // — Jêder (quote / citation) group — a growing list, sibling to Nimûne — // Structured the same way as Nimûne (ol.wiktku-dfn-sublist > li) so it // lines up at the same indentation, and so that typing into the last // citation's Jêgirtin box automatically opens a fresh empty one below it. (function () { var jederGroupDiv = $("<div></div>").addClass("wiktku-dfn-subgroup wiktku-dfn-jeder-group"); var jederLbl = $("<span></span>").addClass("wiktku-dfn-sublabel").text("Jêgirtin: "); var jederList = $("<ol></ol>").addClass("wiktku-dfn-sublist wiktku-dfn-jeder-list"); function buildJederLi() { var lang = getValues().lang || ""; var li = $("<li></li>").addClass("wiktku-dfn-jeder-li"); var dragHandle = $("<span></span>") .addClass("wiktku-jeder-drag-handle") .attr("title", "Bişkûne û bikişîne da ku rêzê biguhezîne"); // Quote text textarea var quoteTa = $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-quote-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 2) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-quote") .attr("placeholder", "Nimûneya emilandinê ji kitêb an çavkaniyeke din binivîse"); quoteTa.on("input", function () { var val = $.trim($(this).val()); var isLast = li.is(jederList.children("li:last-child")); if (val && isLast) { jederList.append(buildJederLi()); } }); li.append(dragHandle).append(quoteTa); // tr/t sub-fields for the quote — shown as needed for the language. var quoteSubWrap = $("<div></div>").addClass("wiktku-dfn-quote-sub"); if (needsTransliteration(lang)) { quoteSubWrap.append( $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-quote-tr-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 2) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-quote-tr") .attr("placeholder", "Transkrîpsiyona jêgirtinê…") ); } if (lang && lang !== "ku") { quoteSubWrap.append( $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-quote-t-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 2) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-quote-t") .attr("placeholder", "Tercimeya jêgirtinê bi kurmancî") ); } if (quoteSubWrap.children().length) li.append(quoteSubWrap); // Citoid auto-fill: fetch citation data from a URL, DOI or ISBN and // prefill the source şablon + fields below (see Gadget-citoid-helper.js). var citoidWrap = $("<div></div>").addClass("wiktku-dfn-quote-citoid"); var citoidInput = $("<input type='text'>") .addClass("wiktku-dfn-quote-citoid-input wiktku-start-narrow") .attr("placeholder", "URL, DOI an ISBN binivîse ku otomatîk were tijekirin…"); var citoidBtn = new OO.ui.ButtonWidget({ label: "Bi Citoid bîne", classes: [ "wiktku-dfn-quote-citoid-btn" ] }); var citoidStatus = $("<span></span>").addClass("wiktku-dfn-quote-citoid-status"); /** * Fetches citation data from Citoid and applies it to this * citation's şablon selector + fields. Mirrors the logic in * Form.prototype._fillFromCitoid (Gadget-wikt.add-examples.js): * - only (re)selects the şablon when it actually differs from * what's already chosen, so a repeat fetch doesn't wipe out * a template the user already picked; * - only fills fields that are currently empty, so it never * overwrites something the user typed by hand; * - falls back to the freeform "bi destê xwe binivîsim" source * only when nothing was typed there yet. */ function runCitoidFetch() { var query = $.trim(citoidInput.val()); if (!query) { mw.notify("Ji kerema xwe re pêşî URL, DOI an ISBNyekê binivîse."); return; } citoidBtn.setDisabled(true); citoidStatus.text("Tê anîn…"); wikt.citoidHelper.ensure().then(function () { return wikt.citoid.fetchJederFields(query); }).then(function (result) { var jederKey = result.jederKey; var hasTpl = !!jederKey && srcSel.find("option[value='" + jederKey + "']").length > 0; var targetVal = hasTpl ? jederKey : "__manual__"; // Only (re)select — and thus rebuild — the field rows if // we're switching to a different şablon than what's // already chosen, so a second fetch doesn't clear fields // the user already filled in by hand. if (srcSel.val() !== targetVal) { srcSel.val(targetVal).trigger("change"); srcSel.trigger("chosen:updated"); } if (hasTpl) { // Tenê qadên vala tijî bike. $.each(result.fields, function (key, val) { var input = srcFields.find("[data-field-key='" + key + "']"); if (input.length && !$.trim(input.val())) { input.val(val); } }); } else { // Şablonek nehat naskirin ji bo vê itemType — rêzikeke // çavkaniyê ya bi destan a ji qadên Citoid tê çêkirin, // lê tenê ger qada destan vala be. var manualField = srcFields.find(".wiktku-dfn-quote-src-manual"); if (!$.trim(manualField.val())) { var parts = []; $.each(["nivîskar", "sernav", "websîte", "kovar", "weşanxane", "sal", "url"], function (_, k) { if (result.fields[k]) parts.push(result.fields[k]); }); manualField.val(parts.join(", ")); } } citoidStatus.text(""); }, function (errorMsg) { citoidStatus.text(typeof errorMsg === "string" ? errorMsg : "Nehat dîtin. Kontrol bike ka URL/DOI/ISBN rast e."); }).always(function () { citoidBtn.setDisabled(false); }); } citoidBtn.on("click", runCitoidFetch); citoidInput.on("keydown", function (e) { if (e.which === 13) { // Enter e.preventDefault(); runCitoidFetch(); } }); citoidWrap.append(citoidInput).append(citoidBtn.$element).append(citoidStatus); // Source template selector, specific to this citation. var srcSel = $("<select></select>").addClass("wiktku-dfn-quote-src-sel"); srcSel.append($("<option value=''>— Çavkaniyê hilbijêre —</option>")); srcSel.append($("<option></option>").val("__manual__").text("Bi destê xwe binivîsim")); var jederDefs = steps.dfn.jederDefs || {}; $.each(jederDefs, function (tplName, def) { srcSel.append($("<option></option>").val(tplName).text(def.label)); }); // Dynamic source fields container. var srcFields = $("<div></div>").addClass("wiktku-dfn-quote-src-fields"); srcSel.on("change", function () { srcFields.empty(); var chosen = $(this).val(); if (!chosen) return; if (chosen === "__manual__") { // Freeform source, written by the user — becomes the 2nd // positional param of {{jêder|lang|…}} instead of çavkanî?. srcFields.append( $("<textarea></textarea>") .attr("rows", 4) .addClass("wiktku-dfn-subfield wiktku-dfn-quote-src-manual") .attr("placeholder", "Çavkaniyê bi destê xwe binivîse…") ); return; } var def = (steps.dfn.jederDefs || {})[chosen]; if (!def) return; $.each(def.fields, function (_, f) { var row = $("<div></div>").addClass("wiktku-dfn-quote-src-row"); var fieldLbl = $("<label></label>").text(f.label + ": "); var inp = $("<textarea></textarea>") .attr("rows", 2) .addClass("wiktku-dfn-quote-src-input wiktku-start-narrow") .attr("data-field-key", f.key) .attr("placeholder", f.label + "…"); row.append(fieldLbl).append(inp); srcFields.append(row); }); }); li.append(citoidWrap).append(srcSel).append(srcFields); return li; } jederGroupDiv.data("buildJederLi", buildJederLi); jederList.append(buildJederLi()); // Make citation rows sortable (drag to reorder). // The last row is always the empty trailing row — cancel its drag. mw.loader.using("jquery.ui.sortable", function () { jederList.sortable({ handle: ".wiktku-jeder-drag-handle", axis: "y", items: "li:not(:last-child)", tolerance: "pointer" }); }); jederGroupDiv.append(jederLbl).append(jederList); block.append(jederGroupDiv); }()); // Apply the initial hide/show state for the sub-groups (matches // tplSelect's starting value, which is normally empty). updateFieldVisibility(); return block; }, /** Grows the sense list when the last mane textarea gets content. */ onDfnInput: function (stepDiv, block, textarea) { var val = $.trim($(textarea).val()); var list = stepDiv.find("ol.wiktku-dfn-list"); var isLast = block.is(list.children("li:last-child")); if (val && isLast) { var newBlock = steps.dfn.buildSenseBlock(stepDiv); list.append(newBlock); // Apply Chosen to the new block's template selector on desktop. if (!isMobile) newBlock.find("select.wiktku-dfn-tpl-select").chosen(chosenOptions); } refresh(); }, /** Grows a sub-list (nimûne/formên alternatîv/hevmane/dijmane/termên koordîne) on input. */ onSubInput: function (list, input, rows, narrow) { var val = $.trim($(input).val()); var item = $(input).parent(); var isLast = item.is(list.children("li:last-child")); if (val && isLast) { var next = $("<textarea></textarea>") .attr("name", "wiktku-dfn-sub-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", rows) .attr("class", "wiktku-dfn-subfield" + (narrow ? " wiktku-start-narrow" : "")); next.on("input", function () { steps.dfn.onSubInput(list, this, rows, narrow); }); list.append($("<li></li>").append(next)); } }, // Populated from [[MediaWiki:Gadget-start.js/data.json]] (tplDefs, posExamples, jederDefs). tplDefs: [], posExamples: {}, jederDefs: {}, build: function (stepDiv) { if (stepDiv.find("ol.wiktku-dfn-list").length) return null; var list = $("<ol class='wiktku-dfn-list'></ol>"); list.append(steps.dfn.buildSenseBlock(stepDiv)); stepDiv.append(list); return null; }, /** Reads all sense blocks from the DOM and returns an array of sense objects. */ getSenses: function (stepDiv) { var senses = []; stepDiv.find("li.wiktku-dfn-sense").each(function () { var block = $(this); var tplSel = block.find("select.wiktku-dfn-tpl-select"); var tpl = tplSel.val() || ""; // noLang: template already encodes the language — don't add |lang| param. var tplNoLang = tpl ? tplSel.find("option[value='" + tpl + "']").attr("data-nolang") === "1" : false; var tplTitle = $.trim(block.find("input.wiktku-dfn-tpl-title").val()); var mane = $.trim(block.find("textarea.wiktku-dfn-mane").val()); var etiket = (function () { var vals = []; block.find(".wiktku-dfn-etiket-list textarea").each(function () { var v = $.trim($(this).val()); if (v) vals.push(v); }); return vals; }()); var kategori = (function () { var vals = []; block.find(".wiktku-dfn-kategori-list textarea").each(function () { var v = $.trim($(this).val()); if (v) vals.push(v); }); return vals; }()); function readList(cls) { var vals = []; block.find("." + cls + "-list textarea").each(function () { var v = $.trim($(this).val()); if (v) vals.push(v); }); return vals; } // Nimûne items are compound: { text, tr?, t? } function readNimuneList() { var items = []; block.find(".wiktku-dfn-nimune-list li.wiktku-dfn-nimune-li").each(function () { var text = $.trim($(this).find(".wiktku-dfn-nimune-text").val()); if (!text) return; var obj = { text: text }; var tr = $.trim($(this).find(".wiktku-dfn-nimune-tr").val()); var t = $.trim($(this).find(".wiktku-dfn-nimune-t").val()); if (tr) obj.tr = tr; if (t) obj.t = t; items.push(obj); }); return items; } // Jêder is a growing list of citations, one per li — mirrors readNimuneList(). function readJederList() { var items = []; block.find(".wiktku-dfn-jeder-list li.wiktku-dfn-jeder-li").each(function () { var li = $(this); var quote = $.trim(li.find(".wiktku-dfn-nimune-quote").val()); if (!quote) return; var obj = { quote: quote }; var qtr = $.trim(li.find(".wiktku-dfn-nimune-quote-tr").val()); var qt = $.trim(li.find(".wiktku-dfn-nimune-quote-t").val()); if (qtr) obj.quoteTr = qtr; if (qt) obj.quoteT = qt; var tplName = li.find(".wiktku-dfn-quote-src-sel").val(); if (tplName === "__manual__") { var manual = $.trim(li.find(".wiktku-dfn-quote-src-manual").val()); if (manual) obj.jederManual = manual; } else if (tplName) { obj.jederTpl = tplName; var fields = {}; li.find(".wiktku-dfn-quote-src-input").each(function () { var k = $(this).attr("data-field-key"); var v = $.trim($(this).val()); if (k && v) fields[k] = v; }); obj.jêderFields = fields; } items.push(obj); }); return items; } senses.push({ tpl: tpl, tplNoLang: tplNoLang, tplTitle: tplTitle, mane: mane, etiket: etiket, kategori: kategori, nimune: readNimuneList(), jeder: readJederList(), alternativ: readList("wiktku-dfn-alternativ"), hevmane: readList("wiktku-dfn-hevmane"), dijmane: readList("wiktku-dfn-dijmane"), koordine: readList("wiktku-dfn-koordine"), jornav: readList("wiktku-dfn-jornav"), jernav: readList("wiktku-dfn-jernav") }); }); return senses; }, getOutput: function (values, callback) { var stepDiv = $("#wiktku-start-dfn"); var senses = steps.dfn.getSenses(stepDiv); var lang = values.lang; // A sense counts as "filled" if it has a mane, a chosen template + title, // or any other content (etîket/hevmane/nimûne/jêder…) worth keeping. var hasMane = senses.some(function (s) { return s.mane !== "" || (s.tpl && s.tplTitle) || senseHasExtraContent(s); }); // True only when at least one sense has a regular mane (needs linkify). var hasRegularMane = senses.some(function (s) { return !s.tpl && s.mane !== ""; }); // nimûne and jêder lines must never pass through linkify — only // the plain mane text should be linkified. We build two parallel // arrays: defLines (sent to linkify) and citeLines (kept aside). // Each entry in citeLines corresponds 1-to-1 with a defLines entry; // a template token {{wiktku-cite-N}} is embedded in defLines so // that after linkify runs we know exactly where to splice them back. // Template-call syntax is guaranteed safe: linkifiers leave {{ }} // tokens completely untouched. var defLines = []; // one entry per kept sense (goes to linkify) var citeLines = []; // parallel — nimûne+jêder for that same sense $.each(senses, function (_, sense) { // — Template sense (e.g. {{guharto|ku|somepage}}) — if (sense.tpl) { if (!sense.tplTitle) return; // skip empty template senses var tplKatTpl = ""; if (sense.kategori && sense.kategori.length) { var tplKatParts = sense.kategori.map(function (k) { return $.trim(k); }) .filter(function (k) { return k !== ""; }); if (tplKatParts.length) { tplKatTpl = "\n#: {{K|" + lang + "|" + tplKatParts.join("|") + "}}"; } } var tplLabelTpl = ""; if (sense.etiket && sense.etiket.length) { var tplLabelParts = sense.etiket.map(function (part) { return $.trim(part); }).filter(function (part) { return part !== ""; }); if (tplLabelParts.length) { tplLabelTpl = " {{e|" + lang + "|" + tplLabelParts.join("|") + "}} "; } } var tplCall = sense.tplNoLang ? "{{" + sense.tpl + "|" + sense.tplTitle + "}}" : "{{" + sense.tpl + "|" + lang + "|" + sense.tplTitle + "}}"; var tplHasJeder = sense.jeder && $.grep(sense.jeder, function (j) { return j && j.quote; }).length > 0; var idx = defLines.length; var cite = formatNimune(sense.nimune, lang, tplHasJeder) + formatJeder(sense.jeder, lang); defLines.push("#" + (tplLabelTpl ? tplLabelTpl : " ") + tplCall + tplKatTpl + (cite ? "{{wiktku-cite-" + idx + "}}" : "")); citeLines.push(cite); return; } // — Normal mane sense — var dfn = sense.mane; if (!dfn && !senseHasExtraContent(sense)) return; // truly empty if (dfn) { dfn = stripWikilinks(dfn); if (dfn[0] !== dfn[0].toUpperCase()) dfn = capitalize(dfn); if (!dfn.match(/[.…?!)\]]$/)) dfn += "."; } else { dfn = "{{mane?|" + lang + "}}"; } var katTpl = ""; if (sense.kategori && sense.kategori.length) { var katParts = sense.kategori.map(function (k) { return $.trim(k); }) .filter(function (k) { return k !== ""; }); if (katParts.length) { katTpl = "\n#: {{K|" + lang + "|" + katParts.join("|") + "}}"; } } var labelTpl = ""; if (sense.etiket && sense.etiket.length) { var labelParts = sense.etiket.map(function (part) { return $.trim(part); }).filter(function (part) { return part !== ""; }); if (labelParts.length) { labelTpl = " {{e|" + lang + "|" + labelParts.join("|") + "}} "; } } var out = "#" + (labelTpl ? labelTpl : " ") + dfn; out += katTpl; function wordLine(tpl, words) { if (!words.length) return ""; return "\n#: {{" + tpl + "|" + lang + "|" + words.join("|") + "}}"; } out += wordLine("alt-r", sense.alternativ); out += wordLine("hevmane", sense.hevmane); out += wordLine("dijmane", sense.dijmane); out += wordLine("koordîne", sense.koordine); out += wordLine("jornav", sense.jornav); out += wordLine("jêrnav", sense.jernav); var hasJeder = sense.jeder && $.grep(sense.jeder, function (j) { return j && j.quote; }).length > 0; var cite = formatNimune(sense.nimune, lang, hasJeder) + formatJeder(sense.jeder, lang); var idx = defLines.length; defLines.push(out + (cite ? "{{wiktku-cite-" + idx + "}}" : "")); citeLines.push(cite); }); // Splice citeLines back into a linkified string, replacing each // {{wiktku-cite-N}} token with its stored nimûne/jêder block. function restoreCites(t) { return t.replace(/\{\{wiktku-cite-(\d+)\}\}/g, function (_, n) { return citeLines[parseInt(n, 10)] || ""; }); } var text = defLines.join("\n") + "\n"; if (!hasMane) { // No definitions entered — emit {{mane?}} with bênimûne. text = "# {{mane?|" + lang + "}}\n#* {{bênimûne|" + lang + "}}\n"; callback(text); return; } if (!hasRegularMane) { // All filled senses are template senses — no linkify needed. callback(restoreCites(text)); return; } var didTryToLoad = function () { if (typeof $.wiktviLinkify === "function") { $.wiktviLinkify(text, function (linked) { callback(restoreCites(linked)); }); } else { callback(restoreCites(text)); } }; mw.loader.using("ext.gadget.linkify", didTryToLoad, didTryToLoad); } }, je: makeWordListStep("je", "jê", "Kelîmeyên jê çêbûyî binivîse", "Jê", "g"), tekildar: makeWordListStep("tekildar", "têkildar", "Kelîmeyên ji aliyê etîmolojiyê ve têkildarî vê kelîmeyê binivîse", "Têkildar", "g"), binereherwiha: makeWordListStep("binereherwiha", "binêre herwiha", "Kelîmeyên din ên eleqedar binivîse", "Binêre herwiha", "g"), etym: { id: "etym", name: "etîmolojî", question_fmt: "Etîmolojiya kelîmeyê binivîse", // etymTpls populated from data.json etymTpls: [], visible: function (values) { return values.lang && values.pos; }, /** Fills (or refills) the insert-dropdown from the current etymTpls array. */ refreshTplSelect: function () { var sel = $("#wiktku-start-etym .wiktku-tpl-insert-select"); if (!sel.length) return; sel.find("option[value!='']").remove(); $.each(steps.etym.etymTpls, function (_, tpl) { sel.append($("<option></option>").val(tpl.snippet).text(tpl.name + " — " + tpl.desc)); }); // Notify Chosen that the option list has changed (no-op on mobile). if (!isMobile) sel.trigger("chosen:updated"); }, build: function (stepDiv) { if (stepDiv.find(".wiktku-etym-wrap").length) return null; var wrap = $("<div class='wiktku-etym-wrap'></div>"); var ta = $("<textarea></textarea>") .attr("name", "wiktku-etym-" + $.now()) .attr("class", "wiktku-start-step-field wiktku-etym-text") .attr("rows", 4) .attr("placeholder", "Nimûne: Ji {{ji|en|ku|apple}}. yan rasterast binivîse…"); // Template insert dropdown — options also refreshed after data.json loads. var sel = $("<select class='wiktku-tpl-insert-select'></select>"); sel.append($("<option value=''>— şablonek lê zêde bike —</option>")); $.each(steps.etym.etymTpls, function (_, tpl) { sel.append($("<option></option>").val(tpl.snippet).text(tpl.name + " — " + tpl.desc)); }); sel.on("change", function () { var snippet = $(this).val(); if (!snippet) return; var lang = getValues().lang || ""; snippet = snippet.replace(/CODE/g, lang).replace(/SOURCELANG/g, "?"); insertAtCursor(ta[0], snippet); $(this).val(""); ta.focus(); }); wrap.append(sel).append($("<br>")).append(ta); stepDiv.append(wrap); return ta; }, output: function (values) { var text = $.trim($("#wiktku-start-etym .wiktku-etym-text").val()); if (text) { return "\n==== Etîmolojî ====\n" + text + "\n"; } // No etymology entered — emit {{ji?|lang}} as a placeholder, // but only when the entry has at least one regular (non-şablon) // sense with content — either real mane text, or an empty mane // with other fields filled in (which dfn.getOutput() renders as // {{mane?|lang}} with those fields attached). A şablon sense // like {{guharto|…}} never counts, filled in or not. var dfnSenses = steps.dfn.getSenses($("#wiktku-start-dfn")); var hasRegularMane = dfnSenses.some(function (s) { return !s.tpl && (s.mane !== "" || senseHasExtraContent(s)); }); if (!hasRegularMane) return ""; return "\n==== Etîmolojî ====\n{{ji?|" + values.lang + "}}\n"; } }, dunde: { id: "dunde", name: "dûnde", question_fmt: "Eger ev kelîme ji vî zimanî ketibe zimanekî din, vî zimanî û kelîmeya wî binivîse", visible: function (values) { return !!values.pos; }, disabledKeys: { "navz": true}, /** * Builds one row: a language dropdown + a growing list of word * inputs. When the dropdown gets a value the next empty row is * appended automatically. Mirrors steps.trans's row widget, but * flat (one shared list — dûnde isn't tied to individual senses). */ buildRow: function (stepDiv) { var row = $("<li class='wiktku-dunde-row wiktku-lang-row'></li>"); // Language selector — chosen is applied after insertion into DOM. var langSel = $(mw.html.element("select", { "class": "wiktku-start-step-keyfield wiktku-start-narrow" })); langSel.attr("data-placeholder", "Zimanekî lê bigere"); populateMenus(langSel, steps.dunde.keys || [], steps.dunde.disabledKeys); // When a language is chosen, ensure a next empty row exists. langSel.on("change", function () { steps.dunde.onLangChange(stepDiv, row); }); // Word list for this language. var wordList = $("<ul class='wiktku-dunde-words wiktku-lang-row-words'></ul>"); var firstWord = steps.dunde.makeWordInput(); wordList.append($("<li></li>").append(firstWord)); if (isMobile) { row.append(wrapNativeSelect(langSel)).append(wordList); } else { row.append(langSel).append(wordList); } return row; }, makeWordInput: function () { var input = $("<textarea></textarea>") .attr("name", "wiktku-dunde-word-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 1) .attr("class", "wiktku-dfn-subfield wiktku-start-narrow") .attr("placeholder", "Kelîme…"); input.on("input", function () { var list = $(this).closest("ul.wiktku-dunde-words"); var item = $(this).parent(); var val = $.trim($(this).val()); if (val && item.is(list.children("li:last-child"))) { var next = steps.dunde.makeWordInput(); list.append($("<li></li>").append(next)); } }); return input; }, onLangChange: function (stepDiv, row) { var list = stepDiv.find("ul.wiktku-dunde-list"); var isLast = row.is(list.children("li.wiktku-dunde-row:last-child")); if (isLast) { var newRow = steps.dunde.buildRow(stepDiv); list.append(newRow); // Init chosen after the new row is in the DOM (desktop only). if (!isMobile) newRow.find("select").chosen(chosenOptions); } // Keep disabled keys in sync across all lang selectors. steps.dunde.syncDisabledKeys(stepDiv); }, /** Disables already-selected languages in all other dropdowns. */ syncDisabledKeys: function (stepDiv) { var taken = $.extend({}, steps.dunde.disabledKeys); stepDiv.find("li.wiktku-dunde-row select").each(function () { var v = $(this).val(); if (v) taken[v] = true; }); stepDiv.find("li.wiktku-dunde-row select").each(function () { var self = $(this); var own = self.val(); self.find("option").each(function () { var code = $(this).val(); if (!code) return; $(this).prop("disabled", taken[code] && code !== own); }); self.trigger("chosen:updated"); }); }, build: function (stepDiv) { if (stepDiv.find("ul.wiktku-dunde-list").length) return null; var list = $("<ul class='wiktku-dunde-list wiktku-lang-row-list'></ul>"); list.append(steps.dunde.buildRow(stepDiv)); stepDiv.append(list); // Init chosen after the select is in the DOM (desktop only). if (!isMobile) list.find("select").chosen(chosenOptions); return null; }, /** Reads all [langcode, words[]] rows from the DOM. */ getRows: function (stepDiv) { var result = []; stepDiv.find("li.wiktku-dunde-row").each(function () { var lang = $(this).find("select").val(); if (!lang) return; var words = []; $(this).find("ul.wiktku-dunde-words textarea").each(function () { var v = $.trim($(this).val()); if (v) words.push(v); }); if (words.length) result.push([lang, words]); }); return result; }, output: function () { var stepDiv = $("#wiktku-start-dunde"); var rows = steps.dunde.getRows(stepDiv); if (!rows.length) return ""; var lines = $.map(rows, function (row) { var lang = row[0], words = row[1]; return "* {{dû|" + lang + "|" + words.join("|") + "}}"; }); return "\n==== Dûnde ====\n" + lines.join("\n") + "\n"; } }, zarava: { id: "zarava", name: "bi zaravayên din", visible: function (values) { return steps.trans.visible(values); }, disabledKeys: { "navz": true }, buildRow: function (group) { var row = $("<li class='wiktku-zarava-row wiktku-lang-row'></li>"); var langSel = $(mw.html.element("select", { "class": "wiktku-start-step-keyfield wiktku-start-narrow" })); populateMenus(langSel, steps.zarava.keys || [], steps.zarava.disabledKeys); langSel.on("change", function () { steps.zarava.onLangChange(group, row); }); var wordList = $("<ul class='wiktku-zarava-words wiktku-lang-row-words'></ul>"); var firstWord = steps.zarava.makeWordInput(); wordList.append($("<li></li>").append(firstWord)); row.append(langSel).append(wordList); return row; }, makeWordInput: function () { var input = $("<textarea></textarea>") .attr("name", "wiktku-zarava-word-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 1) .attr("class", "wiktku-dfn-subfield wiktku-start-narrow") .attr("placeholder", "Tercime…"); input.on("input", function () { var list = $(this).closest("ul.wiktku-zarava-words"); var item = $(this).parent(); var val = $.trim($(this).val()); if (val && item.is(list.children("li:last-child"))) { var next = steps.zarava.makeWordInput(); list.append($("<li></li>").append(next)); } }); return input; }, onLangChange: function (group, row) { var list = group.find("ul.wiktku-zarava-list"); var isLast = row.is(list.children("li.wiktku-zarava-row:last-child")); if (isLast) { var newRow = steps.zarava.buildRow(group); list.append(newRow); } steps.zarava.syncDisabledKeys(group); }, /** Disables already-selected dialects in all other dropdowns within one group. */ syncDisabledKeys: function (group) { var taken = $.extend({}, steps.zarava.disabledKeys); group.find("li.wiktku-zarava-row select").each(function () { var v = $(this).val(); if (v) taken[v] = true; }); group.find("li.wiktku-zarava-row select").each(function () { var self = $(this); var own = self.val(); self.find("option").each(function () { var code = $(this).val(); if (!code) return; $(this).prop("disabled", taken[code] && code !== own); }); }); }, /** Builds (or fetches) the .wiktku-zarava-group for one gloss. */ buildGroup: function (stepDiv, gi) { var group = $("<div class='wiktku-zarava-group'></div>").attr("data-gloss-pos", gi); var list = $("<ul class='wiktku-zarava-list wiktku-lang-row-list'></ul>"); list.append(steps.zarava.buildRow(group)); group.append(list); stepDiv.append(group); return group; }, /** Syncs one .wiktku-zarava-group per current gloss (same logic as steps.trans.build). */ build: function (stepDiv) { var glosses = steps.trans.glossList(); if (!glosses.length) { stepDiv.find(".wiktku-zarava-group").remove(); return null; } var existingGroups = stepDiv.find(".wiktku-zarava-group"); if (existingGroups.length > glosses.length) { existingGroups.slice(glosses.length).remove(); } $.each(glosses, function (gi, gloss) { var group = stepDiv.find(".wiktku-zarava-group[data-gloss-pos='" + gi + "']"); if (!group.length) group = steps.zarava.buildGroup(stepDiv, gi); var label = group.find(".wiktku-zarava-group-label"); if (glosses.length > 1) { if (!label.length) { label = $("<div class='wiktku-zarava-group-label'></div>"); group.prepend(label); } label.text(gloss.index + " " + gloss.text); } else if (label.length) { label.remove(); } }); return null; }, /** Reads the dialect rows for a single gloss group. */ getGroupTranslations: function (group) { var result = []; group.find("li.wiktku-zarava-row").each(function () { var lang = $(this).find("select").val(); if (!lang) return; var words = []; $(this).find("ul.wiktku-zarava-words textarea").each(function () { var v = $.trim($(this).val()); if (v) words.push(v); }); if (words.length) result.push([lang, words]); }); return result; }, /** Reads all rows from the DOM, grouped by gloss position. */ getTranslations: function (stepDiv) { var result = []; stepDiv.find(".wiktku-zarava-group").each(function () { result.push(steps.zarava.getGroupTranslations($(this))); }); return result; }, output: function (values) { if (values.lang !== "ku") return ""; var stepDiv = $("#wiktku-start-zarava"); var glosses = steps.trans.glossList(); if (!glosses.length) return ""; var blocks = $.map(glosses, function (gloss, gi) { var group = stepDiv.find(".wiktku-zarava-group[data-gloss-pos='" + gi + "']"); var rows = group.length ? steps.zarava.getGroupTranslations(group) : []; if (!gloss.text && !rows.length) return undefined; if (rows.length) { rows.sort(function (a, b) { var aLang = langsByCode[a[0]] || []; var bLang = langsByCode[b[0]] || []; return (aLang[2] || "").localeCompare(bLang[2] || "", "ku"); }); } var wordLines = $.map(rows, function (row) { var lang = row[0]; var words = row[1]; var wikiWords = words.map(function (w) { return "{{W|" + lang + "|" + w + "}}"; }).join(", "); return "* {{Z|" + lang + "}}: " + wikiWords; }).join("\n"); if (!wordLines) return undefined; var block = "{{werger-ser|" + (gloss.text || "?") + "|" + gloss.index + "}}"; block += "\n" + wordLines; block += "\n{{werger-bin}}"; return block; }); if (!blocks.length) return ""; return "\n==== Bi zaravayên din ====\n" + blocks.join("\n") + "\n"; } }, trans: { id: "trans", name: "werger", visible: function (values) { if (!(values.lang === "ku" && values.pos)) return false; // Hide Werger only when EVERY sense is a template sense (Guharto etc.) // with a title filled in — i.e. there is real content but no plain // gloss to attach a translation table to. A mix of real + template // senses still shows Werger; the template senses are simply skipped // in output(). // // "Real" here means a non-şablon sense with either mane text or // other filled-in fields (etîket/hevmane/nimûne/jêder…), since // dfn.getOutput() renders the latter too, as {{mane?|lang}} plus // whatever else was filled in. // // When nothing has been filled in at all, output() will emit // {{mane?|lang}} instead of a gloss — but Werger should still show, // since the user may want to add translations before they've // settled on a gloss. var dfnSenses = steps.dfn.getSenses($("#wiktku-start-dfn")); var hasRealSense = dfnSenses.some(function (s) { return !s.tpl && (s.mane !== "" || senseHasExtraContent(s)); }); var hasFilledTplSense = dfnSenses.some(function (s) { return s.tpl && s.tplTitle; }); return hasRealSense || !hasFilledTplSense; }, disabledKeys: { "navz": true, "ku": true, "ckb": true, "sdh": true, "lki": true, "hac": true, "zza": true }, /** * Builds one translation row: a language dropdown + a growing list * of word inputs. When the dropdown gets a value the next empty row * is appended automatically. * * @param group the specific .wiktku-trans-group this row belongs to * (each gloss has its own group and its own list of rows, so the * lookups below must stay scoped to that group rather than the * whole step — the step now holds one list per gloss). */ buildRow: function (group) { var row = $("<li class='wiktku-trans-row wiktku-lang-row'></li>"); // Language selector — chosen is applied after insertion into DOM. var langSel = $(mw.html.element("select", { "class": "wiktku-start-step-keyfield wiktku-start-narrow" })); langSel.attr("data-placeholder", "Zimanekî lê bigere"); populateMenus(langSel, steps.trans.keys || [], steps.trans.disabledKeys); // When a language is chosen, ensure a next empty row exists. langSel.on("change", function () { steps.trans.onLangChange(group, row); }); // Word list for this language. var wordList = $("<ul class='wiktku-trans-words wiktku-lang-row-words'></ul>"); var firstWord = steps.trans.makeWordInput(); wordList.append($("<li></li>").append(firstWord)); if (isMobile) { row.append(wrapNativeSelect(langSel)).append(wordList); } else { row.append(langSel).append(wordList); } return row; }, makeWordInput: function () { var input = $("<textarea></textarea>") .attr("name", "wiktku-trans-word-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 1) .attr("class", "wiktku-dfn-subfield wiktku-start-narrow") .attr("placeholder", "Tercime…"); input.on("input", function () { var list = $(this).closest("ul.wiktku-trans-words"); var item = $(this).parent(); var val = $.trim($(this).val()); if (val && item.is(list.children("li:last-child"))) { var next = steps.trans.makeWordInput(); list.append($("<li></li>").append(next)); } }); return input; }, onLangChange: function (group, row) { var list = group.find("ul.wiktku-trans-list"); var isLast = row.is(list.children("li.wiktku-trans-row:last-child")); if (isLast) { var newRow = steps.trans.buildRow(group); list.append(newRow); // Init chosen after the new row is in the DOM (desktop only). if (!isMobile) newRow.find("select").chosen(chosenOptions); } // Keep disabled keys in sync across this gloss's lang selectors // only — the same language can be used for different senses. steps.trans.syncDisabledKeys(group); }, /** Disables already-selected languages in all other dropdowns within one group. */ syncDisabledKeys: function (group) { var taken = $.extend({}, steps.trans.disabledKeys); group.find("li.wiktku-trans-row select").each(function () { var v = $(this).val(); if (v) taken[v] = true; }); group.find("li.wiktku-trans-row select").each(function () { var self = $(this); var own = self.val(); self.find("option").each(function () { var code = $(this).val(); if (!code) return; $(this).prop("disabled", taken[code] && code !== own); }); self.trigger("chosen:updated"); }); }, /** * Builds (or fetches) the .wiktku-trans-group for one gloss, with * its own label and its own list of translation rows. */ buildGroup: function (stepDiv, gi) { var group = $("<div class='wiktku-trans-group'></div>").attr("data-gloss-pos", gi); var list = $("<ul class='wiktku-trans-list wiktku-lang-row-list'></ul>"); list.append(steps.trans.buildRow(group)); group.append(list); stepDiv.append(group); // Init chosen after the select is in the DOM (desktop only). if (!isMobile) list.find("select").chosen(chosenOptions); return group; }, /** * Syncs one .wiktku-trans-group per current gloss, adding new * groups and removing stale ones as senses are added or removed, * while leaving existing groups (and whatever translations the * user has already typed into them) untouched. Groups are keyed * to their gloss's position in glossList() via data-gloss-pos, so * a group always matches the same sense across rebuilds as long * as senses aren't reordered relative to each other. */ build: function (stepDiv) { var glosses = steps.trans.glossList(); if (!glosses.length) { stepDiv.find(".wiktku-trans-group").remove(); return null; } // Drop groups for glosses that no longer exist (always from the // tail — groups are only ever appended in gloss order below). var existingGroups = stepDiv.find(".wiktku-trans-group"); if (existingGroups.length > glosses.length) { existingGroups.slice(glosses.length).remove(); } $.each(glosses, function (gi, gloss) { var group = stepDiv.find(".wiktku-trans-group[data-gloss-pos='" + gi + "']"); if (!group.length) group = steps.trans.buildGroup(stepDiv, gi); // Only label groups when there's more than one gloss to // distinguish between — a single gloss needs no caption. var label = group.find(".wiktku-trans-group-label"); if (glosses.length > 1) { if (!label.length) { label = $("<div class='wiktku-trans-group-label'></div>"); group.prepend(label); } label.text(gloss.index + " " + gloss.text); } else if (label.length) { label.remove(); } }); return null; }, /** Reads the translation rows for a single gloss group. */ getGroupTranslations: function (group) { var result = []; group.find("li.wiktku-trans-row").each(function () { var lang = $(this).find("select").val(); if (!lang) return; var words = []; $(this).find("ul.wiktku-trans-words textarea").each(function () { var v = $.trim($(this).val()); if (v) words.push(v); }); if (words.length) result.push([lang, words]); }); return result; }, /** * Reads all translation rows from the DOM, grouped by gloss * position — one array of [lang, words] rows per gloss group, in * the same order as the .wiktku-trans-group elements. */ getTranslations: function (stepDiv) { var result = []; stepDiv.find(".wiktku-trans-group").each(function () { result.push(steps.trans.getGroupTranslations($(this))); }); return result; }, /** * Builds the numbered "{ index, gloss }" list — one entry per dfn * sense that has a real mane (skips template senses like Guharto, * which have nothing to caption a translation table with). The * index matches the sense's actual position in the numbered "#" * definition list (1-based), including template senses in the count, * so the number printed next to {{werger-ser}} lines up with the * gloss the reader sees in the entry. * * When nothing has been filled in at all (dfn.getOutput() will emit * {{mane?|lang}} as sense 1), this returns a single placeholder * entry with empty text instead of an empty array, so Werger still * has one group to attach translations to before a gloss exists. * When every filled sense is a template sense instead, this stays * empty — that mirrors trans.visible()'s hidden case, where there's * no group in the DOM for a placeholder to attach to anyway. */ glossList: function () { var dfnSenses = steps.dfn.getSenses($("#wiktku-start-dfn")); var glosses = []; var hasFilledTplSense = false; $.each(dfnSenses, function (i, s) { if (s.tpl) { if (s.tplTitle) hasFilledTplSense = true; return; // template sense — no gloss to caption with } var dfn = s.mane; if (!dfn) { // No mane text, but other fields (etîket/hevmane/nimûne/ // jêder…) are filled — dfn.getOutput() still emits this // sense as a numbered line using {{mane?|lang}}, so it // needs its own gloss group too, just with no caption text. if (senseHasExtraContent(s)) glosses.push({ index: i + 1, text: "" }); return; } if (dfn[0] !== dfn[0].toLowerCase()) dfn = decapitalize(dfn); dfn = stripWikilinks(dfn).replace(/[.…?!)\]،؟]+$/, ""); glosses.push({ index: i + 1, text: dfn }); }); if (!glosses.length && !hasFilledTplSense) { glosses.push({ index: 1, text: "" }); } return glosses; }, output: function (values) { if (values.lang !== "ku") return ""; var stepDiv = $("#wiktku-start-trans"); var glosses = steps.trans.glossList(); // Every sense is a template sense — there's no real gloss // anywhere and no group in the DOM either (glossList() only // returns empty in that case), so skip the section entirely. if (!glosses.length) return ""; // Each gloss now has its own group of translation rows — // attach every gloss's own words under its own werger-ser/-bin // pair instead of dumping everything under the first one. var blocks = $.map(glosses, function (gloss, gi) { var group = stepDiv.find(".wiktku-trans-group[data-gloss-pos='" + gi + "']"); var rows = group.length ? steps.trans.getGroupTranslations(group) : []; // Placeholder gloss (no real mane entered yet) with nothing // translated into it — nothing to output, and gloss.text is // empty so there's no caption to give {{werger-ser}} anyway. if (!gloss.text && !rows.length) return undefined; if (rows.length) { // Sort by Kurdish sort key. rows.sort(function (a, b) { var aLang = langsByCode[a[0]] || []; var bLang = langsByCode[b[0]] || []; return (aLang[2] || "").localeCompare(bLang[2] || "", "ku"); }); } var wordLines = $.map(rows, function (row) { var lang = row[0]; var words = row[1]; var wikiWords = words.map(function (w) { return "{{W|" + lang + "|" + w + "}}"; }).join(", "); return "* {{Z|" + lang + "}}: " + wikiWords; }).join("\n"); var block = "{{werger-ser|" + (gloss.text || "?") + "|" + gloss.index + "}}"; if (wordLines) block += "\n" + wordLines; block += "\n{{werger-bin}}"; return block; }); if (!blocks.length) return ""; return "\n==== Werger ====\n" + blocks.join("\n") + "\n"; } }, }; steps.trans.keys = steps.lang.choices; steps.dunde.keys = steps.lang.choices; steps.zarava.keys = getZaravaKeys(steps.lang.choices); var ordered_steps = [ steps.lang, steps.pron, steps.pos, steps.cinsiyet, steps.lektur, steps.tr, steps.dfn, steps.je, steps.tekildar, steps.etym, steps.dunde, steps.binereherwiha, steps.zarava, steps.trans]; // Step ids that belong to each section (not shared across sections). var PER_SECTION_STEP_IDS = [ "pos", "cinsiyet", "lektur", "tr", "dfn", "je", "tekildar", "etym", "dunde", "binereherwiha", "zarava", "trans" ]; // ── Multi-section state ────────────────────────────────────────────────── // Each entry is a plain snapshot: { pos, cinsiyet, lektur, tr, dfn (senses[]), // je, tekildar, binereherwiha, trans (rows[]) }. var sections = [{}]; // section 0 starts empty (DOM is the truth) var activeSection = 0; function snapshotDfn() { return steps.dfn.getSenses($("#wiktku-start-dfn")); } /** * Rebuild the dfn DOM from a previously snapshotted senses array. */ function restoreDfn(senses) { var stepDiv = $("#wiktku-start-dfn"); // Tear down the existing list so build() recreates it cleanly. stepDiv.find("ol.wiktku-dfn-list").remove(); steps.dfn.build(stepDiv); var list = stepDiv.find("ol.wiktku-dfn-list"); $.each(senses, function (i, sense) { // Ensure enough blocks exist (build() seeds one). var blocks = list.find("li.wiktku-dfn-sense"); var block = blocks.eq(i); if (!block.length) { var nb = steps.dfn.buildSenseBlock(stepDiv); list.append(nb); block = list.find("li.wiktku-dfn-sense").last(); } // Template selector. block.find("select.wiktku-dfn-tpl-select").val(sense.tpl || ""); if (sense.tpl) { block.find("textarea.wiktku-dfn-mane").hide(); block.find("input.wiktku-dfn-tpl-title").val(sense.tplTitle || "").show(); } else { block.find("textarea.wiktku-dfn-mane").val(sense.mane || "").show(); block.find("input.wiktku-dfn-tpl-title").hide().val(""); } // Re-sync the formên alternatîv/hevmane/… hide state now that // tplSelect's value was set programmatically (its own "change" // handler doesn't fire from .val(), so this doesn't happen otherwise). var updateVis = block.data("updateFieldVisibility"); if (updateVis) updateVis(); // Restore a sub-list (etiket, formên alternatîv, hevmane …) from a values array. function restoreSubList(cls, values) { if (!values || !values.length) return; var groupDiv = block.find("." + cls + "-group"); var subList = groupDiv.find("ol, ul").first(); if (!subList.length) return; // group not found // Fill existing items, append new ones as needed. $.each(values, function (j, val) { var items = subList.find("li"); if (j < items.length) { items.eq(j).find("textarea").val(val); } else { var ta = $("<textarea></textarea>") .attr("name", "wiktku-dfn-restore-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 1) .attr("class", "wiktku-dfn-subfield wiktku-start-narrow") .val(val); ta.on("input", function () { steps.dfn.onSubInput(subList, this, 1, true); }); subList.append($("<li></li>").append(ta)); } }); } // Reveal and populate lazy groups that have data. var lazyMap = { "wiktku-dfn-etiket": sense.etiket, "wiktku-dfn-kategori": sense.kategori, "wiktku-dfn-alternativ": sense.alternativ, "wiktku-dfn-hevmane": sense.hevmane, "wiktku-dfn-dijmane": sense.dijmane, "wiktku-dfn-koordine": sense.koordine, "wiktku-dfn-jornav": sense.jornav, "wiktku-dfn-jernav": sense.jernav }; $.each(lazyMap, function (cls, vals) { if (vals && vals.length) restoreSubList(cls, vals); }); // Nimûne items are objects { text, tr?, t? } — restore using the builder. if (sense.nimune && sense.nimune.length) { var nimuneGroupDiv = block.find(".wiktku-dfn-nimune-group"); var nimuneList = nimuneGroupDiv.find("ol.wiktku-dfn-nimune-list"); var buildFn = nimuneGroupDiv.data("buildNimuneLi"); nimuneList.empty(); $.each(sense.nimune, function (_, n) { var text = typeof n === "object" ? (n.text || "") : n; if (!text) return; var li = buildFn ? buildFn() : $("<li class='wiktku-dfn-nimune-li'></li>"); li.find(".wiktku-dfn-nimune-text").val(text); if (n.tr) li.find(".wiktku-dfn-nimune-tr").val(n.tr); if (n.t) li.find(".wiktku-dfn-nimune-t").val(n.t); nimuneList.append(li); }); // Always leave a blank trailing item. if (buildFn) nimuneList.append(buildFn()); } // Restore jêder (quote/citation) entries — a growing list, restored using the // builder just like Nimûne. Accepts either the current array shape or a // single legacy object (from older saved sections) for backwards compatibility. var jederArr = $.isArray(sense.jeder) ? sense.jeder : (sense.jeder ? [sense.jeder] : []); if (jederArr.length) { var jederGroupDiv = block.find(".wiktku-dfn-jeder-group"); var jederList = jederGroupDiv.find("ol.wiktku-dfn-jeder-list"); var buildJederFn = jederGroupDiv.data("buildJederLi"); jederList.empty(); $.each(jederArr, function (_, j) { if (!j || !j.quote) return; var li = buildJederFn ? buildJederFn() : $("<li class='wiktku-dfn-jeder-li'></li>"); li.find(".wiktku-dfn-nimune-quote").val(j.quote); if (j.quoteTr) li.find(".wiktku-dfn-nimune-quote-tr").val(j.quoteTr); if (j.quoteT) li.find(".wiktku-dfn-nimune-quote-t").val(j.quoteT); if (j.jederManual) { var manualSel = li.find(".wiktku-dfn-quote-src-sel"); manualSel.val("__manual__").trigger("change"); li.find(".wiktku-dfn-quote-src-manual").val(j.jederManual); } else if (j.jederTpl) { var srcSel = li.find(".wiktku-dfn-quote-src-sel"); srcSel.val(j.jederTpl).trigger("change"); if (j.jêderFields) { $.each(j.jêderFields, function (key, val) { li.find(".wiktku-dfn-quote-src-input[data-field-key='" + key + "']").val(val); }); } } jederList.append(li); }); // Always leave a blank trailing item, same as Nimûne. if (buildJederFn) jederList.append(buildJederFn()); } }); } /** * Snapshot simple (non-dfn) per-section steps from current DOM into obj. */ function saveCurrentSection() { var snap = {}; $.each(PER_SECTION_STEP_IDS, function (_, id) { if (id === "dfn") { snap.dfn = snapshotDfn(); return; } if (id === "etym") { snap.etym = $.trim($("#wiktku-start-etym .wiktku-etym-text").val()); return; } var step = steps[id]; if (!step) return; var stepDiv = $("#wiktku-start-" + id); if (id === "trans") { snap.trans = steps.trans.getTranslations(stepDiv); return; } if (id === "zarava") { snap.zarava = steps.zarava.getTranslations(stepDiv); return; } if (id === "dunde") { snap.dunde = steps.dunde.getRows(stepDiv); return; } // Generic: read all step fields. var fields = stepDiv.find(".wiktku-start-step-field"); if (step.multiple) { snap[id] = fields.map(function () { return $(this).val(); }).get(); } else { snap[id] = fields.val(); } }); sections[activeSection] = snap; } /** * Restore a previously saved snapshot into the form DOM. */ function restoreSection(snap) { $.each(PER_SECTION_STEP_IDS, function (_, id) { if (id === "dfn") { restoreDfn(snap.dfn || []); return; } if (id === "etym") { $("#wiktku-start-etym .wiktku-etym-wrap").remove(); steps.etym.build($("#wiktku-start-etym")); $("#wiktku-start-etym .wiktku-etym-text").val(snap.etym || ""); return; } if (id === "trans") { // Rebuild trans groups (dfn must already be restored by this // point in the $.each loop, so glossList() reflects it). var transDiv = $("#wiktku-start-trans"); transDiv.find(".wiktku-trans-group").remove(); steps.trans.build(transDiv); var groupsSnap = snap.trans || []; $.each(groupsSnap, function (gi, rows) { var group = transDiv.find(".wiktku-trans-group[data-gloss-pos='" + gi + "']"); if (!group.length) return; // gloss no longer exists — drop its rows var list = group.find("ul.wiktku-trans-list"); $.each(rows, function (j, row) { var lang = row[0], words = row[1]; var lastRow = list.find("li.wiktku-trans-row").last(); lastRow.find("select").val(lang).trigger("change"); var wordList = lastRow.find("ul.wiktku-trans-words"); $.each(words, function (k, word) { var wordItems = wordList.find("li"); if (k < wordItems.length) { wordItems.eq(k).find("textarea").val(word); } else { // .val() below doesn't fire "input", so the normal // auto-grow never runs — append a matching item // ourselves instead of silently dropping the word. var extraInput = steps.trans.makeWordInput(); wordList.append($("<li></li>").append(extraInput)); extraInput.val(word); } }); // Leave one trailing empty field so the row can still grow // when the user types, matching a freshly-built row. if ($.trim(wordList.children("li").last().find("textarea").val())) { wordList.append($("<li></li>").append(steps.trans.makeWordInput())); } }); }); return; } if (id === "zarava") { // Rebuild zarava groups (dfn must already be restored by this // point in the $.each loop, so glossList() reflects it). var zaravaDiv = $("#wiktku-start-zarava"); zaravaDiv.find(".wiktku-zarava-group").remove(); steps.zarava.build(zaravaDiv); var zaravaGroupsSnap = snap.zarava || []; $.each(zaravaGroupsSnap, function (gi, rows) { var group = zaravaDiv.find(".wiktku-zarava-group[data-gloss-pos='" + gi + "']"); if (!group.length) return; // gloss no longer exists — drop its rows var list = group.find("ul.wiktku-zarava-list"); $.each(rows, function (j, row) { var lang = row[0], words = row[1]; var lastRow = list.find("li.wiktku-zarava-row").last(); lastRow.find("select").val(lang).trigger("change"); var wordList = lastRow.find("ul.wiktku-zarava-words"); $.each(words, function (k, word) { var wordItems = wordList.find("li"); if (k < wordItems.length) { wordItems.eq(k).find("textarea").val(word); } else { var extraInput = steps.zarava.makeWordInput(); wordList.append($("<li></li>").append(extraInput)); extraInput.val(word); } }); if ($.trim(wordList.children("li").last().find("textarea").val())) { wordList.append($("<li></li>").append(steps.zarava.makeWordInput())); } }); }); return; } if (id === "dunde") { // Rebuild dunde rows. var dundeDiv = $("#wiktku-start-dunde"); dundeDiv.find("ul.wiktku-dunde-list").remove(); steps.dunde.build(dundeDiv); var dundeRows = snap.dunde || []; $.each(dundeRows, function (i, row) { var lang = row[0], words = row[1]; var list = dundeDiv.find("ul.wiktku-dunde-list"); var lastRow = list.find("li.wiktku-dunde-row").last(); lastRow.find("select").val(lang).trigger("change"); var wordList = lastRow.find("ul.wiktku-dunde-words"); $.each(words, function (j, word) { var wordItems = wordList.find("li"); if (j < wordItems.length) { wordItems.eq(j).find("textarea").val(word); } else { // .val() below doesn't fire "input", so the normal // auto-grow never runs — append a matching item // ourselves instead of silently dropping the word. var extraInput = steps.dunde.makeWordInput(); wordList.append($("<li></li>").append(extraInput)); extraInput.val(word); } }); // Leave one trailing empty field so the row can still grow // when the user types, matching a freshly-built row. if ($.trim(wordList.children("li").last().find("textarea").val())) { wordList.append($("<li></li>").append(steps.dunde.makeWordInput())); } }); return; } var step = steps[id]; if (!step) return; var stepDiv = $("#wiktku-start-" + id); var fields = stepDiv.find(".wiktku-start-step-field"); var val = snap[id]; if (val === undefined || val === null) return; if (step.multiple) { var arr = val; fields.each(function (i) { if (i < arr.length) $(this).val(arr[i]); }); } else { fields.val(val); } // Notify chosen widgets of the programmatic value change. if (!isMobile) fields.filter("select").trigger("chosen:updated"); }); } function getWikitextForCurrentSection(callback) { var values = getValues(); var entry = steps.pos.output(values); steps.dfn.getOutput(values, function (output) { entry += output; entry += steps.je.output(values); entry += steps.tekildar.output(values); entry += steps.etym.output(values); entry += steps.dunde.output(values); entry += steps.binereherwiha.output(values); entry += steps.zarava.output(values); entry += steps.trans.output(values); callback(entry, values); }); } function getWikitextAllSections(callback) { saveCurrentSection(); var results = new Array(sections.length); var sharedValues = getValues(); // lang/pron are shared function processSection(i) { if (i >= sections.length) { // All done — restore original active section. restoreSection(sections[activeSection]); refresh(); callback(results, sharedValues); return; } restoreSection(sections[i]); refresh(); getWikitextForCurrentSection(function (sectionText) { results[i] = sectionText; processSection(i + 1); }); } processSection(0); } /** * Assembles wikitext for all sections plus the shared lang/pron header. */ function getWikitext(callback) { getWikitextAllSections(function (sectionTexts, sharedValues) { var entry = steps.lang.output(sharedValues); entry += steps.pron.output(sharedValues); entry += sectionTexts.join("\n"); // Edit summary uses section 0's values. Read from the saved snapshot // (not the live DOM) so it doesn't mix section 0's pos with whichever // section happens to be active/restored at this point. var dfnSenses = (sections[0] && sections[0].dfn) || []; var dfnSummary = dfnSenses.map(function (s) { return s.mane; }).filter(Boolean).join("; "); var summaryLabel = addLangMode ? "WF:Ziman lê zêde" : "WF:Nû"; var summary = "([[Mediawiki:Gadget-start.js|" + summaryLabel + "]] v.2.0) +" + sharedValues.lang + ":" + sections[0].pos + ":" + dfnSummary; var summaryField = document.getElementById("wpSummary"); if (addLangMode && summaryField.value) { summary = summaryField.value + " " + summary; } summaryField.value = summary; callback(entry); }); } var continueBtn; function getValuesForStep(stepId) { var fields = $("#wiktku-start-" + stepId + " .wiktku-start-step-field"); var step = steps[stepId]; if (step.keys) { var values = {}; fields.each(function (i, field) { var key = $(field).prevAll(".wiktku-start-step-keyfield").val(); if (key) values[key] = $(field).val(); }); return values; } else if (step.multiple) { return fields.map(function () { return $(this).val(); }).get(); } return fields.val(); } function getValues() { var values = {}; $.each(steps, function (stepId) { values[stepId] = getValuesForStep(stepId); }); return values; } function populateMenus(inputs, choices, disabledValues) { if (!disabledValues) disabledValues = {}; var vals = inputs.map(function (i, input) { return $(input).val(); }); inputs.empty(); inputs.append($("<option></option>")); $.each(choices, function (j, choice) { // Append the language code in parentheses so that typing a code // (e.g. "ku") in the search box still finds the language name. var displayText = capitalize(choice[1]); if (choice[2] !== undefined) { // This is a language choice [code, name, sortKey] — show code. displayText = capitalize(choice[1]) + " (" + choice[0] + ")"; } var option = $(mw.html.element("option", { value: choice[0] }, displayText)); if (disabledValues[choice[0]]) option.prop("disabled", true); inputs.append(option); }); inputs.val(function (i) { return vals[i]; }); } /** * Returns a bitmap containing the keys that should be disabled for a key * menu in the given step because they are disabled or already taken by * another key menu. */ function getDisabledKeys(step) { var occupiedKeys = {}; $("#wiktku-start-" + step.id + " .wiktku-start-step-keyfield").each(function () { occupiedKeys[$(this).val()] = true; }); if (step.disabledKeys) $.extend(occupiedKeys, step.disabledKeys); return occupiedKeys; } function buildKeyInput(step) { if (!step.keys) return undefined; var input = $(mw.html.element("select", { "class": "wiktku-start-step-keyfield wiktku-start-narrow" })); input.attr("data-placeholder", "Hilbijêre " + step.keyName); if (isMobile) { populateMenus(input, step.keys, getDisabledKeys(step)); // On mobile return the wrapper; the select is inside it. // Change events still fire on the inner select. return wrapNativeSelect(input); } input.on("chosen:showing_dropdown", function () { $(this).data("wiktku-defaultValue", $(this).val()); }); input.change(function (_, context) { var inputs = $("#wiktku-start-" + step.id + " .wiktku-start-step-keyfield").not(this); var oldValue = $(this).data("wiktku-defaultValue"); var newValue = context.selected; inputs.find("option[value='" + oldValue + "']").prop('disabled', false); inputs.find("option[value='" + newValue + "']").prop('disabled', true); inputs.trigger("chosen:updated"); }); populateMenus(input, step.keys, getDisabledKeys(step)); return input; } /** * If the current text field has text and there are no more text fields after * the current text field in the list, add another text field to the list. */ function refreshForTextField(currentInput, step) { currentInput = $(currentInput); var value = currentInput.val(); var item = currentInput.parent(); if (value && !item.next("li").length) { var nextInput = $("<textarea></textarea>") .attr("name", "wiktku-field-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("class", currentInput.attr("class")) .attr("rows", currentInput.attr("rows") || 1); nextInput.on("input", function (evt) { refreshForTextField(evt.target, step); }); var nextKeyInput = buildKeyInput(step); var nextItem = $("<li></li>").append(nextKeyInput).append(nextInput); item.parent().append(nextItem); if (nextKeyInput) nextKeyInput.chosen(chosenOptions); } var canContinue = !continueBtn.isDisabled(); if ((value && !canContinue) || (!value && canContinue)) { refresh(step); } } function prepareInput(input, step) { if (!input) return; if (step.required) input.prop('required', true); input.change(step, refresh); } /** * Shows and hides all the steps based on whether their prerequisites are met, * and updates placeholders where applicable. */ function refresh(evt) { var values = getValues(); var changedStep = evt && evt.data; var didFocus = false; var canContinue = true; // Re-filter template options in every sense block whenever lang changes. $("#wiktku-start-dfn .wiktku-dfn-tpl-select").each(function () { var fn = $(this).data("updateOptions"); if (typeof fn === "function") fn(); }); // Re-filter pronunciation and etymology template dropdowns when language changes. steps.pron.refreshTplSelect(); steps.etym.refreshTplSelect(); // Sync tr/t sub-fields in every nimûne item to the current language. // tr shown when language needs transliteration; t shown when lang !== "ku". (function () { var lang = values.lang || ""; var showTr = needsTransliteration(lang); var showT = lang && lang !== "ku"; $("#wiktku-start-dfn .wiktku-dfn-nimune-list li.wiktku-dfn-nimune-li").each(function () { var li = $(this); // Ensure the sub-wrapper exists when we need it. var subWrap = li.find(".wiktku-dfn-nimune-sub"); // tr field var trTa = li.find(".wiktku-dfn-nimune-tr"); if (showTr && !trTa.length) { if (!subWrap.length) { subWrap = $("<div></div>").addClass("wiktku-dfn-nimune-sub"); li.append(subWrap); } trTa = $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-tr-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 5) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-tr") .attr("placeholder", "Transkrîpsiyon…"); subWrap.prepend(trTa); } else if (!showTr && trTa.length) { trTa.remove(); } // t field var tTa = li.find(".wiktku-dfn-nimune-t"); if (showT && !tTa.length) { if (!subWrap.length) { subWrap = $("<div></div>").addClass("wiktku-dfn-nimune-sub"); li.append(subWrap); } tTa = $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-t-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 5) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-t") .attr("placeholder", "Tercimeya nimûneyê kurmancî…"); subWrap.append(tTa); } else if (!showT && tTa.length) { tTa.remove(); } // Remove the wrapper if it ended up empty. subWrap = li.find(".wiktku-dfn-nimune-sub"); if (subWrap.length && !subWrap.children().length) subWrap.remove(); }); }()); // Sync tr/t sub-fields in every jêder citation to the current language. // tr shown when language needs transliteration; t shown when lang !== "ku". (function () { var lang = values.lang || ""; var showTr = needsTransliteration(lang); var showT = lang && lang !== "ku"; $("#wiktku-start-dfn .wiktku-dfn-jeder-list li.wiktku-dfn-jeder-li").each(function () { var li = $(this); // Ensure the sub-wrapper exists when we need it. It must sit right // after the quote textarea and before the source selector. var subWrap = li.find(".wiktku-dfn-quote-sub"); // tr field var trTa = li.find(".wiktku-dfn-nimune-quote-tr"); if (showTr && !trTa.length) { if (!subWrap.length) { subWrap = $("<div></div>").addClass("wiktku-dfn-quote-sub"); li.find(".wiktku-dfn-nimune-quote").after(subWrap); } trTa = $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-quote-tr-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 2) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-quote-tr") .attr("placeholder", "Transkrîpsiyona jêgirtinê…"); subWrap.prepend(trTa); } else if (!showTr && trTa.length) { trTa.remove(); } // t field var tTa = li.find(".wiktku-dfn-nimune-quote-t"); if (showT && !tTa.length) { if (!subWrap.length) { subWrap = $("<div></div>").addClass("wiktku-dfn-quote-sub"); li.find(".wiktku-dfn-nimune-quote").after(subWrap); } tTa = $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-quote-t-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 2) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-quote-t") .attr("placeholder", "Tercimeya jêgirtinê ya kurmancî…"); subWrap.append(tTa); } else if (!showT && tTa.length) { tTa.remove(); } // Remove the wrapper if it ended up empty. subWrap = li.find(".wiktku-dfn-quote-sub"); if (subWrap.length && !subWrap.children().length) subWrap.remove(); }); }()); $.each(steps, function (stepId, step) { if (typeof(step.visible) === "function" && !step.visible(values)) { $("#wiktku-start-" + stepId).slideUp(); } else { var stepDiv = $("#wiktku-start-" + stepId); if (changedStep !== step && typeof(step.build) === "function") { prepareInput(step.build(stepDiv, values), step); } var input = stepDiv.find(".wiktku-start-step-field"); if (typeof(step.example) === "function") { // .find() above already reaches nested fields (e.g. the dfn // step's mane textareas inside each sense block), so one // assignment covers every step; dfn keeps its own fallback. var exampleText = step.example(values) || (step.id === "dfn" ? "Mane…" : ""); input.attr("placeholder", exampleText); } var didSlideDown; if (!didFocus && stepDiv.css("display") === "none" && step.required) { didSlideDown = function (evt) { input.focus(); }; didFocus = true; } stepDiv.slideDown(didSlideDown); } if (step.required && (values[stepId] === "" || (step.multiple && values[stepId].join("") === ""))) { canContinue = false; } }); continueBtn.setDisabled(!canContinue); } function destroy() { $("#wiktku-start-form, .noafterwizard").slideUp(function () { $(this).remove(); }); $(".noarticletext .nowizard, #editform").slideDown(); $("#ca-edit").removeClass("selected"); $("#ca-wiktku-nowizard").addClass("selected"); } // Priority order for Kurdish dialects and the navz pseudo-code. // Codes listed here come before all other languages; unlisted codes // are sorted alphabetically by their display name via localeCompare. var LANG_PRIORITY = ["navz", "ku", "hac", "sdh", "lki", "ckb", "zza"]; /** * Inserts a new == {{ziman|code}} == section into existing page wikitext * at the correct sorted position: * 1. Any content before the first language section is preserved at the top. * 2. navz is always first, then ku/hac/sdh/lki/ckb/zza in that order, * then all other languages sorted by display name (localeCompare). */ function insertNewLangSection(existing, wikitext) { var newCodeMatch = wikitext.match(/^== \{\{ziman\|([^}]+)\}\} ==/); var newCode = newCodeMatch ? newCodeMatch[1] : ""; var sections = []; var preamble = ""; var firstMatch = existing.match(/(?:^|\n)== \{\{ziman\|/); if (!firstMatch) { // No existing lang sections at all — just append. var sep = existing && !/\n\s*$/.test(existing) ? "\n\n" : ""; return existing + sep + wikitext; } // Everything before the first == {{ziman|...}} == is the preamble. var firstSectionStart = existing.indexOf("== {{ziman|"); // Walk back to the start of that line. var lineStart = existing.lastIndexOf("\n", firstSectionStart - 1); var preambleEnd = lineStart !== -1 ? lineStart + 1 : 0; preamble = existing.slice(0, preambleEnd); // Parse each language section: header line + everything until the next header. var body = existing.slice(preambleEnd); // NOTE: with the /m flag, a bare "$" matches end-of-*line*, not just // end-of-string — that previously made the non-greedy content group // stop at the section's first line break instead of running to the // next language header (or the real end of the text), silently // dropping the rest of that section's wikitext. (?![\s\S]) matches // only the true end of the string, /m flag or not. var langSectionRe = /^(== \{\{ziman\|([^}]+)\}\} ==\n?)([\s\S]*?)(?=\n== \{\{ziman\||(?![\s\S]))/gm; var m; while ((m = langSectionRe.exec(body)) !== null) { sections.push({ code: m[2], content: m[0] // full text of this section including header }); } // Determine sort rank: priority list first (by index), then alphabetical. function getLangName(code) { var entry = langsByCode[code]; return entry ? entry[1] : code; } function sortRank(code) { var idx = LANG_PRIORITY.indexOf(code); return idx !== -1 ? idx : LANG_PRIORITY.length; } function compareLangs(a, b) { var ra = sortRank(a), rb = sortRank(b); if (ra !== rb) return ra - rb; // Both are outside priority list — sort by display name. return getLangName(a).localeCompare(getLangName(b), userLang); } // Insert the new section into the sorted list. var newSection = { code: newCode, content: wikitext }; var inserted = false; for (var i = 0; i < sections.length; i++) { if (compareLangs(newCode, sections[i].code) < 0) { sections.splice(i, 0, newSection); inserted = true; break; } } if (!inserted) sections.push(newSection); // Re-join: preamble + sections separated by newlines. var joined = sections.map(function (s) { // Ensure each section ends with exactly one newline before the next. return s.content.replace(/\n+$/, ""); }).join("\n"); return preamble + joined + "\n"; } function build() { $(".nowizard, .nowizard .noafterwizard").hide(); var callToAction = $("#wiktku-calltoaction"); var origCallToActionText = callToAction.text(); $(mw.util.addPortletLink("p-views", "#", "Edîtora çavkaniyê veke", "ca-wiktku-nowizard", "Vê rûpelê bi edîtora çavkaniyê çêke", undefined, "#ca-watch")).click(function (evt) { evt.preventDefault(); callToAction.text(origCallToActionText); destroy(); }); if (callToAction.length) { callToAction.text(origCallToActionText + " Forma li jêr ji bo çêkirina madeyeke nû bi kar bîne."); } var startForm = $("<form id='wiktku-start-form'></form>"); var clearPageCheck = null; if (addLangMode) { startForm.append($("<p class='wiktku-addlang-notice'></p>").html( "Bi vê formê tu yê beşeke nû li rûpelê îlawe bikî. Eger ev zimanê ku tu îlawe dikî jixwe di rûpelê de hebe, beşa nû li dawiya vî zimanî dê were îlawekirin. " + "Ji kerema xwe netîceya dawî kontrol bikin, eger problemek derkeve, li <a href='" + mw.util.getUrl('Mediawiki talk:Gadget-start.js') + "'>nîqaşa vê amûrê</a> problemê ragihîne." )); clearPageCheck = $("<input type='checkbox' id='wiktku-clear-page-check'>"); var clearPageLabel = $("<label for='wiktku-clear-page-check'></label>") .text(" Naveroka rûpelê paqij bike (rûpelê ji nû ve binivîse)"); startForm.append( $("<p class='wiktku-addlang-notice'></p>") .append(clearPageCheck) .append(clearPageLabel) ); } var spinner; // Tab bar for switching between POS sections. var sectionTabsDiv = $("<div id='wiktku-section-tabs'></div>"); startForm.submit(function (evt) { evt.preventDefault(); continueBtn.setDisabled(true); spinner.show(); getWikitext(function (wikitext) { if (addLangMode) { var textbox = $("#wpTextbox1"); var existing = textbox.val() || ""; // Check whether the generated lang header already exists in the page. // wikitext always starts with "== {{ziman|CODE}} ==\n" (from steps.lang.output). // If that exact section heading is already present in the existing content, // strip it from the new output and insert the remaining content at the end // of that lang section (just before the next == level-2 heading, or at the // very end of the page if there is no following section). var langHeaderMatch = wikitext.match(/^(== \{\{ziman\|[^}]+\}\} ==\n)/); if (langHeaderMatch) { var langHeader = langHeaderMatch[1]; // e.g. "== {{ziman|ku}} ==\n" // Escape for use in RegExp. var escapedHeader = langHeader.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); if (new RegExp(escapedHeader).test(existing)) { // Strip the header from the new output. var newContent = wikitext.slice(langHeader.length); // Find the insertion point: end of the existing lang section. // A new L2 heading marks the start of the next language block. var afterHeader = existing.indexOf(langHeader); var searchFrom = afterHeader + langHeader.length; // Find the next == … == heading after this section's start. var nextL2 = existing.indexOf("\n== ", searchFrom); var insertAt = nextL2 !== -1 ? nextL2 : existing.length; // Ensure there's a blank line before the inserted block. var before = existing.slice(0, insertAt); var after = existing.slice(insertAt); var sep = /\n\s*$/.test(before) ? "" : "\n"; textbox.val(before + sep + newContent + after); } else { // New language — insert at the correct sorted position. textbox.val(insertNewLangSection(existing, wikitext)); } } else { // Unexpected format — insert at sorted position anyway. textbox.val(insertNewLangSection(existing, wikitext)); } } else { $("#wpTextbox1").val(wikitext); } $("html, body").animate({scrollTop: 0}); callToAction.text("Hindik ma!"); $("#wiktku-preview-container").remove(); destroy(); }); }); $.each(ordered_steps, function (i, step) { var stepDiv = $(mw.html.element("div", { "class": "wiktku-start-step", id: "wiktku-start-" + step.id })); var name = capitalize(step.name); stepDiv.append($(mw.html.element("h3", { "class": "wiktku-start-step-name" }, new mw.html.Raw(mw.html.element("label", { "for": "wiktku-start-" + step.id + "-field" }, name))))); if (step.question_fmt) { stepDiv.append($(mw.html.element("label", { "class": "wiktku-start-step-question", "for": "wiktku-start-" + step.id + "-field" }, step.question_fmt))); if (step.question_br) stepDiv.append($("<br>")); } var input; if (step.choices) { input = $(mw.html.element("select", { "class": "wiktku-start-step-field", id: "wiktku-start-" + step.id + "-field" })); input.attr("data-placeholder", capitalize(step.name) + " hilbijêre "); populateMenus(input, step.choices); if (step.multiple) input.attr("multiple", true); if (isMobile) { stepDiv.append(wrapNativeSelect(input)); } else { stepDiv.append(input); } } else if (typeof(step.build) === "function") { input = step.build(stepDiv); } else { input = $("<textarea></textarea>") .attr("class", "wiktku-start-step-field") .attr("id", "wiktku-start-" + step.id + "-field") .attr("rows", step.rows || 2); if (step.narrow) input.addClass("wiktku-start-narrow"); if (step.multiple) { input.on("input", function (evt) { refreshForTextField(evt.target, step); }); var keyInput = buildKeyInput(step); var list = $(step.ordered ? "<ol></ol>" : "<ul></ul>") .append($("<li></li>").append(keyInput).append(input)); stepDiv.append(list); } else stepDiv.append(input); } prepareInput(input, step); stepDiv.hide(); // Insert tab bar just before the first per-section step. if (step.id === "pos") startForm.append(sectionTabsDiv); startForm.append(stepDiv); }); // ── Section tab helpers ────────────────────────────────────────────── // ── Add-section button — lives in the tab bar, disabled until pos chosen ── var addSectionBtn = new OO.ui.ButtonWidget({ label: "+ Beş zêde bike", disabled: true }); addSectionBtn.on("click", function () { saveCurrentSection(); sections.push({}); activeSection = sections.length - 1; $.each(PER_SECTION_STEP_IDS, function (_, id) { if (id === "dfn") { var stepDiv = $("#wiktku-start-dfn"); stepDiv.find("ol.wiktku-dfn-list").remove(); steps.dfn.build(stepDiv); return; } if (id === "etym") { $("#wiktku-start-etym .wiktku-etym-wrap").remove(); steps.etym.build($("#wiktku-start-etym")); return; } if (id === "trans") { var transDiv = $("#wiktku-start-trans"); transDiv.find(".wiktku-trans-group").remove(); return; } if (id === "zarava") { var zaravaDiv = $("#wiktku-start-zarava"); zaravaDiv.find(".wiktku-zarava-group").remove(); return; } if (id === "dunde") { var dundeDiv = $("#wiktku-start-dunde"); dundeDiv.find("ul.wiktku-dunde-list").remove(); return; } var stepDiv = $("#wiktku-start-" + id); stepDiv.find(".wiktku-start-step-field").val(""); if (!isMobile) stepDiv.find("select.wiktku-start-step-field").trigger("chosen:updated"); }); renderSectionTabs(); refresh(); $("html, body").animate({ scrollTop: sectionTabsDiv.offset().top - 20 }, 300); }); /** Re-render the tab bar to reflect current sections[] and activeSection. */ function renderSectionTabs() { // Detach (not remove) the button first: .empty() strips bound // event data from any children left inside it, which would // silently kill addSectionBtn's click handler on every re-render. addSectionBtn.$element.detach(); sectionTabsDiv.empty(); var lang = getValues().lang || ""; if (!lang) { sectionTabsDiv.hide(); return; } sectionTabsDiv.show(); $.each(sections, function (i) { var posVal = sections[i].pos || ""; var tabLabel = posVal ? capitalize(posVal) : ("Beş " + (i + 1)); var tab = $("<span></span>") .addClass("wiktku-section-tab") .text(tabLabel) .toggleClass("wiktku-tab-active", i === activeSection); (function (idx) { tab.on("click", function () { if (idx === activeSection) return; saveCurrentSection(); activeSection = idx; restoreSection(sections[activeSection]); refresh(); renderSectionTabs(); }); }(i)); sectionTabsDiv.append(tab); }); // Enable "Beş zêde bike" only when the active section has a pos chosen. var activePos = sections[activeSection] && sections[activeSection].pos ? sections[activeSection].pos : getValues().pos; addSectionBtn.setDisabled(!activePos); sectionTabsDiv.append(addSectionBtn.$element); } renderSectionTabs(); // Update the active tab's label whenever pos changes. startForm.on("change", "#wiktku-start-pos-field", function () { renderSectionTabs(); }); // Show the tab bar as soon as a language is selected. startForm.on("change", "#wiktku-start-lang-field", function () { renderSectionTabs(); }); var footer = $("<div id='wiktku-start-footer'></div>"); spinner = $(mw.html.element("img", { id: "wiktku-start-spinner", src: "//upload.wikimedia.org/wikipedia/commons/d/de/Ajax-loader.gif", alt: "Tê barkirin…", title: "Tê barkirin…" })); footer.append(spinner.hide()); continueBtn = new OO.ui.ButtonWidget({ id: "wiktku-unhide-editform", label: "Bişîne", flags: [ "primary", "progressive" ] }); continueBtn.on("click", function () { mw.notify("Tê şandin…", { type: "info", tag: "wiktku-submit" }); startForm.trigger("submit"); }); footer.append(continueBtn.$element); // "Edîtora çavkaniyê veke" button — inline fallback for the portlet link // which is invisible on mobile and easy to miss on desktop. var sourceEditorBtn = new OO.ui.ButtonWidget({ label: "Edîtora çavkaniyê veke", framed: false }); sourceEditorBtn.on("click", function () { destroy(); }); footer.append(sourceEditorBtn.$element); // ── Preview checkboxes ─────────────────────────────────────────────── // Wikitext preview (raw text panel) var previewCheck = $("<input type='checkbox' id='wiktku-preview-toggle'>"); var previewLabel = $("<label for='wiktku-preview-toggle'></label>") .text(" Pêşdîtina wîkîtekstê"); var previewPanel = $("<pre id='wiktku-preview-panel'></pre>").hide(); // Live rendered preview (parsed HTML panel, same logic as AjaxEdit). // Not available on mobile — API polling causes too many problems on small screens. var livePreviewCheck = null; var livePreviewPanel = null; if (!isMobile) { livePreviewCheck = $("<input type='checkbox' id='wiktku-live-preview-toggle'>"); livePreviewPanel = $("<div id='wiktku-live-preview-panel'></div>").hide(); } // Container that holds both panels and switches between stacked / side-by-side. var previewContainer = $("<div id='wiktku-preview-container'></div>"); previewContainer.append(previewPanel); if (!isMobile) previewContainer.append(livePreviewPanel); var previewTimer = null; var livePreviewIntervalId = -1; var livePreviewActive = false; // guards in-flight fetches after uncheck /** Rebuilds wikitext preview if its checkbox is checked. */ function schedulePreview() { if (!previewCheck.prop("checked")) return; clearTimeout(previewTimer); // Debounce: wait 400 ms after the last keystroke before rebuilding. previewTimer = setTimeout(function () { getWikitext(function (wikitext) { previewPanel.text(wikitext).show(); updatePanelLayout(); }); }, 400); } /** Fetches parsed HTML and populates the live preview panel. */ function loadLivePreview() { getWikitext(function (wikitext) { new mw.Api().parse(wikitext, { title: mw.config.get("wgPageName") }).done(function (html) { // Discard result if the user unchecked while the fetch was in flight. if (!livePreviewActive) return; livePreviewPanel.html(html).show(); updatePanelLayout(); }); }); } /** Adjusts panel widths depending on which previews are visible. */ function updatePanelLayout() { var wikitextVisible = previewCheck.prop("checked"); var liveVisible = livePreviewCheck && livePreviewCheck.prop("checked"); if (wikitextVisible && liveVisible) { // Side by side — each panel takes roughly half the available width. previewPanel.css({ "flex": "1 1 45%", "min-width": "280px" }); livePreviewPanel.css({ "flex": "1 1 45%", "min-width": "280px" }); } else { // Full width for whichever is visible — only touch panels that are // actually shown so that setting flex doesn't override display:none. if (wikitextVisible) previewPanel.css({ "flex": "1 1 100%", "min-width": "" }); if (liveVisible && livePreviewPanel) livePreviewPanel.css({ "flex": "1 1 100%", "min-width": "" }); } } previewCheck.on("change", function () { if ($(this).prop("checked")) { schedulePreview(); } else { clearTimeout(previewTimer); previewPanel.hide(); updatePanelLayout(); } }); if (!isMobile) { livePreviewCheck.on("change", function () { if ($(this).prop("checked")) { livePreviewActive = true; livePreviewPanel.show(); loadLivePreview(); livePreviewIntervalId = setInterval(loadLivePreview, 500); } else { livePreviewActive = false; clearInterval(livePreviewIntervalId); livePreviewIntervalId = -1; livePreviewPanel.hide().empty(); updatePanelLayout(); } }); } // Listen on all input/change events on the form and update both previews. startForm.on("input change", function () { schedulePreview(); }); footer.append($("<span style='margin-left:1em'></span>") .append(previewCheck).append(previewLabel)); if (!isMobile) { var livePreviewLabel = $("<label for='wiktku-live-preview-toggle'></label>") .text(" Pêşdîtina zindî"); footer.append($("<span style='margin-left:1em'></span>") .append(livePreviewCheck).append(livePreviewLabel)); } startForm.append(footer); $("#editform").hide().before(startForm); // Insert preview container (holds both panels) after the form. startForm.after(previewContainer); if (!isMobile) startForm.find("select").chosen(chosenOptions); refresh(); // Zimanan ji MediaWiki:Gadget-translation_editor.js/ziman.json bar bike. // Kodên ku bi "-pro" diqedin û navên ku "zimanê destan" tê de heye // tên derxistin. Zimanên xardkirî li serî dimînin, yên din // bi alfabeyê li dû wan tên. // Pinned choices come from MediaWiki:Gadget-start.js/data.json (langChoices), // already loaded into steps.lang.choices before build() runs. var pinnedChoices = steps.lang.choices.slice(); var pinnedCodes = $.map(pinnedChoices, function (choice) { return choice[0]; }); new mw.Api().get({ action: "query", prop: "revisions", titles: "MediaWiki:Gadget-translation_editor.js/ziman.json", rvprop: "content", rvslots: "main", formatversion: 2 }).then(function (data) { var page = data.query.pages[0]; var content = page && page.revisions && page.revisions[0].slots.main.content; var zimanData; try { zimanData = JSON.parse(content); } catch (e) { zimanData = {}; } var extraChoices = []; $.each(zimanData, function (code, name) { // Filter: skip proto-language codes and legendary/reconstructed langs. if (/-pro$/i.test(code)) return; if (/ziman[eê]\s+destan/i.test(name)) return; // Skip codes already in the pinned list (they are handled above). if (pinnedCodes.indexOf(code) !== -1) return; // sortKey: bare name without leading "zimanê " for sorting. var sortKey = name.replace(/^ziman[eê]\s+/i, ""); var choice = [code, name, sortKey]; extraChoices.push(choice); langsByCode[code] = choice; }); // Populate langsByCode for pinned choices too. $.each(pinnedChoices, function (i, choice) { // Ensure pinned choices have a sortKey (index 2). if (choice.length < 3) choice[2] = choice[1]; langsByCode[choice[0]] = choice; }); // Sort the extra choices alphabetically by sort key. extraChoices.sort(function (a, b) { return a[2].localeCompare(b[2], userLang); }); // Final list: pinned first, then the rest. var allChoices = pinnedChoices.concat(extraChoices); steps.lang.choices = allChoices; steps.trans.keys = allChoices; steps.dunde.keys = allChoices; steps.zarava.keys = getZaravaKeys(allChoices); var langMenu = $("#wiktku-start-lang-field"); populateMenus(langMenu, steps.lang.choices); langMenu.trigger("chosen:updated"); var transMenus = $("#wiktku-start-trans .wiktku-start-step-keyfield"); populateMenus(transMenus, steps.trans.keys, getDisabledKeys(steps.trans)); transMenus.trigger("chosen:updated"); var dundeMenus = $("#wiktku-start-dunde .wiktku-start-step-keyfield"); populateMenus(dundeMenus, steps.dunde.keys, getDisabledKeys(steps.dunde)); dundeMenus.trigger("chosen:updated"); var zaravaMenus = $("#wiktku-start-zarava .wiktku-start-step-keyfield"); populateMenus(zaravaMenus, steps.zarava.keys, getDisabledKeys(steps.zarava)); }); } mw.loader.using(["jquery.chosen", "mediawiki.api", "oojs-ui-core"], function () { if (!isMobile) { mw.notify( "Amûr dest pê dike, hinek bisekinin. Not: jkx Sentaks (sentaks highlighter) neaktîv bikin", { type: "info", tag: "wiktku-start-notice", autoHide: true, autoHideSeconds: 10 } ); } // Load metadata, langChoices, posChoices and tplDefs from the companion // data page so they can be updated without touching this script. new mw.Api().get({ action: "query", prop: "revisions", titles: "MediaWiki:Gadget-start.js/data.json", rvprop: "content", rvslots: "main", formatversion: 2 }).then(function (data) { var page = data.query.pages[0]; var content = page && page.revisions && page.revisions[0].slots.main.content; var d; try { d = JSON.parse(content); } catch (e) { d = {}; } // Populate metadata. if (d.metadata) $.extend(metadata, d.metadata); // Populate gender labels. if (d.genderLabels) $.extend(GENDER_BASE_LABELS, d.genderLabels); // Populate lang choices (pinned list used by build() → ziman.json loader). if (d.langChoices) steps.lang.choices = d.langChoices; // Populate POS choices. if (d.posChoices) steps.pos.choices = d.posChoices; // Populate template definitions for the dfn sense-block builder. if (d.tplDefs) steps.dfn.tplDefs = d.tplDefs; // Populate pos placeholder examples. if (d.posExamples) steps.dfn.posExamples = d.posExamples; // Populate citation template definitions for the quote widget. if (d.jederDefs) steps.dfn.jederDefs = d.jederDefs; // Populate pronunciation and etymology template insert lists. if (d.pronTpls) { steps.pron.pronTpls = d.pronTpls; steps.pron.refreshTplSelect(); } if (d.etymTpls) { steps.etym.etymTpls = d.etymTpls; steps.etym.refreshTplSelect(); } // Sync trans/dunde/zarava keys with the (now populated) lang choices. steps.trans.keys = steps.lang.choices; steps.dunde.keys = steps.lang.choices; steps.zarava.keys = getZaravaKeys(steps.lang.choices); }).always(build); }); }); //</nowiki> cfwmyyu2k82nqip9i8i72bqgmntvsng 6265577 6265576 2026-07-19T14:38:21Z Wikihez 7344 6265577 javascript text/javascript // Li ser [[vi:MediaWiki:Gadget-start.js]] hatiye refaktorkirin. //<nowiki> $(function () { if (window.location.href.includes("editintro=User:Wikihez/creation/intro")) { return; // Do not run the script wextê WF:Bilez dişuxile } var ns = mw.config.get("wgNamespaceNumber"); if (ns && !(ns === 2 && mw.config.get("wgPageName").match(/\/ceribandin$|\/test$/))) { return; } var action = mw.config.get("wgAction"); var pageExists = !!mw.config.get("wgArticleId"); // "Zimanek lê zêde bike" mode: triggered from the portlet link below. var addLangMode = pageExists && mw.util.getParamValue("wiktkuaddlang") === "1"; // On a normal page view of an existing page, add the portlet link if (action === "view" && pageExists) { var targetContainer; var skin = mw.config.get('skin'); if (skin === 'vector-2022') { targetContainer = 'p-cactions'; } else if (skin === 'vector') { targetContainer = 'p-tb'; } else { targetContainer = 'p-views'; } mw.util.addPortletLink(targetContainer, mw.util.getUrl(mw.config.get("wgPageName"), { action: "submit", wiktkuaddlang: "1" }), "+Ziman/beşeke din", "ca-wiktku-addlang", "Ji vê rûpelê re ziman an jî beşeke nû zêde bike"); return; } if (!(action === "edit" || action === "submit")) { return; } if (!addLangMode && !$(".mw-newarticletext, .mw-newarticletextanon").length) { return; } function capitalize(str) { if (!str) return str; return str[0].toUpperCase() + str.substr(1); } function decapitalize(str) { if (!str) return str; return str[0].toLowerCase() + str.substr(1); } function escapeRegExp(str) { return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); } function stripWikilinks(str) { return str.replace(/\[\[([^\]|]+)(?:\|([^\]]+))?\]\]/g, function (m, target, display) { return display || target; }); } function insertAtCursor(el, text) { var start = el.selectionStart; var end = el.selectionEnd; var val = el.value; el.value = val.slice(0, start) + text + val.slice(end); var pos = start + text.length; el.selectionStart = el.selectionEnd = pos; } var pageName = mw.config.get("wgPageName").replaceAll(/_/g, " "); if (ns) pageName = pageName.replace(/.*\//, ""); var pageNameRe = escapeRegExp(pageName); var userLang = mw.config.get("wgUserLanguage"); // Mobile detection: MobileFrontend sets wgMFMode, or fall back to touch check. var isMobile = !!mw.config.get("wgMFMode") || window.matchMedia("(pointer: coarse)").matches; var chosenOptions = { width: "20em", disable_search_threshold: 0, placeholder_text_single: "Yekî hilbijêre", placeholder_text_multiple: "Hilbijêre", no_results_text: "Nehat dîtin", enable_split_word_search: true, search_contains: true }; function wrapNativeSelect(select) { var placeholder = select.attr("data-placeholder") || "Lê bigere…"; // Hide the native select — we drive it programmatically. select.hide(); var wrapper = $("<span class='wiktku-native-select-wrap'></span>"); var textInput = $("<input type='search' autocomplete='off'>") .attr("placeholder", placeholder) .addClass("wiktku-start-narrow wiktku-ac-input"); var resultsList = $("<ul class='wiktku-ac-results'></ul>").hide(); // Full option cache — rebuilt when chosen:updated fires. var allOptions = []; function cacheOptions() { allOptions = []; select.find("option").each(function () { var v = $(this).val(); if (!v) return; // skip the empty placeholder option allOptions.push({ value: v, text: $(this).text(), disabled: $(this).prop("disabled") }); }); } cacheOptions(); function showResults(query) { var q = query.trim().toLowerCase(); resultsList.empty(); var matched; if (q) { matched = []; $.each(allOptions, function (_, o) { if (o.disabled) return; var codeMatch = o.value.toLowerCase().indexOf(q) !== -1; var nameMatch = o.text.toLowerCase().indexOf(q) !== -1; if (codeMatch || nameMatch) { matched.push({ opt: o, codeMatch: codeMatch }); } }); // Code matches (especially prefix matches) come first. matched.sort(function (a, b) { var aCode = a.opt.value.toLowerCase(); var bCode = b.opt.value.toLowerCase(); var aPrefix = aCode.indexOf(q) === 0; var bPrefix = bCode.indexOf(q) === 0; if (aPrefix !== bPrefix) return aPrefix ? -1 : 1; if (a.codeMatch !== b.codeMatch) return a.codeMatch ? -1 : 1; return 0; }); matched = matched.map(function (item) { return item.opt; }); } else { matched = allOptions.filter(function (o) { return !o.disabled; }); } if (!matched.length) { resultsList.hide(); return; } $.each(matched.slice(0, 50), function (_, opt) { var li = $("<li></li>").text(opt.text).attr("data-value", opt.value); // Use touchend instead of touchstart so that a scroll gesture does // not accidentally select an item. We track whether the finger moved // between touchstart and touchend — if it did, it was a scroll. var touchMoved = false; li.on("touchstart", function () { touchMoved = false; }); li.on("touchmove", function () { touchMoved = true; }); li.on("touchend", function (e) { if (touchMoved) return; // was a scroll, not a tap e.preventDefault(); selectOption(opt.value, opt.text); }); // Keep mousedown for desktop fallback. li.on("mousedown", function (e) { e.preventDefault(); selectOption(opt.value, opt.text); }); resultsList.append(li); }); // Position the list above or below depending on available viewport space. var inputRect = textInput[0].getBoundingClientRect(); var viewportH = window.innerHeight; var spaceBelow = viewportH - inputRect.bottom - 8; var spaceAbove = inputRect.top - 8; var maxH = Math.min(224, Math.max(spaceBelow, spaceAbove)); // 224px ≈ 14em resultsList.css({ "max-height": maxH + "px", "top": spaceBelow >= spaceAbove ? "100%" : "auto", "bottom": spaceBelow >= spaceAbove ? "auto" : "100%" }); resultsList.show(); } function selectOption(value, text) { textInput.val(text); select.val(value); resultsList.hide(); select.trigger("change"); } textInput.on("input focus", function () { showResults($(this).val()); }); textInput.on("blur", function () { // Short delay so a touchstart on a result item fires first. setTimeout(function () { resultsList.hide(); }, 200); }); // chosen:updated → re-cache (called after ziman.json loads). select.on("chosen:updated", function () { cacheOptions(); // If a value is already selected, keep the display text in sync. var cur = select.val(); if (cur) { var match = $.grep(allOptions, function (o) { return o.value === cur; })[0]; if (match) textInput.val(match.text); } }); // No-op .chosen() so desktop call-sites don't need guarding. select.chosen = function () { return select; }; wrapper.append(textInput).append(resultsList).append(select); return wrapper; } var langsByCode = {}; // Populated from [[MediaWiki:Gadget-start.js/data.json]] at runtime. var metadata = {}; // Zaravayên kurdî yên ku di beşa "Bi zaravayên din" de tên pêşkêşkirin — // ev kod ji beşa Werger têne derxistin daku heman zimên du caran neyê xwendin. var ZARAVA_LANG_CODES = ["ckb", "sdh", "lki", "hac", "zza"]; function getZaravaKeys(choices) { var byCode = {}; $.each(choices || [], function (_, c) { byCode[c[0]] = c; }); var result = []; $.each(ZARAVA_LANG_CODES, function (_, code) { if (byCode[code]) result.push(byCode[code]); }); return result; } function needsTransliteration(langCode) { var meta = metadata[langCode]; if (!meta || !meta.sc) return false; var scripts = Array.isArray(meta.sc) ? meta.sc : [meta.sc]; return scripts.length > 0 && scripts[0] !== "Latn"; } // Kodên cinsiyetê yên di metadata.g de — ji data.json tê dagirtin var GENDER_BASE_LABELS = {}; // Sub-lists that only make sense for a plain (non-şablon) sense — hidden // when a şablon (e.g. {{guharto|…}}) is chosen for that sense, since a // template-based sense has no "own" gloss for alternate forms, synonyms, // antonyms, coordinate terms, hypernyms or hyponyms to attach to. Etîket, // Nimûne and Jêgirtin stay visible either way. var HIDDEN_ON_TPL_GROUPS = [ "wiktku-dfn-alternativ", "wiktku-dfn-hevmane", "wiktku-dfn-dijmane", "wiktku-dfn-koordine", "wiktku-dfn-jornav", "wiktku-dfn-jernav" ]; function genderLabel(code) { if (code === "p") return "Pirjimar"; var pluralMatch = code.match(/^(.+)-p$/); if (pluralMatch && GENDER_BASE_LABELS[pluralMatch[1]]) { return GENDER_BASE_LABELS[pluralMatch[1]] + " (pirjimar)"; } return GENDER_BASE_LABELS[code] || code; } /** * True if a sense has any content worth keeping besides its mane text — * etîket, hevmane/dijmane/koordîne/etc. word lists, nimûne, or jêder * (quote). Used so a sense with an empty mane but filled-in extra * fields still gets emitted (with {{mane?}} standing in for the gloss) * instead of being silently dropped. */ function senseHasExtraContent(s) { if (s.etiket && $.grep(s.etiket, function (e) { return $.trim(e) !== ""; }).length) return true; if (s.kategori && $.grep(s.kategori, function (k) { return $.trim(k) !== ""; }).length) return true; if (s.alternativ.length || s.hevmane.length || s.dijmane.length || s.koordine.length || s.jornav.length || s.jernav.length) return true; if (s.nimune && $.grep(s.nimune, function (n) { return (typeof n === "object" ? n.text : n) !== ""; }).length > 0) return true; if (s.jeder && $.grep(s.jeder, function (j) { return j && j.quote; }).length > 0) return true; return false; } /** * formatNimune: each nimûne item can be { text, tr, t }: * text — example text * tr — transliteration (only when the language needs it) * t — Kurdish translation (third positional param, no key) */ function formatNimune(nimunes, lang, hasJeder) { var hasNimune = nimunes && $.grep(nimunes, function (n) { return (typeof n === "object" ? n.text : n) !== ""; }).length > 0; if (!hasNimune) { return hasJeder ? "" : "\n#* {{bênimûne|" + lang + "}}"; } return $.map(nimunes, function (n) { var text = typeof n === "object" ? n.text : n; if (!text) return undefined; var bolded = text.replace( new RegExp("(" + pageNameRe + "([^( |,|;|\\?|\\.|\\!)]+)?)", "ig"), "'''$1'''"); var tpl = "\n#: {{nm|" + lang + "|" + bolded; if (typeof n === "object") { if (n.tr) tpl += "|tr=" + n.tr; // Translation as third positional param (no key needed). if (n.t) tpl += "|" + n.t; } // Short examples fit on one line together with their translation. // rêz=1 is not used for ku — definitions are shown on separate lines there. if (text.length < 200 && lang !== "ku") tpl += "|rêz=1"; tpl += "}}"; return tpl; }).join(""); } /** * Formats a list of jêder (quote/citation) objects into wikitext lines. * Each entry that has no quote text is skipped. Returns "" when the list * is empty or every entry is blank. * * #* {{jêder-…|lang|jêgirtin=…|tr=…|tercime=…|…fields…}} * * When no template is chosen, the generic {{jêder|…}} template is used * instead. Its 2nd positional param is the user's freeform "bi destê xwe * binivîsim" source text when supplied, or the çavkanî? placeholder otherwise. * If that text contains "=" it is passed as |2=… instead of a bare * positional param, since MediaWiki would otherwise misparse it as its * own key=value pair and break the template: * #* {{jêder|lang|jêgirtin=…|tr=…|tercime=…|<manual source or çavkanî?>}} */ function formatJeder(jederList, lang) { if (!jederList || !jederList.length) return ""; return $.map(jederList, function (jeder) { if (!jeder || !jeder.quote) return undefined; if (jeder.jederTpl) { var cite = "\n#* {{" + jeder.jederTpl + "|" + lang; cite += "|jêgirtin=" + jeder.quote; if (jeder.quoteTr) cite += "|tr=" + jeder.quoteTr; if (jeder.quoteT) cite += "|tercime=" + jeder.quoteT; $.each(jeder.jêderFields || {}, function (key, val) { if (val) cite += "|" + key + "=" + val; }); cite += "}}"; return cite; } var out = "\n#* {{jêder|" + lang + "|jêgirtin=" + jeder.quote; if (jeder.quoteTr) out += "|tr=" + jeder.quoteTr; if (jeder.quoteT) out += "|tercime=" + jeder.quoteT; var srcParam = jeder.jederManual ? jeder.jederManual : "çavkanî?"; // A positional param containing "=" gets parsed as its own key=value // pair by MediaWiki and breaks the template, so force it to be // explicitly named (|2=) whenever that's the case. out += (srcParam.indexOf("=") !== -1 ? "|2=" : "|") + srcParam; out += "}}"; return out; }).join(""); } function makeWordListStep(id, name, question_fmt, header, templateName) { return { id: id, name: name, question_fmt: question_fmt, multiple: true, narrow: true, visible: function (values) { return values.lang && values.pos; }, output: function (values) { var words = $.grep(values[id] || [], function (w) { return !!w; }); if (!words.length) return ""; var lang = values.lang; var section = "\n==== " + header + " ====\n"; if (words.length === 1) { // Single word — keep the simple inline template. return section + "* {{" + templateName + "|" + lang + "|" + words[0] + "}}\n"; } // Multiple words — use {{kol3}} with one positional param per word. var params = "cure=" + header + "\n" + $.map(words, function (w) { return "|" + w; }).join("\n"); return section + "{{kol3|" + lang + "|" + params + "\n}}\n"; } }; } var steps = { lang: { id: "lang", required: true, name: "ziman", question_fmt: '"' + pageName + '" bi çi zimanî ye?', question_br: true, // Populated from [[MediaWiki:Gadget-start.js/data.json]] (langChoices). choices: [], output: function (values) { return "== {{ziman|" + values.lang + "}} ==\n"; } }, pron: { id: "pron", name: "bilêvkirin", question_fmt: '"' + pageName + '" çawa tê telafûzkirin?', // pronTpls populated from data.json pronTpls: [], visible: function (values) { if (!values.lang) return false; // In addLangMode, only skip pron when this langcode's section // already exists in the page — if it's a new language, show it. if (addLangMode) { var existing = $("#wpTextbox1").val() || ""; var header = "== {{ziman|" + values.lang + "}} =="; return existing.indexOf(header) === -1; } return true; }, /** Fills (or refills) the insert-dropdown from the current pronTpls array, filtering by language. */ refreshTplSelect: function () { var sel = $("#wiktku-start-pron .wiktku-tpl-insert-select"); if (!sel.length) return; var lang = getValues().lang || ""; sel.find("option[value!='']").remove(); $.each(steps.pron.pronTpls, function (_, tpl) { // Filter: if tpl.langs exists, only show if lang is in that list; otherwise show always var allowed = !tpl.langs || tpl.langs.indexOf(lang) !== -1; if (allowed) { sel.append($("<option></option>") .val(tpl.snippet) .text(tpl.name + " — " + tpl.desc) .attr("data-nolang", tpl.noLang ? "1" : "")); } }); // Notify Chosen that the option list has changed (no-op on mobile). if (!isMobile) sel.trigger("chosen:updated"); }, build: function (stepDiv) { if (stepDiv.find(".wiktku-pron-wrap").length) return null; var wrap = $("<div class='wiktku-pron-wrap'></div>"); var ta = $("<textarea></textarea>") .attr("name", "wiktku-pron-" + $.now()) .attr("class", "wiktku-start-step-field wiktku-pron-text") .attr("rows", 4) .attr("placeholder", "Nimûne: {{IPA|ku|/pɛɪ̯n/}} yan {{kîte|ku|he|ce|ki|rin}}"); // Template insert dropdown — filtered by language. var sel = $("<select class='wiktku-tpl-insert-select'></select>"); sel.append($("<option value=''>— şablonek lê zêde bike —</option>")); var lang = getValues().lang || ""; $.each(steps.pron.pronTpls, function (_, tpl) { // Filter: if tpl.langs exists, only show if lang is in that list; otherwise show always var allowed = !tpl.langs || tpl.langs.indexOf(lang) !== -1; if (allowed) { sel.append($("<option></option>") .val(tpl.snippet) .text(tpl.name + " — " + tpl.desc) .attr("data-nolang", tpl.noLang ? "1" : "")); } }); sel.on("change", function () { var snippet = $(this).val(); if (!snippet) return; var lang = getValues().lang || ""; // Check if the selected option has noLang flag var selectedOption = sel.find("option:selected"); var hasNoLang = selectedOption.attr("data-nolang") === "1"; if (!hasNoLang) { snippet = snippet.replace(/CODE/g, lang).replace(/SOURCELANG/g, "?"); } insertAtCursor(ta[0], snippet); $(this).val(""); ta.focus(); }); wrap.append(sel).append($("<br>")).append(ta); stepDiv.append(wrap); return ta; }, output: function () { var text = $.trim($("#wiktku-start-pron .wiktku-pron-text").val()); if (!text) return ""; var lines = text.split("\n"); var out = $.map(lines, function (line) { line = $.trim(line); if (!line) return undefined; return line.charAt(0) === "*" ? line : "* " + line; }).join("\n"); return "\n=== Bilêvkirin ===\n" + out + "\n"; } }, pos: { id: "pos", required: true, name: "Cureyê rêzimanî", question_fmt: 'Cureyê rêzimanî yê "' + pageName + '" çi ye?', visible: function (values) { return values.lang; }, question_br: true, // Populated from [[MediaWiki:Gadget-start.js/data.json]] (posChoices). choices: [], output: function (values) { var pos = values.pos || ""; var cinsiyet = values.cinsiyet || ""; // from the cinsiyet step var lekTur = values.lektur || ""; // from the lêker transitivity step var capitalizedPos = capitalize(pos); var outputString = "\n=== " + capitalizedPos + " ===\n"; // Add ku-tewîn-nav for single-word navdêr/serenav with known gender. if (!pageName.includes(" ") && cinsiyet && GENDER_BASE_LABELS[cinsiyet] && (pos === "navdêr" || pos === "serenav") && values.lang === "ku") { outputString += "{{ku-tewîn-nav|" + pageName + "|" + GENDER_BASE_LABELS[cinsiyet]; if (pos === "serenav") outputString += "|y"; outputString += "}}\n"; } outputString += "{{" + pos + "|" + values.lang; if (pos === "navdêr" || pos === "serenav") { if (cinsiyet) { outputString += "|c=" + cinsiyet; } else if (values.lang === "ku") { // Unknown gender — prompt editor to fill it in. outputString += "|c=?"; } } else if (/^lêker/.test(pos) && lekTur) { outputString += "|c=" + lekTur; } if (values.tr) { outputString += "|tr=" + values.tr; } outputString += "}}\n"; return outputString; } }, /** * cinsiyet (grammatical gender) — only shown for navdêr/serenav, û * tenê ger metadata ji bo zimanê hilbijartî lîsteyeke "g" (cinsiyet) * were dayîn. Opsiyonên vê gavê ne sabît in — ji metadata[values.lang].g * têne çêkirin, ji ber ku di hemû zimanan de cinsiyet tine. */ cinsiyet: { id: "cinsiyet", name: "cinsiyet", question_fmt: 'Cinsiyeta "' + pageName + '" çi ye?', question_br: true, visible: function (values) { var meta = metadata[values.lang]; return !!(values.lang && (values.pos === "navdêr" || values.pos === "serenav") && meta && meta.g && meta.g.length); }, build: function (stepDiv, values) { var select = stepDiv.find("select.wiktku-start-step-field"); if (!select.length) { select = $(mw.html.element("select", { "class": "wiktku-start-step-field", id: "wiktku-start-cinsiyet-field" })); stepDiv.append(select); } if (!values) return select; var meta = metadata[values.lang]; var codes = (meta && meta.g) || []; var prevVal = select.val(); var choices = $.map(codes, function (code) { return [[code, genderLabel(code)]]; }); populateMenus(select, choices); if ($.grep(choices, function (c) { return c[0] === prevVal; }).length) { select.val(prevVal); } if (!isMobile) select.trigger("chosen:updated"); return select; }, output: function () { return ""; } // consumed by pos.output }, /** * Lêker transitivity — only shown for any lêker variant. */ lektur: { id: "lektur", name: "Cureyê lêkerê (fiîlê)", question_fmt: "Cureyê lêkerê (fiîlê) çi ye?", question_br: true, visible: function (values) { return values.lang && values.pos && /^lêker/.test(values.pos); }, // Dictionary: value → display label. Add new types here. choices: [ ["gh", "gerguhêz"], ['x-gh', 'xwerû-gerguhêz'], ['p-gh', 'pêkhatî-gerguhêz'], ['h-gh', 'hevedudanî-gerguhêz'], ['b-gh', 'biwêjî-gerguhêz'], ["ngh", "negerguhêz"], ['x-ngh', 'xwerû-negerguhêz'], ['p-ngh', 'pêkhatî-negerguhêz'], ['h-ngh', 'hevedudanî-negerguhêz'], ['b-ngh', 'biwêjî-negerguhêz'] ], output: function () { return ""; } // consumed by pos.output }, tr: { id: "tr", name: "transkrîpsiyon", question_fmt: "Transkrîpsiyona kelîmeyê", multiple: false, narrow: true, visible: function (values) { return values.lang && values.pos && needsTransliteration(values.lang); } }, dfn: { id: "dfn", // required: true, ger mane tinebe [[Şablon:mane?]] bi kar bîne name: "Mane", question_fmt: "Maneya kelîmeyê binivîse. Mane otomatîk tê lînkkirin! Ji bo tercimeyan beşa 'Werger' bi kar bîne!", multiple: true, ordered: true, rows: 3, visible: function (values) { return values.lang && values.pos; }, example: function (values) { // posExamples loaded from [[MediaWiki:Gadget-start.js/data.json]]. var examples = steps.dfn.posExamples || {}; var full = values.pos || ""; return examples[full] || ""; }, /** * Builds one sense block (<li>) inside the ordered list. * Each block contains: * - a textarea for the definition * - an expandable nimûne list * - single-row sub-lists for formên alternatîv, hevmane, dijmane */ buildSenseBlock: function (stepDiv) { var block = $("<li class='wiktku-dfn-sense'></li>"); // — Mane textarea (declared first so the template handler can reference it) — var dfnArea = $("<textarea></textarea>") .attr("name", "wiktku-dfn-mane-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("class", "wiktku-start-step-field wiktku-dfn-mane") .attr("rows", 6) .attr("placeholder", "Mane…"); dfnArea.on("input", function () { steps.dfn.onDfnInput(stepDiv, block, this); }); // — Template selector (optional — replaces mane when chosen) — // Template definitions loaded from [[MediaWiki:Gadget-start.js/data.json]]. var tplDefs = steps.dfn.tplDefs || []; // Cache of all non-placeholder option elements — used by updateTplOptions // to remove/re-add options (the only approach compatible with Chosen.js). var _allTplOptions = []; var tplSelect = $(mw.html.element("select", { "class": "wiktku-dfn-tpl-select" })); tplSelect.append($("<option value=''>— yan jî şablonek hilbijêre —</option>")); $.each(tplDefs, function (_, tpl) { var opt = $("<option></option>") .val(tpl.name) .text(tpl.name) .attr("data-langs", tpl.langs ? tpl.langs.join(",") : "") .attr("data-nolang", tpl.noLang ? "1" : ""); tplSelect.append(opt); _allTplOptions.push(opt[0]); }); function updateTplOptions() { var lang = getValues().lang || ""; var currentVal = tplSelect.val(); var currentStillValid = false; // Detach all non-placeholder options, then re-attach only the visible ones. // This is the only approach that works correctly with both native <select> // and Chosen.js on desktop. tplSelect.find("option[value!='']").detach(); $.each(_allTplOptions, function (_, opt) { var allowed = $(opt).attr("data-langs"); var visible = !allowed || allowed.split(",").indexOf(lang) !== -1; if (visible) { tplSelect.append(opt); if ($(opt).val() === currentVal) currentStillValid = true; } }); if (!isMobile) tplSelect.trigger("chosen:updated"); if (currentVal && !currentStillValid) { tplSelect.val(""); dfnArea.show(); tplTitleInput.hide().val(""); } } // Store updater on the element so refresh() can call it for all blocks. tplSelect.data("updateOptions", updateTplOptions); var tplTitleInput = $("<input type='text'>") .addClass("wiktku-dfn-tpl-title wiktku-start-narrow") .attr("placeholder", "Navê rûpelê…") .hide(); // Grow the sense list when the title field of the last block gets content, // mirroring what onDfnInput does for the plain mane textarea. tplTitleInput.on("input", function () { steps.dfn.onDfnInput(stepDiv, block, this); }); /** * When a şablon sense is chosen, formên alternatîv/hevmane/dijmane/ * termên koordîne/jornav/jêrnav don't apply (there's no plain gloss * to hang them off), so hide those subgroups. Etîket, Nimûne and * Jêgirtin stay visible and still usable for a şablon sense. */ function updateFieldVisibility() { var isTpl = !!tplSelect.val(); $.each(HIDDEN_ON_TPL_GROUPS, function (_, cls) { block.find("." + cls + "-group").toggle(!isTpl); }); } // Store on the block so restoreDfn() can re-sync visibility // after programmatically setting tplSelect's value. block.data("updateFieldVisibility", updateFieldVisibility); tplSelect.on("change", function () { var chosen = $(this).val(); if (chosen) { dfnArea.hide(); tplTitleInput.show().focus(); } else { dfnArea.show(); tplTitleInput.hide().val(""); } updateFieldVisibility(); // Re-run refresh so the Werger step visibility updates. refresh(); }); var tplRow = $("<div></div>").addClass("wiktku-dfn-tpl-row") .append(tplSelect).append(" ").append(tplTitleInput); block.append(tplRow); block.append(dfnArea); // Apply lang filter on initial build. updateTplOptions(); // — Sub-field groups — // All groups are always visible with a placeholder textarea. // Nimûne is last in the DOM and last in the output. var allGroups = [ { cls: "wiktku-dfn-etiket", label: "Etîket", rows: 1, narrow: true, izah: "xisûsen, Mêrdîn, anatomî, Badînî" }, { cls: "wiktku-dfn-kategori", label: "Kategorî", rows: 1, narrow: true, izah: "Kategoriya ku ev mane lê tê zêdekirin" }, { cls: "wiktku-dfn-alternativ", label: "Formên alternatîv", rows: 1, narrow: true, izah: "Varyantên vê kelîmeyê" }, { cls: "wiktku-dfn-hevmane", label: "Hevmane", rows: 1, narrow: true, izah: "Spehî hevmaneya Bedew e." }, { cls: "wiktku-dfn-dijmane", label: "Dijmane", rows: 1, narrow: true, izah: "Zengîn dijmaneya feqîr e." }, { cls: "wiktku-dfn-koordine", label: "Termên koordîne", rows: 1, narrow: true, izah: "Pisîk û kûçik termên koordîne ne çunkî Jornavên wan gelek in" }, { cls: "wiktku-dfn-jornav", label: "Jornav", rows: 1, narrow: true, izah: "Heywan jornavê guhandar e" }, { cls: "wiktku-dfn-jernav", label: "Jêrnav", rows: 1, narrow: true, izah: "Guhandar jêrnavê heywan e" }, { cls: "wiktku-dfn-nimune", label: "Nimûne", rows: 2, narrow: false } ]; $.each(allGroups, function (_, g) { var groupDiv = $("<div></div>").addClass("wiktku-dfn-subgroup " + g.cls + "-group"); function buildNimuneLi() { var lang = getValues().lang || ""; var li = $("<li></li>").addClass("wiktku-dfn-nimune-li"); var mainTa = $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-text-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", g.rows) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-text") .attr("placeholder", "Nimûneya emilandina kelîmeyê tu bi xwe binivîse…"); mainTa.on("input", function () { var val = $.trim($(this).val()); var isLast = li.is(list.children("li:last-child")); if (val && isLast) { list.append(buildNimuneLi()); } }); li.append(mainTa); var subWrap = $("<div></div>").addClass("wiktku-dfn-nimune-sub"); if (needsTransliteration(lang)) { subWrap.append( $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-tr-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 5) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-tr") .attr("placeholder", "Transkrîpsiyona bi alfabeya latînî") ); } if (lang && lang !== "ku") { subWrap.append( $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-t-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 5) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-t") .attr("placeholder", "Tercimeya kurmancî") ); } if (subWrap.children().length) li.append(subWrap); return li; } if (g.cls === "wiktku-dfn-nimune") { // Nimûne — compound widget with tr/t sub-fields. var lbl = $("<span></span>").addClass("wiktku-dfn-sublabel").text(g.label + ": "); var list = $("<ol></ol>").addClass("wiktku-dfn-sublist " + g.cls + "-list"); groupDiv.data("buildNimuneLi", buildNimuneLi); list.append(buildNimuneLi()); groupDiv.append(lbl).append(list); block.append(groupDiv); } else { // Regular always-visible group — label + growing textarea list. var lbl = $("<span></span>").addClass("wiktku-dfn-sublabel").text(g.label + ": " + g.izah); var list = $("<ol></ol>").addClass("wiktku-dfn-sublist " + g.cls + "-list"); var firstInput = $("<textarea></textarea>") .attr("name", g.cls + "-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", g.rows) .attr("class", "wiktku-dfn-subfield" + (g.narrow ? " wiktku-start-narrow" : "")) .attr("placeholder", g.label + "…"); firstInput.on("input", function () { steps.dfn.onSubInput(list, this, g.rows, g.narrow); }); list.append($("<li></li>").append(firstInput)); groupDiv.append(lbl).append(list); block.append(groupDiv); } }); // — Jêder (quote / citation) group — a growing list, sibling to Nimûne — // Structured the same way as Nimûne (ol.wiktku-dfn-sublist > li) so it // lines up at the same indentation, and so that typing into the last // citation's Jêgirtin box automatically opens a fresh empty one below it. (function () { var jederGroupDiv = $("<div></div>").addClass("wiktku-dfn-subgroup wiktku-dfn-jeder-group"); var jederLbl = $("<span></span>").addClass("wiktku-dfn-sublabel").text("Jêgirtin: "); var jederList = $("<ol></ol>").addClass("wiktku-dfn-sublist wiktku-dfn-jeder-list"); function buildJederLi() { var lang = getValues().lang || ""; var li = $("<li></li>").addClass("wiktku-dfn-jeder-li"); var dragHandle = $("<span></span>") .addClass("wiktku-jeder-drag-handle") .attr("title", "Bişkûne û bikişîne da ku rêzê biguhezîne"); // Quote text textarea var quoteTa = $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-quote-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 2) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-quote") .attr("placeholder", "Nimûneya emilandinê ji kitêb an çavkaniyeke din binivîse"); quoteTa.on("input", function () { var val = $.trim($(this).val()); var isLast = li.is(jederList.children("li:last-child")); if (val && isLast) { jederList.append(buildJederLi()); } }); li.append(dragHandle).append(quoteTa); // tr/t sub-fields for the quote — shown as needed for the language. var quoteSubWrap = $("<div></div>").addClass("wiktku-dfn-quote-sub"); if (needsTransliteration(lang)) { quoteSubWrap.append( $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-quote-tr-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 2) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-quote-tr") .attr("placeholder", "Transkrîpsiyona jêgirtinê…") ); } if (lang && lang !== "ku") { quoteSubWrap.append( $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-quote-t-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 2) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-quote-t") .attr("placeholder", "Tercimeya jêgirtinê bi kurmancî") ); } if (quoteSubWrap.children().length) li.append(quoteSubWrap); // Citoid auto-fill: fetch citation data from a URL, DOI or ISBN and // prefill the source şablon + fields below (see Gadget-citoid-helper.js). var citoidWrap = $("<div></div>").addClass("wiktku-dfn-quote-citoid"); var citoidInput = $("<input type='text'>") .addClass("wiktku-dfn-quote-citoid-input wiktku-start-narrow") .attr("placeholder", "URL, DOI an ISBN binivîse ku otomatîk were tijekirin…"); var citoidBtn = new OO.ui.ButtonWidget({ label: "Bi Citoid bîne", classes: [ "wiktku-dfn-quote-citoid-btn" ] }); var citoidStatus = $("<span></span>").addClass("wiktku-dfn-quote-citoid-status"); /** * Fetches citation data from Citoid and applies it to this * citation's şablon selector + fields. Mirrors the logic in * Form.prototype._fillFromCitoid (Gadget-wikt.add-examples.js): * - only (re)selects the şablon when it actually differs from * what's already chosen, so a repeat fetch doesn't wipe out * a template the user already picked; * - only fills fields that are currently empty, so it never * overwrites something the user typed by hand; * - falls back to the freeform "bi destê xwe binivîsim" source * only when nothing was typed there yet. */ function runCitoidFetch() { var query = $.trim(citoidInput.val()); if (!query) { mw.notify("Ji kerema xwe re pêşî URL, DOI an ISBNyekê binivîse."); return; } citoidBtn.setDisabled(true); citoidStatus.text("Tê anîn…"); wikt.citoidHelper.ensure().then(function () { return wikt.citoid.fetchJederFields(query); }).then(function (result) { var jederKey = result.jederKey; var hasTpl = !!jederKey && srcSel.find("option[value='" + jederKey + "']").length > 0; var targetVal = hasTpl ? jederKey : "__manual__"; // Only (re)select — and thus rebuild — the field rows if // we're switching to a different şablon than what's // already chosen, so a second fetch doesn't clear fields // the user already filled in by hand. if (srcSel.val() !== targetVal) { srcSel.val(targetVal).trigger("change"); srcSel.trigger("chosen:updated"); } if (hasTpl) { // Tenê qadên vala tijî bike. $.each(result.fields, function (key, val) { var input = srcFields.find("[data-field-key='" + key + "']"); if (input.length && !$.trim(input.val())) { input.val(val); } }); } else { // Şablonek nehat naskirin ji bo vê itemType — rêzikeke // çavkaniyê ya bi destan a ji qadên Citoid tê çêkirin, // lê tenê ger qada destan vala be. var manualField = srcFields.find(".wiktku-dfn-quote-src-manual"); if (!$.trim(manualField.val())) { var parts = []; $.each(["nivîskar", "sernav", "websîte", "kovar", "weşanxane", "sal", "url"], function (_, k) { if (result.fields[k]) parts.push(result.fields[k]); }); manualField.val(parts.join(", ")); } } citoidStatus.text(""); }, function (errorMsg) { citoidStatus.text(typeof errorMsg === "string" ? errorMsg : "Nehat dîtin. Kontrol bike ka URL/DOI/ISBN rast e."); }).always(function () { citoidBtn.setDisabled(false); }); } citoidBtn.on("click", runCitoidFetch); citoidInput.on("keydown", function (e) { if (e.which === 13) { // Enter e.preventDefault(); runCitoidFetch(); } }); citoidWrap.append(citoidInput).append(citoidBtn.$element).append(citoidStatus); // Source template selector, specific to this citation. var srcSel = $("<select></select>").addClass("wiktku-dfn-quote-src-sel"); srcSel.append($("<option value=''>— Çavkaniyê hilbijêre —</option>")); srcSel.append($("<option></option>").val("__manual__").text("Bi destê xwe binivîsim")); var jederDefs = steps.dfn.jederDefs || {}; $.each(jederDefs, function (tplName, def) { srcSel.append($("<option></option>").val(tplName).text(def.label)); }); // Dynamic source fields container. var srcFields = $("<div></div>").addClass("wiktku-dfn-quote-src-fields"); srcSel.on("change", function () { srcFields.empty(); var chosen = $(this).val(); if (!chosen) return; if (chosen === "__manual__") { // Freeform source, written by the user — becomes the 2nd // positional param of {{jêder|lang|…}} instead of çavkanî?. srcFields.append( $("<textarea></textarea>") .attr("rows", 4) .addClass("wiktku-dfn-subfield wiktku-dfn-quote-src-manual") .attr("placeholder", "Çavkaniyê bi destê xwe binivîse…") ); return; } var def = (steps.dfn.jederDefs || {})[chosen]; if (!def) return; $.each(def.fields, function (_, f) { var row = $("<div></div>").addClass("wiktku-dfn-quote-src-row"); var fieldLbl = $("<label></label>").text(f.label + ": "); var inp = $("<textarea></textarea>") .attr("rows", 2) .addClass("wiktku-dfn-quote-src-input wiktku-start-narrow") .attr("data-field-key", f.key) .attr("placeholder", f.label + "…"); row.append(fieldLbl).append(inp); srcFields.append(row); }); }); li.append(citoidWrap).append(srcSel).append(srcFields); return li; } jederGroupDiv.data("buildJederLi", buildJederLi); jederList.append(buildJederLi()); // Make citation rows sortable (drag to reorder). // The last row is always the empty trailing row — cancel its drag. mw.loader.using("jquery.ui.sortable", function () { jederList.sortable({ handle: ".wiktku-jeder-drag-handle", axis: "y", items: "li:not(:last-child)", tolerance: "pointer" }); }); jederGroupDiv.append(jederLbl).append(jederList); block.append(jederGroupDiv); }()); // Apply the initial hide/show state for the sub-groups (matches // tplSelect's starting value, which is normally empty). updateFieldVisibility(); return block; }, /** Grows the sense list when the last mane textarea gets content. */ onDfnInput: function (stepDiv, block, textarea) { var val = $.trim($(textarea).val()); var list = stepDiv.find("ol.wiktku-dfn-list"); var isLast = block.is(list.children("li:last-child")); if (val && isLast) { var newBlock = steps.dfn.buildSenseBlock(stepDiv); list.append(newBlock); // Apply Chosen to the new block's template selector on desktop. if (!isMobile) newBlock.find("select.wiktku-dfn-tpl-select").chosen(chosenOptions); } refresh(); }, /** Grows a sub-list (nimûne/formên alternatîv/hevmane/dijmane/termên koordîne) on input. */ onSubInput: function (list, input, rows, narrow) { var val = $.trim($(input).val()); var item = $(input).parent(); var isLast = item.is(list.children("li:last-child")); if (val && isLast) { var next = $("<textarea></textarea>") .attr("name", "wiktku-dfn-sub-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", rows) .attr("class", "wiktku-dfn-subfield" + (narrow ? " wiktku-start-narrow" : "")); next.on("input", function () { steps.dfn.onSubInput(list, this, rows, narrow); }); list.append($("<li></li>").append(next)); } }, // Populated from [[MediaWiki:Gadget-start.js/data.json]] (tplDefs, posExamples, jederDefs). tplDefs: [], posExamples: {}, jederDefs: {}, build: function (stepDiv) { if (stepDiv.find("ol.wiktku-dfn-list").length) return null; var list = $("<ol class='wiktku-dfn-list'></ol>"); list.append(steps.dfn.buildSenseBlock(stepDiv)); stepDiv.append(list); return null; }, /** Reads all sense blocks from the DOM and returns an array of sense objects. */ getSenses: function (stepDiv) { var senses = []; stepDiv.find("li.wiktku-dfn-sense").each(function () { var block = $(this); var tplSel = block.find("select.wiktku-dfn-tpl-select"); var tpl = tplSel.val() || ""; // noLang: template already encodes the language — don't add |lang| param. var tplNoLang = tpl ? tplSel.find("option[value='" + tpl + "']").attr("data-nolang") === "1" : false; var tplTitle = $.trim(block.find("input.wiktku-dfn-tpl-title").val()); var mane = $.trim(block.find("textarea.wiktku-dfn-mane").val()); var etiket = (function () { var vals = []; block.find(".wiktku-dfn-etiket-list textarea").each(function () { var v = $.trim($(this).val()); if (v) vals.push(v); }); return vals; }()); var kategori = (function () { var vals = []; block.find(".wiktku-dfn-kategori-list textarea").each(function () { var v = $.trim($(this).val()); if (v) vals.push(v); }); return vals; }()); function readList(cls) { var vals = []; block.find("." + cls + "-list textarea").each(function () { var v = $.trim($(this).val()); if (v) vals.push(v); }); return vals; } // Nimûne items are compound: { text, tr?, t? } function readNimuneList() { var items = []; block.find(".wiktku-dfn-nimune-list li.wiktku-dfn-nimune-li").each(function () { var text = $.trim($(this).find(".wiktku-dfn-nimune-text").val()); if (!text) return; var obj = { text: text }; var tr = $.trim($(this).find(".wiktku-dfn-nimune-tr").val()); var t = $.trim($(this).find(".wiktku-dfn-nimune-t").val()); if (tr) obj.tr = tr; if (t) obj.t = t; items.push(obj); }); return items; } // Jêder is a growing list of citations, one per li — mirrors readNimuneList(). function readJederList() { var items = []; block.find(".wiktku-dfn-jeder-list li.wiktku-dfn-jeder-li").each(function () { var li = $(this); var quote = $.trim(li.find(".wiktku-dfn-nimune-quote").val()); if (!quote) return; var obj = { quote: quote }; var qtr = $.trim(li.find(".wiktku-dfn-nimune-quote-tr").val()); var qt = $.trim(li.find(".wiktku-dfn-nimune-quote-t").val()); if (qtr) obj.quoteTr = qtr; if (qt) obj.quoteT = qt; var tplName = li.find(".wiktku-dfn-quote-src-sel").val(); if (tplName === "__manual__") { var manual = $.trim(li.find(".wiktku-dfn-quote-src-manual").val()); if (manual) obj.jederManual = manual; } else if (tplName) { obj.jederTpl = tplName; var fields = {}; li.find(".wiktku-dfn-quote-src-input").each(function () { var k = $(this).attr("data-field-key"); var v = $.trim($(this).val()); if (k && v) fields[k] = v; }); obj.jêderFields = fields; } items.push(obj); }); return items; } senses.push({ tpl: tpl, tplNoLang: tplNoLang, tplTitle: tplTitle, mane: mane, etiket: etiket, kategori: kategori, nimune: readNimuneList(), jeder: readJederList(), alternativ: readList("wiktku-dfn-alternativ"), hevmane: readList("wiktku-dfn-hevmane"), dijmane: readList("wiktku-dfn-dijmane"), koordine: readList("wiktku-dfn-koordine"), jornav: readList("wiktku-dfn-jornav"), jernav: readList("wiktku-dfn-jernav") }); }); return senses; }, getOutput: function (values, callback) { var stepDiv = $("#wiktku-start-dfn"); var senses = steps.dfn.getSenses(stepDiv); var lang = values.lang; // A sense counts as "filled" if it has a mane, a chosen template + title, // or any other content (etîket/hevmane/nimûne/jêder…) worth keeping. var hasMane = senses.some(function (s) { return s.mane !== "" || (s.tpl && s.tplTitle) || senseHasExtraContent(s); }); // True only when at least one sense has a regular mane (needs linkify). var hasRegularMane = senses.some(function (s) { return !s.tpl && s.mane !== ""; }); // nimûne and jêder lines must never pass through linkify — only // the plain mane text should be linkified. We build two parallel // arrays: defLines (sent to linkify) and citeLines (kept aside). // Each entry in citeLines corresponds 1-to-1 with a defLines entry; // a template token {{wiktku-cite-N}} is embedded in defLines so // that after linkify runs we know exactly where to splice them back. // Template-call syntax is guaranteed safe: linkifiers leave {{ }} // tokens completely untouched. var defLines = []; // one entry per kept sense (goes to linkify) var citeLines = []; // parallel — nimûne+jêder for that same sense $.each(senses, function (_, sense) { // — Template sense (e.g. {{guharto|ku|somepage}}) — if (sense.tpl) { if (!sense.tplTitle) return; // skip empty template senses var tplKatTpl = ""; if (sense.kategori && sense.kategori.length) { var tplKatParts = sense.kategori.map(function (k) { return $.trim(k); }) .filter(function (k) { return k !== ""; }); if (tplKatParts.length) { tplKatTpl = "\n#: {{K|" + lang + "|" + tplKatParts.join("|") + "}}"; } } var tplLabelTpl = ""; if (sense.etiket && sense.etiket.length) { var tplLabelParts = sense.etiket.map(function (part) { return $.trim(part); }).filter(function (part) { return part !== ""; }); if (tplLabelParts.length) { tplLabelTpl = " {{e|" + lang + "|" + tplLabelParts.join("|") + "}} "; } } var tplCall = sense.tplNoLang ? "{{" + sense.tpl + "|" + sense.tplTitle + "}}" : "{{" + sense.tpl + "|" + lang + "|" + sense.tplTitle + "}}"; var tplHasJeder = sense.jeder && $.grep(sense.jeder, function (j) { return j && j.quote; }).length > 0; var idx = defLines.length; var cite = formatNimune(sense.nimune, lang, tplHasJeder) + formatJeder(sense.jeder, lang); defLines.push("#" + (tplLabelTpl ? tplLabelTpl : " ") + tplCall + tplKatTpl + (cite ? "{{wiktku-cite-" + idx + "}}" : "")); citeLines.push(cite); return; } // — Normal mane sense — var dfn = sense.mane; if (!dfn && !senseHasExtraContent(sense)) return; // truly empty if (dfn) { dfn = stripWikilinks(dfn); if (dfn[0] !== dfn[0].toUpperCase()) dfn = capitalize(dfn); if (!dfn.match(/[.…?!)\]]$/)) dfn += "."; } else { dfn = "{{mane?|" + lang + "}}"; } var katTpl = ""; if (sense.kategori && sense.kategori.length) { var katParts = sense.kategori.map(function (k) { return $.trim(k); }) .filter(function (k) { return k !== ""; }); if (katParts.length) { katTpl = "\n#: {{K|" + lang + "|" + katParts.join("|") + "}}"; } } var labelTpl = ""; if (sense.etiket && sense.etiket.length) { var labelParts = sense.etiket.map(function (part) { return $.trim(part); }).filter(function (part) { return part !== ""; }); if (labelParts.length) { labelTpl = " {{e|" + lang + "|" + labelParts.join("|") + "}} "; } } var out = "#" + (labelTpl ? labelTpl : " ") + dfn; out += katTpl; function wordLine(tpl, words) { if (!words.length) return ""; return "\n#: {{" + tpl + "|" + lang + "|" + words.join("|") + "}}"; } out += wordLine("alt-r", sense.alternativ); out += wordLine("hevmane", sense.hevmane); out += wordLine("dijmane", sense.dijmane); out += wordLine("koordîne", sense.koordine); out += wordLine("jornav", sense.jornav); out += wordLine("jêrnav", sense.jernav); var hasJeder = sense.jeder && $.grep(sense.jeder, function (j) { return j && j.quote; }).length > 0; var cite = formatNimune(sense.nimune, lang, hasJeder) + formatJeder(sense.jeder, lang); var idx = defLines.length; defLines.push(out + (cite ? "{{wiktku-cite-" + idx + "}}" : "")); citeLines.push(cite); }); // Splice citeLines back into a linkified string, replacing each // {{wiktku-cite-N}} token with its stored nimûne/jêder block. function restoreCites(t) { return t.replace(/\{\{wiktku-cite-(\d+)\}\}/g, function (_, n) { return citeLines[parseInt(n, 10)] || ""; }); } var text = defLines.join("\n") + "\n"; if (!hasMane) { // No definitions entered — emit {{mane?}} with bênimûne. text = "# {{mane?|" + lang + "}}\n#* {{bênimûne|" + lang + "}}\n"; callback(text); return; } if (!hasRegularMane) { // All filled senses are template senses — no linkify needed. callback(restoreCites(text)); return; } var didTryToLoad = function () { if (typeof $.wiktviLinkify === "function") { $.wiktviLinkify(text, function (linked) { callback(restoreCites(linked)); }); } else { callback(restoreCites(text)); } }; mw.loader.using("ext.gadget.linkify", didTryToLoad, didTryToLoad); } }, je: makeWordListStep("je", "jê", "Kelîmeyên jê çêbûyî binivîse", "Jê", "g"), tekildar: makeWordListStep("tekildar", "têkildar", "Kelîmeyên ji aliyê etîmolojiyê ve têkildarî vê kelîmeyê binivîse", "Têkildar", "g"), binereherwiha: makeWordListStep("binereherwiha", "binêre herwiha", "Kelîmeyên din ên eleqedar binivîse", "Binêre herwiha", "g"), etym: { id: "etym", name: "etîmolojî", question_fmt: "Etîmolojiya kelîmeyê binivîse", // etymTpls populated from data.json etymTpls: [], visible: function (values) { return values.lang && values.pos; }, /** Fills (or refills) the insert-dropdown from the current etymTpls array. */ refreshTplSelect: function () { var sel = $("#wiktku-start-etym .wiktku-tpl-insert-select"); if (!sel.length) return; sel.find("option[value!='']").remove(); $.each(steps.etym.etymTpls, function (_, tpl) { sel.append($("<option></option>").val(tpl.snippet).text(tpl.name + " — " + tpl.desc)); }); // Notify Chosen that the option list has changed (no-op on mobile). if (!isMobile) sel.trigger("chosen:updated"); }, build: function (stepDiv) { if (stepDiv.find(".wiktku-etym-wrap").length) return null; var wrap = $("<div class='wiktku-etym-wrap'></div>"); var ta = $("<textarea></textarea>") .attr("name", "wiktku-etym-" + $.now()) .attr("class", "wiktku-start-step-field wiktku-etym-text") .attr("rows", 4) .attr("placeholder", "Nimûne: Ji {{ji|en|ku|apple}}. yan rasterast binivîse…"); // Template insert dropdown — options also refreshed after data.json loads. var sel = $("<select class='wiktku-tpl-insert-select'></select>"); sel.append($("<option value=''>— şablonek lê zêde bike —</option>")); $.each(steps.etym.etymTpls, function (_, tpl) { sel.append($("<option></option>").val(tpl.snippet).text(tpl.name + " — " + tpl.desc)); }); sel.on("change", function () { var snippet = $(this).val(); if (!snippet) return; var lang = getValues().lang || ""; snippet = snippet.replace(/CODE/g, lang).replace(/SOURCELANG/g, "?"); insertAtCursor(ta[0], snippet); $(this).val(""); ta.focus(); }); wrap.append(sel).append($("<br>")).append(ta); stepDiv.append(wrap); return ta; }, output: function (values) { var text = $.trim($("#wiktku-start-etym .wiktku-etym-text").val()); if (text) { return "\n==== Etîmolojî ====\n" + text + "\n"; } // No etymology entered — emit {{ji?|lang}} as a placeholder, // but only when the entry has at least one regular (non-şablon) // sense with content — either real mane text, or an empty mane // with other fields filled in (which dfn.getOutput() renders as // {{mane?|lang}} with those fields attached). A şablon sense // like {{guharto|…}} never counts, filled in or not. var dfnSenses = steps.dfn.getSenses($("#wiktku-start-dfn")); var hasRegularMane = dfnSenses.some(function (s) { return !s.tpl && (s.mane !== "" || senseHasExtraContent(s)); }); if (!hasRegularMane) return ""; return "\n==== Etîmolojî ====\n{{ji?|" + values.lang + "}}\n"; } }, dunde: { id: "dunde", name: "dûnde", question_fmt: "Eger ev kelîme ji vî zimanî ketibe zimanekî din, vî zimanî û kelîmeya wî binivîse", visible: function (values) { return !!values.pos; }, disabledKeys: { "navz": true}, /** * Builds one row: a language dropdown + a growing list of word * inputs. When the dropdown gets a value the next empty row is * appended automatically. Mirrors steps.trans's row widget, but * flat (one shared list — dûnde isn't tied to individual senses). */ buildRow: function (stepDiv) { var row = $("<li class='wiktku-dunde-row wiktku-lang-row'></li>"); // Language selector — chosen is applied after insertion into DOM. var langSel = $(mw.html.element("select", { "class": "wiktku-start-step-keyfield wiktku-start-narrow" })); langSel.attr("data-placeholder", "Zimanekî lê bigere"); populateMenus(langSel, steps.dunde.keys || [], steps.dunde.disabledKeys); // When a language is chosen, ensure a next empty row exists. langSel.on("change", function () { steps.dunde.onLangChange(stepDiv, row); }); // Word list for this language. var wordList = $("<ul class='wiktku-dunde-words wiktku-lang-row-words'></ul>"); var firstWord = steps.dunde.makeWordInput(); wordList.append($("<li></li>").append(firstWord)); if (isMobile) { row.append(wrapNativeSelect(langSel)).append(wordList); } else { row.append(langSel).append(wordList); } return row; }, makeWordInput: function () { var input = $("<textarea></textarea>") .attr("name", "wiktku-dunde-word-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 1) .attr("class", "wiktku-dfn-subfield wiktku-start-narrow") .attr("placeholder", "Kelîme…"); input.on("input", function () { var list = $(this).closest("ul.wiktku-dunde-words"); var item = $(this).parent(); var val = $.trim($(this).val()); if (val && item.is(list.children("li:last-child"))) { var next = steps.dunde.makeWordInput(); list.append($("<li></li>").append(next)); } }); return input; }, onLangChange: function (stepDiv, row) { var list = stepDiv.find("ul.wiktku-dunde-list"); var isLast = row.is(list.children("li.wiktku-dunde-row:last-child")); if (isLast) { var newRow = steps.dunde.buildRow(stepDiv); list.append(newRow); // Init chosen after the new row is in the DOM (desktop only). if (!isMobile) newRow.find("select").chosen(chosenOptions); } // Keep disabled keys in sync across all lang selectors. steps.dunde.syncDisabledKeys(stepDiv); }, /** Disables already-selected languages in all other dropdowns. */ syncDisabledKeys: function (stepDiv) { var taken = $.extend({}, steps.dunde.disabledKeys); stepDiv.find("li.wiktku-dunde-row select").each(function () { var v = $(this).val(); if (v) taken[v] = true; }); stepDiv.find("li.wiktku-dunde-row select").each(function () { var self = $(this); var own = self.val(); self.find("option").each(function () { var code = $(this).val(); if (!code) return; $(this).prop("disabled", taken[code] && code !== own); }); self.trigger("chosen:updated"); }); }, build: function (stepDiv) { if (stepDiv.find("ul.wiktku-dunde-list").length) return null; var list = $("<ul class='wiktku-dunde-list wiktku-lang-row-list'></ul>"); list.append(steps.dunde.buildRow(stepDiv)); stepDiv.append(list); // Init chosen after the select is in the DOM (desktop only). if (!isMobile) list.find("select").chosen(chosenOptions); return null; }, /** Reads all [langcode, words[]] rows from the DOM. */ getRows: function (stepDiv) { var result = []; stepDiv.find("li.wiktku-dunde-row").each(function () { var lang = $(this).find("select").val(); if (!lang) return; var words = []; $(this).find("ul.wiktku-dunde-words textarea").each(function () { var v = $.trim($(this).val()); if (v) words.push(v); }); if (words.length) result.push([lang, words]); }); return result; }, output: function () { var stepDiv = $("#wiktku-start-dunde"); var rows = steps.dunde.getRows(stepDiv); if (!rows.length) return ""; var lines = $.map(rows, function (row) { var lang = row[0], words = row[1]; return "* {{dû|" + lang + "|" + words.join("|") + "}}"; }); return "\n==== Dûnde ====\n" + lines.join("\n") + "\n"; } }, zarava: { id: "zarava", name: "bi zaravayên din", visible: function (values) { return steps.trans.visible(values); }, disabledKeys: { "navz": true }, buildRow: function (group) { var row = $("<li class='wiktku-zarava-row wiktku-lang-row'></li>"); var langSel = $(mw.html.element("select", { "class": "wiktku-start-step-keyfield wiktku-start-narrow" })); populateMenus(langSel, steps.zarava.keys || [], steps.zarava.disabledKeys); langSel.on("change", function () { steps.zarava.onLangChange(group, row); }); var wordList = $("<ul class='wiktku-zarava-words wiktku-lang-row-words'></ul>"); var firstWord = steps.zarava.makeWordInput(); wordList.append($("<li></li>").append(firstWord)); row.append(langSel).append(wordList); return row; }, makeWordInput: function () { var input = $("<textarea></textarea>") .attr("name", "wiktku-zarava-word-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 1) .attr("class", "wiktku-dfn-subfield wiktku-start-narrow") .attr("placeholder", "Tercime…"); input.on("input", function () { var list = $(this).closest("ul.wiktku-zarava-words"); var item = $(this).parent(); var val = $.trim($(this).val()); if (val && item.is(list.children("li:last-child"))) { var next = steps.zarava.makeWordInput(); list.append($("<li></li>").append(next)); } }); return input; }, onLangChange: function (group, row) { var list = group.find("ul.wiktku-zarava-list"); var isLast = row.is(list.children("li.wiktku-zarava-row:last-child")); if (isLast) { var newRow = steps.zarava.buildRow(group); list.append(newRow); } steps.zarava.syncDisabledKeys(group); }, /** Disables already-selected dialects in all other dropdowns within one group. */ syncDisabledKeys: function (group) { var taken = $.extend({}, steps.zarava.disabledKeys); group.find("li.wiktku-zarava-row select").each(function () { var v = $(this).val(); if (v) taken[v] = true; }); group.find("li.wiktku-zarava-row select").each(function () { var self = $(this); var own = self.val(); self.find("option").each(function () { var code = $(this).val(); if (!code) return; $(this).prop("disabled", taken[code] && code !== own); }); }); }, /** Builds (or fetches) the .wiktku-zarava-group for one gloss. */ buildGroup: function (stepDiv, gi) { var group = $("<div class='wiktku-zarava-group'></div>").attr("data-gloss-pos", gi); var list = $("<ul class='wiktku-zarava-list wiktku-lang-row-list'></ul>"); list.append(steps.zarava.buildRow(group)); group.append(list); stepDiv.append(group); return group; }, /** Syncs one .wiktku-zarava-group per current gloss (same logic as steps.trans.build). */ build: function (stepDiv) { var glosses = steps.trans.glossList(); if (!glosses.length) { stepDiv.find(".wiktku-zarava-group").remove(); return null; } var existingGroups = stepDiv.find(".wiktku-zarava-group"); if (existingGroups.length > glosses.length) { existingGroups.slice(glosses.length).remove(); } $.each(glosses, function (gi, gloss) { var group = stepDiv.find(".wiktku-zarava-group[data-gloss-pos='" + gi + "']"); if (!group.length) group = steps.zarava.buildGroup(stepDiv, gi); var label = group.find(".wiktku-zarava-group-label"); if (glosses.length > 1) { if (!label.length) { label = $("<div class='wiktku-zarava-group-label'></div>"); group.prepend(label); } label.text(gloss.index + " " + gloss.text); } else if (label.length) { label.remove(); } }); return null; }, /** Reads the dialect rows for a single gloss group. */ getGroupTranslations: function (group) { var result = []; group.find("li.wiktku-zarava-row").each(function () { var lang = $(this).find("select").val(); if (!lang) return; var words = []; $(this).find("ul.wiktku-zarava-words textarea").each(function () { var v = $.trim($(this).val()); if (v) words.push(v); }); if (words.length) result.push([lang, words]); }); return result; }, /** Reads all rows from the DOM, grouped by gloss position. */ getTranslations: function (stepDiv) { var result = []; stepDiv.find(".wiktku-zarava-group").each(function () { result.push(steps.zarava.getGroupTranslations($(this))); }); return result; }, output: function (values) { if (values.lang !== "ku") return ""; var stepDiv = $("#wiktku-start-zarava"); var glosses = steps.trans.glossList(); if (!glosses.length) return ""; var blocks = $.map(glosses, function (gloss, gi) { var group = stepDiv.find(".wiktku-zarava-group[data-gloss-pos='" + gi + "']"); var rows = group.length ? steps.zarava.getGroupTranslations(group) : []; if (!gloss.text && !rows.length) return undefined; if (rows.length) { rows.sort(function (a, b) { var aLang = langsByCode[a[0]] || []; var bLang = langsByCode[b[0]] || []; return (aLang[2] || "").localeCompare(bLang[2] || "", "ku"); }); } var wordLines = $.map(rows, function (row) { var lang = row[0]; var words = row[1]; var wikiWords = words.map(function (w) { return "{{W|" + lang + "|" + w + "}}"; }).join(", "); return "* {{Z|" + lang + "}}: " + wikiWords; }).join("\n"); if (!wordLines) return undefined; var block = "{{werger-ser|" + (gloss.text || "?") + "|" + gloss.index + "}}"; block += "\n" + wordLines; block += "\n{{werger-bin}}"; return block; }); if (!blocks.length) return ""; return "\n==== Bi zaravayên din ====\n" + blocks.join("\n") + "\n"; } }, trans: { id: "trans", name: "werger", visible: function (values) { if (!(values.lang === "ku" && values.pos)) return false; // Hide Werger only when EVERY sense is a template sense (Guharto etc.) // with a title filled in — i.e. there is real content but no plain // gloss to attach a translation table to. A mix of real + template // senses still shows Werger; the template senses are simply skipped // in output(). // // "Real" here means a non-şablon sense with either mane text or // other filled-in fields (etîket/hevmane/nimûne/jêder…), since // dfn.getOutput() renders the latter too, as {{mane?|lang}} plus // whatever else was filled in. // // When nothing has been filled in at all, output() will emit // {{mane?|lang}} instead of a gloss — but Werger should still show, // since the user may want to add translations before they've // settled on a gloss. var dfnSenses = steps.dfn.getSenses($("#wiktku-start-dfn")); var hasRealSense = dfnSenses.some(function (s) { return !s.tpl && (s.mane !== "" || senseHasExtraContent(s)); }); var hasFilledTplSense = dfnSenses.some(function (s) { return s.tpl && s.tplTitle; }); return hasRealSense || !hasFilledTplSense; }, disabledKeys: { "navz": true, "ku": true, "ckb": true, "sdh": true, "lki": true, "hac": true, "zza": true }, /** * Builds one translation row: a language dropdown + a growing list * of word inputs. When the dropdown gets a value the next empty row * is appended automatically. * * @param group the specific .wiktku-trans-group this row belongs to * (each gloss has its own group and its own list of rows, so the * lookups below must stay scoped to that group rather than the * whole step — the step now holds one list per gloss). */ buildRow: function (group) { var row = $("<li class='wiktku-trans-row wiktku-lang-row'></li>"); // Language selector — chosen is applied after insertion into DOM. var langSel = $(mw.html.element("select", { "class": "wiktku-start-step-keyfield wiktku-start-narrow" })); langSel.attr("data-placeholder", "Zimanekî lê bigere"); populateMenus(langSel, steps.trans.keys || [], steps.trans.disabledKeys); // When a language is chosen, ensure a next empty row exists. langSel.on("change", function () { steps.trans.onLangChange(group, row); }); // Word list for this language. var wordList = $("<ul class='wiktku-trans-words wiktku-lang-row-words'></ul>"); var firstWord = steps.trans.makeWordInput(); wordList.append($("<li></li>").append(firstWord)); if (isMobile) { row.append(wrapNativeSelect(langSel)).append(wordList); } else { row.append(langSel).append(wordList); } return row; }, makeWordInput: function () { var input = $("<textarea></textarea>") .attr("name", "wiktku-trans-word-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 1) .attr("class", "wiktku-dfn-subfield wiktku-start-narrow") .attr("placeholder", "Tercime…"); input.on("input", function () { var list = $(this).closest("ul.wiktku-trans-words"); var item = $(this).parent(); var val = $.trim($(this).val()); if (val && item.is(list.children("li:last-child"))) { var next = steps.trans.makeWordInput(); list.append($("<li></li>").append(next)); } }); return input; }, onLangChange: function (group, row) { var list = group.find("ul.wiktku-trans-list"); var isLast = row.is(list.children("li.wiktku-trans-row:last-child")); if (isLast) { var newRow = steps.trans.buildRow(group); list.append(newRow); // Init chosen after the new row is in the DOM (desktop only). if (!isMobile) newRow.find("select").chosen(chosenOptions); } // Keep disabled keys in sync across this gloss's lang selectors // only — the same language can be used for different senses. steps.trans.syncDisabledKeys(group); }, /** Disables already-selected languages in all other dropdowns within one group. */ syncDisabledKeys: function (group) { var taken = $.extend({}, steps.trans.disabledKeys); group.find("li.wiktku-trans-row select").each(function () { var v = $(this).val(); if (v) taken[v] = true; }); group.find("li.wiktku-trans-row select").each(function () { var self = $(this); var own = self.val(); self.find("option").each(function () { var code = $(this).val(); if (!code) return; $(this).prop("disabled", taken[code] && code !== own); }); self.trigger("chosen:updated"); }); }, /** * Builds (or fetches) the .wiktku-trans-group for one gloss, with * its own label and its own list of translation rows. */ buildGroup: function (stepDiv, gi) { var group = $("<div class='wiktku-trans-group'></div>").attr("data-gloss-pos", gi); var list = $("<ul class='wiktku-trans-list wiktku-lang-row-list'></ul>"); list.append(steps.trans.buildRow(group)); group.append(list); stepDiv.append(group); // Init chosen after the select is in the DOM (desktop only). if (!isMobile) list.find("select").chosen(chosenOptions); return group; }, /** * Syncs one .wiktku-trans-group per current gloss, adding new * groups and removing stale ones as senses are added or removed, * while leaving existing groups (and whatever translations the * user has already typed into them) untouched. Groups are keyed * to their gloss's position in glossList() via data-gloss-pos, so * a group always matches the same sense across rebuilds as long * as senses aren't reordered relative to each other. */ build: function (stepDiv) { var glosses = steps.trans.glossList(); if (!glosses.length) { stepDiv.find(".wiktku-trans-group").remove(); return null; } // Drop groups for glosses that no longer exist (always from the // tail — groups are only ever appended in gloss order below). var existingGroups = stepDiv.find(".wiktku-trans-group"); if (existingGroups.length > glosses.length) { existingGroups.slice(glosses.length).remove(); } $.each(glosses, function (gi, gloss) { var group = stepDiv.find(".wiktku-trans-group[data-gloss-pos='" + gi + "']"); if (!group.length) group = steps.trans.buildGroup(stepDiv, gi); // Only label groups when there's more than one gloss to // distinguish between — a single gloss needs no caption. var label = group.find(".wiktku-trans-group-label"); if (glosses.length > 1) { if (!label.length) { label = $("<div class='wiktku-trans-group-label'></div>"); group.prepend(label); } label.text(gloss.index + " " + gloss.text); } else if (label.length) { label.remove(); } }); return null; }, /** Reads the translation rows for a single gloss group. */ getGroupTranslations: function (group) { var result = []; group.find("li.wiktku-trans-row").each(function () { var lang = $(this).find("select").val(); if (!lang) return; var words = []; $(this).find("ul.wiktku-trans-words textarea").each(function () { var v = $.trim($(this).val()); if (v) words.push(v); }); if (words.length) result.push([lang, words]); }); return result; }, /** * Reads all translation rows from the DOM, grouped by gloss * position — one array of [lang, words] rows per gloss group, in * the same order as the .wiktku-trans-group elements. */ getTranslations: function (stepDiv) { var result = []; stepDiv.find(".wiktku-trans-group").each(function () { result.push(steps.trans.getGroupTranslations($(this))); }); return result; }, /** * Builds the numbered "{ index, gloss }" list — one entry per dfn * sense that has a real mane (skips template senses like Guharto, * which have nothing to caption a translation table with). The * index matches the sense's actual position in the numbered "#" * definition list (1-based), including template senses in the count, * so the number printed next to {{werger-ser}} lines up with the * gloss the reader sees in the entry. * * When nothing has been filled in at all (dfn.getOutput() will emit * {{mane?|lang}} as sense 1), this returns a single placeholder * entry with empty text instead of an empty array, so Werger still * has one group to attach translations to before a gloss exists. * When every filled sense is a template sense instead, this stays * empty — that mirrors trans.visible()'s hidden case, where there's * no group in the DOM for a placeholder to attach to anyway. */ glossList: function () { var dfnSenses = steps.dfn.getSenses($("#wiktku-start-dfn")); var glosses = []; var hasFilledTplSense = false; $.each(dfnSenses, function (i, s) { if (s.tpl) { if (s.tplTitle) hasFilledTplSense = true; return; // template sense — no gloss to caption with } var dfn = s.mane; if (!dfn) { // No mane text, but other fields (etîket/hevmane/nimûne/ // jêder…) are filled — dfn.getOutput() still emits this // sense as a numbered line using {{mane?|lang}}, so it // needs its own gloss group too, just with no caption text. if (senseHasExtraContent(s)) glosses.push({ index: i + 1, text: "" }); return; } if (dfn[0] !== dfn[0].toLowerCase()) dfn = decapitalize(dfn); dfn = stripWikilinks(dfn).replace(/[.…?!)\]،؟]+$/, ""); glosses.push({ index: i + 1, text: dfn }); }); if (!glosses.length && !hasFilledTplSense) { glosses.push({ index: 1, text: "" }); } return glosses; }, output: function (values) { if (values.lang !== "ku") return ""; var stepDiv = $("#wiktku-start-trans"); var glosses = steps.trans.glossList(); // Every sense is a template sense — there's no real gloss // anywhere and no group in the DOM either (glossList() only // returns empty in that case), so skip the section entirely. if (!glosses.length) return ""; // Each gloss now has its own group of translation rows — // attach every gloss's own words under its own werger-ser/-bin // pair instead of dumping everything under the first one. var blocks = $.map(glosses, function (gloss, gi) { var group = stepDiv.find(".wiktku-trans-group[data-gloss-pos='" + gi + "']"); var rows = group.length ? steps.trans.getGroupTranslations(group) : []; // Placeholder gloss (no real mane entered yet) with nothing // translated into it — nothing to output, and gloss.text is // empty so there's no caption to give {{werger-ser}} anyway. if (!gloss.text && !rows.length) return undefined; if (rows.length) { // Sort by Kurdish sort key. rows.sort(function (a, b) { var aLang = langsByCode[a[0]] || []; var bLang = langsByCode[b[0]] || []; return (aLang[2] || "").localeCompare(bLang[2] || "", "ku"); }); } var wordLines = $.map(rows, function (row) { var lang = row[0]; var words = row[1]; var wikiWords = words.map(function (w) { return "{{W|" + lang + "|" + w + "}}"; }).join(", "); return "* {{Z|" + lang + "}}: " + wikiWords; }).join("\n"); var block = "{{werger-ser|" + (gloss.text || "?") + "|" + gloss.index + "}}"; if (wordLines) block += "\n" + wordLines; block += "\n{{werger-bin}}"; return block; }); if (!blocks.length) return ""; return "\n==== Werger ====\n" + blocks.join("\n") + "\n"; } }, }; steps.trans.keys = steps.lang.choices; steps.dunde.keys = steps.lang.choices; steps.zarava.keys = getZaravaKeys(steps.lang.choices); var ordered_steps = [ steps.lang, steps.pron, steps.pos, steps.cinsiyet, steps.lektur, steps.tr, steps.dfn, steps.je, steps.tekildar, steps.etym, steps.dunde, steps.binereherwiha, steps.zarava, steps.trans]; // Step ids that belong to each section (not shared across sections). var PER_SECTION_STEP_IDS = [ "pos", "cinsiyet", "lektur", "tr", "dfn", "je", "tekildar", "etym", "dunde", "binereherwiha", "zarava", "trans" ]; // ── Multi-section state ────────────────────────────────────────────────── // Each entry is a plain snapshot: { pos, cinsiyet, lektur, tr, dfn (senses[]), // je, tekildar, binereherwiha, trans (rows[]) }. var sections = [{}]; // section 0 starts empty (DOM is the truth) var activeSection = 0; function snapshotDfn() { return steps.dfn.getSenses($("#wiktku-start-dfn")); } /** * Rebuild the dfn DOM from a previously snapshotted senses array. */ function restoreDfn(senses) { var stepDiv = $("#wiktku-start-dfn"); // Tear down the existing list so build() recreates it cleanly. stepDiv.find("ol.wiktku-dfn-list").remove(); steps.dfn.build(stepDiv); var list = stepDiv.find("ol.wiktku-dfn-list"); $.each(senses, function (i, sense) { // Ensure enough blocks exist (build() seeds one). var blocks = list.find("li.wiktku-dfn-sense"); var block = blocks.eq(i); if (!block.length) { var nb = steps.dfn.buildSenseBlock(stepDiv); list.append(nb); block = list.find("li.wiktku-dfn-sense").last(); } // Template selector. block.find("select.wiktku-dfn-tpl-select").val(sense.tpl || ""); if (sense.tpl) { block.find("textarea.wiktku-dfn-mane").hide(); block.find("input.wiktku-dfn-tpl-title").val(sense.tplTitle || "").show(); } else { block.find("textarea.wiktku-dfn-mane").val(sense.mane || "").show(); block.find("input.wiktku-dfn-tpl-title").hide().val(""); } // Re-sync the formên alternatîv/hevmane/… hide state now that // tplSelect's value was set programmatically (its own "change" // handler doesn't fire from .val(), so this doesn't happen otherwise). var updateVis = block.data("updateFieldVisibility"); if (updateVis) updateVis(); // Restore a sub-list (etiket, formên alternatîv, hevmane …) from a values array. function restoreSubList(cls, values) { if (!values || !values.length) return; var groupDiv = block.find("." + cls + "-group"); var subList = groupDiv.find("ol, ul").first(); if (!subList.length) return; // group not found // Fill existing items, append new ones as needed. $.each(values, function (j, val) { var items = subList.find("li"); if (j < items.length) { items.eq(j).find("textarea").val(val); } else { var ta = $("<textarea></textarea>") .attr("name", "wiktku-dfn-restore-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 1) .attr("class", "wiktku-dfn-subfield wiktku-start-narrow") .val(val); ta.on("input", function () { steps.dfn.onSubInput(subList, this, 1, true); }); subList.append($("<li></li>").append(ta)); } }); } // Reveal and populate lazy groups that have data. var lazyMap = { "wiktku-dfn-etiket": sense.etiket, "wiktku-dfn-kategori": sense.kategori, "wiktku-dfn-alternativ": sense.alternativ, "wiktku-dfn-hevmane": sense.hevmane, "wiktku-dfn-dijmane": sense.dijmane, "wiktku-dfn-koordine": sense.koordine, "wiktku-dfn-jornav": sense.jornav, "wiktku-dfn-jernav": sense.jernav }; $.each(lazyMap, function (cls, vals) { if (vals && vals.length) restoreSubList(cls, vals); }); // Nimûne items are objects { text, tr?, t? } — restore using the builder. if (sense.nimune && sense.nimune.length) { var nimuneGroupDiv = block.find(".wiktku-dfn-nimune-group"); var nimuneList = nimuneGroupDiv.find("ol.wiktku-dfn-nimune-list"); var buildFn = nimuneGroupDiv.data("buildNimuneLi"); nimuneList.empty(); $.each(sense.nimune, function (_, n) { var text = typeof n === "object" ? (n.text || "") : n; if (!text) return; var li = buildFn ? buildFn() : $("<li class='wiktku-dfn-nimune-li'></li>"); li.find(".wiktku-dfn-nimune-text").val(text); if (n.tr) li.find(".wiktku-dfn-nimune-tr").val(n.tr); if (n.t) li.find(".wiktku-dfn-nimune-t").val(n.t); nimuneList.append(li); }); // Always leave a blank trailing item. if (buildFn) nimuneList.append(buildFn()); } // Restore jêder (quote/citation) entries — a growing list, restored using the // builder just like Nimûne. Accepts either the current array shape or a // single legacy object (from older saved sections) for backwards compatibility. var jederArr = $.isArray(sense.jeder) ? sense.jeder : (sense.jeder ? [sense.jeder] : []); if (jederArr.length) { var jederGroupDiv = block.find(".wiktku-dfn-jeder-group"); var jederList = jederGroupDiv.find("ol.wiktku-dfn-jeder-list"); var buildJederFn = jederGroupDiv.data("buildJederLi"); jederList.empty(); $.each(jederArr, function (_, j) { if (!j || !j.quote) return; var li = buildJederFn ? buildJederFn() : $("<li class='wiktku-dfn-jeder-li'></li>"); li.find(".wiktku-dfn-nimune-quote").val(j.quote); if (j.quoteTr) li.find(".wiktku-dfn-nimune-quote-tr").val(j.quoteTr); if (j.quoteT) li.find(".wiktku-dfn-nimune-quote-t").val(j.quoteT); if (j.jederManual) { var manualSel = li.find(".wiktku-dfn-quote-src-sel"); manualSel.val("__manual__").trigger("change"); li.find(".wiktku-dfn-quote-src-manual").val(j.jederManual); } else if (j.jederTpl) { var srcSel = li.find(".wiktku-dfn-quote-src-sel"); srcSel.val(j.jederTpl).trigger("change"); if (j.jêderFields) { $.each(j.jêderFields, function (key, val) { li.find(".wiktku-dfn-quote-src-input[data-field-key='" + key + "']").val(val); }); } } jederList.append(li); }); // Always leave a blank trailing item, same as Nimûne. if (buildJederFn) jederList.append(buildJederFn()); } }); } /** * Snapshot simple (non-dfn) per-section steps from current DOM into obj. */ function saveCurrentSection() { var snap = {}; $.each(PER_SECTION_STEP_IDS, function (_, id) { if (id === "dfn") { snap.dfn = snapshotDfn(); return; } if (id === "etym") { snap.etym = $.trim($("#wiktku-start-etym .wiktku-etym-text").val()); return; } var step = steps[id]; if (!step) return; var stepDiv = $("#wiktku-start-" + id); if (id === "trans") { snap.trans = steps.trans.getTranslations(stepDiv); return; } if (id === "zarava") { snap.zarava = steps.zarava.getTranslations(stepDiv); return; } if (id === "dunde") { snap.dunde = steps.dunde.getRows(stepDiv); return; } // Generic: read all step fields. var fields = stepDiv.find(".wiktku-start-step-field"); if (step.multiple) { snap[id] = fields.map(function () { return $(this).val(); }).get(); } else { snap[id] = fields.val(); } }); sections[activeSection] = snap; } /** * Restore a previously saved snapshot into the form DOM. */ function restoreSection(snap) { $.each(PER_SECTION_STEP_IDS, function (_, id) { if (id === "dfn") { restoreDfn(snap.dfn || []); return; } if (id === "etym") { $("#wiktku-start-etym .wiktku-etym-wrap").remove(); steps.etym.build($("#wiktku-start-etym")); $("#wiktku-start-etym .wiktku-etym-text").val(snap.etym || ""); return; } if (id === "trans") { // Rebuild trans groups (dfn must already be restored by this // point in the $.each loop, so glossList() reflects it). var transDiv = $("#wiktku-start-trans"); transDiv.find(".wiktku-trans-group").remove(); steps.trans.build(transDiv); var groupsSnap = snap.trans || []; $.each(groupsSnap, function (gi, rows) { var group = transDiv.find(".wiktku-trans-group[data-gloss-pos='" + gi + "']"); if (!group.length) return; // gloss no longer exists — drop its rows var list = group.find("ul.wiktku-trans-list"); $.each(rows, function (j, row) { var lang = row[0], words = row[1]; var lastRow = list.find("li.wiktku-trans-row").last(); lastRow.find("select").val(lang).trigger("change"); var wordList = lastRow.find("ul.wiktku-trans-words"); $.each(words, function (k, word) { var wordItems = wordList.find("li"); if (k < wordItems.length) { wordItems.eq(k).find("textarea").val(word); } else { // .val() below doesn't fire "input", so the normal // auto-grow never runs — append a matching item // ourselves instead of silently dropping the word. var extraInput = steps.trans.makeWordInput(); wordList.append($("<li></li>").append(extraInput)); extraInput.val(word); } }); // Leave one trailing empty field so the row can still grow // when the user types, matching a freshly-built row. if ($.trim(wordList.children("li").last().find("textarea").val())) { wordList.append($("<li></li>").append(steps.trans.makeWordInput())); } }); }); return; } if (id === "zarava") { // Rebuild zarava groups (dfn must already be restored by this // point in the $.each loop, so glossList() reflects it). var zaravaDiv = $("#wiktku-start-zarava"); zaravaDiv.find(".wiktku-zarava-group").remove(); steps.zarava.build(zaravaDiv); var zaravaGroupsSnap = snap.zarava || []; $.each(zaravaGroupsSnap, function (gi, rows) { var group = zaravaDiv.find(".wiktku-zarava-group[data-gloss-pos='" + gi + "']"); if (!group.length) return; // gloss no longer exists — drop its rows var list = group.find("ul.wiktku-zarava-list"); $.each(rows, function (j, row) { var lang = row[0], words = row[1]; var lastRow = list.find("li.wiktku-zarava-row").last(); lastRow.find("select").val(lang).trigger("change"); var wordList = lastRow.find("ul.wiktku-zarava-words"); $.each(words, function (k, word) { var wordItems = wordList.find("li"); if (k < wordItems.length) { wordItems.eq(k).find("textarea").val(word); } else { var extraInput = steps.zarava.makeWordInput(); wordList.append($("<li></li>").append(extraInput)); extraInput.val(word); } }); if ($.trim(wordList.children("li").last().find("textarea").val())) { wordList.append($("<li></li>").append(steps.zarava.makeWordInput())); } }); }); return; } if (id === "dunde") { // Rebuild dunde rows. var dundeDiv = $("#wiktku-start-dunde"); dundeDiv.find("ul.wiktku-dunde-list").remove(); steps.dunde.build(dundeDiv); var dundeRows = snap.dunde || []; $.each(dundeRows, function (i, row) { var lang = row[0], words = row[1]; var list = dundeDiv.find("ul.wiktku-dunde-list"); var lastRow = list.find("li.wiktku-dunde-row").last(); lastRow.find("select").val(lang).trigger("change"); var wordList = lastRow.find("ul.wiktku-dunde-words"); $.each(words, function (j, word) { var wordItems = wordList.find("li"); if (j < wordItems.length) { wordItems.eq(j).find("textarea").val(word); } else { // .val() below doesn't fire "input", so the normal // auto-grow never runs — append a matching item // ourselves instead of silently dropping the word. var extraInput = steps.dunde.makeWordInput(); wordList.append($("<li></li>").append(extraInput)); extraInput.val(word); } }); // Leave one trailing empty field so the row can still grow // when the user types, matching a freshly-built row. if ($.trim(wordList.children("li").last().find("textarea").val())) { wordList.append($("<li></li>").append(steps.dunde.makeWordInput())); } }); return; } var step = steps[id]; if (!step) return; var stepDiv = $("#wiktku-start-" + id); var fields = stepDiv.find(".wiktku-start-step-field"); var val = snap[id]; if (val === undefined || val === null) return; if (step.multiple) { var arr = val; fields.each(function (i) { if (i < arr.length) $(this).val(arr[i]); }); } else { fields.val(val); } // Notify chosen widgets of the programmatic value change. if (!isMobile) fields.filter("select").trigger("chosen:updated"); }); } function getWikitextForCurrentSection(callback) { var values = getValues(); var entry = steps.pos.output(values); steps.dfn.getOutput(values, function (output) { entry += output; entry += steps.je.output(values); entry += steps.tekildar.output(values); entry += steps.etym.output(values); entry += steps.dunde.output(values); entry += steps.binereherwiha.output(values); entry += steps.zarava.output(values); entry += steps.trans.output(values); callback(entry, values); }); } function getWikitextAllSections(callback) { saveCurrentSection(); var results = new Array(sections.length); var sharedValues = getValues(); // lang/pron are shared function processSection(i) { if (i >= sections.length) { // All done — restore original active section. restoreSection(sections[activeSection]); refresh(); callback(results, sharedValues); return; } restoreSection(sections[i]); refresh(); getWikitextForCurrentSection(function (sectionText) { results[i] = sectionText; processSection(i + 1); }); } processSection(0); } /** * Assembles wikitext for all sections plus the shared lang/pron header. */ function getWikitext(callback) { getWikitextAllSections(function (sectionTexts, sharedValues) { var entry = steps.lang.output(sharedValues); entry += steps.pron.output(sharedValues); entry += sectionTexts.join("\n"); // Edit summary uses section 0's values. Read from the saved snapshot // (not the live DOM) so it doesn't mix section 0's pos with whichever // section happens to be active/restored at this point. var dfnSenses = (sections[0] && sections[0].dfn) || []; var dfnSummary = dfnSenses.map(function (s) { return s.mane; }).filter(Boolean).join("; "); var summary = "([[Mediawiki:Gadget-start.js|WF:NÛ]] v.2.0) +" + sharedValues.lang + ":" + sections[0].pos + ":" + dfnSummary; var summaryField = document.getElementById("wpSummary"); if (addLangMode && summaryField.value) { summary = summaryField.value + " " + summary; } summaryField.value = summary; callback(entry); }); } var continueBtn; function getValuesForStep(stepId) { var fields = $("#wiktku-start-" + stepId + " .wiktku-start-step-field"); var step = steps[stepId]; if (step.keys) { var values = {}; fields.each(function (i, field) { var key = $(field).prevAll(".wiktku-start-step-keyfield").val(); if (key) values[key] = $(field).val(); }); return values; } else if (step.multiple) { return fields.map(function () { return $(this).val(); }).get(); } return fields.val(); } function getValues() { var values = {}; $.each(steps, function (stepId) { values[stepId] = getValuesForStep(stepId); }); return values; } function populateMenus(inputs, choices, disabledValues) { if (!disabledValues) disabledValues = {}; var vals = inputs.map(function (i, input) { return $(input).val(); }); inputs.empty(); inputs.append($("<option></option>")); $.each(choices, function (j, choice) { // Append the language code in parentheses so that typing a code // (e.g. "ku") in the search box still finds the language name. var displayText = capitalize(choice[1]); if (choice[2] !== undefined) { // This is a language choice [code, name, sortKey] — show code. displayText = capitalize(choice[1]) + " (" + choice[0] + ")"; } var option = $(mw.html.element("option", { value: choice[0] }, displayText)); if (disabledValues[choice[0]]) option.prop("disabled", true); inputs.append(option); }); inputs.val(function (i) { return vals[i]; }); } /** * Returns a bitmap containing the keys that should be disabled for a key * menu in the given step because they are disabled or already taken by * another key menu. */ function getDisabledKeys(step) { var occupiedKeys = {}; $("#wiktku-start-" + step.id + " .wiktku-start-step-keyfield").each(function () { occupiedKeys[$(this).val()] = true; }); if (step.disabledKeys) $.extend(occupiedKeys, step.disabledKeys); return occupiedKeys; } function buildKeyInput(step) { if (!step.keys) return undefined; var input = $(mw.html.element("select", { "class": "wiktku-start-step-keyfield wiktku-start-narrow" })); input.attr("data-placeholder", "Hilbijêre " + step.keyName); if (isMobile) { populateMenus(input, step.keys, getDisabledKeys(step)); // On mobile return the wrapper; the select is inside it. // Change events still fire on the inner select. return wrapNativeSelect(input); } input.on("chosen:showing_dropdown", function () { $(this).data("wiktku-defaultValue", $(this).val()); }); input.change(function (_, context) { var inputs = $("#wiktku-start-" + step.id + " .wiktku-start-step-keyfield").not(this); var oldValue = $(this).data("wiktku-defaultValue"); var newValue = context.selected; inputs.find("option[value='" + oldValue + "']").prop('disabled', false); inputs.find("option[value='" + newValue + "']").prop('disabled', true); inputs.trigger("chosen:updated"); }); populateMenus(input, step.keys, getDisabledKeys(step)); return input; } /** * If the current text field has text and there are no more text fields after * the current text field in the list, add another text field to the list. */ function refreshForTextField(currentInput, step) { currentInput = $(currentInput); var value = currentInput.val(); var item = currentInput.parent(); if (value && !item.next("li").length) { var nextInput = $("<textarea></textarea>") .attr("name", "wiktku-field-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("class", currentInput.attr("class")) .attr("rows", currentInput.attr("rows") || 1); nextInput.on("input", function (evt) { refreshForTextField(evt.target, step); }); var nextKeyInput = buildKeyInput(step); var nextItem = $("<li></li>").append(nextKeyInput).append(nextInput); item.parent().append(nextItem); if (nextKeyInput) nextKeyInput.chosen(chosenOptions); } var canContinue = !continueBtn.isDisabled(); if ((value && !canContinue) || (!value && canContinue)) { refresh(step); } } function prepareInput(input, step) { if (!input) return; if (step.required) input.prop('required', true); input.change(step, refresh); } /** * Shows and hides all the steps based on whether their prerequisites are met, * and updates placeholders where applicable. */ function refresh(evt) { var values = getValues(); var changedStep = evt && evt.data; var didFocus = false; var canContinue = true; // Re-filter template options in every sense block whenever lang changes. $("#wiktku-start-dfn .wiktku-dfn-tpl-select").each(function () { var fn = $(this).data("updateOptions"); if (typeof fn === "function") fn(); }); // Re-filter pronunciation and etymology template dropdowns when language changes. steps.pron.refreshTplSelect(); steps.etym.refreshTplSelect(); // Sync tr/t sub-fields in every nimûne item to the current language. // tr shown when language needs transliteration; t shown when lang !== "ku". (function () { var lang = values.lang || ""; var showTr = needsTransliteration(lang); var showT = lang && lang !== "ku"; $("#wiktku-start-dfn .wiktku-dfn-nimune-list li.wiktku-dfn-nimune-li").each(function () { var li = $(this); // Ensure the sub-wrapper exists when we need it. var subWrap = li.find(".wiktku-dfn-nimune-sub"); // tr field var trTa = li.find(".wiktku-dfn-nimune-tr"); if (showTr && !trTa.length) { if (!subWrap.length) { subWrap = $("<div></div>").addClass("wiktku-dfn-nimune-sub"); li.append(subWrap); } trTa = $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-tr-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 5) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-tr") .attr("placeholder", "Transkrîpsiyon…"); subWrap.prepend(trTa); } else if (!showTr && trTa.length) { trTa.remove(); } // t field var tTa = li.find(".wiktku-dfn-nimune-t"); if (showT && !tTa.length) { if (!subWrap.length) { subWrap = $("<div></div>").addClass("wiktku-dfn-nimune-sub"); li.append(subWrap); } tTa = $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-t-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 5) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-t") .attr("placeholder", "Tercimeya nimûneyê kurmancî…"); subWrap.append(tTa); } else if (!showT && tTa.length) { tTa.remove(); } // Remove the wrapper if it ended up empty. subWrap = li.find(".wiktku-dfn-nimune-sub"); if (subWrap.length && !subWrap.children().length) subWrap.remove(); }); }()); // Sync tr/t sub-fields in every jêder citation to the current language. // tr shown when language needs transliteration; t shown when lang !== "ku". (function () { var lang = values.lang || ""; var showTr = needsTransliteration(lang); var showT = lang && lang !== "ku"; $("#wiktku-start-dfn .wiktku-dfn-jeder-list li.wiktku-dfn-jeder-li").each(function () { var li = $(this); // Ensure the sub-wrapper exists when we need it. It must sit right // after the quote textarea and before the source selector. var subWrap = li.find(".wiktku-dfn-quote-sub"); // tr field var trTa = li.find(".wiktku-dfn-nimune-quote-tr"); if (showTr && !trTa.length) { if (!subWrap.length) { subWrap = $("<div></div>").addClass("wiktku-dfn-quote-sub"); li.find(".wiktku-dfn-nimune-quote").after(subWrap); } trTa = $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-quote-tr-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 2) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-quote-tr") .attr("placeholder", "Transkrîpsiyona jêgirtinê…"); subWrap.prepend(trTa); } else if (!showTr && trTa.length) { trTa.remove(); } // t field var tTa = li.find(".wiktku-dfn-nimune-quote-t"); if (showT && !tTa.length) { if (!subWrap.length) { subWrap = $("<div></div>").addClass("wiktku-dfn-quote-sub"); li.find(".wiktku-dfn-nimune-quote").after(subWrap); } tTa = $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-quote-t-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 2) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-quote-t") .attr("placeholder", "Tercimeya jêgirtinê ya kurmancî…"); subWrap.append(tTa); } else if (!showT && tTa.length) { tTa.remove(); } // Remove the wrapper if it ended up empty. subWrap = li.find(".wiktku-dfn-quote-sub"); if (subWrap.length && !subWrap.children().length) subWrap.remove(); }); }()); $.each(steps, function (stepId, step) { if (typeof(step.visible) === "function" && !step.visible(values)) { $("#wiktku-start-" + stepId).slideUp(); } else { var stepDiv = $("#wiktku-start-" + stepId); if (changedStep !== step && typeof(step.build) === "function") { prepareInput(step.build(stepDiv, values), step); } var input = stepDiv.find(".wiktku-start-step-field"); if (typeof(step.example) === "function") { // .find() above already reaches nested fields (e.g. the dfn // step's mane textareas inside each sense block), so one // assignment covers every step; dfn keeps its own fallback. var exampleText = step.example(values) || (step.id === "dfn" ? "Mane…" : ""); input.attr("placeholder", exampleText); } var didSlideDown; if (!didFocus && stepDiv.css("display") === "none" && step.required) { didSlideDown = function (evt) { input.focus(); }; didFocus = true; } stepDiv.slideDown(didSlideDown); } if (step.required && (values[stepId] === "" || (step.multiple && values[stepId].join("") === ""))) { canContinue = false; } }); continueBtn.setDisabled(!canContinue); } function destroy() { $("#wiktku-start-form, .noafterwizard").slideUp(function () { $(this).remove(); }); $(".noarticletext .nowizard, #editform").slideDown(); $("#ca-edit").removeClass("selected"); $("#ca-wiktku-nowizard").addClass("selected"); } // Priority order for Kurdish dialects and the navz pseudo-code. // Codes listed here come before all other languages; unlisted codes // are sorted alphabetically by their display name via localeCompare. var LANG_PRIORITY = ["navz", "ku", "hac", "sdh", "lki", "ckb", "zza"]; /** * Inserts a new == {{ziman|code}} == section into existing page wikitext * at the correct sorted position: * 1. Any content before the first language section is preserved at the top. * 2. navz is always first, then ku/hac/sdh/lki/ckb/zza in that order, * then all other languages sorted by display name (localeCompare). */ function insertNewLangSection(existing, wikitext) { var newCodeMatch = wikitext.match(/^== \{\{ziman\|([^}]+)\}\} ==/); var newCode = newCodeMatch ? newCodeMatch[1] : ""; var sections = []; var preamble = ""; var firstMatch = existing.match(/(?:^|\n)== \{\{ziman\|/); if (!firstMatch) { // No existing lang sections at all — just append. var sep = existing && !/\n\s*$/.test(existing) ? "\n\n" : ""; return existing + sep + wikitext; } // Everything before the first == {{ziman|...}} == is the preamble. var firstSectionStart = existing.indexOf("== {{ziman|"); // Walk back to the start of that line. var lineStart = existing.lastIndexOf("\n", firstSectionStart - 1); var preambleEnd = lineStart !== -1 ? lineStart + 1 : 0; preamble = existing.slice(0, preambleEnd); // Parse each language section: header line + everything until the next header. var body = existing.slice(preambleEnd); // NOTE: with the /m flag, a bare "$" matches end-of-*line*, not just // end-of-string — that previously made the non-greedy content group // stop at the section's first line break instead of running to the // next language header (or the real end of the text), silently // dropping the rest of that section's wikitext. (?![\s\S]) matches // only the true end of the string, /m flag or not. var langSectionRe = /^(== \{\{ziman\|([^}]+)\}\} ==\n?)([\s\S]*?)(?=\n== \{\{ziman\||(?![\s\S]))/gm; var m; while ((m = langSectionRe.exec(body)) !== null) { sections.push({ code: m[2], content: m[0] // full text of this section including header }); } // Determine sort rank: priority list first (by index), then alphabetical. function getLangName(code) { var entry = langsByCode[code]; return entry ? entry[1] : code; } function sortRank(code) { var idx = LANG_PRIORITY.indexOf(code); return idx !== -1 ? idx : LANG_PRIORITY.length; } function compareLangs(a, b) { var ra = sortRank(a), rb = sortRank(b); if (ra !== rb) return ra - rb; // Both are outside priority list — sort by display name. return getLangName(a).localeCompare(getLangName(b), userLang); } // Insert the new section into the sorted list. var newSection = { code: newCode, content: wikitext }; var inserted = false; for (var i = 0; i < sections.length; i++) { if (compareLangs(newCode, sections[i].code) < 0) { sections.splice(i, 0, newSection); inserted = true; break; } } if (!inserted) sections.push(newSection); // Re-join: preamble + sections separated by newlines. var joined = sections.map(function (s) { // Ensure each section ends with exactly one newline before the next. return s.content.replace(/\n+$/, ""); }).join("\n"); return preamble + joined + "\n"; } function build() { $(".nowizard, .nowizard .noafterwizard").hide(); var callToAction = $("#wiktku-calltoaction"); var origCallToActionText = callToAction.text(); $(mw.util.addPortletLink("p-views", "#", "Edîtora çavkaniyê veke", "ca-wiktku-nowizard", "Vê rûpelê bi edîtora çavkaniyê çêke", undefined, "#ca-watch")).click(function (evt) { evt.preventDefault(); callToAction.text(origCallToActionText); destroy(); }); if (callToAction.length) { callToAction.text(origCallToActionText + " Forma li jêr ji bo çêkirina madeyeke nû bi kar bîne."); } var startForm = $("<form id='wiktku-start-form'></form>"); var clearPageCheck = null; if (addLangMode) { startForm.append($("<p class='wiktku-addlang-notice'></p>").html( "Bi vê formê tu yê beşeke nû li rûpelê îlawe bikî. Eger ev zimanê ku tu îlawe dikî jixwe di rûpelê de hebe, beşa nû li dawiya vî zimanî dê were îlawekirin. " + "Ji kerema xwe netîceya dawî kontrol bikin, eger problemek derkeve, li <a href='" + mw.util.getUrl('Mediawiki talk:Gadget-start.js') + "'>nîqaşa vê amûrê</a> problemê ragihîne." )); clearPageCheck = $("<input type='checkbox' id='wiktku-clear-page-check'>"); var clearPageLabel = $("<label for='wiktku-clear-page-check'></label>") .text(" Naveroka rûpelê paqij bike (rûpelê ji nû ve binivîse)"); startForm.append( $("<p class='wiktku-addlang-notice'></p>") .append(clearPageCheck) .append(clearPageLabel) ); } var spinner; // Tab bar for switching between POS sections. var sectionTabsDiv = $("<div id='wiktku-section-tabs'></div>"); startForm.submit(function (evt) { evt.preventDefault(); continueBtn.setDisabled(true); spinner.show(); getWikitext(function (wikitext) { if (addLangMode) { var textbox = $("#wpTextbox1"); var existing = textbox.val() || ""; // Check whether the generated lang header already exists in the page. // wikitext always starts with "== {{ziman|CODE}} ==\n" (from steps.lang.output). // If that exact section heading is already present in the existing content, // strip it from the new output and insert the remaining content at the end // of that lang section (just before the next == level-2 heading, or at the // very end of the page if there is no following section). var langHeaderMatch = wikitext.match(/^(== \{\{ziman\|[^}]+\}\} ==\n)/); if (langHeaderMatch) { var langHeader = langHeaderMatch[1]; // e.g. "== {{ziman|ku}} ==\n" // Escape for use in RegExp. var escapedHeader = langHeader.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); if (new RegExp(escapedHeader).test(existing)) { // Strip the header from the new output. var newContent = wikitext.slice(langHeader.length); // Find the insertion point: end of the existing lang section. // A new L2 heading marks the start of the next language block. var afterHeader = existing.indexOf(langHeader); var searchFrom = afterHeader + langHeader.length; // Find the next == … == heading after this section's start. var nextL2 = existing.indexOf("\n== ", searchFrom); var insertAt = nextL2 !== -1 ? nextL2 : existing.length; // Ensure there's a blank line before the inserted block. var before = existing.slice(0, insertAt); var after = existing.slice(insertAt); var sep = /\n\s*$/.test(before) ? "" : "\n"; textbox.val(before + sep + newContent + after); } else { // New language — insert at the correct sorted position. textbox.val(insertNewLangSection(existing, wikitext)); } } else { // Unexpected format — insert at sorted position anyway. textbox.val(insertNewLangSection(existing, wikitext)); } } else { $("#wpTextbox1").val(wikitext); } $("html, body").animate({scrollTop: 0}); callToAction.text("Hindik ma!"); $("#wiktku-preview-container").remove(); destroy(); }); }); $.each(ordered_steps, function (i, step) { var stepDiv = $(mw.html.element("div", { "class": "wiktku-start-step", id: "wiktku-start-" + step.id })); var name = capitalize(step.name); stepDiv.append($(mw.html.element("h3", { "class": "wiktku-start-step-name" }, new mw.html.Raw(mw.html.element("label", { "for": "wiktku-start-" + step.id + "-field" }, name))))); if (step.question_fmt) { stepDiv.append($(mw.html.element("label", { "class": "wiktku-start-step-question", "for": "wiktku-start-" + step.id + "-field" }, step.question_fmt))); if (step.question_br) stepDiv.append($("<br>")); } var input; if (step.choices) { input = $(mw.html.element("select", { "class": "wiktku-start-step-field", id: "wiktku-start-" + step.id + "-field" })); input.attr("data-placeholder", capitalize(step.name) + " hilbijêre "); populateMenus(input, step.choices); if (step.multiple) input.attr("multiple", true); if (isMobile) { stepDiv.append(wrapNativeSelect(input)); } else { stepDiv.append(input); } } else if (typeof(step.build) === "function") { input = step.build(stepDiv); } else { input = $("<textarea></textarea>") .attr("class", "wiktku-start-step-field") .attr("id", "wiktku-start-" + step.id + "-field") .attr("rows", step.rows || 2); if (step.narrow) input.addClass("wiktku-start-narrow"); if (step.multiple) { input.on("input", function (evt) { refreshForTextField(evt.target, step); }); var keyInput = buildKeyInput(step); var list = $(step.ordered ? "<ol></ol>" : "<ul></ul>") .append($("<li></li>").append(keyInput).append(input)); stepDiv.append(list); } else stepDiv.append(input); } prepareInput(input, step); stepDiv.hide(); // Insert tab bar just before the first per-section step. if (step.id === "pos") startForm.append(sectionTabsDiv); startForm.append(stepDiv); }); // ── Section tab helpers ────────────────────────────────────────────── // ── Add-section button — lives in the tab bar, disabled until pos chosen ── var addSectionBtn = new OO.ui.ButtonWidget({ label: "+ Beş zêde bike", disabled: true }); addSectionBtn.on("click", function () { saveCurrentSection(); sections.push({}); activeSection = sections.length - 1; $.each(PER_SECTION_STEP_IDS, function (_, id) { if (id === "dfn") { var stepDiv = $("#wiktku-start-dfn"); stepDiv.find("ol.wiktku-dfn-list").remove(); steps.dfn.build(stepDiv); return; } if (id === "etym") { $("#wiktku-start-etym .wiktku-etym-wrap").remove(); steps.etym.build($("#wiktku-start-etym")); return; } if (id === "trans") { var transDiv = $("#wiktku-start-trans"); transDiv.find(".wiktku-trans-group").remove(); return; } if (id === "zarava") { var zaravaDiv = $("#wiktku-start-zarava"); zaravaDiv.find(".wiktku-zarava-group").remove(); return; } if (id === "dunde") { var dundeDiv = $("#wiktku-start-dunde"); dundeDiv.find("ul.wiktku-dunde-list").remove(); return; } var stepDiv = $("#wiktku-start-" + id); stepDiv.find(".wiktku-start-step-field").val(""); if (!isMobile) stepDiv.find("select.wiktku-start-step-field").trigger("chosen:updated"); }); renderSectionTabs(); refresh(); $("html, body").animate({ scrollTop: sectionTabsDiv.offset().top - 20 }, 300); }); /** Re-render the tab bar to reflect current sections[] and activeSection. */ function renderSectionTabs() { // Detach (not remove) the button first: .empty() strips bound // event data from any children left inside it, which would // silently kill addSectionBtn's click handler on every re-render. addSectionBtn.$element.detach(); sectionTabsDiv.empty(); var lang = getValues().lang || ""; if (!lang) { sectionTabsDiv.hide(); return; } sectionTabsDiv.show(); $.each(sections, function (i) { var posVal = sections[i].pos || ""; var tabLabel = posVal ? capitalize(posVal) : ("Beş " + (i + 1)); var tab = $("<span></span>") .addClass("wiktku-section-tab") .text(tabLabel) .toggleClass("wiktku-tab-active", i === activeSection); (function (idx) { tab.on("click", function () { if (idx === activeSection) return; saveCurrentSection(); activeSection = idx; restoreSection(sections[activeSection]); refresh(); renderSectionTabs(); }); }(i)); sectionTabsDiv.append(tab); }); // Enable "Beş zêde bike" only when the active section has a pos chosen. var activePos = sections[activeSection] && sections[activeSection].pos ? sections[activeSection].pos : getValues().pos; addSectionBtn.setDisabled(!activePos); sectionTabsDiv.append(addSectionBtn.$element); } renderSectionTabs(); // Update the active tab's label whenever pos changes. startForm.on("change", "#wiktku-start-pos-field", function () { renderSectionTabs(); }); // Show the tab bar as soon as a language is selected. startForm.on("change", "#wiktku-start-lang-field", function () { renderSectionTabs(); }); var footer = $("<div id='wiktku-start-footer'></div>"); spinner = $(mw.html.element("img", { id: "wiktku-start-spinner", src: "//upload.wikimedia.org/wikipedia/commons/d/de/Ajax-loader.gif", alt: "Tê barkirin…", title: "Tê barkirin…" })); footer.append(spinner.hide()); continueBtn = new OO.ui.ButtonWidget({ id: "wiktku-unhide-editform", label: "Bişîne", flags: [ "primary", "progressive" ] }); continueBtn.on("click", function () { mw.notify("Tê şandin…", { type: "info", tag: "wiktku-submit" }); startForm.trigger("submit"); }); footer.append(continueBtn.$element); // "Edîtora çavkaniyê veke" button — inline fallback for the portlet link // which is invisible on mobile and easy to miss on desktop. var sourceEditorBtn = new OO.ui.ButtonWidget({ label: "Edîtora çavkaniyê veke", framed: false }); sourceEditorBtn.on("click", function () { destroy(); }); footer.append(sourceEditorBtn.$element); // ── Preview checkboxes ─────────────────────────────────────────────── // Wikitext preview (raw text panel) var previewCheck = $("<input type='checkbox' id='wiktku-preview-toggle'>"); var previewLabel = $("<label for='wiktku-preview-toggle'></label>") .text(" Pêşdîtina wîkîtekstê"); var previewPanel = $("<pre id='wiktku-preview-panel'></pre>").hide(); // Live rendered preview (parsed HTML panel, same logic as AjaxEdit). // Not available on mobile — API polling causes too many problems on small screens. var livePreviewCheck = null; var livePreviewPanel = null; if (!isMobile) { livePreviewCheck = $("<input type='checkbox' id='wiktku-live-preview-toggle'>"); livePreviewPanel = $("<div id='wiktku-live-preview-panel'></div>").hide(); } // Container that holds both panels and switches between stacked / side-by-side. var previewContainer = $("<div id='wiktku-preview-container'></div>"); previewContainer.append(previewPanel); if (!isMobile) previewContainer.append(livePreviewPanel); var previewTimer = null; var livePreviewIntervalId = -1; var livePreviewActive = false; // guards in-flight fetches after uncheck /** Rebuilds wikitext preview if its checkbox is checked. */ function schedulePreview() { if (!previewCheck.prop("checked")) return; clearTimeout(previewTimer); // Debounce: wait 400 ms after the last keystroke before rebuilding. previewTimer = setTimeout(function () { getWikitext(function (wikitext) { previewPanel.text(wikitext).show(); updatePanelLayout(); }); }, 400); } /** Fetches parsed HTML and populates the live preview panel. */ function loadLivePreview() { getWikitext(function (wikitext) { new mw.Api().parse(wikitext, { title: mw.config.get("wgPageName") }).done(function (html) { // Discard result if the user unchecked while the fetch was in flight. if (!livePreviewActive) return; livePreviewPanel.html(html).show(); updatePanelLayout(); }); }); } /** Adjusts panel widths depending on which previews are visible. */ function updatePanelLayout() { var wikitextVisible = previewCheck.prop("checked"); var liveVisible = livePreviewCheck && livePreviewCheck.prop("checked"); if (wikitextVisible && liveVisible) { // Side by side — each panel takes roughly half the available width. previewPanel.css({ "flex": "1 1 45%", "min-width": "280px" }); livePreviewPanel.css({ "flex": "1 1 45%", "min-width": "280px" }); } else { // Full width for whichever is visible — only touch panels that are // actually shown so that setting flex doesn't override display:none. if (wikitextVisible) previewPanel.css({ "flex": "1 1 100%", "min-width": "" }); if (liveVisible && livePreviewPanel) livePreviewPanel.css({ "flex": "1 1 100%", "min-width": "" }); } } previewCheck.on("change", function () { if ($(this).prop("checked")) { schedulePreview(); } else { clearTimeout(previewTimer); previewPanel.hide(); updatePanelLayout(); } }); if (!isMobile) { livePreviewCheck.on("change", function () { if ($(this).prop("checked")) { livePreviewActive = true; livePreviewPanel.show(); loadLivePreview(); livePreviewIntervalId = setInterval(loadLivePreview, 500); } else { livePreviewActive = false; clearInterval(livePreviewIntervalId); livePreviewIntervalId = -1; livePreviewPanel.hide().empty(); updatePanelLayout(); } }); } // Listen on all input/change events on the form and update both previews. startForm.on("input change", function () { schedulePreview(); }); footer.append($("<span style='margin-left:1em'></span>") .append(previewCheck).append(previewLabel)); if (!isMobile) { var livePreviewLabel = $("<label for='wiktku-live-preview-toggle'></label>") .text(" Pêşdîtina zindî"); footer.append($("<span style='margin-left:1em'></span>") .append(livePreviewCheck).append(livePreviewLabel)); } startForm.append(footer); $("#editform").hide().before(startForm); // Insert preview container (holds both panels) after the form. startForm.after(previewContainer); if (!isMobile) startForm.find("select").chosen(chosenOptions); refresh(); // Zimanan ji MediaWiki:Gadget-translation_editor.js/ziman.json bar bike. // Kodên ku bi "-pro" diqedin û navên ku "zimanê destan" tê de heye // tên derxistin. Zimanên xardkirî li serî dimînin, yên din // bi alfabeyê li dû wan tên. // Pinned choices come from MediaWiki:Gadget-start.js/data.json (langChoices), // already loaded into steps.lang.choices before build() runs. var pinnedChoices = steps.lang.choices.slice(); var pinnedCodes = $.map(pinnedChoices, function (choice) { return choice[0]; }); new mw.Api().get({ action: "query", prop: "revisions", titles: "MediaWiki:Gadget-translation_editor.js/ziman.json", rvprop: "content", rvslots: "main", formatversion: 2 }).then(function (data) { var page = data.query.pages[0]; var content = page && page.revisions && page.revisions[0].slots.main.content; var zimanData; try { zimanData = JSON.parse(content); } catch (e) { zimanData = {}; } var extraChoices = []; $.each(zimanData, function (code, name) { // Filter: skip proto-language codes and legendary/reconstructed langs. if (/-pro$/i.test(code)) return; if (/ziman[eê]\s+destan/i.test(name)) return; // Skip codes already in the pinned list (they are handled above). if (pinnedCodes.indexOf(code) !== -1) return; // sortKey: bare name without leading "zimanê " for sorting. var sortKey = name.replace(/^ziman[eê]\s+/i, ""); var choice = [code, name, sortKey]; extraChoices.push(choice); langsByCode[code] = choice; }); // Populate langsByCode for pinned choices too. $.each(pinnedChoices, function (i, choice) { // Ensure pinned choices have a sortKey (index 2). if (choice.length < 3) choice[2] = choice[1]; langsByCode[choice[0]] = choice; }); // Sort the extra choices alphabetically by sort key. extraChoices.sort(function (a, b) { return a[2].localeCompare(b[2], userLang); }); // Final list: pinned first, then the rest. var allChoices = pinnedChoices.concat(extraChoices); steps.lang.choices = allChoices; steps.trans.keys = allChoices; steps.dunde.keys = allChoices; steps.zarava.keys = getZaravaKeys(allChoices); var langMenu = $("#wiktku-start-lang-field"); populateMenus(langMenu, steps.lang.choices); langMenu.trigger("chosen:updated"); var transMenus = $("#wiktku-start-trans .wiktku-start-step-keyfield"); populateMenus(transMenus, steps.trans.keys, getDisabledKeys(steps.trans)); transMenus.trigger("chosen:updated"); var dundeMenus = $("#wiktku-start-dunde .wiktku-start-step-keyfield"); populateMenus(dundeMenus, steps.dunde.keys, getDisabledKeys(steps.dunde)); dundeMenus.trigger("chosen:updated"); var zaravaMenus = $("#wiktku-start-zarava .wiktku-start-step-keyfield"); populateMenus(zaravaMenus, steps.zarava.keys, getDisabledKeys(steps.zarava)); }); } mw.loader.using(["jquery.chosen", "mediawiki.api", "oojs-ui-core"], function () { if (!isMobile) { mw.notify( "Amûr dest pê dike, hinek bisekinin. Not: jkx Sentaks (sentaks highlighter) neaktîv bikin", { type: "info", tag: "wiktku-start-notice", autoHide: true, autoHideSeconds: 10 } ); } // Load metadata, langChoices, posChoices and tplDefs from the companion // data page so they can be updated without touching this script. new mw.Api().get({ action: "query", prop: "revisions", titles: "MediaWiki:Gadget-start.js/data.json", rvprop: "content", rvslots: "main", formatversion: 2 }).then(function (data) { var page = data.query.pages[0]; var content = page && page.revisions && page.revisions[0].slots.main.content; var d; try { d = JSON.parse(content); } catch (e) { d = {}; } // Populate metadata. if (d.metadata) $.extend(metadata, d.metadata); // Populate gender labels. if (d.genderLabels) $.extend(GENDER_BASE_LABELS, d.genderLabels); // Populate lang choices (pinned list used by build() → ziman.json loader). if (d.langChoices) steps.lang.choices = d.langChoices; // Populate POS choices. if (d.posChoices) steps.pos.choices = d.posChoices; // Populate template definitions for the dfn sense-block builder. if (d.tplDefs) steps.dfn.tplDefs = d.tplDefs; // Populate pos placeholder examples. if (d.posExamples) steps.dfn.posExamples = d.posExamples; // Populate citation template definitions for the quote widget. if (d.jederDefs) steps.dfn.jederDefs = d.jederDefs; // Populate pronunciation and etymology template insert lists. if (d.pronTpls) { steps.pron.pronTpls = d.pronTpls; steps.pron.refreshTplSelect(); } if (d.etymTpls) { steps.etym.etymTpls = d.etymTpls; steps.etym.refreshTplSelect(); } // Sync trans/dunde/zarava keys with the (now populated) lang choices. steps.trans.keys = steps.lang.choices; steps.dunde.keys = steps.lang.choices; steps.zarava.keys = getZaravaKeys(steps.lang.choices); }).always(build); }); }); //</nowiki> bvwp5tc3b6uji9gj6arj7opfhlnhnlx 6265578 6265577 2026-07-19T14:54:39Z Wikihez 7344 6265578 javascript text/javascript // Li ser [[vi:MediaWiki:Gadget-start.js]] hatiye refaktorkirin. //<nowiki> $(function () { if (window.location.href.includes("editintro=User:Wikihez/creation/intro")) { return; // Do not run the script wextê WF:Bilez dişuxile } var ns = mw.config.get("wgNamespaceNumber"); if (ns && !(ns === 2 && mw.config.get("wgPageName").match(/\/ceribandin$|\/test$/))) { return; } var action = mw.config.get("wgAction"); var pageExists = !!mw.config.get("wgArticleId"); // "Zimanek lê zêde bike" mode: triggered from the portlet link below. var addLangMode = pageExists && mw.util.getParamValue("wiktkuaddlang") === "1"; // On a normal page view of an existing page, add the portlet link if (action === "view" && pageExists) { var targetContainer; var skin = mw.config.get('skin'); if (skin === 'vector-2022') { targetContainer = 'p-cactions'; } else if (skin === 'vector') { targetContainer = 'p-tb'; } else { targetContainer = 'p-views'; } mw.util.addPortletLink(targetContainer, mw.util.getUrl(mw.config.get("wgPageName"), { action: "submit", wiktkuaddlang: "1" }), "+Ziman/beşeke din", "ca-wiktku-addlang", "Ji vê rûpelê re ziman an jî beşeke nû zêde bike"); return; } if (!(action === "edit" || action === "submit")) { return; } if (!addLangMode && !$(".mw-newarticletext, .mw-newarticletextanon").length) { return; } function capitalize(str) { if (!str) return str; return str[0].toUpperCase() + str.substr(1); } function decapitalize(str) { if (!str) return str; return str[0].toLowerCase() + str.substr(1); } function escapeRegExp(str) { return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); } function stripWikilinks(str) { return str.replace(/\[\[([^\]|]+)(?:\|([^\]]+))?\]\]/g, function (m, target, display) { return display || target; }); } function insertAtCursor(el, text) { var start = el.selectionStart; var end = el.selectionEnd; var val = el.value; el.value = val.slice(0, start) + text + val.slice(end); var pos = start + text.length; el.selectionStart = el.selectionEnd = pos; } var pageName = mw.config.get("wgPageName").replaceAll(/_/g, " "); if (ns) pageName = pageName.replace(/.*\//, ""); var pageNameRe = escapeRegExp(pageName); var userLang = mw.config.get("wgUserLanguage"); // Mobile detection: MobileFrontend sets wgMFMode, or fall back to touch check. var isMobile = !!mw.config.get("wgMFMode") || window.matchMedia("(pointer: coarse)").matches; var chosenOptions = { width: "20em", disable_search_threshold: 0, placeholder_text_single: "Yekî hilbijêre", placeholder_text_multiple: "Hilbijêre", no_results_text: "Nehat dîtin", enable_split_word_search: true, search_contains: true }; function wrapNativeSelect(select) { var placeholder = select.attr("data-placeholder") || "Lê bigere…"; // Hide the native select — we drive it programmatically. select.hide(); var wrapper = $("<span class='wiktku-native-select-wrap'></span>"); var textInput = $("<input type='search' autocomplete='off'>") .attr("placeholder", placeholder) .addClass("wiktku-start-narrow wiktku-ac-input"); var resultsList = $("<ul class='wiktku-ac-results'></ul>").hide(); // Full option cache — rebuilt when chosen:updated fires. var allOptions = []; function cacheOptions() { allOptions = []; select.find("option").each(function () { var v = $(this).val(); if (!v) return; // skip the empty placeholder option allOptions.push({ value: v, text: $(this).text(), disabled: $(this).prop("disabled") }); }); } cacheOptions(); function showResults(query) { var q = query.trim().toLowerCase(); resultsList.empty(); var matched; if (q) { matched = []; $.each(allOptions, function (_, o) { if (o.disabled) return; var codeMatch = o.value.toLowerCase().indexOf(q) !== -1; var nameMatch = o.text.toLowerCase().indexOf(q) !== -1; if (codeMatch || nameMatch) { matched.push({ opt: o, codeMatch: codeMatch }); } }); // Code matches (especially prefix matches) come first. matched.sort(function (a, b) { var aCode = a.opt.value.toLowerCase(); var bCode = b.opt.value.toLowerCase(); var aPrefix = aCode.indexOf(q) === 0; var bPrefix = bCode.indexOf(q) === 0; if (aPrefix !== bPrefix) return aPrefix ? -1 : 1; if (a.codeMatch !== b.codeMatch) return a.codeMatch ? -1 : 1; return 0; }); matched = matched.map(function (item) { return item.opt; }); } else { matched = allOptions.filter(function (o) { return !o.disabled; }); } if (!matched.length) { resultsList.hide(); return; } $.each(matched.slice(0, 50), function (_, opt) { var li = $("<li></li>").text(opt.text).attr("data-value", opt.value); // Use touchend instead of touchstart so that a scroll gesture does // not accidentally select an item. We track whether the finger moved // between touchstart and touchend — if it did, it was a scroll. var touchMoved = false; li.on("touchstart", function () { touchMoved = false; }); li.on("touchmove", function () { touchMoved = true; }); li.on("touchend", function (e) { if (touchMoved) return; // was a scroll, not a tap e.preventDefault(); selectOption(opt.value, opt.text); }); // Keep mousedown for desktop fallback. li.on("mousedown", function (e) { e.preventDefault(); selectOption(opt.value, opt.text); }); resultsList.append(li); }); // Position the list above or below depending on available viewport space. var inputRect = textInput[0].getBoundingClientRect(); var viewportH = window.innerHeight; var spaceBelow = viewportH - inputRect.bottom - 8; var spaceAbove = inputRect.top - 8; var maxH = Math.min(224, Math.max(spaceBelow, spaceAbove)); // 224px ≈ 14em resultsList.css({ "max-height": maxH + "px", "top": spaceBelow >= spaceAbove ? "100%" : "auto", "bottom": spaceBelow >= spaceAbove ? "auto" : "100%" }); resultsList.show(); } function selectOption(value, text) { textInput.val(text); select.val(value); resultsList.hide(); select.trigger("change"); } textInput.on("input focus", function () { showResults($(this).val()); }); textInput.on("blur", function () { // Short delay so a touchstart on a result item fires first. setTimeout(function () { resultsList.hide(); }, 200); }); // chosen:updated → re-cache (called after ziman.json loads). select.on("chosen:updated", function () { cacheOptions(); // If a value is already selected, keep the display text in sync. var cur = select.val(); if (cur) { var match = $.grep(allOptions, function (o) { return o.value === cur; })[0]; if (match) textInput.val(match.text); } }); // No-op .chosen() so desktop call-sites don't need guarding. select.chosen = function () { return select; }; wrapper.append(textInput).append(resultsList).append(select); return wrapper; } var langsByCode = {}; // Populated from [[MediaWiki:Gadget-start.js/data.json]] at runtime. var metadata = {}; // Zaravayên kurdî yên ku di beşa "Bi zaravayên din" de tên pêşkêşkirin — // ev kod ji beşa Werger têne derxistin daku heman zimên du caran neyê xwendin. var ZARAVA_LANG_CODES = ["ckb", "sdh", "lki", "hac", "zza"]; function getZaravaKeys(choices) { var byCode = {}; $.each(choices || [], function (_, c) { byCode[c[0]] = c; }); var result = []; $.each(ZARAVA_LANG_CODES, function (_, code) { if (byCode[code]) result.push(byCode[code]); }); return result; } function needsTransliteration(langCode) { var meta = metadata[langCode]; if (!meta || !meta.sc) return false; var scripts = Array.isArray(meta.sc) ? meta.sc : [meta.sc]; return scripts.length > 0 && scripts[0] !== "Latn"; } // Kodên cinsiyetê yên di metadata.g de — ji data.json tê dagirtin var GENDER_BASE_LABELS = {}; // Sub-lists that only make sense for a plain (non-şablon) sense — hidden // when a şablon (e.g. {{guharto|…}}) is chosen for that sense, since a // template-based sense has no "own" gloss for alternate forms, synonyms, // antonyms, coordinate terms, hypernyms or hyponyms to attach to. Etîket, // Nimûne and Jêgirtin stay visible either way. var HIDDEN_ON_TPL_GROUPS = [ "wiktku-dfn-alternativ", "wiktku-dfn-hevmane", "wiktku-dfn-dijmane", "wiktku-dfn-koordine", "wiktku-dfn-jornav", "wiktku-dfn-jernav" ]; function genderLabel(code) { if (code === "p") return "Pirjimar"; var pluralMatch = code.match(/^(.+)-p$/); if (pluralMatch && GENDER_BASE_LABELS[pluralMatch[1]]) { return GENDER_BASE_LABELS[pluralMatch[1]] + " (pirjimar)"; } return GENDER_BASE_LABELS[code] || code; } /** * True if a sense has any content worth keeping besides its mane text — * etîket, hevmane/dijmane/koordîne/etc. word lists, nimûne, or jêder * (quote). Used so a sense with an empty mane but filled-in extra * fields still gets emitted (with {{mane?}} standing in for the gloss) * instead of being silently dropped. */ function senseHasExtraContent(s) { if (s.etiket && $.grep(s.etiket, function (e) { return $.trim(e) !== ""; }).length) return true; if (s.kategori && $.grep(s.kategori, function (k) { return $.trim(k) !== ""; }).length) return true; if (s.alternativ.length || s.hevmane.length || s.dijmane.length || s.koordine.length || s.jornav.length || s.jernav.length) return true; if (s.nimune && $.grep(s.nimune, function (n) { return (typeof n === "object" ? n.text : n) !== ""; }).length > 0) return true; if (s.jeder && $.grep(s.jeder, function (j) { return j && j.quote; }).length > 0) return true; return false; } /** * formatNimune: each nimûne item can be { text, tr, t }: * text — example text * tr — transliteration (only when the language needs it) * t — Kurdish translation (third positional param, no key) */ function formatNimune(nimunes, lang, hasJeder) { var hasNimune = nimunes && $.grep(nimunes, function (n) { return (typeof n === "object" ? n.text : n) !== ""; }).length > 0; if (!hasNimune) { return hasJeder ? "" : "\n#* {{bênimûne|" + lang + "}}"; } return $.map(nimunes, function (n) { var text = typeof n === "object" ? n.text : n; if (!text) return undefined; var bolded = text.replace( new RegExp("(" + pageNameRe + "([^( |,|;|\\?|\\.|\\!)]+)?)", "ig"), "'''$1'''"); var tpl = "\n#: {{nm|" + lang + "|" + bolded; if (typeof n === "object") { if (n.tr) tpl += "|tr=" + n.tr; // Translation as third positional param (no key needed). if (n.t) tpl += "|" + n.t; } // Short examples fit on one line together with their translation. // rêz=1 is not used for ku — definitions are shown on separate lines there. if (text.length < 200 && lang !== "ku") tpl += "|rêz=1"; tpl += "}}"; return tpl; }).join(""); } /** * Formats a list of jêder (quote/citation) objects into wikitext lines. * Each entry that has no quote text is skipped. Returns "" when the list * is empty or every entry is blank. * * #* {{jêder-…|lang|jêgirtin=…|tr=…|tercime=…|…fields…}} * * When no template is chosen, the generic {{jêder|…}} template is used * instead. Its 2nd positional param is the user's freeform "bi destê xwe * binivîsim" source text when supplied, or the çavkanî? placeholder otherwise. * If that text contains "=" it is passed as |2=… instead of a bare * positional param, since MediaWiki would otherwise misparse it as its * own key=value pair and break the template: * #* {{jêder|lang|jêgirtin=…|tr=…|tercime=…|<manual source or çavkanî?>}} */ function formatJeder(jederList, lang) { if (!jederList || !jederList.length) return ""; return $.map(jederList, function (jeder) { if (!jeder || !jeder.quote) return undefined; if (jeder.jederTpl) { var cite = "\n#* {{" + jeder.jederTpl + "|" + lang; cite += "|jêgirtin=" + jeder.quote; if (jeder.quoteTr) cite += "|tr=" + jeder.quoteTr; if (jeder.quoteT) cite += "|tercime=" + jeder.quoteT; $.each(jeder.jêderFields || {}, function (key, val) { if (val) cite += "|" + key + "=" + val; }); cite += "}}"; return cite; } var out = "\n#* {{jêder|" + lang + "|jêgirtin=" + jeder.quote; if (jeder.quoteTr) out += "|tr=" + jeder.quoteTr; if (jeder.quoteT) out += "|tercime=" + jeder.quoteT; var srcParam = jeder.jederManual ? jeder.jederManual : "çavkanî?"; // A positional param containing "=" gets parsed as its own key=value // pair by MediaWiki and breaks the template, so force it to be // explicitly named (|2=) whenever that's the case. out += (srcParam.indexOf("=") !== -1 ? "|2=" : "|") + srcParam; out += "}}"; return out; }).join(""); } function makeWordListStep(id, name, question_fmt, header, templateName) { return { id: id, name: name, question_fmt: question_fmt, multiple: true, narrow: true, visible: function (values) { return values.lang && values.pos; }, output: function (values) { var words = $.grep(values[id] || [], function (w) { return !!w; }); if (!words.length) return ""; var lang = values.lang; var section = "\n==== " + header + " ====\n"; if (words.length === 1) { // Single word — keep the simple inline template. return section + "* {{" + templateName + "|" + lang + "|" + words[0] + "}}\n"; } // Multiple words — use {{kol3}} with one positional param per word. var params = "cure=" + header + "\n" + $.map(words, function (w) { return "|" + w; }).join("\n"); return section + "{{kol3|" + lang + "|" + params + "\n}}\n"; } }; } var steps = { lang: { id: "lang", required: true, name: "ziman", question_fmt: '"' + pageName + '" bi çi zimanî ye?', question_br: true, // Populated from [[MediaWiki:Gadget-start.js/data.json]] (langChoices). choices: [], output: function (values) { return "== {{ziman|" + values.lang + "}} ==\n"; } }, pron: { id: "pron", name: "bilêvkirin", question_fmt: '"' + pageName + '" çawa tê telafûzkirin?', // pronTpls populated from data.json pronTpls: [], visible: function (values) { if (!values.lang) return false; // In addLangMode, only skip pron when this langcode's section // already exists in the page — if it's a new language, show it. if (addLangMode) { // If the user wants to wipe the page and start over, the // existing content is irrelevant — always show pron. var clearPageCheck = $("#wiktku-clear-page-check"); if (clearPageCheck.length && clearPageCheck.prop("checked")) { return true; } var existing = $("#wpTextbox1").val() || ""; var header = "== {{ziman|" + values.lang + "}} =="; return existing.indexOf(header) === -1; } return true; }, /** Fills (or refills) the insert-dropdown from the current pronTpls array, filtering by language. */ refreshTplSelect: function () { var sel = $("#wiktku-start-pron .wiktku-tpl-insert-select"); if (!sel.length) return; var lang = getValues().lang || ""; sel.find("option[value!='']").remove(); $.each(steps.pron.pronTpls, function (_, tpl) { // Filter: if tpl.langs exists, only show if lang is in that list; otherwise show always var allowed = !tpl.langs || tpl.langs.indexOf(lang) !== -1; if (allowed) { sel.append($("<option></option>") .val(tpl.snippet) .text(tpl.name + " — " + tpl.desc) .attr("data-nolang", tpl.noLang ? "1" : "")); } }); // Notify Chosen that the option list has changed (no-op on mobile). if (!isMobile) sel.trigger("chosen:updated"); }, build: function (stepDiv) { if (stepDiv.find(".wiktku-pron-wrap").length) return null; var wrap = $("<div class='wiktku-pron-wrap'></div>"); var ta = $("<textarea></textarea>") .attr("name", "wiktku-pron-" + $.now()) .attr("class", "wiktku-start-step-field wiktku-pron-text") .attr("rows", 4) .attr("placeholder", "Nimûne: {{IPA|ku|/pɛɪ̯n/}} yan {{kîte|ku|he|ce|ki|rin}}"); // Template insert dropdown — filtered by language. var sel = $("<select class='wiktku-tpl-insert-select'></select>"); sel.append($("<option value=''>— şablonek lê zêde bike —</option>")); var lang = getValues().lang || ""; $.each(steps.pron.pronTpls, function (_, tpl) { // Filter: if tpl.langs exists, only show if lang is in that list; otherwise show always var allowed = !tpl.langs || tpl.langs.indexOf(lang) !== -1; if (allowed) { sel.append($("<option></option>") .val(tpl.snippet) .text(tpl.name + " — " + tpl.desc) .attr("data-nolang", tpl.noLang ? "1" : "")); } }); sel.on("change", function () { var snippet = $(this).val(); if (!snippet) return; var lang = getValues().lang || ""; // Check if the selected option has noLang flag var selectedOption = sel.find("option:selected"); var hasNoLang = selectedOption.attr("data-nolang") === "1"; if (!hasNoLang) { snippet = snippet.replace(/CODE/g, lang).replace(/SOURCELANG/g, "?"); } insertAtCursor(ta[0], snippet); $(this).val(""); ta.focus(); }); wrap.append(sel).append($("<br>")).append(ta); stepDiv.append(wrap); return ta; }, output: function () { var text = $.trim($("#wiktku-start-pron .wiktku-pron-text").val()); if (!text) return ""; var lines = text.split("\n"); var out = $.map(lines, function (line) { line = $.trim(line); if (!line) return undefined; return line.charAt(0) === "*" ? line : "* " + line; }).join("\n"); return "\n=== Bilêvkirin ===\n" + out + "\n"; } }, pos: { id: "pos", required: true, name: "Cureyê rêzimanî", question_fmt: 'Cureyê rêzimanî yê "' + pageName + '" çi ye?', visible: function (values) { return values.lang; }, question_br: true, // Populated from [[MediaWiki:Gadget-start.js/data.json]] (posChoices). choices: [], output: function (values) { var pos = values.pos || ""; var cinsiyet = values.cinsiyet || ""; // from the cinsiyet step var lekTur = values.lektur || ""; // from the lêker transitivity step var capitalizedPos = capitalize(pos); var outputString = "\n=== " + capitalizedPos + " ===\n"; // Add ku-tewîn-nav for single-word navdêr/serenav with known gender. if (!pageName.includes(" ") && cinsiyet && GENDER_BASE_LABELS[cinsiyet] && (pos === "navdêr" || pos === "serenav") && values.lang === "ku") { outputString += "{{ku-tewîn-nav|" + pageName + "|" + GENDER_BASE_LABELS[cinsiyet]; if (pos === "serenav") outputString += "|y"; outputString += "}}\n"; } outputString += "{{" + pos + "|" + values.lang; if (pos === "navdêr" || pos === "serenav") { if (cinsiyet) { outputString += "|c=" + cinsiyet; } else if (values.lang === "ku") { // Unknown gender — prompt editor to fill it in. outputString += "|c=?"; } } else if (/^lêker/.test(pos) && lekTur) { outputString += "|c=" + lekTur; } if (values.tr) { outputString += "|tr=" + values.tr; } outputString += "}}\n"; return outputString; } }, /** * cinsiyet (grammatical gender) — only shown for navdêr/serenav, û * tenê ger metadata ji bo zimanê hilbijartî lîsteyeke "g" (cinsiyet) * were dayîn. Opsiyonên vê gavê ne sabît in — ji metadata[values.lang].g * têne çêkirin, ji ber ku di hemû zimanan de cinsiyet tine. */ cinsiyet: { id: "cinsiyet", name: "cinsiyet", question_fmt: 'Cinsiyeta "' + pageName + '" çi ye?', question_br: true, visible: function (values) { var meta = metadata[values.lang]; return !!(values.lang && (values.pos === "navdêr" || values.pos === "serenav") && meta && meta.g && meta.g.length); }, build: function (stepDiv, values) { var select = stepDiv.find("select.wiktku-start-step-field"); if (!select.length) { select = $(mw.html.element("select", { "class": "wiktku-start-step-field", id: "wiktku-start-cinsiyet-field" })); stepDiv.append(select); } if (!values) return select; var meta = metadata[values.lang]; var codes = (meta && meta.g) || []; var prevVal = select.val(); var choices = $.map(codes, function (code) { return [[code, genderLabel(code)]]; }); populateMenus(select, choices); if ($.grep(choices, function (c) { return c[0] === prevVal; }).length) { select.val(prevVal); } if (!isMobile) select.trigger("chosen:updated"); return select; }, output: function () { return ""; } // consumed by pos.output }, /** * Lêker transitivity — only shown for any lêker variant. */ lektur: { id: "lektur", name: "Cureyê lêkerê (fiîlê)", question_fmt: "Cureyê lêkerê (fiîlê) çi ye?", question_br: true, visible: function (values) { return values.lang && values.pos && /^lêker/.test(values.pos); }, // Dictionary: value → display label. Add new types here. choices: [ ["gh", "gerguhêz"], ['x-gh', 'xwerû-gerguhêz'], ['p-gh', 'pêkhatî-gerguhêz'], ['h-gh', 'hevedudanî-gerguhêz'], ['b-gh', 'biwêjî-gerguhêz'], ["ngh", "negerguhêz"], ['x-ngh', 'xwerû-negerguhêz'], ['p-ngh', 'pêkhatî-negerguhêz'], ['h-ngh', 'hevedudanî-negerguhêz'], ['b-ngh', 'biwêjî-negerguhêz'] ], output: function () { return ""; } // consumed by pos.output }, tr: { id: "tr", name: "transkrîpsiyon", question_fmt: "Transkrîpsiyona kelîmeyê", multiple: false, narrow: true, visible: function (values) { return values.lang && values.pos && needsTransliteration(values.lang); } }, dfn: { id: "dfn", // required: true, ger mane tinebe [[Şablon:mane?]] bi kar bîne name: "Mane", question_fmt: "Maneya kelîmeyê binivîse. Mane otomatîk tê lînkkirin! Ji bo tercimeyan beşa 'Werger' bi kar bîne!", multiple: true, ordered: true, rows: 3, visible: function (values) { return values.lang && values.pos; }, example: function (values) { // posExamples loaded from [[MediaWiki:Gadget-start.js/data.json]]. var examples = steps.dfn.posExamples || {}; var full = values.pos || ""; return examples[full] || ""; }, /** * Builds one sense block (<li>) inside the ordered list. * Each block contains: * - a textarea for the definition * - an expandable nimûne list * - single-row sub-lists for formên alternatîv, hevmane, dijmane */ buildSenseBlock: function (stepDiv) { var block = $("<li class='wiktku-dfn-sense'></li>"); // — Mane textarea (declared first so the template handler can reference it) — var dfnArea = $("<textarea></textarea>") .attr("name", "wiktku-dfn-mane-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("class", "wiktku-start-step-field wiktku-dfn-mane") .attr("rows", 6) .attr("placeholder", "Mane…"); dfnArea.on("input", function () { steps.dfn.onDfnInput(stepDiv, block, this); }); // — Template selector (optional — replaces mane when chosen) — // Template definitions loaded from [[MediaWiki:Gadget-start.js/data.json]]. var tplDefs = steps.dfn.tplDefs || []; // Cache of all non-placeholder option elements — used by updateTplOptions // to remove/re-add options (the only approach compatible with Chosen.js). var _allTplOptions = []; var tplSelect = $(mw.html.element("select", { "class": "wiktku-dfn-tpl-select" })); tplSelect.append($("<option value=''>— yan jî şablonek hilbijêre —</option>")); $.each(tplDefs, function (_, tpl) { var opt = $("<option></option>") .val(tpl.name) .text(tpl.name) .attr("data-langs", tpl.langs ? tpl.langs.join(",") : "") .attr("data-nolang", tpl.noLang ? "1" : ""); tplSelect.append(opt); _allTplOptions.push(opt[0]); }); function updateTplOptions() { var lang = getValues().lang || ""; var currentVal = tplSelect.val(); var currentStillValid = false; // Detach all non-placeholder options, then re-attach only the visible ones. // This is the only approach that works correctly with both native <select> // and Chosen.js on desktop. tplSelect.find("option[value!='']").detach(); $.each(_allTplOptions, function (_, opt) { var allowed = $(opt).attr("data-langs"); var visible = !allowed || allowed.split(",").indexOf(lang) !== -1; if (visible) { tplSelect.append(opt); if ($(opt).val() === currentVal) currentStillValid = true; } }); if (!isMobile) tplSelect.trigger("chosen:updated"); if (currentVal && !currentStillValid) { tplSelect.val(""); dfnArea.show(); tplTitleInput.hide().val(""); } } // Store updater on the element so refresh() can call it for all blocks. tplSelect.data("updateOptions", updateTplOptions); var tplTitleInput = $("<input type='text'>") .addClass("wiktku-dfn-tpl-title wiktku-start-narrow") .attr("placeholder", "Navê rûpelê…") .hide(); // Grow the sense list when the title field of the last block gets content, // mirroring what onDfnInput does for the plain mane textarea. tplTitleInput.on("input", function () { steps.dfn.onDfnInput(stepDiv, block, this); }); /** * When a şablon sense is chosen, formên alternatîv/hevmane/dijmane/ * termên koordîne/jornav/jêrnav don't apply (there's no plain gloss * to hang them off), so hide those subgroups. Etîket, Nimûne and * Jêgirtin stay visible and still usable for a şablon sense. */ function updateFieldVisibility() { var isTpl = !!tplSelect.val(); $.each(HIDDEN_ON_TPL_GROUPS, function (_, cls) { block.find("." + cls + "-group").toggle(!isTpl); }); } // Store on the block so restoreDfn() can re-sync visibility // after programmatically setting tplSelect's value. block.data("updateFieldVisibility", updateFieldVisibility); tplSelect.on("change", function () { var chosen = $(this).val(); if (chosen) { dfnArea.hide(); tplTitleInput.show().focus(); } else { dfnArea.show(); tplTitleInput.hide().val(""); } updateFieldVisibility(); // Re-run refresh so the Werger step visibility updates. refresh(); }); var tplRow = $("<div></div>").addClass("wiktku-dfn-tpl-row") .append(tplSelect).append(" ").append(tplTitleInput); block.append(tplRow); block.append(dfnArea); // Apply lang filter on initial build. updateTplOptions(); // — Sub-field groups — // All groups are always visible with a placeholder textarea. // Nimûne is last in the DOM and last in the output. var allGroups = [ { cls: "wiktku-dfn-etiket", label: "Etîket", rows: 1, narrow: true, izah: "xisûsen, Mêrdîn, anatomî, Badînî" }, { cls: "wiktku-dfn-kategori", label: "Kategorî", rows: 1, narrow: true, izah: "Kategoriya ku ev mane lê tê zêdekirin" }, { cls: "wiktku-dfn-alternativ", label: "Formên alternatîv", rows: 1, narrow: true, izah: "Varyantên vê kelîmeyê" }, { cls: "wiktku-dfn-hevmane", label: "Hevmane", rows: 1, narrow: true, izah: "Spehî hevmaneya Bedew e." }, { cls: "wiktku-dfn-dijmane", label: "Dijmane", rows: 1, narrow: true, izah: "Zengîn dijmaneya feqîr e." }, { cls: "wiktku-dfn-koordine", label: "Termên koordîne", rows: 1, narrow: true, izah: "Pisîk û kûçik termên koordîne ne çunkî Jornavên wan gelek in" }, { cls: "wiktku-dfn-jornav", label: "Jornav", rows: 1, narrow: true, izah: "Heywan jornavê guhandar e" }, { cls: "wiktku-dfn-jernav", label: "Jêrnav", rows: 1, narrow: true, izah: "Guhandar jêrnavê heywan e" }, { cls: "wiktku-dfn-nimune", label: "Nimûne", rows: 2, narrow: false } ]; $.each(allGroups, function (_, g) { var groupDiv = $("<div></div>").addClass("wiktku-dfn-subgroup " + g.cls + "-group"); function buildNimuneLi() { var lang = getValues().lang || ""; var li = $("<li></li>").addClass("wiktku-dfn-nimune-li"); var mainTa = $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-text-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", g.rows) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-text") .attr("placeholder", "Nimûneya emilandina kelîmeyê tu bi xwe binivîse…"); mainTa.on("input", function () { var val = $.trim($(this).val()); var isLast = li.is(list.children("li:last-child")); if (val && isLast) { list.append(buildNimuneLi()); } }); li.append(mainTa); var subWrap = $("<div></div>").addClass("wiktku-dfn-nimune-sub"); if (needsTransliteration(lang)) { subWrap.append( $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-tr-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 5) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-tr") .attr("placeholder", "Transkrîpsiyona bi alfabeya latînî") ); } if (lang && lang !== "ku") { subWrap.append( $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-t-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 5) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-t") .attr("placeholder", "Tercimeya kurmancî") ); } if (subWrap.children().length) li.append(subWrap); return li; } if (g.cls === "wiktku-dfn-nimune") { // Nimûne — compound widget with tr/t sub-fields. var lbl = $("<span></span>").addClass("wiktku-dfn-sublabel").text(g.label + ": "); var list = $("<ol></ol>").addClass("wiktku-dfn-sublist " + g.cls + "-list"); groupDiv.data("buildNimuneLi", buildNimuneLi); list.append(buildNimuneLi()); groupDiv.append(lbl).append(list); block.append(groupDiv); } else { // Regular always-visible group — label + growing textarea list. var lbl = $("<span></span>").addClass("wiktku-dfn-sublabel").text(g.label + ": " + g.izah); var list = $("<ol></ol>").addClass("wiktku-dfn-sublist " + g.cls + "-list"); var firstInput = $("<textarea></textarea>") .attr("name", g.cls + "-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", g.rows) .attr("class", "wiktku-dfn-subfield" + (g.narrow ? " wiktku-start-narrow" : "")) .attr("placeholder", g.label + "…"); firstInput.on("input", function () { steps.dfn.onSubInput(list, this, g.rows, g.narrow); }); list.append($("<li></li>").append(firstInput)); groupDiv.append(lbl).append(list); block.append(groupDiv); } }); // — Jêder (quote / citation) group — a growing list, sibling to Nimûne — // Structured the same way as Nimûne (ol.wiktku-dfn-sublist > li) so it // lines up at the same indentation, and so that typing into the last // citation's Jêgirtin box automatically opens a fresh empty one below it. (function () { var jederGroupDiv = $("<div></div>").addClass("wiktku-dfn-subgroup wiktku-dfn-jeder-group"); var jederLbl = $("<span></span>").addClass("wiktku-dfn-sublabel").text("Jêgirtin: "); var jederList = $("<ol></ol>").addClass("wiktku-dfn-sublist wiktku-dfn-jeder-list"); function buildJederLi() { var lang = getValues().lang || ""; var li = $("<li></li>").addClass("wiktku-dfn-jeder-li"); var dragHandle = $("<span></span>") .addClass("wiktku-jeder-drag-handle") .attr("title", "Bişkûne û bikişîne da ku rêzê biguhezîne"); // Quote text textarea var quoteTa = $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-quote-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 2) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-quote") .attr("placeholder", "Nimûneya emilandinê ji kitêb an çavkaniyeke din binivîse"); quoteTa.on("input", function () { var val = $.trim($(this).val()); var isLast = li.is(jederList.children("li:last-child")); if (val && isLast) { jederList.append(buildJederLi()); } }); li.append(dragHandle).append(quoteTa); // tr/t sub-fields for the quote — shown as needed for the language. var quoteSubWrap = $("<div></div>").addClass("wiktku-dfn-quote-sub"); if (needsTransliteration(lang)) { quoteSubWrap.append( $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-quote-tr-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 2) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-quote-tr") .attr("placeholder", "Transkrîpsiyona jêgirtinê…") ); } if (lang && lang !== "ku") { quoteSubWrap.append( $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-quote-t-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 2) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-quote-t") .attr("placeholder", "Tercimeya jêgirtinê bi kurmancî") ); } if (quoteSubWrap.children().length) li.append(quoteSubWrap); // Citoid auto-fill: fetch citation data from a URL, DOI or ISBN and // prefill the source şablon + fields below (see Gadget-citoid-helper.js). var citoidWrap = $("<div></div>").addClass("wiktku-dfn-quote-citoid"); var citoidInput = $("<input type='text'>") .addClass("wiktku-dfn-quote-citoid-input wiktku-start-narrow") .attr("placeholder", "URL, DOI an ISBN binivîse ku otomatîk were tijekirin…"); var citoidBtn = new OO.ui.ButtonWidget({ label: "Bi Citoid bîne", classes: [ "wiktku-dfn-quote-citoid-btn" ] }); var citoidStatus = $("<span></span>").addClass("wiktku-dfn-quote-citoid-status"); /** * Fetches citation data from Citoid and applies it to this * citation's şablon selector + fields. Mirrors the logic in * Form.prototype._fillFromCitoid (Gadget-wikt.add-examples.js): * - only (re)selects the şablon when it actually differs from * what's already chosen, so a repeat fetch doesn't wipe out * a template the user already picked; * - only fills fields that are currently empty, so it never * overwrites something the user typed by hand; * - falls back to the freeform "bi destê xwe binivîsim" source * only when nothing was typed there yet. */ function runCitoidFetch() { var query = $.trim(citoidInput.val()); if (!query) { mw.notify("Ji kerema xwe re pêşî URL, DOI an ISBNyekê binivîse."); return; } citoidBtn.setDisabled(true); citoidStatus.text("Tê anîn…"); wikt.citoidHelper.ensure().then(function () { return wikt.citoid.fetchJederFields(query); }).then(function (result) { var jederKey = result.jederKey; var hasTpl = !!jederKey && srcSel.find("option[value='" + jederKey + "']").length > 0; var targetVal = hasTpl ? jederKey : "__manual__"; // Only (re)select — and thus rebuild — the field rows if // we're switching to a different şablon than what's // already chosen, so a second fetch doesn't clear fields // the user already filled in by hand. if (srcSel.val() !== targetVal) { srcSel.val(targetVal).trigger("change"); srcSel.trigger("chosen:updated"); } if (hasTpl) { // Tenê qadên vala tijî bike. $.each(result.fields, function (key, val) { var input = srcFields.find("[data-field-key='" + key + "']"); if (input.length && !$.trim(input.val())) { input.val(val); } }); } else { // Şablonek nehat naskirin ji bo vê itemType — rêzikeke // çavkaniyê ya bi destan a ji qadên Citoid tê çêkirin, // lê tenê ger qada destan vala be. var manualField = srcFields.find(".wiktku-dfn-quote-src-manual"); if (!$.trim(manualField.val())) { var parts = []; $.each(["nivîskar", "sernav", "websîte", "kovar", "weşanxane", "sal", "url"], function (_, k) { if (result.fields[k]) parts.push(result.fields[k]); }); manualField.val(parts.join(", ")); } } citoidStatus.text(""); }, function (errorMsg) { citoidStatus.text(typeof errorMsg === "string" ? errorMsg : "Nehat dîtin. Kontrol bike ka URL/DOI/ISBN rast e."); }).always(function () { citoidBtn.setDisabled(false); }); } citoidBtn.on("click", runCitoidFetch); citoidInput.on("keydown", function (e) { if (e.which === 13) { // Enter e.preventDefault(); runCitoidFetch(); } }); citoidWrap.append(citoidInput).append(citoidBtn.$element).append(citoidStatus); // Source template selector, specific to this citation. var srcSel = $("<select></select>").addClass("wiktku-dfn-quote-src-sel"); srcSel.append($("<option value=''>— Çavkaniyê hilbijêre —</option>")); srcSel.append($("<option></option>").val("__manual__").text("Bi destê xwe binivîsim")); var jederDefs = steps.dfn.jederDefs || {}; $.each(jederDefs, function (tplName, def) { srcSel.append($("<option></option>").val(tplName).text(def.label)); }); // Dynamic source fields container. var srcFields = $("<div></div>").addClass("wiktku-dfn-quote-src-fields"); srcSel.on("change", function () { srcFields.empty(); var chosen = $(this).val(); if (!chosen) return; if (chosen === "__manual__") { // Freeform source, written by the user — becomes the 2nd // positional param of {{jêder|lang|…}} instead of çavkanî?. srcFields.append( $("<textarea></textarea>") .attr("rows", 4) .addClass("wiktku-dfn-subfield wiktku-dfn-quote-src-manual") .attr("placeholder", "Çavkaniyê bi destê xwe binivîse…") ); return; } var def = (steps.dfn.jederDefs || {})[chosen]; if (!def) return; $.each(def.fields, function (_, f) { var row = $("<div></div>").addClass("wiktku-dfn-quote-src-row"); var fieldLbl = $("<label></label>").text(f.label + ": "); var inp = $("<textarea></textarea>") .attr("rows", 2) .addClass("wiktku-dfn-quote-src-input wiktku-start-narrow") .attr("data-field-key", f.key) .attr("placeholder", f.label + "…"); row.append(fieldLbl).append(inp); srcFields.append(row); }); }); li.append(citoidWrap).append(srcSel).append(srcFields); return li; } jederGroupDiv.data("buildJederLi", buildJederLi); jederList.append(buildJederLi()); // Make citation rows sortable (drag to reorder). // The last row is always the empty trailing row — cancel its drag. mw.loader.using("jquery.ui.sortable", function () { jederList.sortable({ handle: ".wiktku-jeder-drag-handle", axis: "y", items: "li:not(:last-child)", tolerance: "pointer" }); }); jederGroupDiv.append(jederLbl).append(jederList); block.append(jederGroupDiv); }()); // Apply the initial hide/show state for the sub-groups (matches // tplSelect's starting value, which is normally empty). updateFieldVisibility(); return block; }, /** Grows the sense list when the last mane textarea gets content. */ onDfnInput: function (stepDiv, block, textarea) { var val = $.trim($(textarea).val()); var list = stepDiv.find("ol.wiktku-dfn-list"); var isLast = block.is(list.children("li:last-child")); if (val && isLast) { var newBlock = steps.dfn.buildSenseBlock(stepDiv); list.append(newBlock); // Apply Chosen to the new block's template selector on desktop. if (!isMobile) newBlock.find("select.wiktku-dfn-tpl-select").chosen(chosenOptions); } refresh(); }, /** Grows a sub-list (nimûne/formên alternatîv/hevmane/dijmane/termên koordîne) on input. */ onSubInput: function (list, input, rows, narrow) { var val = $.trim($(input).val()); var item = $(input).parent(); var isLast = item.is(list.children("li:last-child")); if (val && isLast) { var next = $("<textarea></textarea>") .attr("name", "wiktku-dfn-sub-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", rows) .attr("class", "wiktku-dfn-subfield" + (narrow ? " wiktku-start-narrow" : "")); next.on("input", function () { steps.dfn.onSubInput(list, this, rows, narrow); }); list.append($("<li></li>").append(next)); } }, // Populated from [[MediaWiki:Gadget-start.js/data.json]] (tplDefs, posExamples, jederDefs). tplDefs: [], posExamples: {}, jederDefs: {}, build: function (stepDiv) { if (stepDiv.find("ol.wiktku-dfn-list").length) return null; var list = $("<ol class='wiktku-dfn-list'></ol>"); list.append(steps.dfn.buildSenseBlock(stepDiv)); stepDiv.append(list); return null; }, /** Reads all sense blocks from the DOM and returns an array of sense objects. */ getSenses: function (stepDiv) { var senses = []; stepDiv.find("li.wiktku-dfn-sense").each(function () { var block = $(this); var tplSel = block.find("select.wiktku-dfn-tpl-select"); var tpl = tplSel.val() || ""; // noLang: template already encodes the language — don't add |lang| param. var tplNoLang = tpl ? tplSel.find("option[value='" + tpl + "']").attr("data-nolang") === "1" : false; var tplTitle = $.trim(block.find("input.wiktku-dfn-tpl-title").val()); var mane = $.trim(block.find("textarea.wiktku-dfn-mane").val()); var etiket = (function () { var vals = []; block.find(".wiktku-dfn-etiket-list textarea").each(function () { var v = $.trim($(this).val()); if (v) vals.push(v); }); return vals; }()); var kategori = (function () { var vals = []; block.find(".wiktku-dfn-kategori-list textarea").each(function () { var v = $.trim($(this).val()); if (v) vals.push(v); }); return vals; }()); function readList(cls) { var vals = []; block.find("." + cls + "-list textarea").each(function () { var v = $.trim($(this).val()); if (v) vals.push(v); }); return vals; } // Nimûne items are compound: { text, tr?, t? } function readNimuneList() { var items = []; block.find(".wiktku-dfn-nimune-list li.wiktku-dfn-nimune-li").each(function () { var text = $.trim($(this).find(".wiktku-dfn-nimune-text").val()); if (!text) return; var obj = { text: text }; var tr = $.trim($(this).find(".wiktku-dfn-nimune-tr").val()); var t = $.trim($(this).find(".wiktku-dfn-nimune-t").val()); if (tr) obj.tr = tr; if (t) obj.t = t; items.push(obj); }); return items; } // Jêder is a growing list of citations, one per li — mirrors readNimuneList(). function readJederList() { var items = []; block.find(".wiktku-dfn-jeder-list li.wiktku-dfn-jeder-li").each(function () { var li = $(this); var quote = $.trim(li.find(".wiktku-dfn-nimune-quote").val()); if (!quote) return; var obj = { quote: quote }; var qtr = $.trim(li.find(".wiktku-dfn-nimune-quote-tr").val()); var qt = $.trim(li.find(".wiktku-dfn-nimune-quote-t").val()); if (qtr) obj.quoteTr = qtr; if (qt) obj.quoteT = qt; var tplName = li.find(".wiktku-dfn-quote-src-sel").val(); if (tplName === "__manual__") { var manual = $.trim(li.find(".wiktku-dfn-quote-src-manual").val()); if (manual) obj.jederManual = manual; } else if (tplName) { obj.jederTpl = tplName; var fields = {}; li.find(".wiktku-dfn-quote-src-input").each(function () { var k = $(this).attr("data-field-key"); var v = $.trim($(this).val()); if (k && v) fields[k] = v; }); obj.jêderFields = fields; } items.push(obj); }); return items; } senses.push({ tpl: tpl, tplNoLang: tplNoLang, tplTitle: tplTitle, mane: mane, etiket: etiket, kategori: kategori, nimune: readNimuneList(), jeder: readJederList(), alternativ: readList("wiktku-dfn-alternativ"), hevmane: readList("wiktku-dfn-hevmane"), dijmane: readList("wiktku-dfn-dijmane"), koordine: readList("wiktku-dfn-koordine"), jornav: readList("wiktku-dfn-jornav"), jernav: readList("wiktku-dfn-jernav") }); }); return senses; }, getOutput: function (values, callback) { var stepDiv = $("#wiktku-start-dfn"); var senses = steps.dfn.getSenses(stepDiv); var lang = values.lang; // A sense counts as "filled" if it has a mane, a chosen template + title, // or any other content (etîket/hevmane/nimûne/jêder…) worth keeping. var hasMane = senses.some(function (s) { return s.mane !== "" || (s.tpl && s.tplTitle) || senseHasExtraContent(s); }); // True only when at least one sense has a regular mane (needs linkify). var hasRegularMane = senses.some(function (s) { return !s.tpl && s.mane !== ""; }); // nimûne and jêder lines must never pass through linkify — only // the plain mane text should be linkified. We build two parallel // arrays: defLines (sent to linkify) and citeLines (kept aside). // Each entry in citeLines corresponds 1-to-1 with a defLines entry; // a template token {{wiktku-cite-N}} is embedded in defLines so // that after linkify runs we know exactly where to splice them back. // Template-call syntax is guaranteed safe: linkifiers leave {{ }} // tokens completely untouched. var defLines = []; // one entry per kept sense (goes to linkify) var citeLines = []; // parallel — nimûne+jêder for that same sense $.each(senses, function (_, sense) { // — Template sense (e.g. {{guharto|ku|somepage}}) — if (sense.tpl) { if (!sense.tplTitle) return; // skip empty template senses var tplKatTpl = ""; if (sense.kategori && sense.kategori.length) { var tplKatParts = sense.kategori.map(function (k) { return $.trim(k); }) .filter(function (k) { return k !== ""; }); if (tplKatParts.length) { tplKatTpl = "{{K|" + lang + "|" + tplKatParts.join("|") + "}} "; } } var tplLabelTpl = ""; if (sense.etiket && sense.etiket.length) { var tplLabelParts = sense.etiket.map(function (part) { return $.trim(part); }).filter(function (part) { return part !== ""; }); if (tplLabelParts.length) { tplLabelTpl = " {{e|" + lang + "|" + tplLabelParts.join("|") + "}} "; } } var tplCall = sense.tplNoLang ? "{{" + sense.tpl + "|" + sense.tplTitle + "}}" : "{{" + sense.tpl + "|" + lang + "|" + sense.tplTitle + "}}"; var tplHasJeder = sense.jeder && $.grep(sense.jeder, function (j) { return j && j.quote; }).length > 0; var idx = defLines.length; var cite = formatNimune(sense.nimune, lang, tplHasJeder) + formatJeder(sense.jeder, lang); defLines.push("#" + (tplLabelTpl ? tplLabelTpl : " ") + tplCall + tplKatTpl + (cite ? "{{wiktku-cite-" + idx + "}}" : "")); citeLines.push(cite); return; } // — Normal mane sense — var dfn = sense.mane; if (!dfn && !senseHasExtraContent(sense)) return; // truly empty if (dfn) { dfn = stripWikilinks(dfn); if (dfn[0] !== dfn[0].toUpperCase()) dfn = capitalize(dfn); if (!dfn.match(/[.…?!)\]]$/)) dfn += "."; } else { dfn = "{{mane?|" + lang + "}}"; } var katTpl = ""; if (sense.kategori && sense.kategori.length) { var katParts = sense.kategori.map(function (k) { return $.trim(k); }) .filter(function (k) { return k !== ""; }); if (katParts.length) { katTpl = "{{K|" + lang + "|" + katParts.join("|") + "}}"; } } var labelTpl = ""; if (sense.etiket && sense.etiket.length) { var labelParts = sense.etiket.map(function (part) { return $.trim(part); }).filter(function (part) { return part !== ""; }); if (labelParts.length) { labelTpl = " {{e|" + lang + "|" + labelParts.join("|") + "}} "; } } var out = "#" + (labelTpl ? labelTpl : " ") + dfn; out += katTpl; function wordLine(tpl, words) { if (!words.length) return ""; return "\n#: {{" + tpl + "|" + lang + "|" + words.join("|") + "}}"; } out += wordLine("alt-r", sense.alternativ); out += wordLine("hevmane", sense.hevmane); out += wordLine("dijmane", sense.dijmane); out += wordLine("koordîne", sense.koordine); out += wordLine("jornav", sense.jornav); out += wordLine("jêrnav", sense.jernav); var hasJeder = sense.jeder && $.grep(sense.jeder, function (j) { return j && j.quote; }).length > 0; var cite = formatNimune(sense.nimune, lang, hasJeder) + formatJeder(sense.jeder, lang); var idx = defLines.length; defLines.push(out + (cite ? "{{wiktku-cite-" + idx + "}}" : "")); citeLines.push(cite); }); // Splice citeLines back into a linkified string, replacing each // {{wiktku-cite-N}} token with its stored nimûne/jêder block. function restoreCites(t) { return t.replace(/\{\{wiktku-cite-(\d+)\}\}/g, function (_, n) { return citeLines[parseInt(n, 10)] || ""; }); } var text = defLines.join("\n") + "\n"; if (!hasMane) { // No definitions entered — emit {{mane?}} with bênimûne. text = "# {{mane?|" + lang + "}}\n#* {{bênimûne|" + lang + "}}\n"; callback(text); return; } if (!hasRegularMane) { // All filled senses are template senses — no linkify needed. callback(restoreCites(text)); return; } var didTryToLoad = function () { if (typeof $.wiktviLinkify === "function") { $.wiktviLinkify(text, function (linked) { callback(restoreCites(linked)); }); } else { callback(restoreCites(text)); } }; mw.loader.using("ext.gadget.linkify", didTryToLoad, didTryToLoad); } }, je: makeWordListStep("je", "jê", "Kelîmeyên jê çêbûyî binivîse", "Jê", "g"), tekildar: makeWordListStep("tekildar", "têkildar", "Kelîmeyên ji aliyê etîmolojiyê ve têkildarî vê kelîmeyê binivîse", "Têkildar", "g"), binereherwiha: makeWordListStep("binereherwiha", "binêre herwiha", "Kelîmeyên din ên eleqedar binivîse", "Binêre herwiha", "g"), etym: { id: "etym", name: "etîmolojî", question_fmt: "Etîmolojiya kelîmeyê binivîse", // etymTpls populated from data.json etymTpls: [], visible: function (values) { return values.lang && values.pos; }, /** Fills (or refills) the insert-dropdown from the current etymTpls array. */ refreshTplSelect: function () { var sel = $("#wiktku-start-etym .wiktku-tpl-insert-select"); if (!sel.length) return; sel.find("option[value!='']").remove(); $.each(steps.etym.etymTpls, function (_, tpl) { sel.append($("<option></option>").val(tpl.snippet).text(tpl.name + " — " + tpl.desc)); }); // Notify Chosen that the option list has changed (no-op on mobile). if (!isMobile) sel.trigger("chosen:updated"); }, build: function (stepDiv) { if (stepDiv.find(".wiktku-etym-wrap").length) return null; var wrap = $("<div class='wiktku-etym-wrap'></div>"); var ta = $("<textarea></textarea>") .attr("name", "wiktku-etym-" + $.now()) .attr("class", "wiktku-start-step-field wiktku-etym-text") .attr("rows", 4) .attr("placeholder", "Nimûne: Ji {{ji|en|ku|apple}}. yan rasterast binivîse…"); // Template insert dropdown — options also refreshed after data.json loads. var sel = $("<select class='wiktku-tpl-insert-select'></select>"); sel.append($("<option value=''>— şablonek lê zêde bike —</option>")); $.each(steps.etym.etymTpls, function (_, tpl) { sel.append($("<option></option>").val(tpl.snippet).text(tpl.name + " — " + tpl.desc)); }); sel.on("change", function () { var snippet = $(this).val(); if (!snippet) return; var lang = getValues().lang || ""; snippet = snippet.replace(/CODE/g, lang).replace(/SOURCELANG/g, "?"); insertAtCursor(ta[0], snippet); $(this).val(""); ta.focus(); }); wrap.append(sel).append($("<br>")).append(ta); stepDiv.append(wrap); return ta; }, output: function (values) { var text = $.trim($("#wiktku-start-etym .wiktku-etym-text").val()); if (text) { return "\n==== Etîmolojî ====\n" + text + "\n"; } // No etymology entered — emit {{ji?|lang}} as a placeholder, // but only when the entry has at least one regular (non-şablon) // sense with content — either real mane text, or an empty mane // with other fields filled in (which dfn.getOutput() renders as // {{mane?|lang}} with those fields attached). A şablon sense // like {{guharto|…}} never counts, filled in or not. var dfnSenses = steps.dfn.getSenses($("#wiktku-start-dfn")); var hasRegularMane = dfnSenses.some(function (s) { return !s.tpl && (s.mane !== "" || senseHasExtraContent(s)); }); if (!hasRegularMane) return ""; return "\n==== Etîmolojî ====\n{{ji?|" + values.lang + "}}\n"; } }, dunde: { id: "dunde", name: "dûnde", question_fmt: "Eger ev kelîme ji vî zimanî ketibe zimanekî din, vî zimanî û kelîmeya wî binivîse", visible: function (values) { return !!values.pos; }, disabledKeys: { "navz": true}, /** * Builds one row: a language dropdown + a growing list of word * inputs. When the dropdown gets a value the next empty row is * appended automatically. Mirrors steps.trans's row widget, but * flat (one shared list — dûnde isn't tied to individual senses). */ buildRow: function (stepDiv) { var row = $("<li class='wiktku-dunde-row wiktku-lang-row'></li>"); // Language selector — chosen is applied after insertion into DOM. var langSel = $(mw.html.element("select", { "class": "wiktku-start-step-keyfield wiktku-start-narrow" })); langSel.attr("data-placeholder", "Zimanekî lê bigere"); populateMenus(langSel, steps.dunde.keys || [], steps.dunde.disabledKeys); // When a language is chosen, ensure a next empty row exists. langSel.on("change", function () { steps.dunde.onLangChange(stepDiv, row); }); // Word list for this language. var wordList = $("<ul class='wiktku-dunde-words wiktku-lang-row-words'></ul>"); var firstWord = steps.dunde.makeWordInput(); wordList.append($("<li></li>").append(firstWord)); if (isMobile) { row.append(wrapNativeSelect(langSel)).append(wordList); } else { row.append(langSel).append(wordList); } return row; }, makeWordInput: function () { var input = $("<textarea></textarea>") .attr("name", "wiktku-dunde-word-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 1) .attr("class", "wiktku-dfn-subfield wiktku-start-narrow") .attr("placeholder", "Kelîme…"); input.on("input", function () { var list = $(this).closest("ul.wiktku-dunde-words"); var item = $(this).parent(); var val = $.trim($(this).val()); if (val && item.is(list.children("li:last-child"))) { var next = steps.dunde.makeWordInput(); list.append($("<li></li>").append(next)); } }); return input; }, onLangChange: function (stepDiv, row) { var list = stepDiv.find("ul.wiktku-dunde-list"); var isLast = row.is(list.children("li.wiktku-dunde-row:last-child")); if (isLast) { var newRow = steps.dunde.buildRow(stepDiv); list.append(newRow); // Init chosen after the new row is in the DOM (desktop only). if (!isMobile) newRow.find("select").chosen(chosenOptions); } // Keep disabled keys in sync across all lang selectors. steps.dunde.syncDisabledKeys(stepDiv); }, /** Disables already-selected languages in all other dropdowns. */ syncDisabledKeys: function (stepDiv) { var taken = $.extend({}, steps.dunde.disabledKeys); stepDiv.find("li.wiktku-dunde-row select").each(function () { var v = $(this).val(); if (v) taken[v] = true; }); stepDiv.find("li.wiktku-dunde-row select").each(function () { var self = $(this); var own = self.val(); self.find("option").each(function () { var code = $(this).val(); if (!code) return; $(this).prop("disabled", taken[code] && code !== own); }); self.trigger("chosen:updated"); }); }, build: function (stepDiv) { if (stepDiv.find("ul.wiktku-dunde-list").length) return null; var list = $("<ul class='wiktku-dunde-list wiktku-lang-row-list'></ul>"); list.append(steps.dunde.buildRow(stepDiv)); stepDiv.append(list); // Init chosen after the select is in the DOM (desktop only). if (!isMobile) list.find("select").chosen(chosenOptions); return null; }, /** Reads all [langcode, words[]] rows from the DOM. */ getRows: function (stepDiv) { var result = []; stepDiv.find("li.wiktku-dunde-row").each(function () { var lang = $(this).find("select").val(); if (!lang) return; var words = []; $(this).find("ul.wiktku-dunde-words textarea").each(function () { var v = $.trim($(this).val()); if (v) words.push(v); }); if (words.length) result.push([lang, words]); }); return result; }, output: function () { var stepDiv = $("#wiktku-start-dunde"); var rows = steps.dunde.getRows(stepDiv); if (!rows.length) return ""; var lines = $.map(rows, function (row) { var lang = row[0], words = row[1]; return "* {{dû|" + lang + "|" + words.join("|") + "}}"; }); return "\n==== Dûnde ====\n" + lines.join("\n") + "\n"; } }, zarava: { id: "zarava", name: "bi zaravayên din", visible: function (values) { return steps.trans.visible(values); }, disabledKeys: { "navz": true }, buildRow: function (group) { var row = $("<li class='wiktku-zarava-row wiktku-lang-row'></li>"); var langSel = $(mw.html.element("select", { "class": "wiktku-start-step-keyfield wiktku-start-narrow" })); populateMenus(langSel, steps.zarava.keys || [], steps.zarava.disabledKeys); langSel.on("change", function () { steps.zarava.onLangChange(group, row); }); var wordList = $("<ul class='wiktku-zarava-words wiktku-lang-row-words'></ul>"); var firstWord = steps.zarava.makeWordInput(); wordList.append($("<li></li>").append(firstWord)); row.append(langSel).append(wordList); return row; }, makeWordInput: function () { var input = $("<textarea></textarea>") .attr("name", "wiktku-zarava-word-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 1) .attr("class", "wiktku-dfn-subfield wiktku-start-narrow") .attr("placeholder", "Tercime…"); input.on("input", function () { var list = $(this).closest("ul.wiktku-zarava-words"); var item = $(this).parent(); var val = $.trim($(this).val()); if (val && item.is(list.children("li:last-child"))) { var next = steps.zarava.makeWordInput(); list.append($("<li></li>").append(next)); } }); return input; }, onLangChange: function (group, row) { var list = group.find("ul.wiktku-zarava-list"); var isLast = row.is(list.children("li.wiktku-zarava-row:last-child")); if (isLast) { var newRow = steps.zarava.buildRow(group); list.append(newRow); } steps.zarava.syncDisabledKeys(group); }, /** Disables already-selected dialects in all other dropdowns within one group. */ syncDisabledKeys: function (group) { var taken = $.extend({}, steps.zarava.disabledKeys); group.find("li.wiktku-zarava-row select").each(function () { var v = $(this).val(); if (v) taken[v] = true; }); group.find("li.wiktku-zarava-row select").each(function () { var self = $(this); var own = self.val(); self.find("option").each(function () { var code = $(this).val(); if (!code) return; $(this).prop("disabled", taken[code] && code !== own); }); }); }, /** Builds (or fetches) the .wiktku-zarava-group for one gloss. */ buildGroup: function (stepDiv, gi) { var group = $("<div class='wiktku-zarava-group'></div>").attr("data-gloss-pos", gi); var list = $("<ul class='wiktku-zarava-list wiktku-lang-row-list'></ul>"); list.append(steps.zarava.buildRow(group)); group.append(list); stepDiv.append(group); return group; }, /** Syncs one .wiktku-zarava-group per current gloss (same logic as steps.trans.build). */ build: function (stepDiv) { var glosses = steps.trans.glossList(); if (!glosses.length) { stepDiv.find(".wiktku-zarava-group").remove(); return null; } var existingGroups = stepDiv.find(".wiktku-zarava-group"); if (existingGroups.length > glosses.length) { existingGroups.slice(glosses.length).remove(); } $.each(glosses, function (gi, gloss) { var group = stepDiv.find(".wiktku-zarava-group[data-gloss-pos='" + gi + "']"); if (!group.length) group = steps.zarava.buildGroup(stepDiv, gi); var label = group.find(".wiktku-zarava-group-label"); if (glosses.length > 1) { if (!label.length) { label = $("<div class='wiktku-zarava-group-label'></div>"); group.prepend(label); } label.text(gloss.index + " " + gloss.text); } else if (label.length) { label.remove(); } }); return null; }, /** Reads the dialect rows for a single gloss group. */ getGroupTranslations: function (group) { var result = []; group.find("li.wiktku-zarava-row").each(function () { var lang = $(this).find("select").val(); if (!lang) return; var words = []; $(this).find("ul.wiktku-zarava-words textarea").each(function () { var v = $.trim($(this).val()); if (v) words.push(v); }); if (words.length) result.push([lang, words]); }); return result; }, /** Reads all rows from the DOM, grouped by gloss position. */ getTranslations: function (stepDiv) { var result = []; stepDiv.find(".wiktku-zarava-group").each(function () { result.push(steps.zarava.getGroupTranslations($(this))); }); return result; }, output: function (values) { if (values.lang !== "ku") return ""; var stepDiv = $("#wiktku-start-zarava"); var glosses = steps.trans.glossList(); if (!glosses.length) return ""; var blocks = $.map(glosses, function (gloss, gi) { var group = stepDiv.find(".wiktku-zarava-group[data-gloss-pos='" + gi + "']"); var rows = group.length ? steps.zarava.getGroupTranslations(group) : []; if (!gloss.text && !rows.length) return undefined; if (rows.length) { rows.sort(function (a, b) { var aLang = langsByCode[a[0]] || []; var bLang = langsByCode[b[0]] || []; return (aLang[2] || "").localeCompare(bLang[2] || "", "ku"); }); } var wordLines = $.map(rows, function (row) { var lang = row[0]; var words = row[1]; var wikiWords = words.map(function (w) { return "{{W|" + lang + "|" + w + "}}"; }).join(", "); return "* {{Z|" + lang + "}}: " + wikiWords; }).join("\n"); if (!wordLines) return undefined; var block = "{{werger-ser|" + (gloss.text || "?") + "|" + gloss.index + "}}"; block += "\n" + wordLines; block += "\n{{werger-bin}}"; return block; }); if (!blocks.length) return ""; return "\n==== Bi zaravayên din ====\n" + blocks.join("\n") + "\n"; } }, trans: { id: "trans", name: "werger", visible: function (values) { if (!(values.lang === "ku" && values.pos)) return false; // Hide Werger only when EVERY sense is a template sense (Guharto etc.) // with a title filled in — i.e. there is real content but no plain // gloss to attach a translation table to. A mix of real + template // senses still shows Werger; the template senses are simply skipped // in output(). // // "Real" here means a non-şablon sense with either mane text or // other filled-in fields (etîket/hevmane/nimûne/jêder…), since // dfn.getOutput() renders the latter too, as {{mane?|lang}} plus // whatever else was filled in. // // When nothing has been filled in at all, output() will emit // {{mane?|lang}} instead of a gloss — but Werger should still show, // since the user may want to add translations before they've // settled on a gloss. var dfnSenses = steps.dfn.getSenses($("#wiktku-start-dfn")); var hasRealSense = dfnSenses.some(function (s) { return !s.tpl && (s.mane !== "" || senseHasExtraContent(s)); }); var hasFilledTplSense = dfnSenses.some(function (s) { return s.tpl && s.tplTitle; }); return hasRealSense || !hasFilledTplSense; }, disabledKeys: { "navz": true, "ku": true, "ckb": true, "sdh": true, "lki": true, "hac": true, "zza": true }, /** * Builds one translation row: a language dropdown + a growing list * of word inputs. When the dropdown gets a value the next empty row * is appended automatically. * * @param group the specific .wiktku-trans-group this row belongs to * (each gloss has its own group and its own list of rows, so the * lookups below must stay scoped to that group rather than the * whole step — the step now holds one list per gloss). */ buildRow: function (group) { var row = $("<li class='wiktku-trans-row wiktku-lang-row'></li>"); // Language selector — chosen is applied after insertion into DOM. var langSel = $(mw.html.element("select", { "class": "wiktku-start-step-keyfield wiktku-start-narrow" })); langSel.attr("data-placeholder", "Zimanekî lê bigere"); populateMenus(langSel, steps.trans.keys || [], steps.trans.disabledKeys); // When a language is chosen, ensure a next empty row exists. langSel.on("change", function () { steps.trans.onLangChange(group, row); }); // Word list for this language. var wordList = $("<ul class='wiktku-trans-words wiktku-lang-row-words'></ul>"); var firstWord = steps.trans.makeWordInput(); wordList.append($("<li></li>").append(firstWord)); if (isMobile) { row.append(wrapNativeSelect(langSel)).append(wordList); } else { row.append(langSel).append(wordList); } return row; }, makeWordInput: function () { var input = $("<textarea></textarea>") .attr("name", "wiktku-trans-word-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 1) .attr("class", "wiktku-dfn-subfield wiktku-start-narrow") .attr("placeholder", "Tercime…"); input.on("input", function () { var list = $(this).closest("ul.wiktku-trans-words"); var item = $(this).parent(); var val = $.trim($(this).val()); if (val && item.is(list.children("li:last-child"))) { var next = steps.trans.makeWordInput(); list.append($("<li></li>").append(next)); } }); return input; }, onLangChange: function (group, row) { var list = group.find("ul.wiktku-trans-list"); var isLast = row.is(list.children("li.wiktku-trans-row:last-child")); if (isLast) { var newRow = steps.trans.buildRow(group); list.append(newRow); // Init chosen after the new row is in the DOM (desktop only). if (!isMobile) newRow.find("select").chosen(chosenOptions); } // Keep disabled keys in sync across this gloss's lang selectors // only — the same language can be used for different senses. steps.trans.syncDisabledKeys(group); }, /** Disables already-selected languages in all other dropdowns within one group. */ syncDisabledKeys: function (group) { var taken = $.extend({}, steps.trans.disabledKeys); group.find("li.wiktku-trans-row select").each(function () { var v = $(this).val(); if (v) taken[v] = true; }); group.find("li.wiktku-trans-row select").each(function () { var self = $(this); var own = self.val(); self.find("option").each(function () { var code = $(this).val(); if (!code) return; $(this).prop("disabled", taken[code] && code !== own); }); self.trigger("chosen:updated"); }); }, /** * Builds (or fetches) the .wiktku-trans-group for one gloss, with * its own label and its own list of translation rows. */ buildGroup: function (stepDiv, gi) { var group = $("<div class='wiktku-trans-group'></div>").attr("data-gloss-pos", gi); var list = $("<ul class='wiktku-trans-list wiktku-lang-row-list'></ul>"); list.append(steps.trans.buildRow(group)); group.append(list); stepDiv.append(group); // Init chosen after the select is in the DOM (desktop only). if (!isMobile) list.find("select").chosen(chosenOptions); return group; }, /** * Syncs one .wiktku-trans-group per current gloss, adding new * groups and removing stale ones as senses are added or removed, * while leaving existing groups (and whatever translations the * user has already typed into them) untouched. Groups are keyed * to their gloss's position in glossList() via data-gloss-pos, so * a group always matches the same sense across rebuilds as long * as senses aren't reordered relative to each other. */ build: function (stepDiv) { var glosses = steps.trans.glossList(); if (!glosses.length) { stepDiv.find(".wiktku-trans-group").remove(); return null; } // Drop groups for glosses that no longer exist (always from the // tail — groups are only ever appended in gloss order below). var existingGroups = stepDiv.find(".wiktku-trans-group"); if (existingGroups.length > glosses.length) { existingGroups.slice(glosses.length).remove(); } $.each(glosses, function (gi, gloss) { var group = stepDiv.find(".wiktku-trans-group[data-gloss-pos='" + gi + "']"); if (!group.length) group = steps.trans.buildGroup(stepDiv, gi); // Only label groups when there's more than one gloss to // distinguish between — a single gloss needs no caption. var label = group.find(".wiktku-trans-group-label"); if (glosses.length > 1) { if (!label.length) { label = $("<div class='wiktku-trans-group-label'></div>"); group.prepend(label); } label.text(gloss.index + " " + gloss.text); } else if (label.length) { label.remove(); } }); return null; }, /** Reads the translation rows for a single gloss group. */ getGroupTranslations: function (group) { var result = []; group.find("li.wiktku-trans-row").each(function () { var lang = $(this).find("select").val(); if (!lang) return; var words = []; $(this).find("ul.wiktku-trans-words textarea").each(function () { var v = $.trim($(this).val()); if (v) words.push(v); }); if (words.length) result.push([lang, words]); }); return result; }, /** * Reads all translation rows from the DOM, grouped by gloss * position — one array of [lang, words] rows per gloss group, in * the same order as the .wiktku-trans-group elements. */ getTranslations: function (stepDiv) { var result = []; stepDiv.find(".wiktku-trans-group").each(function () { result.push(steps.trans.getGroupTranslations($(this))); }); return result; }, /** * Builds the numbered "{ index, gloss }" list — one entry per dfn * sense that has a real mane (skips template senses like Guharto, * which have nothing to caption a translation table with). The * index matches the sense's actual position in the numbered "#" * definition list (1-based), including template senses in the count, * so the number printed next to {{werger-ser}} lines up with the * gloss the reader sees in the entry. * * When nothing has been filled in at all (dfn.getOutput() will emit * {{mane?|lang}} as sense 1), this returns a single placeholder * entry with empty text instead of an empty array, so Werger still * has one group to attach translations to before a gloss exists. * When every filled sense is a template sense instead, this stays * empty — that mirrors trans.visible()'s hidden case, where there's * no group in the DOM for a placeholder to attach to anyway. */ glossList: function () { var dfnSenses = steps.dfn.getSenses($("#wiktku-start-dfn")); var glosses = []; var hasFilledTplSense = false; $.each(dfnSenses, function (i, s) { if (s.tpl) { if (s.tplTitle) hasFilledTplSense = true; return; // template sense — no gloss to caption with } var dfn = s.mane; if (!dfn) { // No mane text, but other fields (etîket/hevmane/nimûne/ // jêder…) are filled — dfn.getOutput() still emits this // sense as a numbered line using {{mane?|lang}}, so it // needs its own gloss group too, just with no caption text. if (senseHasExtraContent(s)) glosses.push({ index: i + 1, text: "" }); return; } if (dfn[0] !== dfn[0].toLowerCase()) dfn = decapitalize(dfn); dfn = stripWikilinks(dfn).replace(/[.…?!)\]،؟]+$/, ""); glosses.push({ index: i + 1, text: dfn }); }); if (!glosses.length && !hasFilledTplSense) { glosses.push({ index: 1, text: "" }); } return glosses; }, output: function (values) { if (values.lang !== "ku") return ""; var stepDiv = $("#wiktku-start-trans"); var glosses = steps.trans.glossList(); // Every sense is a template sense — there's no real gloss // anywhere and no group in the DOM either (glossList() only // returns empty in that case), so skip the section entirely. if (!glosses.length) return ""; // Each gloss now has its own group of translation rows — // attach every gloss's own words under its own werger-ser/-bin // pair instead of dumping everything under the first one. var blocks = $.map(glosses, function (gloss, gi) { var group = stepDiv.find(".wiktku-trans-group[data-gloss-pos='" + gi + "']"); var rows = group.length ? steps.trans.getGroupTranslations(group) : []; // Placeholder gloss (no real mane entered yet) with nothing // translated into it — nothing to output, and gloss.text is // empty so there's no caption to give {{werger-ser}} anyway. if (!gloss.text && !rows.length) return undefined; if (rows.length) { // Sort by Kurdish sort key. rows.sort(function (a, b) { var aLang = langsByCode[a[0]] || []; var bLang = langsByCode[b[0]] || []; return (aLang[2] || "").localeCompare(bLang[2] || "", "ku"); }); } var wordLines = $.map(rows, function (row) { var lang = row[0]; var words = row[1]; var wikiWords = words.map(function (w) { return "{{W|" + lang + "|" + w + "}}"; }).join(", "); return "* {{Z|" + lang + "}}: " + wikiWords; }).join("\n"); var block = "{{werger-ser|" + (gloss.text || "?") + "|" + gloss.index + "}}"; if (wordLines) block += "\n" + wordLines; block += "\n{{werger-bin}}"; return block; }); if (!blocks.length) return ""; return "\n==== Werger ====\n" + blocks.join("\n") + "\n"; } }, }; steps.trans.keys = steps.lang.choices; steps.dunde.keys = steps.lang.choices; steps.zarava.keys = getZaravaKeys(steps.lang.choices); var ordered_steps = [ steps.lang, steps.pron, steps.pos, steps.cinsiyet, steps.lektur, steps.tr, steps.dfn, steps.je, steps.tekildar, steps.etym, steps.dunde, steps.binereherwiha, steps.zarava, steps.trans]; // Step ids that belong to each section (not shared across sections). var PER_SECTION_STEP_IDS = [ "pos", "cinsiyet", "lektur", "tr", "dfn", "je", "tekildar", "etym", "dunde", "binereherwiha", "zarava", "trans" ]; // ── Multi-section state ────────────────────────────────────────────────── // Each entry is a plain snapshot: { pos, cinsiyet, lektur, tr, dfn (senses[]), // je, tekildar, binereherwiha, trans (rows[]) }. var sections = [{}]; // section 0 starts empty (DOM is the truth) var activeSection = 0; function snapshotDfn() { return steps.dfn.getSenses($("#wiktku-start-dfn")); } /** * Rebuild the dfn DOM from a previously snapshotted senses array. */ function restoreDfn(senses) { var stepDiv = $("#wiktku-start-dfn"); // Tear down the existing list so build() recreates it cleanly. stepDiv.find("ol.wiktku-dfn-list").remove(); steps.dfn.build(stepDiv); var list = stepDiv.find("ol.wiktku-dfn-list"); $.each(senses, function (i, sense) { // Ensure enough blocks exist (build() seeds one). var blocks = list.find("li.wiktku-dfn-sense"); var block = blocks.eq(i); if (!block.length) { var nb = steps.dfn.buildSenseBlock(stepDiv); list.append(nb); block = list.find("li.wiktku-dfn-sense").last(); } // Template selector. block.find("select.wiktku-dfn-tpl-select").val(sense.tpl || ""); if (sense.tpl) { block.find("textarea.wiktku-dfn-mane").hide(); block.find("input.wiktku-dfn-tpl-title").val(sense.tplTitle || "").show(); } else { block.find("textarea.wiktku-dfn-mane").val(sense.mane || "").show(); block.find("input.wiktku-dfn-tpl-title").hide().val(""); } // Re-sync the formên alternatîv/hevmane/… hide state now that // tplSelect's value was set programmatically (its own "change" // handler doesn't fire from .val(), so this doesn't happen otherwise). var updateVis = block.data("updateFieldVisibility"); if (updateVis) updateVis(); // Restore a sub-list (etiket, formên alternatîv, hevmane …) from a values array. function restoreSubList(cls, values) { if (!values || !values.length) return; var groupDiv = block.find("." + cls + "-group"); var subList = groupDiv.find("ol, ul").first(); if (!subList.length) return; // group not found // Fill existing items, append new ones as needed. $.each(values, function (j, val) { var items = subList.find("li"); if (j < items.length) { items.eq(j).find("textarea").val(val); } else { var ta = $("<textarea></textarea>") .attr("name", "wiktku-dfn-restore-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 1) .attr("class", "wiktku-dfn-subfield wiktku-start-narrow") .val(val); ta.on("input", function () { steps.dfn.onSubInput(subList, this, 1, true); }); subList.append($("<li></li>").append(ta)); } }); } // Reveal and populate lazy groups that have data. var lazyMap = { "wiktku-dfn-etiket": sense.etiket, "wiktku-dfn-kategori": sense.kategori, "wiktku-dfn-alternativ": sense.alternativ, "wiktku-dfn-hevmane": sense.hevmane, "wiktku-dfn-dijmane": sense.dijmane, "wiktku-dfn-koordine": sense.koordine, "wiktku-dfn-jornav": sense.jornav, "wiktku-dfn-jernav": sense.jernav }; $.each(lazyMap, function (cls, vals) { if (vals && vals.length) restoreSubList(cls, vals); }); // Nimûne items are objects { text, tr?, t? } — restore using the builder. if (sense.nimune && sense.nimune.length) { var nimuneGroupDiv = block.find(".wiktku-dfn-nimune-group"); var nimuneList = nimuneGroupDiv.find("ol.wiktku-dfn-nimune-list"); var buildFn = nimuneGroupDiv.data("buildNimuneLi"); nimuneList.empty(); $.each(sense.nimune, function (_, n) { var text = typeof n === "object" ? (n.text || "") : n; if (!text) return; var li = buildFn ? buildFn() : $("<li class='wiktku-dfn-nimune-li'></li>"); li.find(".wiktku-dfn-nimune-text").val(text); if (n.tr) li.find(".wiktku-dfn-nimune-tr").val(n.tr); if (n.t) li.find(".wiktku-dfn-nimune-t").val(n.t); nimuneList.append(li); }); // Always leave a blank trailing item. if (buildFn) nimuneList.append(buildFn()); } // Restore jêder (quote/citation) entries — a growing list, restored using the // builder just like Nimûne. Accepts either the current array shape or a // single legacy object (from older saved sections) for backwards compatibility. var jederArr = $.isArray(sense.jeder) ? sense.jeder : (sense.jeder ? [sense.jeder] : []); if (jederArr.length) { var jederGroupDiv = block.find(".wiktku-dfn-jeder-group"); var jederList = jederGroupDiv.find("ol.wiktku-dfn-jeder-list"); var buildJederFn = jederGroupDiv.data("buildJederLi"); jederList.empty(); $.each(jederArr, function (_, j) { if (!j || !j.quote) return; var li = buildJederFn ? buildJederFn() : $("<li class='wiktku-dfn-jeder-li'></li>"); li.find(".wiktku-dfn-nimune-quote").val(j.quote); if (j.quoteTr) li.find(".wiktku-dfn-nimune-quote-tr").val(j.quoteTr); if (j.quoteT) li.find(".wiktku-dfn-nimune-quote-t").val(j.quoteT); if (j.jederManual) { var manualSel = li.find(".wiktku-dfn-quote-src-sel"); manualSel.val("__manual__").trigger("change"); li.find(".wiktku-dfn-quote-src-manual").val(j.jederManual); } else if (j.jederTpl) { var srcSel = li.find(".wiktku-dfn-quote-src-sel"); srcSel.val(j.jederTpl).trigger("change"); if (j.jêderFields) { $.each(j.jêderFields, function (key, val) { li.find(".wiktku-dfn-quote-src-input[data-field-key='" + key + "']").val(val); }); } } jederList.append(li); }); // Always leave a blank trailing item, same as Nimûne. if (buildJederFn) jederList.append(buildJederFn()); } }); } /** * Snapshot simple (non-dfn) per-section steps from current DOM into obj. */ function saveCurrentSection() { var snap = {}; $.each(PER_SECTION_STEP_IDS, function (_, id) { if (id === "dfn") { snap.dfn = snapshotDfn(); return; } if (id === "etym") { snap.etym = $.trim($("#wiktku-start-etym .wiktku-etym-text").val()); return; } var step = steps[id]; if (!step) return; var stepDiv = $("#wiktku-start-" + id); if (id === "trans") { snap.trans = steps.trans.getTranslations(stepDiv); return; } if (id === "zarava") { snap.zarava = steps.zarava.getTranslations(stepDiv); return; } if (id === "dunde") { snap.dunde = steps.dunde.getRows(stepDiv); return; } // Generic: read all step fields. var fields = stepDiv.find(".wiktku-start-step-field"); if (step.multiple) { snap[id] = fields.map(function () { return $(this).val(); }).get(); } else { snap[id] = fields.val(); } }); sections[activeSection] = snap; } /** * Restore a previously saved snapshot into the form DOM. */ function restoreSection(snap) { $.each(PER_SECTION_STEP_IDS, function (_, id) { if (id === "dfn") { restoreDfn(snap.dfn || []); return; } if (id === "etym") { $("#wiktku-start-etym .wiktku-etym-wrap").remove(); steps.etym.build($("#wiktku-start-etym")); $("#wiktku-start-etym .wiktku-etym-text").val(snap.etym || ""); return; } if (id === "trans") { // Rebuild trans groups (dfn must already be restored by this // point in the $.each loop, so glossList() reflects it). var transDiv = $("#wiktku-start-trans"); transDiv.find(".wiktku-trans-group").remove(); steps.trans.build(transDiv); var groupsSnap = snap.trans || []; $.each(groupsSnap, function (gi, rows) { var group = transDiv.find(".wiktku-trans-group[data-gloss-pos='" + gi + "']"); if (!group.length) return; // gloss no longer exists — drop its rows var list = group.find("ul.wiktku-trans-list"); $.each(rows, function (j, row) { var lang = row[0], words = row[1]; var lastRow = list.find("li.wiktku-trans-row").last(); lastRow.find("select").val(lang).trigger("change"); var wordList = lastRow.find("ul.wiktku-trans-words"); $.each(words, function (k, word) { var wordItems = wordList.find("li"); if (k < wordItems.length) { wordItems.eq(k).find("textarea").val(word); } else { // .val() below doesn't fire "input", so the normal // auto-grow never runs — append a matching item // ourselves instead of silently dropping the word. var extraInput = steps.trans.makeWordInput(); wordList.append($("<li></li>").append(extraInput)); extraInput.val(word); } }); // Leave one trailing empty field so the row can still grow // when the user types, matching a freshly-built row. if ($.trim(wordList.children("li").last().find("textarea").val())) { wordList.append($("<li></li>").append(steps.trans.makeWordInput())); } }); }); return; } if (id === "zarava") { // Rebuild zarava groups (dfn must already be restored by this // point in the $.each loop, so glossList() reflects it). var zaravaDiv = $("#wiktku-start-zarava"); zaravaDiv.find(".wiktku-zarava-group").remove(); steps.zarava.build(zaravaDiv); var zaravaGroupsSnap = snap.zarava || []; $.each(zaravaGroupsSnap, function (gi, rows) { var group = zaravaDiv.find(".wiktku-zarava-group[data-gloss-pos='" + gi + "']"); if (!group.length) return; // gloss no longer exists — drop its rows var list = group.find("ul.wiktku-zarava-list"); $.each(rows, function (j, row) { var lang = row[0], words = row[1]; var lastRow = list.find("li.wiktku-zarava-row").last(); lastRow.find("select").val(lang).trigger("change"); var wordList = lastRow.find("ul.wiktku-zarava-words"); $.each(words, function (k, word) { var wordItems = wordList.find("li"); if (k < wordItems.length) { wordItems.eq(k).find("textarea").val(word); } else { var extraInput = steps.zarava.makeWordInput(); wordList.append($("<li></li>").append(extraInput)); extraInput.val(word); } }); if ($.trim(wordList.children("li").last().find("textarea").val())) { wordList.append($("<li></li>").append(steps.zarava.makeWordInput())); } }); }); return; } if (id === "dunde") { // Rebuild dunde rows. var dundeDiv = $("#wiktku-start-dunde"); dundeDiv.find("ul.wiktku-dunde-list").remove(); steps.dunde.build(dundeDiv); var dundeRows = snap.dunde || []; $.each(dundeRows, function (i, row) { var lang = row[0], words = row[1]; var list = dundeDiv.find("ul.wiktku-dunde-list"); var lastRow = list.find("li.wiktku-dunde-row").last(); lastRow.find("select").val(lang).trigger("change"); var wordList = lastRow.find("ul.wiktku-dunde-words"); $.each(words, function (j, word) { var wordItems = wordList.find("li"); if (j < wordItems.length) { wordItems.eq(j).find("textarea").val(word); } else { // .val() below doesn't fire "input", so the normal // auto-grow never runs — append a matching item // ourselves instead of silently dropping the word. var extraInput = steps.dunde.makeWordInput(); wordList.append($("<li></li>").append(extraInput)); extraInput.val(word); } }); // Leave one trailing empty field so the row can still grow // when the user types, matching a freshly-built row. if ($.trim(wordList.children("li").last().find("textarea").val())) { wordList.append($("<li></li>").append(steps.dunde.makeWordInput())); } }); return; } var step = steps[id]; if (!step) return; var stepDiv = $("#wiktku-start-" + id); var fields = stepDiv.find(".wiktku-start-step-field"); var val = snap[id]; if (val === undefined || val === null) return; if (step.multiple) { var arr = val; fields.each(function (i) { if (i < arr.length) $(this).val(arr[i]); }); } else { fields.val(val); } // Notify chosen widgets of the programmatic value change. if (!isMobile) fields.filter("select").trigger("chosen:updated"); }); } function getWikitextForCurrentSection(callback) { var values = getValues(); var entry = steps.pos.output(values); steps.dfn.getOutput(values, function (output) { entry += output; entry += steps.je.output(values); entry += steps.tekildar.output(values); entry += steps.etym.output(values); entry += steps.dunde.output(values); entry += steps.binereherwiha.output(values); entry += steps.zarava.output(values); entry += steps.trans.output(values); callback(entry, values); }); } function getWikitextAllSections(callback) { saveCurrentSection(); var results = new Array(sections.length); var sharedValues = getValues(); // lang/pron are shared function processSection(i) { if (i >= sections.length) { // All done — restore original active section. restoreSection(sections[activeSection]); refresh(); callback(results, sharedValues); return; } restoreSection(sections[i]); refresh(); getWikitextForCurrentSection(function (sectionText) { results[i] = sectionText; processSection(i + 1); }); } processSection(0); } /** * Assembles wikitext for all sections plus the shared lang/pron header. */ function getWikitext(callback) { getWikitextAllSections(function (sectionTexts, sharedValues) { var entry = steps.lang.output(sharedValues); entry += steps.pron.output(sharedValues); entry += sectionTexts.join("\n"); // Edit summary uses section 0's values. Read from the saved snapshot // (not the live DOM) so it doesn't mix section 0's pos with whichever // section happens to be active/restored at this point. var dfnSenses = (sections[0] && sections[0].dfn) || []; var dfnSummary = dfnSenses.map(function (s) { return s.mane; }).filter(Boolean).join("; "); var summary = "([[Mediawiki:Gadget-start.js|WF:NÛ]] v.2.0) +" + sharedValues.lang + ":" + sections[0].pos + ":" + dfnSummary; var summaryField = document.getElementById("wpSummary"); if (addLangMode && summaryField.value) { summary = summaryField.value + " " + summary; } summaryField.value = summary; callback(entry); }); } var continueBtn; function getValuesForStep(stepId) { var fields = $("#wiktku-start-" + stepId + " .wiktku-start-step-field"); var step = steps[stepId]; if (step.keys) { var values = {}; fields.each(function (i, field) { var key = $(field).prevAll(".wiktku-start-step-keyfield").val(); if (key) values[key] = $(field).val(); }); return values; } else if (step.multiple) { return fields.map(function () { return $(this).val(); }).get(); } return fields.val(); } function getValues() { var values = {}; $.each(steps, function (stepId) { values[stepId] = getValuesForStep(stepId); }); return values; } function populateMenus(inputs, choices, disabledValues) { if (!disabledValues) disabledValues = {}; var vals = inputs.map(function (i, input) { return $(input).val(); }); inputs.empty(); inputs.append($("<option></option>")); $.each(choices, function (j, choice) { // Append the language code in parentheses so that typing a code // (e.g. "ku") in the search box still finds the language name. var displayText = capitalize(choice[1]); if (choice[2] !== undefined) { // This is a language choice [code, name, sortKey] — show code. displayText = capitalize(choice[1]) + " (" + choice[0] + ")"; } var option = $(mw.html.element("option", { value: choice[0] }, displayText)); if (disabledValues[choice[0]]) option.prop("disabled", true); inputs.append(option); }); inputs.val(function (i) { return vals[i]; }); } /** * Returns a bitmap containing the keys that should be disabled for a key * menu in the given step because they are disabled or already taken by * another key menu. */ function getDisabledKeys(step) { var occupiedKeys = {}; $("#wiktku-start-" + step.id + " .wiktku-start-step-keyfield").each(function () { occupiedKeys[$(this).val()] = true; }); if (step.disabledKeys) $.extend(occupiedKeys, step.disabledKeys); return occupiedKeys; } function buildKeyInput(step) { if (!step.keys) return undefined; var input = $(mw.html.element("select", { "class": "wiktku-start-step-keyfield wiktku-start-narrow" })); input.attr("data-placeholder", "Hilbijêre " + step.keyName); if (isMobile) { populateMenus(input, step.keys, getDisabledKeys(step)); // On mobile return the wrapper; the select is inside it. // Change events still fire on the inner select. return wrapNativeSelect(input); } input.on("chosen:showing_dropdown", function () { $(this).data("wiktku-defaultValue", $(this).val()); }); input.change(function (_, context) { var inputs = $("#wiktku-start-" + step.id + " .wiktku-start-step-keyfield").not(this); var oldValue = $(this).data("wiktku-defaultValue"); var newValue = context.selected; inputs.find("option[value='" + oldValue + "']").prop('disabled', false); inputs.find("option[value='" + newValue + "']").prop('disabled', true); inputs.trigger("chosen:updated"); }); populateMenus(input, step.keys, getDisabledKeys(step)); return input; } /** * If the current text field has text and there are no more text fields after * the current text field in the list, add another text field to the list. */ function refreshForTextField(currentInput, step) { currentInput = $(currentInput); var value = currentInput.val(); var item = currentInput.parent(); if (value && !item.next("li").length) { var nextInput = $("<textarea></textarea>") .attr("name", "wiktku-field-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("class", currentInput.attr("class")) .attr("rows", currentInput.attr("rows") || 1); nextInput.on("input", function (evt) { refreshForTextField(evt.target, step); }); var nextKeyInput = buildKeyInput(step); var nextItem = $("<li></li>").append(nextKeyInput).append(nextInput); item.parent().append(nextItem); if (nextKeyInput) nextKeyInput.chosen(chosenOptions); } var canContinue = !continueBtn.isDisabled(); if ((value && !canContinue) || (!value && canContinue)) { refresh(step); } } function prepareInput(input, step) { if (!input) return; if (step.required) input.prop('required', true); input.change(step, refresh); } /** * Shows and hides all the steps based on whether their prerequisites are met, * and updates placeholders where applicable. */ function refresh(evt) { var values = getValues(); var changedStep = evt && evt.data; var didFocus = false; var canContinue = true; // Re-filter template options in every sense block whenever lang changes. $("#wiktku-start-dfn .wiktku-dfn-tpl-select").each(function () { var fn = $(this).data("updateOptions"); if (typeof fn === "function") fn(); }); // Re-filter pronunciation and etymology template dropdowns when language changes. steps.pron.refreshTplSelect(); steps.etym.refreshTplSelect(); // Sync tr/t sub-fields in every nimûne item to the current language. // tr shown when language needs transliteration; t shown when lang !== "ku". (function () { var lang = values.lang || ""; var showTr = needsTransliteration(lang); var showT = lang && lang !== "ku"; $("#wiktku-start-dfn .wiktku-dfn-nimune-list li.wiktku-dfn-nimune-li").each(function () { var li = $(this); // Ensure the sub-wrapper exists when we need it. var subWrap = li.find(".wiktku-dfn-nimune-sub"); // tr field var trTa = li.find(".wiktku-dfn-nimune-tr"); if (showTr && !trTa.length) { if (!subWrap.length) { subWrap = $("<div></div>").addClass("wiktku-dfn-nimune-sub"); li.append(subWrap); } trTa = $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-tr-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 5) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-tr") .attr("placeholder", "Transkrîpsiyon…"); subWrap.prepend(trTa); } else if (!showTr && trTa.length) { trTa.remove(); } // t field var tTa = li.find(".wiktku-dfn-nimune-t"); if (showT && !tTa.length) { if (!subWrap.length) { subWrap = $("<div></div>").addClass("wiktku-dfn-nimune-sub"); li.append(subWrap); } tTa = $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-t-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 5) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-t") .attr("placeholder", "Tercimeya nimûneyê kurmancî…"); subWrap.append(tTa); } else if (!showT && tTa.length) { tTa.remove(); } // Remove the wrapper if it ended up empty. subWrap = li.find(".wiktku-dfn-nimune-sub"); if (subWrap.length && !subWrap.children().length) subWrap.remove(); }); }()); // Sync tr/t sub-fields in every jêder citation to the current language. // tr shown when language needs transliteration; t shown when lang !== "ku". (function () { var lang = values.lang || ""; var showTr = needsTransliteration(lang); var showT = lang && lang !== "ku"; $("#wiktku-start-dfn .wiktku-dfn-jeder-list li.wiktku-dfn-jeder-li").each(function () { var li = $(this); // Ensure the sub-wrapper exists when we need it. It must sit right // after the quote textarea and before the source selector. var subWrap = li.find(".wiktku-dfn-quote-sub"); // tr field var trTa = li.find(".wiktku-dfn-nimune-quote-tr"); if (showTr && !trTa.length) { if (!subWrap.length) { subWrap = $("<div></div>").addClass("wiktku-dfn-quote-sub"); li.find(".wiktku-dfn-nimune-quote").after(subWrap); } trTa = $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-quote-tr-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 2) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-quote-tr") .attr("placeholder", "Transkrîpsiyona jêgirtinê…"); subWrap.prepend(trTa); } else if (!showTr && trTa.length) { trTa.remove(); } // t field var tTa = li.find(".wiktku-dfn-nimune-quote-t"); if (showT && !tTa.length) { if (!subWrap.length) { subWrap = $("<div></div>").addClass("wiktku-dfn-quote-sub"); li.find(".wiktku-dfn-nimune-quote").after(subWrap); } tTa = $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-quote-t-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 2) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-quote-t") .attr("placeholder", "Tercimeya jêgirtinê ya kurmancî…"); subWrap.append(tTa); } else if (!showT && tTa.length) { tTa.remove(); } // Remove the wrapper if it ended up empty. subWrap = li.find(".wiktku-dfn-quote-sub"); if (subWrap.length && !subWrap.children().length) subWrap.remove(); }); }()); $.each(steps, function (stepId, step) { if (typeof(step.visible) === "function" && !step.visible(values)) { $("#wiktku-start-" + stepId).slideUp(); } else { var stepDiv = $("#wiktku-start-" + stepId); if (changedStep !== step && typeof(step.build) === "function") { prepareInput(step.build(stepDiv, values), step); } var input = stepDiv.find(".wiktku-start-step-field"); if (typeof(step.example) === "function") { // .find() above already reaches nested fields (e.g. the dfn // step's mane textareas inside each sense block), so one // assignment covers every step; dfn keeps its own fallback. var exampleText = step.example(values) || (step.id === "dfn" ? "Mane…" : ""); input.attr("placeholder", exampleText); } var didSlideDown; if (!didFocus && stepDiv.css("display") === "none" && step.required) { didSlideDown = function (evt) { input.focus(); }; didFocus = true; } stepDiv.slideDown(didSlideDown); } if (step.required && (values[stepId] === "" || (step.multiple && values[stepId].join("") === ""))) { canContinue = false; } }); continueBtn.setDisabled(!canContinue); } function destroy() { $("#wiktku-start-form, .noafterwizard").slideUp(function () { $(this).remove(); }); $(".noarticletext .nowizard, #editform").slideDown(); $("#ca-edit").removeClass("selected"); $("#ca-wiktku-nowizard").addClass("selected"); } // Priority order for Kurdish dialects and the navz pseudo-code. // Codes listed here come before all other languages; unlisted codes // are sorted alphabetically by their display name via localeCompare. var LANG_PRIORITY = ["navz", "ku", "hac", "sdh", "lki", "ckb", "zza"]; /** * Inserts a new == {{ziman|code}} == section into existing page wikitext * at the correct sorted position: * 1. Any content before the first language section is preserved at the top. * 2. navz is always first, then ku/hac/sdh/lki/ckb/zza in that order, * then all other languages sorted by display name (localeCompare). */ function insertNewLangSection(existing, wikitext) { var newCodeMatch = wikitext.match(/^== \{\{ziman\|([^}]+)\}\} ==/); var newCode = newCodeMatch ? newCodeMatch[1] : ""; var sections = []; var preamble = ""; var firstMatch = existing.match(/(?:^|\n)== \{\{ziman\|/); if (!firstMatch) { // No existing lang sections at all — just append. var sep = existing && !/\n\s*$/.test(existing) ? "\n\n" : ""; return existing + sep + wikitext; } // Everything before the first == {{ziman|...}} == is the preamble. var firstSectionStart = existing.indexOf("== {{ziman|"); // Walk back to the start of that line. var lineStart = existing.lastIndexOf("\n", firstSectionStart - 1); var preambleEnd = lineStart !== -1 ? lineStart + 1 : 0; preamble = existing.slice(0, preambleEnd); // Parse each language section: header line + everything until the next header. var body = existing.slice(preambleEnd); // NOTE: with the /m flag, a bare "$" matches end-of-*line*, not just // end-of-string — that previously made the non-greedy content group // stop at the section's first line break instead of running to the // next language header (or the real end of the text), silently // dropping the rest of that section's wikitext. (?![\s\S]) matches // only the true end of the string, /m flag or not. var langSectionRe = /^(== \{\{ziman\|([^}]+)\}\} ==\n?)([\s\S]*?)(?=\n== \{\{ziman\||(?![\s\S]))/gm; var m; while ((m = langSectionRe.exec(body)) !== null) { sections.push({ code: m[2], content: m[0] // full text of this section including header }); } // Determine sort rank: priority list first (by index), then alphabetical. function getLangName(code) { var entry = langsByCode[code]; return entry ? entry[1] : code; } function sortRank(code) { var idx = LANG_PRIORITY.indexOf(code); return idx !== -1 ? idx : LANG_PRIORITY.length; } function compareLangs(a, b) { var ra = sortRank(a), rb = sortRank(b); if (ra !== rb) return ra - rb; // Both are outside priority list — sort by display name. return getLangName(a).localeCompare(getLangName(b), userLang); } // Insert the new section into the sorted list. var newSection = { code: newCode, content: wikitext }; var inserted = false; for (var i = 0; i < sections.length; i++) { if (compareLangs(newCode, sections[i].code) < 0) { sections.splice(i, 0, newSection); inserted = true; break; } } if (!inserted) sections.push(newSection); // Re-join: preamble + sections separated by newlines. var joined = sections.map(function (s) { // Ensure each section ends with exactly one newline before the next. return s.content.replace(/\n+$/, ""); }).join("\n"); return preamble + joined + "\n"; } function build() { $(".nowizard, .nowizard .noafterwizard").hide(); var callToAction = $("#wiktku-calltoaction"); var origCallToActionText = callToAction.text(); $(mw.util.addPortletLink("p-views", "#", "Edîtora çavkaniyê veke", "ca-wiktku-nowizard", "Vê rûpelê bi edîtora çavkaniyê çêke", undefined, "#ca-watch")).click(function (evt) { evt.preventDefault(); callToAction.text(origCallToActionText); destroy(); }); if (callToAction.length) { callToAction.text(origCallToActionText + " Forma li jêr ji bo çêkirina madeyeke nû bi kar bîne."); } var startForm = $("<form id='wiktku-start-form'></form>"); var clearPageCheck = null; if (addLangMode) { startForm.append($("<p class='wiktku-addlang-notice'></p>").html( "Bi vê formê tu yê beşeke nû li rûpelê îlawe bikî. Eger ev zimanê ku tu îlawe dikî jixwe di rûpelê de hebe, beşa nû li dawiya vî zimanî dê were îlawekirin. " + "Ji kerema xwe netîceya dawî kontrol bikin, eger problemek derkeve, li <a href='" + mw.util.getUrl('Mediawiki talk:Gadget-start.js') + "'>nîqaşa vê amûrê</a> problemê ragihîne." )); clearPageCheck = $("<input type='checkbox' id='wiktku-clear-page-check'>"); var clearPageLabel = $("<label for='wiktku-clear-page-check'></label>") .text(" Naveroka rûpelê paqij bike (rûpelê ji nû ve binivîse)"); startForm.append( $("<p class='wiktku-addlang-notice'></p>") .append(clearPageCheck) .append(clearPageLabel) ); // Re-evaluate step visibility (e.g. the pron step) whenever this // is toggled, since it changes what counts as "existing content". clearPageCheck.on("change", function () { refresh(); }); } var spinner; // Tab bar for switching between POS sections. var sectionTabsDiv = $("<div id='wiktku-section-tabs'></div>"); startForm.submit(function (evt) { evt.preventDefault(); continueBtn.setDisabled(true); spinner.show(); getWikitext(function (wikitext) { if (addLangMode && clearPageCheck && clearPageCheck.prop("checked")) { // User asked to wipe the page and start fresh — just // write the newly generated wikitext as the full content. $("#wpTextbox1").val(wikitext); } else if (addLangMode) { var textbox = $("#wpTextbox1"); var existing = textbox.val() || ""; // Check whether the generated lang header already exists in the page. // wikitext always starts with "== {{ziman|CODE}} ==\n" (from steps.lang.output). // If that exact section heading is already present in the existing content, // strip it from the new output and insert the remaining content at the end // of that lang section (just before the next == level-2 heading, or at the // very end of the page if there is no following section). var langHeaderMatch = wikitext.match(/^(== \{\{ziman\|[^}]+\}\} ==\n)/); if (langHeaderMatch) { var langHeader = langHeaderMatch[1]; // e.g. "== {{ziman|ku}} ==\n" // Escape for use in RegExp. var escapedHeader = langHeader.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); if (new RegExp(escapedHeader).test(existing)) { // Strip the header from the new output. var newContent = wikitext.slice(langHeader.length); // Find the insertion point: end of the existing lang section. // A new L2 heading marks the start of the next language block. var afterHeader = existing.indexOf(langHeader); var searchFrom = afterHeader + langHeader.length; // Find the next == … == heading after this section's start. var nextL2 = existing.indexOf("\n== ", searchFrom); var insertAt = nextL2 !== -1 ? nextL2 : existing.length; // Ensure there's a blank line before the inserted block. var before = existing.slice(0, insertAt); var after = existing.slice(insertAt); var sep = /\n\s*$/.test(before) ? "" : "\n"; textbox.val(before + sep + newContent + after); } else { // New language — insert at the correct sorted position. textbox.val(insertNewLangSection(existing, wikitext)); } } else { // Unexpected format — insert at sorted position anyway. textbox.val(insertNewLangSection(existing, wikitext)); } } else { $("#wpTextbox1").val(wikitext); } $("html, body").animate({scrollTop: 0}); callToAction.text("Hindik ma!"); $("#wiktku-preview-container").remove(); destroy(); }); }); $.each(ordered_steps, function (i, step) { var stepDiv = $(mw.html.element("div", { "class": "wiktku-start-step", id: "wiktku-start-" + step.id })); var name = capitalize(step.name); stepDiv.append($(mw.html.element("h3", { "class": "wiktku-start-step-name" }, new mw.html.Raw(mw.html.element("label", { "for": "wiktku-start-" + step.id + "-field" }, name))))); if (step.question_fmt) { stepDiv.append($(mw.html.element("label", { "class": "wiktku-start-step-question", "for": "wiktku-start-" + step.id + "-field" }, step.question_fmt))); if (step.question_br) stepDiv.append($("<br>")); } var input; if (step.choices) { input = $(mw.html.element("select", { "class": "wiktku-start-step-field", id: "wiktku-start-" + step.id + "-field" })); input.attr("data-placeholder", capitalize(step.name) + " hilbijêre "); populateMenus(input, step.choices); if (step.multiple) input.attr("multiple", true); if (isMobile) { stepDiv.append(wrapNativeSelect(input)); } else { stepDiv.append(input); } } else if (typeof(step.build) === "function") { input = step.build(stepDiv); } else { input = $("<textarea></textarea>") .attr("class", "wiktku-start-step-field") .attr("id", "wiktku-start-" + step.id + "-field") .attr("rows", step.rows || 2); if (step.narrow) input.addClass("wiktku-start-narrow"); if (step.multiple) { input.on("input", function (evt) { refreshForTextField(evt.target, step); }); var keyInput = buildKeyInput(step); var list = $(step.ordered ? "<ol></ol>" : "<ul></ul>") .append($("<li></li>").append(keyInput).append(input)); stepDiv.append(list); } else stepDiv.append(input); } prepareInput(input, step); stepDiv.hide(); // Insert tab bar just before the first per-section step. if (step.id === "pos") startForm.append(sectionTabsDiv); startForm.append(stepDiv); }); // ── Section tab helpers ────────────────────────────────────────────── // ── Add-section button — lives in the tab bar, disabled until pos chosen ── var addSectionBtn = new OO.ui.ButtonWidget({ label: "+ Beş zêde bike", disabled: true }); addSectionBtn.on("click", function () { saveCurrentSection(); sections.push({}); activeSection = sections.length - 1; $.each(PER_SECTION_STEP_IDS, function (_, id) { if (id === "dfn") { var stepDiv = $("#wiktku-start-dfn"); stepDiv.find("ol.wiktku-dfn-list").remove(); steps.dfn.build(stepDiv); return; } if (id === "etym") { $("#wiktku-start-etym .wiktku-etym-wrap").remove(); steps.etym.build($("#wiktku-start-etym")); return; } if (id === "trans") { var transDiv = $("#wiktku-start-trans"); transDiv.find(".wiktku-trans-group").remove(); return; } if (id === "zarava") { var zaravaDiv = $("#wiktku-start-zarava"); zaravaDiv.find(".wiktku-zarava-group").remove(); return; } if (id === "dunde") { var dundeDiv = $("#wiktku-start-dunde"); dundeDiv.find("ul.wiktku-dunde-list").remove(); return; } var stepDiv = $("#wiktku-start-" + id); stepDiv.find(".wiktku-start-step-field").val(""); if (!isMobile) stepDiv.find("select.wiktku-start-step-field").trigger("chosen:updated"); }); renderSectionTabs(); refresh(); $("html, body").animate({ scrollTop: sectionTabsDiv.offset().top - 20 }, 300); }); /** Re-render the tab bar to reflect current sections[] and activeSection. */ function renderSectionTabs() { // Detach (not remove) the button first: .empty() strips bound // event data from any children left inside it, which would // silently kill addSectionBtn's click handler on every re-render. addSectionBtn.$element.detach(); sectionTabsDiv.empty(); var lang = getValues().lang || ""; if (!lang) { sectionTabsDiv.hide(); return; } sectionTabsDiv.show(); $.each(sections, function (i) { var posVal = sections[i].pos || ""; var tabLabel = posVal ? capitalize(posVal) : ("Beş " + (i + 1)); var tab = $("<span></span>") .addClass("wiktku-section-tab") .text(tabLabel) .toggleClass("wiktku-tab-active", i === activeSection); (function (idx) { tab.on("click", function () { if (idx === activeSection) return; saveCurrentSection(); activeSection = idx; restoreSection(sections[activeSection]); refresh(); renderSectionTabs(); }); }(i)); sectionTabsDiv.append(tab); }); // Enable "Beş zêde bike" only when the active section has a pos chosen. var activePos = sections[activeSection] && sections[activeSection].pos ? sections[activeSection].pos : getValues().pos; addSectionBtn.setDisabled(!activePos); sectionTabsDiv.append(addSectionBtn.$element); } renderSectionTabs(); // Update the active tab's label whenever pos changes. startForm.on("change", "#wiktku-start-pos-field", function () { renderSectionTabs(); }); // Show the tab bar as soon as a language is selected. startForm.on("change", "#wiktku-start-lang-field", function () { renderSectionTabs(); }); var footer = $("<div id='wiktku-start-footer'></div>"); spinner = $(mw.html.element("img", { id: "wiktku-start-spinner", src: "//upload.wikimedia.org/wikipedia/commons/d/de/Ajax-loader.gif", alt: "Tê barkirin…", title: "Tê barkirin…" })); footer.append(spinner.hide()); continueBtn = new OO.ui.ButtonWidget({ id: "wiktku-unhide-editform", label: "Bişîne", flags: [ "primary", "progressive" ] }); continueBtn.on("click", function () { mw.notify("Tê şandin…", { type: "info", tag: "wiktku-submit" }); startForm.trigger("submit"); }); footer.append(continueBtn.$element); // "Edîtora çavkaniyê veke" button — inline fallback for the portlet link // which is invisible on mobile and easy to miss on desktop. var sourceEditorBtn = new OO.ui.ButtonWidget({ label: "Edîtora çavkaniyê veke", framed: false }); sourceEditorBtn.on("click", function () { destroy(); }); footer.append(sourceEditorBtn.$element); // ── Preview checkboxes ─────────────────────────────────────────────── // Wikitext preview (raw text panel) var previewCheck = $("<input type='checkbox' id='wiktku-preview-toggle'>"); var previewLabel = $("<label for='wiktku-preview-toggle'></label>") .text(" Pêşdîtina wîkîtekstê"); var previewPanel = $("<pre id='wiktku-preview-panel'></pre>").hide(); // Live rendered preview (parsed HTML panel, same logic as AjaxEdit). // Not available on mobile — API polling causes too many problems on small screens. var livePreviewCheck = null; var livePreviewPanel = null; if (!isMobile) { livePreviewCheck = $("<input type='checkbox' id='wiktku-live-preview-toggle'>"); livePreviewPanel = $("<div id='wiktku-live-preview-panel'></div>").hide(); } // Container that holds both panels and switches between stacked / side-by-side. var previewContainer = $("<div id='wiktku-preview-container'></div>"); previewContainer.append(previewPanel); if (!isMobile) previewContainer.append(livePreviewPanel); var previewTimer = null; var livePreviewIntervalId = -1; var livePreviewActive = false; // guards in-flight fetches after uncheck /** Rebuilds wikitext preview if its checkbox is checked. */ function schedulePreview() { if (!previewCheck.prop("checked")) return; clearTimeout(previewTimer); // Debounce: wait 400 ms after the last keystroke before rebuilding. previewTimer = setTimeout(function () { getWikitext(function (wikitext) { previewPanel.text(wikitext).show(); updatePanelLayout(); }); }, 400); } /** Fetches parsed HTML and populates the live preview panel. */ function loadLivePreview() { getWikitext(function (wikitext) { new mw.Api().parse(wikitext, { title: mw.config.get("wgPageName") }).done(function (html) { // Discard result if the user unchecked while the fetch was in flight. if (!livePreviewActive) return; livePreviewPanel.html(html).show(); updatePanelLayout(); }); }); } /** Adjusts panel widths depending on which previews are visible. */ function updatePanelLayout() { var wikitextVisible = previewCheck.prop("checked"); var liveVisible = livePreviewCheck && livePreviewCheck.prop("checked"); if (wikitextVisible && liveVisible) { // Side by side — each panel takes roughly half the available width. previewPanel.css({ "flex": "1 1 45%", "min-width": "280px" }); livePreviewPanel.css({ "flex": "1 1 45%", "min-width": "280px" }); } else { // Full width for whichever is visible — only touch panels that are // actually shown so that setting flex doesn't override display:none. if (wikitextVisible) previewPanel.css({ "flex": "1 1 100%", "min-width": "" }); if (liveVisible && livePreviewPanel) livePreviewPanel.css({ "flex": "1 1 100%", "min-width": "" }); } } previewCheck.on("change", function () { if ($(this).prop("checked")) { schedulePreview(); } else { clearTimeout(previewTimer); previewPanel.hide(); updatePanelLayout(); } }); if (!isMobile) { livePreviewCheck.on("change", function () { if ($(this).prop("checked")) { livePreviewActive = true; livePreviewPanel.show(); loadLivePreview(); livePreviewIntervalId = setInterval(loadLivePreview, 500); } else { livePreviewActive = false; clearInterval(livePreviewIntervalId); livePreviewIntervalId = -1; livePreviewPanel.hide().empty(); updatePanelLayout(); } }); } // Listen on all input/change events on the form and update both previews. startForm.on("input change", function () { schedulePreview(); }); footer.append($("<span style='margin-left:1em'></span>") .append(previewCheck).append(previewLabel)); if (!isMobile) { var livePreviewLabel = $("<label for='wiktku-live-preview-toggle'></label>") .text(" Pêşdîtina zindî"); footer.append($("<span style='margin-left:1em'></span>") .append(livePreviewCheck).append(livePreviewLabel)); } startForm.append(footer); $("#editform").hide().before(startForm); // Insert preview container (holds both panels) after the form. startForm.after(previewContainer); if (!isMobile) startForm.find("select").chosen(chosenOptions); refresh(); // Zimanan ji MediaWiki:Gadget-translation_editor.js/ziman.json bar bike. // Kodên ku bi "-pro" diqedin û navên ku "zimanê destan" tê de heye // tên derxistin. Zimanên xardkirî li serî dimînin, yên din // bi alfabeyê li dû wan tên. // Pinned choices come from MediaWiki:Gadget-start.js/data.json (langChoices), // already loaded into steps.lang.choices before build() runs. var pinnedChoices = steps.lang.choices.slice(); var pinnedCodes = $.map(pinnedChoices, function (choice) { return choice[0]; }); new mw.Api().get({ action: "query", prop: "revisions", titles: "MediaWiki:Gadget-translation_editor.js/ziman.json", rvprop: "content", rvslots: "main", formatversion: 2 }).then(function (data) { var page = data.query.pages[0]; var content = page && page.revisions && page.revisions[0].slots.main.content; var zimanData; try { zimanData = JSON.parse(content); } catch (e) { zimanData = {}; } var extraChoices = []; $.each(zimanData, function (code, name) { // Filter: skip proto-language codes and legendary/reconstructed langs. if (/-pro$/i.test(code)) return; if (/ziman[eê]\s+destan/i.test(name)) return; // Skip codes already in the pinned list (they are handled above). if (pinnedCodes.indexOf(code) !== -1) return; // sortKey: bare name without leading "zimanê " for sorting. var sortKey = name.replace(/^ziman[eê]\s+/i, ""); var choice = [code, name, sortKey]; extraChoices.push(choice); langsByCode[code] = choice; }); // Populate langsByCode for pinned choices too. $.each(pinnedChoices, function (i, choice) { // Ensure pinned choices have a sortKey (index 2). if (choice.length < 3) choice[2] = choice[1]; langsByCode[choice[0]] = choice; }); // Sort the extra choices alphabetically by sort key. extraChoices.sort(function (a, b) { return a[2].localeCompare(b[2], userLang); }); // Final list: pinned first, then the rest. var allChoices = pinnedChoices.concat(extraChoices); steps.lang.choices = allChoices; steps.trans.keys = allChoices; steps.dunde.keys = allChoices; steps.zarava.keys = getZaravaKeys(allChoices); var langMenu = $("#wiktku-start-lang-field"); populateMenus(langMenu, steps.lang.choices); langMenu.trigger("chosen:updated"); var transMenus = $("#wiktku-start-trans .wiktku-start-step-keyfield"); populateMenus(transMenus, steps.trans.keys, getDisabledKeys(steps.trans)); transMenus.trigger("chosen:updated"); var dundeMenus = $("#wiktku-start-dunde .wiktku-start-step-keyfield"); populateMenus(dundeMenus, steps.dunde.keys, getDisabledKeys(steps.dunde)); dundeMenus.trigger("chosen:updated"); var zaravaMenus = $("#wiktku-start-zarava .wiktku-start-step-keyfield"); populateMenus(zaravaMenus, steps.zarava.keys, getDisabledKeys(steps.zarava)); }); } mw.loader.using(["jquery.chosen", "mediawiki.api", "oojs-ui-core"], function () { if (!isMobile) { mw.notify( "Amûr dest pê dike, hinek bisekinin. Not: jkx Sentaks (sentaks highlighter) neaktîv bikin", { type: "info", tag: "wiktku-start-notice", autoHide: true, autoHideSeconds: 10 } ); } // Load metadata, langChoices, posChoices and tplDefs from the companion // data page so they can be updated without touching this script. new mw.Api().get({ action: "query", prop: "revisions", titles: "MediaWiki:Gadget-start.js/data.json", rvprop: "content", rvslots: "main", formatversion: 2 }).then(function (data) { var page = data.query.pages[0]; var content = page && page.revisions && page.revisions[0].slots.main.content; var d; try { d = JSON.parse(content); } catch (e) { d = {}; } // Populate metadata. if (d.metadata) $.extend(metadata, d.metadata); // Populate gender labels. if (d.genderLabels) $.extend(GENDER_BASE_LABELS, d.genderLabels); // Populate lang choices (pinned list used by build() → ziman.json loader). if (d.langChoices) steps.lang.choices = d.langChoices; // Populate POS choices. if (d.posChoices) steps.pos.choices = d.posChoices; // Populate template definitions for the dfn sense-block builder. if (d.tplDefs) steps.dfn.tplDefs = d.tplDefs; // Populate pos placeholder examples. if (d.posExamples) steps.dfn.posExamples = d.posExamples; // Populate citation template definitions for the quote widget. if (d.jederDefs) steps.dfn.jederDefs = d.jederDefs; // Populate pronunciation and etymology template insert lists. if (d.pronTpls) { steps.pron.pronTpls = d.pronTpls; steps.pron.refreshTplSelect(); } if (d.etymTpls) { steps.etym.etymTpls = d.etymTpls; steps.etym.refreshTplSelect(); } // Sync trans/dunde/zarava keys with the (now populated) lang choices. steps.trans.keys = steps.lang.choices; steps.dunde.keys = steps.lang.choices; steps.zarava.keys = getZaravaKeys(steps.lang.choices); }).always(build); }); }); //</nowiki> msm8fekiol4t7z5sja8dw4oyy5b002c 6265579 6265578 2026-07-19T14:58:09Z Wikihez 7344 6265579 javascript text/javascript // Li ser [[vi:MediaWiki:Gadget-start.js]] hatiye refaktorkirin. //<nowiki> $(function () { if (window.location.href.includes("editintro=User:Wikihez/creation/intro")) { return; // Do not run the script wextê WF:Bilez dişuxile } var ns = mw.config.get("wgNamespaceNumber"); if (ns && !(ns === 2 && mw.config.get("wgPageName").match(/\/ceribandin$|\/test$/))) { return; } var action = mw.config.get("wgAction"); var pageExists = !!mw.config.get("wgArticleId"); // "Zimanek lê zêde bike" mode: triggered from the portlet link below. var addLangMode = pageExists && mw.util.getParamValue("wiktkuaddlang") === "1"; // On a normal page view of an existing page, add the portlet link if (action === "view" && pageExists) { var targetContainer; var skin = mw.config.get('skin'); if (skin === 'vector-2022') { targetContainer = 'p-cactions'; } else if (skin === 'vector') { targetContainer = 'p-tb'; } else { targetContainer = 'p-views'; } mw.util.addPortletLink(targetContainer, mw.util.getUrl(mw.config.get("wgPageName"), { action: "submit", wiktkuaddlang: "1" }), "+Ziman/beşeke din", "ca-wiktku-addlang", "Ji vê rûpelê re ziman an jî beşeke nû zêde bike"); return; } if (!(action === "edit" || action === "submit")) { return; } if (!addLangMode && !$(".mw-newarticletext, .mw-newarticletextanon").length) { return; } function capitalize(str) { if (!str) return str; return str[0].toUpperCase() + str.substr(1); } function decapitalize(str) { if (!str) return str; return str[0].toLowerCase() + str.substr(1); } function escapeRegExp(str) { return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); } function stripWikilinks(str) { return str.replace(/\[\[([^\]|]+)(?:\|([^\]]+))?\]\]/g, function (m, target, display) { return display || target; }); } function insertAtCursor(el, text) { var start = el.selectionStart; var end = el.selectionEnd; var val = el.value; el.value = val.slice(0, start) + text + val.slice(end); var pos = start + text.length; el.selectionStart = el.selectionEnd = pos; } var pageName = mw.config.get("wgPageName").replaceAll(/_/g, " "); if (ns) pageName = pageName.replace(/.*\//, ""); var pageNameRe = escapeRegExp(pageName); var userLang = mw.config.get("wgUserLanguage"); // Mobile detection: MobileFrontend sets wgMFMode, or fall back to touch check. var isMobile = !!mw.config.get("wgMFMode") || window.matchMedia("(pointer: coarse)").matches; var chosenOptions = { width: "20em", disable_search_threshold: 0, placeholder_text_single: "Yekî hilbijêre", placeholder_text_multiple: "Hilbijêre", no_results_text: "Nehat dîtin", enable_split_word_search: true, search_contains: true }; function wrapNativeSelect(select) { var placeholder = select.attr("data-placeholder") || "Lê bigere…"; // Hide the native select — we drive it programmatically. select.hide(); var wrapper = $("<span class='wiktku-native-select-wrap'></span>"); var textInput = $("<input type='search' autocomplete='off'>") .attr("placeholder", placeholder) .addClass("wiktku-start-narrow wiktku-ac-input"); var resultsList = $("<ul class='wiktku-ac-results'></ul>").hide(); // Full option cache — rebuilt when chosen:updated fires. var allOptions = []; function cacheOptions() { allOptions = []; select.find("option").each(function () { var v = $(this).val(); if (!v) return; // skip the empty placeholder option allOptions.push({ value: v, text: $(this).text(), disabled: $(this).prop("disabled") }); }); } cacheOptions(); function showResults(query) { var q = query.trim().toLowerCase(); resultsList.empty(); var matched; if (q) { matched = []; $.each(allOptions, function (_, o) { if (o.disabled) return; var codeMatch = o.value.toLowerCase().indexOf(q) !== -1; var nameMatch = o.text.toLowerCase().indexOf(q) !== -1; if (codeMatch || nameMatch) { matched.push({ opt: o, codeMatch: codeMatch }); } }); // Code matches (especially prefix matches) come first. matched.sort(function (a, b) { var aCode = a.opt.value.toLowerCase(); var bCode = b.opt.value.toLowerCase(); var aPrefix = aCode.indexOf(q) === 0; var bPrefix = bCode.indexOf(q) === 0; if (aPrefix !== bPrefix) return aPrefix ? -1 : 1; if (a.codeMatch !== b.codeMatch) return a.codeMatch ? -1 : 1; return 0; }); matched = matched.map(function (item) { return item.opt; }); } else { matched = allOptions.filter(function (o) { return !o.disabled; }); } if (!matched.length) { resultsList.hide(); return; } $.each(matched.slice(0, 50), function (_, opt) { var li = $("<li></li>").text(opt.text).attr("data-value", opt.value); // Use touchend instead of touchstart so that a scroll gesture does // not accidentally select an item. We track whether the finger moved // between touchstart and touchend — if it did, it was a scroll. var touchMoved = false; li.on("touchstart", function () { touchMoved = false; }); li.on("touchmove", function () { touchMoved = true; }); li.on("touchend", function (e) { if (touchMoved) return; // was a scroll, not a tap e.preventDefault(); selectOption(opt.value, opt.text); }); // Keep mousedown for desktop fallback. li.on("mousedown", function (e) { e.preventDefault(); selectOption(opt.value, opt.text); }); resultsList.append(li); }); // Position the list above or below depending on available viewport space. var inputRect = textInput[0].getBoundingClientRect(); var viewportH = window.innerHeight; var spaceBelow = viewportH - inputRect.bottom - 8; var spaceAbove = inputRect.top - 8; var maxH = Math.min(224, Math.max(spaceBelow, spaceAbove)); // 224px ≈ 14em resultsList.css({ "max-height": maxH + "px", "top": spaceBelow >= spaceAbove ? "100%" : "auto", "bottom": spaceBelow >= spaceAbove ? "auto" : "100%" }); resultsList.show(); } function selectOption(value, text) { textInput.val(text); select.val(value); resultsList.hide(); select.trigger("change"); } textInput.on("input focus", function () { showResults($(this).val()); }); textInput.on("blur", function () { // Short delay so a touchstart on a result item fires first. setTimeout(function () { resultsList.hide(); }, 200); }); // chosen:updated → re-cache (called after ziman.json loads). select.on("chosen:updated", function () { cacheOptions(); // If a value is already selected, keep the display text in sync. var cur = select.val(); if (cur) { var match = $.grep(allOptions, function (o) { return o.value === cur; })[0]; if (match) textInput.val(match.text); } }); // No-op .chosen() so desktop call-sites don't need guarding. select.chosen = function () { return select; }; wrapper.append(textInput).append(resultsList).append(select); return wrapper; } var langsByCode = {}; // Populated from [[MediaWiki:Gadget-start.js/data.json]] at runtime. var metadata = {}; // Zaravayên kurdî yên ku di beşa "Bi zaravayên din" de tên pêşkêşkirin — // ev kod ji beşa Werger têne derxistin daku heman zimên du caran neyê xwendin. var ZARAVA_LANG_CODES = ["ckb", "sdh", "lki", "hac", "zza"]; function getZaravaKeys(choices) { var byCode = {}; $.each(choices || [], function (_, c) { byCode[c[0]] = c; }); var result = []; $.each(ZARAVA_LANG_CODES, function (_, code) { if (byCode[code]) result.push(byCode[code]); }); return result; } function needsTransliteration(langCode) { var meta = metadata[langCode]; if (!meta || !meta.sc) return false; var scripts = Array.isArray(meta.sc) ? meta.sc : [meta.sc]; return scripts.length > 0 && scripts[0] !== "Latn"; } // Kodên cinsiyetê yên di metadata.g de — ji data.json tê dagirtin var GENDER_BASE_LABELS = {}; // Sub-lists that only make sense for a plain (non-şablon) sense — hidden // when a şablon (e.g. {{guharto|…}}) is chosen for that sense, since a // template-based sense has no "own" gloss for alternate forms, synonyms, // antonyms, coordinate terms, hypernyms or hyponyms to attach to. Etîket, // Nimûne and Jêgirtin stay visible either way. var HIDDEN_ON_TPL_GROUPS = [ "wiktku-dfn-alternativ", "wiktku-dfn-hevmane", "wiktku-dfn-dijmane", "wiktku-dfn-koordine", "wiktku-dfn-jornav", "wiktku-dfn-jernav" ]; function genderLabel(code) { if (code === "p") return "Pirjimar"; var pluralMatch = code.match(/^(.+)-p$/); if (pluralMatch && GENDER_BASE_LABELS[pluralMatch[1]]) { return GENDER_BASE_LABELS[pluralMatch[1]] + " (pirjimar)"; } return GENDER_BASE_LABELS[code] || code; } /** * True if a sense has any content worth keeping besides its mane text — * etîket, hevmane/dijmane/koordîne/etc. word lists, nimûne, or jêder * (quote). Used so a sense with an empty mane but filled-in extra * fields still gets emitted (with {{mane?}} standing in for the gloss) * instead of being silently dropped. */ function senseHasExtraContent(s) { if (s.etiket && $.grep(s.etiket, function (e) { return $.trim(e) !== ""; }).length) return true; if (s.kategori && $.grep(s.kategori, function (k) { return $.trim(k) !== ""; }).length) return true; if (s.alternativ.length || s.hevmane.length || s.dijmane.length || s.koordine.length || s.jornav.length || s.jernav.length) return true; if (s.nimune && $.grep(s.nimune, function (n) { return (typeof n === "object" ? n.text : n) !== ""; }).length > 0) return true; if (senseHasJeder(s)) return true; return false; } /** * formatNimune: each nimûne item can be { text, tr, t }: * text — example text * tr — transliteration (only when the language needs it) * t — Kurdish translation (third positional param, no key) */ function formatNimune(nimunes, lang, hasJeder) { var hasNimune = nimunes && $.grep(nimunes, function (n) { return (typeof n === "object" ? n.text : n) !== ""; }).length > 0; if (!hasNimune) { return hasJeder ? "" : "\n#* {{bênimûne|" + lang + "}}"; } return $.map(nimunes, function (n) { var text = typeof n === "object" ? n.text : n; if (!text) return undefined; var bolded = text.replace( new RegExp("(" + pageNameRe + "([^( |,|;|\\?|\\.|\\!)]+)?)", "ig"), "'''$1'''"); var tpl = "\n#: {{nm|" + lang + "|" + bolded; if (typeof n === "object") { if (n.tr) tpl += "|tr=" + n.tr; // Translation as third positional param (no key needed). if (n.t) tpl += "|" + n.t; } // Short examples fit on one line together with their translation. // rêz=1 is not used for ku — definitions are shown on separate lines there. if (text.length < 200 && lang !== "ku") tpl += "|rêz=1"; tpl += "}}"; return tpl; }).join(""); } /** * Formats a list of jêder (quote/citation) objects into wikitext lines. * Each entry that has no quote text is skipped. Returns "" when the list * is empty or every entry is blank. * * #* {{jêder-…|lang|jêgirtin=…|tr=…|tercime=…|…fields…}} * * When no template is chosen, the generic {{jêder|…}} template is used * instead. Its 2nd positional param is the user's freeform "bi destê xwe * binivîsim" source text when supplied, or the çavkanî? placeholder otherwise. * If that text contains "=" it is passed as |2=… instead of a bare * positional param, since MediaWiki would otherwise misparse it as its * own key=value pair and break the template: * #* {{jêder|lang|jêgirtin=…|tr=…|tercime=…|<manual source or çavkanî?>}} */ function formatJeder(jederList, lang) { if (!jederList || !jederList.length) return ""; return $.map(jederList, function (jeder) { if (!jeder || !jeder.quote) return undefined; if (jeder.jederTpl) { var cite = "\n#* {{" + jeder.jederTpl + "|" + lang; cite += "|jêgirtin=" + jeder.quote; if (jeder.quoteTr) cite += "|tr=" + jeder.quoteTr; if (jeder.quoteT) cite += "|tercime=" + jeder.quoteT; $.each(jeder.jêderFields || {}, function (key, val) { if (val) cite += "|" + key + "=" + val; }); cite += "}}"; return cite; } var out = "\n#* {{jêder|" + lang + "|jêgirtin=" + jeder.quote; if (jeder.quoteTr) out += "|tr=" + jeder.quoteTr; if (jeder.quoteT) out += "|tercime=" + jeder.quoteT; var srcParam = jeder.jederManual ? jeder.jederManual : "çavkanî?"; // A positional param containing "=" gets parsed as its own key=value // pair by MediaWiki and breaks the template, so force it to be // explicitly named (|2=) whenever that's the case. out += (srcParam.indexOf("=") !== -1 ? "|2=" : "|") + srcParam; out += "}}"; return out; }).join(""); } /** * True if a sense has at least one jêder entry with actual quote text. */ function senseHasJeder(sense) { return !!(sense.jeder && $.grep(sense.jeder, function (j) { return j && j.quote; }).length > 0); } /** * Builds the "\n#: {{K|lang|cat1|cat2|…}}" category-template line for a * sense's kategorî field, or "" if none are filled in. */ function buildKatTpl(sense, lang) { if (!sense.kategori || !sense.kategori.length) return ""; var parts = sense.kategori.map(function (k) { return $.trim(k); }) .filter(function (k) { return k !== ""; }); if (!parts.length) return ""; return "\n#: {{K|" + lang + "|" + parts.join("|") + "}}"; } /** * Builds the " {{e|lang|label1|label2|…}} " label-template snippet for * a sense's etîket field, or "" if none are filled in. */ function buildLabelTpl(sense, lang) { if (!sense.etiket || !sense.etiket.length) return ""; var parts = sense.etiket.map(function (part) { return $.trim(part); }) .filter(function (part) { return part !== ""; }); if (!parts.length) return ""; return " {{e|" + lang + "|" + parts.join("|") + "}} "; } /** * Assembles the nimûne + jêder wikitext block for a sense. Shared by * both the template-sense and normal-mane-sense branches below. */ function buildCite(sense, lang) { return formatNimune(sense.nimune, lang, senseHasJeder(sense)) + formatJeder(sense.jeder, lang); } function makeWordListStep(id, name, question_fmt, header, templateName) { return { id: id, name: name, question_fmt: question_fmt, multiple: true, narrow: true, visible: function (values) { return values.lang && values.pos; }, output: function (values) { var words = $.grep(values[id] || [], function (w) { return !!w; }); if (!words.length) return ""; var lang = values.lang; var section = "\n==== " + header + " ====\n"; if (words.length === 1) { // Single word — keep the simple inline template. return section + "* {{" + templateName + "|" + lang + "|" + words[0] + "}}\n"; } // Multiple words — use {{kol3}} with one positional param per word. var params = "cure=" + header + "\n" + $.map(words, function (w) { return "|" + w; }).join("\n"); return section + "{{kol3|" + lang + "|" + params + "\n}}\n"; } }; } var steps = { lang: { id: "lang", required: true, name: "ziman", question_fmt: '"' + pageName + '" bi çi zimanî ye?', question_br: true, // Populated from [[MediaWiki:Gadget-start.js/data.json]] (langChoices). choices: [], output: function (values) { return "== {{ziman|" + values.lang + "}} ==\n"; } }, pron: { id: "pron", name: "bilêvkirin", question_fmt: '"' + pageName + '" çawa tê telafûzkirin?', // pronTpls populated from data.json pronTpls: [], visible: function (values) { if (!values.lang) return false; // In addLangMode, only skip pron when this langcode's section // already exists in the page — if it's a new language, show it. if (addLangMode) { // If the user wants to wipe the page and start over, the // existing content is irrelevant — always show pron. var clearPageCheck = $("#wiktku-clear-page-check"); if (clearPageCheck.length && clearPageCheck.prop("checked")) { return true; } var existing = $("#wpTextbox1").val() || ""; var header = "== {{ziman|" + values.lang + "}} =="; return existing.indexOf(header) === -1; } return true; }, /** Fills (or refills) the insert-dropdown from the current pronTpls array, filtering by language. */ refreshTplSelect: function () { var sel = $("#wiktku-start-pron .wiktku-tpl-insert-select"); if (!sel.length) return; var lang = getValues().lang || ""; sel.find("option[value!='']").remove(); $.each(steps.pron.pronTpls, function (_, tpl) { // Filter: if tpl.langs exists, only show if lang is in that list; otherwise show always var allowed = !tpl.langs || tpl.langs.indexOf(lang) !== -1; if (allowed) { sel.append($("<option></option>") .val(tpl.snippet) .text(tpl.name + " — " + tpl.desc) .attr("data-nolang", tpl.noLang ? "1" : "")); } }); // Notify Chosen that the option list has changed (no-op on mobile). if (!isMobile) sel.trigger("chosen:updated"); }, build: function (stepDiv) { if (stepDiv.find(".wiktku-pron-wrap").length) return null; var wrap = $("<div class='wiktku-pron-wrap'></div>"); var ta = $("<textarea></textarea>") .attr("name", "wiktku-pron-" + $.now()) .attr("class", "wiktku-start-step-field wiktku-pron-text") .attr("rows", 4) .attr("placeholder", "Nimûne: {{IPA|ku|/pɛɪ̯n/}} yan {{kîte|ku|he|ce|ki|rin}}"); // Template insert dropdown — filtered by language. var sel = $("<select class='wiktku-tpl-insert-select'></select>"); sel.append($("<option value=''>— şablonek lê zêde bike —</option>")); var lang = getValues().lang || ""; $.each(steps.pron.pronTpls, function (_, tpl) { // Filter: if tpl.langs exists, only show if lang is in that list; otherwise show always var allowed = !tpl.langs || tpl.langs.indexOf(lang) !== -1; if (allowed) { sel.append($("<option></option>") .val(tpl.snippet) .text(tpl.name + " — " + tpl.desc) .attr("data-nolang", tpl.noLang ? "1" : "")); } }); sel.on("change", function () { var snippet = $(this).val(); if (!snippet) return; var lang = getValues().lang || ""; // Check if the selected option has noLang flag var selectedOption = sel.find("option:selected"); var hasNoLang = selectedOption.attr("data-nolang") === "1"; if (!hasNoLang) { snippet = snippet.replace(/CODE/g, lang).replace(/SOURCELANG/g, "?"); } insertAtCursor(ta[0], snippet); $(this).val(""); ta.focus(); }); wrap.append(sel).append($("<br>")).append(ta); stepDiv.append(wrap); return ta; }, output: function () { var text = $.trim($("#wiktku-start-pron .wiktku-pron-text").val()); if (!text) return ""; var lines = text.split("\n"); var out = $.map(lines, function (line) { line = $.trim(line); if (!line) return undefined; return line.charAt(0) === "*" ? line : "* " + line; }).join("\n"); return "\n=== Bilêvkirin ===\n" + out + "\n"; } }, pos: { id: "pos", required: true, name: "Cureyê rêzimanî", question_fmt: 'Cureyê rêzimanî yê "' + pageName + '" çi ye?', visible: function (values) { return values.lang; }, question_br: true, // Populated from [[MediaWiki:Gadget-start.js/data.json]] (posChoices). choices: [], output: function (values) { var pos = values.pos || ""; var cinsiyet = values.cinsiyet || ""; // from the cinsiyet step var lekTur = values.lektur || ""; // from the lêker transitivity step var capitalizedPos = capitalize(pos); var outputString = "\n=== " + capitalizedPos + " ===\n"; // Add ku-tewîn-nav for single-word navdêr/serenav with known gender. if (!pageName.includes(" ") && cinsiyet && GENDER_BASE_LABELS[cinsiyet] && (pos === "navdêr" || pos === "serenav") && values.lang === "ku") { outputString += "{{ku-tewîn-nav|" + pageName + "|" + GENDER_BASE_LABELS[cinsiyet]; if (pos === "serenav") outputString += "|y"; outputString += "}}\n"; } outputString += "{{" + pos + "|" + values.lang; if (pos === "navdêr" || pos === "serenav") { if (cinsiyet) { outputString += "|c=" + cinsiyet; } else if (values.lang === "ku") { // Unknown gender — prompt editor to fill it in. outputString += "|c=?"; } } else if (/^lêker/.test(pos) && lekTur) { outputString += "|c=" + lekTur; } if (values.tr) { outputString += "|tr=" + values.tr; } outputString += "}}\n"; return outputString; } }, /** * cinsiyet (grammatical gender) — only shown for navdêr/serenav, û * tenê ger metadata ji bo zimanê hilbijartî lîsteyeke "g" (cinsiyet) * were dayîn. Opsiyonên vê gavê ne sabît in — ji metadata[values.lang].g * têne çêkirin, ji ber ku di hemû zimanan de cinsiyet tine. */ cinsiyet: { id: "cinsiyet", name: "cinsiyet", question_fmt: 'Cinsiyeta "' + pageName + '" çi ye?', question_br: true, visible: function (values) { var meta = metadata[values.lang]; return !!(values.lang && (values.pos === "navdêr" || values.pos === "serenav") && meta && meta.g && meta.g.length); }, build: function (stepDiv, values) { var select = stepDiv.find("select.wiktku-start-step-field"); if (!select.length) { select = $(mw.html.element("select", { "class": "wiktku-start-step-field", id: "wiktku-start-cinsiyet-field" })); stepDiv.append(select); } if (!values) return select; var meta = metadata[values.lang]; var codes = (meta && meta.g) || []; var prevVal = select.val(); var choices = $.map(codes, function (code) { return [[code, genderLabel(code)]]; }); populateMenus(select, choices); if ($.grep(choices, function (c) { return c[0] === prevVal; }).length) { select.val(prevVal); } if (!isMobile) select.trigger("chosen:updated"); return select; }, output: function () { return ""; } // consumed by pos.output }, /** * Lêker transitivity — only shown for any lêker variant. */ lektur: { id: "lektur", name: "Cureyê lêkerê (fiîlê)", question_fmt: "Cureyê lêkerê (fiîlê) çi ye?", question_br: true, visible: function (values) { return values.lang && values.pos && /^lêker/.test(values.pos); }, // Dictionary: value → display label. Add new types here. choices: [ ["gh", "gerguhêz"], ['x-gh', 'xwerû-gerguhêz'], ['p-gh', 'pêkhatî-gerguhêz'], ['h-gh', 'hevedudanî-gerguhêz'], ['b-gh', 'biwêjî-gerguhêz'], ["ngh", "negerguhêz"], ['x-ngh', 'xwerû-negerguhêz'], ['p-ngh', 'pêkhatî-negerguhêz'], ['h-ngh', 'hevedudanî-negerguhêz'], ['b-ngh', 'biwêjî-negerguhêz'] ], output: function () { return ""; } // consumed by pos.output }, tr: { id: "tr", name: "transkrîpsiyon", question_fmt: "Transkrîpsiyona kelîmeyê", multiple: false, narrow: true, visible: function (values) { return values.lang && values.pos && needsTransliteration(values.lang); } }, dfn: { id: "dfn", // required: true, ger mane tinebe [[Şablon:mane?]] bi kar bîne name: "Mane", question_fmt: "Maneya kelîmeyê binivîse. Mane otomatîk tê lînkkirin! Ji bo tercimeyan beşa 'Werger' bi kar bîne!", multiple: true, ordered: true, rows: 3, visible: function (values) { return values.lang && values.pos; }, example: function (values) { // posExamples loaded from [[MediaWiki:Gadget-start.js/data.json]]. var examples = steps.dfn.posExamples || {}; var full = values.pos || ""; return examples[full] || ""; }, /** * Builds one sense block (<li>) inside the ordered list. * Each block contains: * - a textarea for the definition * - an expandable nimûne list * - single-row sub-lists for formên alternatîv, hevmane, dijmane */ buildSenseBlock: function (stepDiv) { var block = $("<li class='wiktku-dfn-sense'></li>"); // — Mane textarea (declared first so the template handler can reference it) — var dfnArea = $("<textarea></textarea>") .attr("name", "wiktku-dfn-mane-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("class", "wiktku-start-step-field wiktku-dfn-mane") .attr("rows", 6) .attr("placeholder", "Mane…"); dfnArea.on("input", function () { steps.dfn.onDfnInput(stepDiv, block, this); }); // — Template selector (optional — replaces mane when chosen) — // Template definitions loaded from [[MediaWiki:Gadget-start.js/data.json]]. var tplDefs = steps.dfn.tplDefs || []; // Cache of all non-placeholder option elements — used by updateTplOptions // to remove/re-add options (the only approach compatible with Chosen.js). var _allTplOptions = []; var tplSelect = $(mw.html.element("select", { "class": "wiktku-dfn-tpl-select" })); tplSelect.append($("<option value=''>— yan jî şablonek hilbijêre —</option>")); $.each(tplDefs, function (_, tpl) { var opt = $("<option></option>") .val(tpl.name) .text(tpl.name) .attr("data-langs", tpl.langs ? tpl.langs.join(",") : "") .attr("data-nolang", tpl.noLang ? "1" : ""); tplSelect.append(opt); _allTplOptions.push(opt[0]); }); function updateTplOptions() { var lang = getValues().lang || ""; var currentVal = tplSelect.val(); var currentStillValid = false; // Detach all non-placeholder options, then re-attach only the visible ones. // This is the only approach that works correctly with both native <select> // and Chosen.js on desktop. tplSelect.find("option[value!='']").detach(); $.each(_allTplOptions, function (_, opt) { var allowed = $(opt).attr("data-langs"); var visible = !allowed || allowed.split(",").indexOf(lang) !== -1; if (visible) { tplSelect.append(opt); if ($(opt).val() === currentVal) currentStillValid = true; } }); if (!isMobile) tplSelect.trigger("chosen:updated"); if (currentVal && !currentStillValid) { tplSelect.val(""); dfnArea.show(); tplTitleInput.hide().val(""); } } // Store updater on the element so refresh() can call it for all blocks. tplSelect.data("updateOptions", updateTplOptions); var tplTitleInput = $("<input type='text'>") .addClass("wiktku-dfn-tpl-title wiktku-start-narrow") .attr("placeholder", "Navê rûpelê…") .hide(); // Grow the sense list when the title field of the last block gets content, // mirroring what onDfnInput does for the plain mane textarea. tplTitleInput.on("input", function () { steps.dfn.onDfnInput(stepDiv, block, this); }); /** * When a şablon sense is chosen, formên alternatîv/hevmane/dijmane/ * termên koordîne/jornav/jêrnav don't apply (there's no plain gloss * to hang them off), so hide those subgroups. Etîket, Nimûne and * Jêgirtin stay visible and still usable for a şablon sense. */ function updateFieldVisibility() { var isTpl = !!tplSelect.val(); $.each(HIDDEN_ON_TPL_GROUPS, function (_, cls) { block.find("." + cls + "-group").toggle(!isTpl); }); } // Store on the block so restoreDfn() can re-sync visibility // after programmatically setting tplSelect's value. block.data("updateFieldVisibility", updateFieldVisibility); tplSelect.on("change", function () { var chosen = $(this).val(); if (chosen) { dfnArea.hide(); tplTitleInput.show().focus(); } else { dfnArea.show(); tplTitleInput.hide().val(""); } updateFieldVisibility(); // Re-run refresh so the Werger step visibility updates. refresh(); }); var tplRow = $("<div></div>").addClass("wiktku-dfn-tpl-row") .append(tplSelect).append(" ").append(tplTitleInput); block.append(tplRow); block.append(dfnArea); // Apply lang filter on initial build. updateTplOptions(); // — Sub-field groups — // All groups are always visible with a placeholder textarea. // Nimûne is last in the DOM and last in the output. var allGroups = [ { cls: "wiktku-dfn-etiket", label: "Etîket", rows: 1, narrow: true, izah: "xisûsen, Mêrdîn, anatomî, Badînî" }, { cls: "wiktku-dfn-kategori", label: "Kategorî", rows: 1, narrow: true, izah: "Kategoriya ku ev mane lê tê zêdekirin" }, { cls: "wiktku-dfn-alternativ", label: "Formên alternatîv", rows: 1, narrow: true, izah: "Varyantên vê kelîmeyê" }, { cls: "wiktku-dfn-hevmane", label: "Hevmane", rows: 1, narrow: true, izah: "Spehî hevmaneya Bedew e." }, { cls: "wiktku-dfn-dijmane", label: "Dijmane", rows: 1, narrow: true, izah: "Zengîn dijmaneya feqîr e." }, { cls: "wiktku-dfn-koordine", label: "Termên koordîne", rows: 1, narrow: true, izah: "Pisîk û kûçik termên koordîne ne çunkî Jornavên wan gelek in" }, { cls: "wiktku-dfn-jornav", label: "Jornav", rows: 1, narrow: true, izah: "Heywan jornavê guhandar e" }, { cls: "wiktku-dfn-jernav", label: "Jêrnav", rows: 1, narrow: true, izah: "Guhandar jêrnavê heywan e" }, { cls: "wiktku-dfn-nimune", label: "Nimûne", rows: 2, narrow: false } ]; $.each(allGroups, function (_, g) { var groupDiv = $("<div></div>").addClass("wiktku-dfn-subgroup " + g.cls + "-group"); function buildNimuneLi() { var lang = getValues().lang || ""; var li = $("<li></li>").addClass("wiktku-dfn-nimune-li"); var mainTa = $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-text-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", g.rows) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-text") .attr("placeholder", "Nimûneya emilandina kelîmeyê tu bi xwe binivîse…"); mainTa.on("input", function () { var val = $.trim($(this).val()); var isLast = li.is(list.children("li:last-child")); if (val && isLast) { list.append(buildNimuneLi()); } }); li.append(mainTa); var subWrap = $("<div></div>").addClass("wiktku-dfn-nimune-sub"); if (needsTransliteration(lang)) { subWrap.append( $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-tr-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 5) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-tr") .attr("placeholder", "Transkrîpsiyona bi alfabeya latînî") ); } if (lang && lang !== "ku") { subWrap.append( $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-t-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 5) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-t") .attr("placeholder", "Tercimeya kurmancî") ); } if (subWrap.children().length) li.append(subWrap); return li; } if (g.cls === "wiktku-dfn-nimune") { // Nimûne — compound widget with tr/t sub-fields. var lbl = $("<span></span>").addClass("wiktku-dfn-sublabel").text(g.label + ": "); var list = $("<ol></ol>").addClass("wiktku-dfn-sublist " + g.cls + "-list"); groupDiv.data("buildNimuneLi", buildNimuneLi); list.append(buildNimuneLi()); groupDiv.append(lbl).append(list); block.append(groupDiv); } else { // Regular always-visible group — label + growing textarea list. var lbl = $("<span></span>").addClass("wiktku-dfn-sublabel").text(g.label + ": " + g.izah); var list = $("<ol></ol>").addClass("wiktku-dfn-sublist " + g.cls + "-list"); var firstInput = $("<textarea></textarea>") .attr("name", g.cls + "-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", g.rows) .attr("class", "wiktku-dfn-subfield" + (g.narrow ? " wiktku-start-narrow" : "")) .attr("placeholder", g.label + "…"); firstInput.on("input", function () { steps.dfn.onSubInput(list, this, g.rows, g.narrow); }); list.append($("<li></li>").append(firstInput)); groupDiv.append(lbl).append(list); block.append(groupDiv); } }); // — Jêder (quote / citation) group — a growing list, sibling to Nimûne — // Structured the same way as Nimûne (ol.wiktku-dfn-sublist > li) so it // lines up at the same indentation, and so that typing into the last // citation's Jêgirtin box automatically opens a fresh empty one below it. (function () { var jederGroupDiv = $("<div></div>").addClass("wiktku-dfn-subgroup wiktku-dfn-jeder-group"); var jederLbl = $("<span></span>").addClass("wiktku-dfn-sublabel").text("Jêgirtin: "); var jederList = $("<ol></ol>").addClass("wiktku-dfn-sublist wiktku-dfn-jeder-list"); function buildJederLi() { var lang = getValues().lang || ""; var li = $("<li></li>").addClass("wiktku-dfn-jeder-li"); var dragHandle = $("<span></span>") .addClass("wiktku-jeder-drag-handle") .attr("title", "Bişkûne û bikişîne da ku rêzê biguhezîne"); // Quote text textarea var quoteTa = $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-quote-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 2) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-quote") .attr("placeholder", "Nimûneya emilandinê ji kitêb an çavkaniyeke din binivîse"); quoteTa.on("input", function () { var val = $.trim($(this).val()); var isLast = li.is(jederList.children("li:last-child")); if (val && isLast) { jederList.append(buildJederLi()); } }); li.append(dragHandle).append(quoteTa); // tr/t sub-fields for the quote — shown as needed for the language. var quoteSubWrap = $("<div></div>").addClass("wiktku-dfn-quote-sub"); if (needsTransliteration(lang)) { quoteSubWrap.append( $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-quote-tr-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 2) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-quote-tr") .attr("placeholder", "Transkrîpsiyona jêgirtinê…") ); } if (lang && lang !== "ku") { quoteSubWrap.append( $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-quote-t-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 2) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-quote-t") .attr("placeholder", "Tercimeya jêgirtinê bi kurmancî") ); } if (quoteSubWrap.children().length) li.append(quoteSubWrap); // Citoid auto-fill: fetch citation data from a URL, DOI or ISBN and // prefill the source şablon + fields below (see Gadget-citoid-helper.js). var citoidWrap = $("<div></div>").addClass("wiktku-dfn-quote-citoid"); var citoidInput = $("<input type='text'>") .addClass("wiktku-dfn-quote-citoid-input wiktku-start-narrow") .attr("placeholder", "URL, DOI an ISBN binivîse ku otomatîk were tijekirin…"); var citoidBtn = new OO.ui.ButtonWidget({ label: "Bi Citoid bîne", classes: [ "wiktku-dfn-quote-citoid-btn" ] }); var citoidStatus = $("<span></span>").addClass("wiktku-dfn-quote-citoid-status"); /** * Fetches citation data from Citoid and applies it to this * citation's şablon selector + fields. Mirrors the logic in * Form.prototype._fillFromCitoid (Gadget-wikt.add-examples.js): * - only (re)selects the şablon when it actually differs from * what's already chosen, so a repeat fetch doesn't wipe out * a template the user already picked; * - only fills fields that are currently empty, so it never * overwrites something the user typed by hand; * - falls back to the freeform "bi destê xwe binivîsim" source * only when nothing was typed there yet. */ function runCitoidFetch() { var query = $.trim(citoidInput.val()); if (!query) { mw.notify("Ji kerema xwe re pêşî URL, DOI an ISBNyekê binivîse."); return; } citoidBtn.setDisabled(true); citoidStatus.text("Tê anîn…"); wikt.citoidHelper.ensure().then(function () { return wikt.citoid.fetchJederFields(query); }).then(function (result) { var jederKey = result.jederKey; var hasTpl = !!jederKey && srcSel.find("option[value='" + jederKey + "']").length > 0; var targetVal = hasTpl ? jederKey : "__manual__"; // Only (re)select — and thus rebuild — the field rows if // we're switching to a different şablon than what's // already chosen, so a second fetch doesn't clear fields // the user already filled in by hand. if (srcSel.val() !== targetVal) { srcSel.val(targetVal).trigger("change"); srcSel.trigger("chosen:updated"); } if (hasTpl) { // Tenê qadên vala tijî bike. $.each(result.fields, function (key, val) { var input = srcFields.find("[data-field-key='" + key + "']"); if (input.length && !$.trim(input.val())) { input.val(val); } }); } else { // Şablonek nehat naskirin ji bo vê itemType — rêzikeke // çavkaniyê ya bi destan a ji qadên Citoid tê çêkirin, // lê tenê ger qada destan vala be. var manualField = srcFields.find(".wiktku-dfn-quote-src-manual"); if (!$.trim(manualField.val())) { var parts = []; $.each(["nivîskar", "sernav", "websîte", "kovar", "weşanxane", "sal", "url"], function (_, k) { if (result.fields[k]) parts.push(result.fields[k]); }); manualField.val(parts.join(", ")); } } citoidStatus.text(""); }, function (errorMsg) { citoidStatus.text(typeof errorMsg === "string" ? errorMsg : "Nehat dîtin. Kontrol bike ka URL/DOI/ISBN rast e."); }).always(function () { citoidBtn.setDisabled(false); }); } citoidBtn.on("click", runCitoidFetch); citoidInput.on("keydown", function (e) { if (e.which === 13) { // Enter e.preventDefault(); runCitoidFetch(); } }); citoidWrap.append(citoidInput).append(citoidBtn.$element).append(citoidStatus); // Source template selector, specific to this citation. var srcSel = $("<select></select>").addClass("wiktku-dfn-quote-src-sel"); srcSel.append($("<option value=''>— Çavkaniyê hilbijêre —</option>")); srcSel.append($("<option></option>").val("__manual__").text("Bi destê xwe binivîsim")); var jederDefs = steps.dfn.jederDefs || {}; $.each(jederDefs, function (tplName, def) { srcSel.append($("<option></option>").val(tplName).text(def.label)); }); // Dynamic source fields container. var srcFields = $("<div></div>").addClass("wiktku-dfn-quote-src-fields"); srcSel.on("change", function () { srcFields.empty(); var chosen = $(this).val(); if (!chosen) return; if (chosen === "__manual__") { // Freeform source, written by the user — becomes the 2nd // positional param of {{jêder|lang|…}} instead of çavkanî?. srcFields.append( $("<textarea></textarea>") .attr("rows", 4) .addClass("wiktku-dfn-subfield wiktku-dfn-quote-src-manual") .attr("placeholder", "Çavkaniyê bi destê xwe binivîse…") ); return; } var def = (steps.dfn.jederDefs || {})[chosen]; if (!def) return; $.each(def.fields, function (_, f) { var row = $("<div></div>").addClass("wiktku-dfn-quote-src-row"); var fieldLbl = $("<label></label>").text(f.label + ": "); var inp = $("<textarea></textarea>") .attr("rows", 2) .addClass("wiktku-dfn-quote-src-input wiktku-start-narrow") .attr("data-field-key", f.key) .attr("placeholder", f.label + "…"); row.append(fieldLbl).append(inp); srcFields.append(row); }); }); li.append(citoidWrap).append(srcSel).append(srcFields); return li; } jederGroupDiv.data("buildJederLi", buildJederLi); jederList.append(buildJederLi()); // Make citation rows sortable (drag to reorder). // The last row is always the empty trailing row — cancel its drag. mw.loader.using("jquery.ui.sortable", function () { jederList.sortable({ handle: ".wiktku-jeder-drag-handle", axis: "y", items: "li:not(:last-child)", tolerance: "pointer" }); }); jederGroupDiv.append(jederLbl).append(jederList); block.append(jederGroupDiv); }()); // Apply the initial hide/show state for the sub-groups (matches // tplSelect's starting value, which is normally empty). updateFieldVisibility(); return block; }, /** Grows the sense list when the last mane textarea gets content. */ onDfnInput: function (stepDiv, block, textarea) { var val = $.trim($(textarea).val()); var list = stepDiv.find("ol.wiktku-dfn-list"); var isLast = block.is(list.children("li:last-child")); if (val && isLast) { var newBlock = steps.dfn.buildSenseBlock(stepDiv); list.append(newBlock); // Apply Chosen to the new block's template selector on desktop. if (!isMobile) newBlock.find("select.wiktku-dfn-tpl-select").chosen(chosenOptions); } refresh(); }, /** Grows a sub-list (nimûne/formên alternatîv/hevmane/dijmane/termên koordîne) on input. */ onSubInput: function (list, input, rows, narrow) { var val = $.trim($(input).val()); var item = $(input).parent(); var isLast = item.is(list.children("li:last-child")); if (val && isLast) { var next = $("<textarea></textarea>") .attr("name", "wiktku-dfn-sub-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", rows) .attr("class", "wiktku-dfn-subfield" + (narrow ? " wiktku-start-narrow" : "")); next.on("input", function () { steps.dfn.onSubInput(list, this, rows, narrow); }); list.append($("<li></li>").append(next)); } }, // Populated from [[MediaWiki:Gadget-start.js/data.json]] (tplDefs, posExamples, jederDefs). tplDefs: [], posExamples: {}, jederDefs: {}, build: function (stepDiv) { if (stepDiv.find("ol.wiktku-dfn-list").length) return null; var list = $("<ol class='wiktku-dfn-list'></ol>"); list.append(steps.dfn.buildSenseBlock(stepDiv)); stepDiv.append(list); return null; }, /** Reads all sense blocks from the DOM and returns an array of sense objects. */ getSenses: function (stepDiv) { var senses = []; stepDiv.find("li.wiktku-dfn-sense").each(function () { var block = $(this); var tplSel = block.find("select.wiktku-dfn-tpl-select"); var tpl = tplSel.val() || ""; // noLang: template already encodes the language — don't add |lang| param. var tplNoLang = tpl ? tplSel.find("option[value='" + tpl + "']").attr("data-nolang") === "1" : false; var tplTitle = $.trim(block.find("input.wiktku-dfn-tpl-title").val()); var mane = $.trim(block.find("textarea.wiktku-dfn-mane").val()); var etiket = (function () { var vals = []; block.find(".wiktku-dfn-etiket-list textarea").each(function () { var v = $.trim($(this).val()); if (v) vals.push(v); }); return vals; }()); var kategori = (function () { var vals = []; block.find(".wiktku-dfn-kategori-list textarea").each(function () { var v = $.trim($(this).val()); if (v) vals.push(v); }); return vals; }()); function readList(cls) { var vals = []; block.find("." + cls + "-list textarea").each(function () { var v = $.trim($(this).val()); if (v) vals.push(v); }); return vals; } // Nimûne items are compound: { text, tr?, t? } function readNimuneList() { var items = []; block.find(".wiktku-dfn-nimune-list li.wiktku-dfn-nimune-li").each(function () { var text = $.trim($(this).find(".wiktku-dfn-nimune-text").val()); if (!text) return; var obj = { text: text }; var tr = $.trim($(this).find(".wiktku-dfn-nimune-tr").val()); var t = $.trim($(this).find(".wiktku-dfn-nimune-t").val()); if (tr) obj.tr = tr; if (t) obj.t = t; items.push(obj); }); return items; } // Jêder is a growing list of citations, one per li — mirrors readNimuneList(). function readJederList() { var items = []; block.find(".wiktku-dfn-jeder-list li.wiktku-dfn-jeder-li").each(function () { var li = $(this); var quote = $.trim(li.find(".wiktku-dfn-nimune-quote").val()); if (!quote) return; var obj = { quote: quote }; var qtr = $.trim(li.find(".wiktku-dfn-nimune-quote-tr").val()); var qt = $.trim(li.find(".wiktku-dfn-nimune-quote-t").val()); if (qtr) obj.quoteTr = qtr; if (qt) obj.quoteT = qt; var tplName = li.find(".wiktku-dfn-quote-src-sel").val(); if (tplName === "__manual__") { var manual = $.trim(li.find(".wiktku-dfn-quote-src-manual").val()); if (manual) obj.jederManual = manual; } else if (tplName) { obj.jederTpl = tplName; var fields = {}; li.find(".wiktku-dfn-quote-src-input").each(function () { var k = $(this).attr("data-field-key"); var v = $.trim($(this).val()); if (k && v) fields[k] = v; }); obj.jêderFields = fields; } items.push(obj); }); return items; } senses.push({ tpl: tpl, tplNoLang: tplNoLang, tplTitle: tplTitle, mane: mane, etiket: etiket, kategori: kategori, nimune: readNimuneList(), jeder: readJederList(), alternativ: readList("wiktku-dfn-alternativ"), hevmane: readList("wiktku-dfn-hevmane"), dijmane: readList("wiktku-dfn-dijmane"), koordine: readList("wiktku-dfn-koordine"), jornav: readList("wiktku-dfn-jornav"), jernav: readList("wiktku-dfn-jernav") }); }); return senses; }, getOutput: function (values, callback) { var stepDiv = $("#wiktku-start-dfn"); var senses = steps.dfn.getSenses(stepDiv); var lang = values.lang; // A sense counts as "filled" if it has a mane, a chosen template + title, // or any other content (etîket/hevmane/nimûne/jêder…) worth keeping. var hasMane = senses.some(function (s) { return s.mane !== "" || (s.tpl && s.tplTitle) || senseHasExtraContent(s); }); // True only when at least one sense has a regular mane (needs linkify). var hasRegularMane = senses.some(function (s) { return !s.tpl && s.mane !== ""; }); // nimûne and jêder lines must never pass through linkify — only // the plain mane text should be linkified. We build two parallel // arrays: defLines (sent to linkify) and citeLines (kept aside). // Each entry in citeLines corresponds 1-to-1 with a defLines entry; // a template token {{wiktku-cite-N}} is embedded in defLines so // that after linkify runs we know exactly where to splice them back. // Template-call syntax is guaranteed safe: linkifiers leave {{ }} // tokens completely untouched. var defLines = []; // one entry per kept sense (goes to linkify) var citeLines = []; // parallel — nimûne+jêder for that same sense $.each(senses, function (_, sense) { // — Template sense (e.g. {{guharto|ku|somepage}}) — if (sense.tpl) { if (!sense.tplTitle) return; // skip empty template senses var tplKatTpl = buildKatTpl(sense, lang); var tplLabelTpl = buildLabelTpl(sense, lang); var tplCall = sense.tplNoLang ? "{{" + sense.tpl + "|" + sense.tplTitle + "}}" : "{{" + sense.tpl + "|" + lang + "|" + sense.tplTitle + "}}"; var idx = defLines.length; var cite = buildCite(sense, lang); defLines.push("#" + (tplLabelTpl ? tplLabelTpl : " ") + tplCall + tplKatTpl + (cite ? "{{wiktku-cite-" + idx + "}}" : "")); citeLines.push(cite); return; } // — Normal mane sense — var dfn = sense.mane; if (!dfn && !senseHasExtraContent(sense)) return; // truly empty if (dfn) { dfn = stripWikilinks(dfn); if (dfn[0] !== dfn[0].toUpperCase()) dfn = capitalize(dfn); if (!dfn.match(/[.…?!)\]]$/)) dfn += "."; } else { dfn = "{{mane?|" + lang + "}}"; } var katTpl = buildKatTpl(sense, lang); var labelTpl = buildLabelTpl(sense, lang); var out = "#" + (labelTpl ? labelTpl : " ") + dfn; out += katTpl; function wordLine(tpl, words) { if (!words.length) return ""; return "\n#: {{" + tpl + "|" + lang + "|" + words.join("|") + "}}"; } out += wordLine("alt-r", sense.alternativ); out += wordLine("hevmane", sense.hevmane); out += wordLine("dijmane", sense.dijmane); out += wordLine("koordîne", sense.koordine); out += wordLine("jornav", sense.jornav); out += wordLine("jêrnav", sense.jernav); var cite = buildCite(sense, lang); var idx = defLines.length; defLines.push(out + (cite ? "{{wiktku-cite-" + idx + "}}" : "")); citeLines.push(cite); }); // Splice citeLines back into a linkified string, replacing each // {{wiktku-cite-N}} token with its stored nimûne/jêder block. function restoreCites(t) { return t.replace(/\{\{wiktku-cite-(\d+)\}\}/g, function (_, n) { return citeLines[parseInt(n, 10)] || ""; }); } var text = defLines.join("\n") + "\n"; if (!hasMane) { // No definitions entered — emit {{mane?}} with bênimûne. text = "# {{mane?|" + lang + "}}\n#* {{bênimûne|" + lang + "}}\n"; callback(text); return; } if (!hasRegularMane) { // All filled senses are template senses — no linkify needed. callback(restoreCites(text)); return; } var didTryToLoad = function () { if (typeof $.wiktviLinkify === "function") { $.wiktviLinkify(text, function (linked) { callback(restoreCites(linked)); }); } else { callback(restoreCites(text)); } }; mw.loader.using("ext.gadget.linkify", didTryToLoad, didTryToLoad); } }, je: makeWordListStep("je", "jê", "Kelîmeyên jê çêbûyî binivîse", "Jê", "g"), tekildar: makeWordListStep("tekildar", "têkildar", "Kelîmeyên ji aliyê etîmolojiyê ve têkildarî vê kelîmeyê binivîse", "Têkildar", "g"), binereherwiha: makeWordListStep("binereherwiha", "binêre herwiha", "Kelîmeyên din ên eleqedar binivîse", "Binêre herwiha", "g"), etym: { id: "etym", name: "etîmolojî", question_fmt: "Etîmolojiya kelîmeyê binivîse", // etymTpls populated from data.json etymTpls: [], visible: function (values) { return values.lang && values.pos; }, /** Fills (or refills) the insert-dropdown from the current etymTpls array. */ refreshTplSelect: function () { var sel = $("#wiktku-start-etym .wiktku-tpl-insert-select"); if (!sel.length) return; sel.find("option[value!='']").remove(); $.each(steps.etym.etymTpls, function (_, tpl) { sel.append($("<option></option>").val(tpl.snippet).text(tpl.name + " — " + tpl.desc)); }); // Notify Chosen that the option list has changed (no-op on mobile). if (!isMobile) sel.trigger("chosen:updated"); }, build: function (stepDiv) { if (stepDiv.find(".wiktku-etym-wrap").length) return null; var wrap = $("<div class='wiktku-etym-wrap'></div>"); var ta = $("<textarea></textarea>") .attr("name", "wiktku-etym-" + $.now()) .attr("class", "wiktku-start-step-field wiktku-etym-text") .attr("rows", 4) .attr("placeholder", "Nimûne: Ji {{ji|en|ku|apple}}. yan rasterast binivîse…"); // Template insert dropdown — options also refreshed after data.json loads. var sel = $("<select class='wiktku-tpl-insert-select'></select>"); sel.append($("<option value=''>— şablonek lê zêde bike —</option>")); $.each(steps.etym.etymTpls, function (_, tpl) { sel.append($("<option></option>").val(tpl.snippet).text(tpl.name + " — " + tpl.desc)); }); sel.on("change", function () { var snippet = $(this).val(); if (!snippet) return; var lang = getValues().lang || ""; snippet = snippet.replace(/CODE/g, lang).replace(/SOURCELANG/g, "?"); insertAtCursor(ta[0], snippet); $(this).val(""); ta.focus(); }); wrap.append(sel).append($("<br>")).append(ta); stepDiv.append(wrap); return ta; }, output: function (values) { var text = $.trim($("#wiktku-start-etym .wiktku-etym-text").val()); if (text) { return "\n==== Etîmolojî ====\n" + text + "\n"; } // No etymology entered — emit {{ji?|lang}} as a placeholder, // but only when the entry has at least one regular (non-şablon) // sense with content — either real mane text, or an empty mane // with other fields filled in (which dfn.getOutput() renders as // {{mane?|lang}} with those fields attached). A şablon sense // like {{guharto|…}} never counts, filled in or not. var dfnSenses = steps.dfn.getSenses($("#wiktku-start-dfn")); var hasRegularMane = dfnSenses.some(function (s) { return !s.tpl && (s.mane !== "" || senseHasExtraContent(s)); }); if (!hasRegularMane) return ""; return "\n==== Etîmolojî ====\n{{ji?|" + values.lang + "}}\n"; } }, dunde: { id: "dunde", name: "dûnde", question_fmt: "Eger ev kelîme ji vî zimanî ketibe zimanekî din, vî zimanî û kelîmeya wî binivîse", visible: function (values) { return !!values.pos; }, disabledKeys: { "navz": true}, /** * Builds one row: a language dropdown + a growing list of word * inputs. When the dropdown gets a value the next empty row is * appended automatically. Mirrors steps.trans's row widget, but * flat (one shared list — dûnde isn't tied to individual senses). */ buildRow: function (stepDiv) { var row = $("<li class='wiktku-dunde-row wiktku-lang-row'></li>"); // Language selector — chosen is applied after insertion into DOM. var langSel = $(mw.html.element("select", { "class": "wiktku-start-step-keyfield wiktku-start-narrow" })); langSel.attr("data-placeholder", "Zimanekî lê bigere"); populateMenus(langSel, steps.dunde.keys || [], steps.dunde.disabledKeys); // When a language is chosen, ensure a next empty row exists. langSel.on("change", function () { steps.dunde.onLangChange(stepDiv, row); }); // Word list for this language. var wordList = $("<ul class='wiktku-dunde-words wiktku-lang-row-words'></ul>"); var firstWord = steps.dunde.makeWordInput(); wordList.append($("<li></li>").append(firstWord)); if (isMobile) { row.append(wrapNativeSelect(langSel)).append(wordList); } else { row.append(langSel).append(wordList); } return row; }, makeWordInput: function () { var input = $("<textarea></textarea>") .attr("name", "wiktku-dunde-word-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 1) .attr("class", "wiktku-dfn-subfield wiktku-start-narrow") .attr("placeholder", "Kelîme…"); input.on("input", function () { var list = $(this).closest("ul.wiktku-dunde-words"); var item = $(this).parent(); var val = $.trim($(this).val()); if (val && item.is(list.children("li:last-child"))) { var next = steps.dunde.makeWordInput(); list.append($("<li></li>").append(next)); } }); return input; }, onLangChange: function (stepDiv, row) { var list = stepDiv.find("ul.wiktku-dunde-list"); var isLast = row.is(list.children("li.wiktku-dunde-row:last-child")); if (isLast) { var newRow = steps.dunde.buildRow(stepDiv); list.append(newRow); // Init chosen after the new row is in the DOM (desktop only). if (!isMobile) newRow.find("select").chosen(chosenOptions); } // Keep disabled keys in sync across all lang selectors. steps.dunde.syncDisabledKeys(stepDiv); }, /** Disables already-selected languages in all other dropdowns. */ syncDisabledKeys: function (stepDiv) { var taken = $.extend({}, steps.dunde.disabledKeys); stepDiv.find("li.wiktku-dunde-row select").each(function () { var v = $(this).val(); if (v) taken[v] = true; }); stepDiv.find("li.wiktku-dunde-row select").each(function () { var self = $(this); var own = self.val(); self.find("option").each(function () { var code = $(this).val(); if (!code) return; $(this).prop("disabled", taken[code] && code !== own); }); self.trigger("chosen:updated"); }); }, build: function (stepDiv) { if (stepDiv.find("ul.wiktku-dunde-list").length) return null; var list = $("<ul class='wiktku-dunde-list wiktku-lang-row-list'></ul>"); list.append(steps.dunde.buildRow(stepDiv)); stepDiv.append(list); // Init chosen after the select is in the DOM (desktop only). if (!isMobile) list.find("select").chosen(chosenOptions); return null; }, /** Reads all [langcode, words[]] rows from the DOM. */ getRows: function (stepDiv) { var result = []; stepDiv.find("li.wiktku-dunde-row").each(function () { var lang = $(this).find("select").val(); if (!lang) return; var words = []; $(this).find("ul.wiktku-dunde-words textarea").each(function () { var v = $.trim($(this).val()); if (v) words.push(v); }); if (words.length) result.push([lang, words]); }); return result; }, output: function () { var stepDiv = $("#wiktku-start-dunde"); var rows = steps.dunde.getRows(stepDiv); if (!rows.length) return ""; var lines = $.map(rows, function (row) { var lang = row[0], words = row[1]; return "* {{dû|" + lang + "|" + words.join("|") + "}}"; }); return "\n==== Dûnde ====\n" + lines.join("\n") + "\n"; } }, zarava: { id: "zarava", name: "bi zaravayên din", visible: function (values) { return steps.trans.visible(values); }, disabledKeys: { "navz": true }, buildRow: function (group) { var row = $("<li class='wiktku-zarava-row wiktku-lang-row'></li>"); var langSel = $(mw.html.element("select", { "class": "wiktku-start-step-keyfield wiktku-start-narrow" })); populateMenus(langSel, steps.zarava.keys || [], steps.zarava.disabledKeys); langSel.on("change", function () { steps.zarava.onLangChange(group, row); }); var wordList = $("<ul class='wiktku-zarava-words wiktku-lang-row-words'></ul>"); var firstWord = steps.zarava.makeWordInput(); wordList.append($("<li></li>").append(firstWord)); row.append(langSel).append(wordList); return row; }, makeWordInput: function () { var input = $("<textarea></textarea>") .attr("name", "wiktku-zarava-word-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 1) .attr("class", "wiktku-dfn-subfield wiktku-start-narrow") .attr("placeholder", "Tercime…"); input.on("input", function () { var list = $(this).closest("ul.wiktku-zarava-words"); var item = $(this).parent(); var val = $.trim($(this).val()); if (val && item.is(list.children("li:last-child"))) { var next = steps.zarava.makeWordInput(); list.append($("<li></li>").append(next)); } }); return input; }, onLangChange: function (group, row) { var list = group.find("ul.wiktku-zarava-list"); var isLast = row.is(list.children("li.wiktku-zarava-row:last-child")); if (isLast) { var newRow = steps.zarava.buildRow(group); list.append(newRow); } steps.zarava.syncDisabledKeys(group); }, /** Disables already-selected dialects in all other dropdowns within one group. */ syncDisabledKeys: function (group) { var taken = $.extend({}, steps.zarava.disabledKeys); group.find("li.wiktku-zarava-row select").each(function () { var v = $(this).val(); if (v) taken[v] = true; }); group.find("li.wiktku-zarava-row select").each(function () { var self = $(this); var own = self.val(); self.find("option").each(function () { var code = $(this).val(); if (!code) return; $(this).prop("disabled", taken[code] && code !== own); }); }); }, /** Builds (or fetches) the .wiktku-zarava-group for one gloss. */ buildGroup: function (stepDiv, gi) { var group = $("<div class='wiktku-zarava-group'></div>").attr("data-gloss-pos", gi); var list = $("<ul class='wiktku-zarava-list wiktku-lang-row-list'></ul>"); list.append(steps.zarava.buildRow(group)); group.append(list); stepDiv.append(group); return group; }, /** Syncs one .wiktku-zarava-group per current gloss (same logic as steps.trans.build). */ build: function (stepDiv) { var glosses = steps.trans.glossList(); if (!glosses.length) { stepDiv.find(".wiktku-zarava-group").remove(); return null; } var existingGroups = stepDiv.find(".wiktku-zarava-group"); if (existingGroups.length > glosses.length) { existingGroups.slice(glosses.length).remove(); } $.each(glosses, function (gi, gloss) { var group = stepDiv.find(".wiktku-zarava-group[data-gloss-pos='" + gi + "']"); if (!group.length) group = steps.zarava.buildGroup(stepDiv, gi); var label = group.find(".wiktku-zarava-group-label"); if (glosses.length > 1) { if (!label.length) { label = $("<div class='wiktku-zarava-group-label'></div>"); group.prepend(label); } label.text(gloss.index + " " + gloss.text); } else if (label.length) { label.remove(); } }); return null; }, /** Reads the dialect rows for a single gloss group. */ getGroupTranslations: function (group) { var result = []; group.find("li.wiktku-zarava-row").each(function () { var lang = $(this).find("select").val(); if (!lang) return; var words = []; $(this).find("ul.wiktku-zarava-words textarea").each(function () { var v = $.trim($(this).val()); if (v) words.push(v); }); if (words.length) result.push([lang, words]); }); return result; }, /** Reads all rows from the DOM, grouped by gloss position. */ getTranslations: function (stepDiv) { var result = []; stepDiv.find(".wiktku-zarava-group").each(function () { result.push(steps.zarava.getGroupTranslations($(this))); }); return result; }, output: function (values) { if (values.lang !== "ku") return ""; var stepDiv = $("#wiktku-start-zarava"); var glosses = steps.trans.glossList(); if (!glosses.length) return ""; var blocks = $.map(glosses, function (gloss, gi) { var group = stepDiv.find(".wiktku-zarava-group[data-gloss-pos='" + gi + "']"); var rows = group.length ? steps.zarava.getGroupTranslations(group) : []; if (!gloss.text && !rows.length) return undefined; if (rows.length) { rows.sort(function (a, b) { var aLang = langsByCode[a[0]] || []; var bLang = langsByCode[b[0]] || []; return (aLang[2] || "").localeCompare(bLang[2] || "", "ku"); }); } var wordLines = $.map(rows, function (row) { var lang = row[0]; var words = row[1]; var wikiWords = words.map(function (w) { return "{{W|" + lang + "|" + w + "}}"; }).join(", "); return "* {{Z|" + lang + "}}: " + wikiWords; }).join("\n"); if (!wordLines) return undefined; var block = "{{werger-ser|" + (gloss.text || "?") + "|" + gloss.index + "}}"; block += "\n" + wordLines; block += "\n{{werger-bin}}"; return block; }); if (!blocks.length) return ""; return "\n==== Bi zaravayên din ====\n" + blocks.join("\n") + "\n"; } }, trans: { id: "trans", name: "werger", visible: function (values) { if (!(values.lang === "ku" && values.pos)) return false; // Hide Werger only when EVERY sense is a template sense (Guharto etc.) // with a title filled in — i.e. there is real content but no plain // gloss to attach a translation table to. A mix of real + template // senses still shows Werger; the template senses are simply skipped // in output(). // // "Real" here means a non-şablon sense with either mane text or // other filled-in fields (etîket/hevmane/nimûne/jêder…), since // dfn.getOutput() renders the latter too, as {{mane?|lang}} plus // whatever else was filled in. // // When nothing has been filled in at all, output() will emit // {{mane?|lang}} instead of a gloss — but Werger should still show, // since the user may want to add translations before they've // settled on a gloss. var dfnSenses = steps.dfn.getSenses($("#wiktku-start-dfn")); var hasRealSense = dfnSenses.some(function (s) { return !s.tpl && (s.mane !== "" || senseHasExtraContent(s)); }); var hasFilledTplSense = dfnSenses.some(function (s) { return s.tpl && s.tplTitle; }); return hasRealSense || !hasFilledTplSense; }, disabledKeys: { "navz": true, "ku": true, "ckb": true, "sdh": true, "lki": true, "hac": true, "zza": true }, /** * Builds one translation row: a language dropdown + a growing list * of word inputs. When the dropdown gets a value the next empty row * is appended automatically. * * @param group the specific .wiktku-trans-group this row belongs to * (each gloss has its own group and its own list of rows, so the * lookups below must stay scoped to that group rather than the * whole step — the step now holds one list per gloss). */ buildRow: function (group) { var row = $("<li class='wiktku-trans-row wiktku-lang-row'></li>"); // Language selector — chosen is applied after insertion into DOM. var langSel = $(mw.html.element("select", { "class": "wiktku-start-step-keyfield wiktku-start-narrow" })); langSel.attr("data-placeholder", "Zimanekî lê bigere"); populateMenus(langSel, steps.trans.keys || [], steps.trans.disabledKeys); // When a language is chosen, ensure a next empty row exists. langSel.on("change", function () { steps.trans.onLangChange(group, row); }); // Word list for this language. var wordList = $("<ul class='wiktku-trans-words wiktku-lang-row-words'></ul>"); var firstWord = steps.trans.makeWordInput(); wordList.append($("<li></li>").append(firstWord)); if (isMobile) { row.append(wrapNativeSelect(langSel)).append(wordList); } else { row.append(langSel).append(wordList); } return row; }, makeWordInput: function () { var input = $("<textarea></textarea>") .attr("name", "wiktku-trans-word-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 1) .attr("class", "wiktku-dfn-subfield wiktku-start-narrow") .attr("placeholder", "Tercime…"); input.on("input", function () { var list = $(this).closest("ul.wiktku-trans-words"); var item = $(this).parent(); var val = $.trim($(this).val()); if (val && item.is(list.children("li:last-child"))) { var next = steps.trans.makeWordInput(); list.append($("<li></li>").append(next)); } }); return input; }, onLangChange: function (group, row) { var list = group.find("ul.wiktku-trans-list"); var isLast = row.is(list.children("li.wiktku-trans-row:last-child")); if (isLast) { var newRow = steps.trans.buildRow(group); list.append(newRow); // Init chosen after the new row is in the DOM (desktop only). if (!isMobile) newRow.find("select").chosen(chosenOptions); } // Keep disabled keys in sync across this gloss's lang selectors // only — the same language can be used for different senses. steps.trans.syncDisabledKeys(group); }, /** Disables already-selected languages in all other dropdowns within one group. */ syncDisabledKeys: function (group) { var taken = $.extend({}, steps.trans.disabledKeys); group.find("li.wiktku-trans-row select").each(function () { var v = $(this).val(); if (v) taken[v] = true; }); group.find("li.wiktku-trans-row select").each(function () { var self = $(this); var own = self.val(); self.find("option").each(function () { var code = $(this).val(); if (!code) return; $(this).prop("disabled", taken[code] && code !== own); }); self.trigger("chosen:updated"); }); }, /** * Builds (or fetches) the .wiktku-trans-group for one gloss, with * its own label and its own list of translation rows. */ buildGroup: function (stepDiv, gi) { var group = $("<div class='wiktku-trans-group'></div>").attr("data-gloss-pos", gi); var list = $("<ul class='wiktku-trans-list wiktku-lang-row-list'></ul>"); list.append(steps.trans.buildRow(group)); group.append(list); stepDiv.append(group); // Init chosen after the select is in the DOM (desktop only). if (!isMobile) list.find("select").chosen(chosenOptions); return group; }, /** * Syncs one .wiktku-trans-group per current gloss, adding new * groups and removing stale ones as senses are added or removed, * while leaving existing groups (and whatever translations the * user has already typed into them) untouched. Groups are keyed * to their gloss's position in glossList() via data-gloss-pos, so * a group always matches the same sense across rebuilds as long * as senses aren't reordered relative to each other. */ build: function (stepDiv) { var glosses = steps.trans.glossList(); if (!glosses.length) { stepDiv.find(".wiktku-trans-group").remove(); return null; } // Drop groups for glosses that no longer exist (always from the // tail — groups are only ever appended in gloss order below). var existingGroups = stepDiv.find(".wiktku-trans-group"); if (existingGroups.length > glosses.length) { existingGroups.slice(glosses.length).remove(); } $.each(glosses, function (gi, gloss) { var group = stepDiv.find(".wiktku-trans-group[data-gloss-pos='" + gi + "']"); if (!group.length) group = steps.trans.buildGroup(stepDiv, gi); // Only label groups when there's more than one gloss to // distinguish between — a single gloss needs no caption. var label = group.find(".wiktku-trans-group-label"); if (glosses.length > 1) { if (!label.length) { label = $("<div class='wiktku-trans-group-label'></div>"); group.prepend(label); } label.text(gloss.index + " " + gloss.text); } else if (label.length) { label.remove(); } }); return null; }, /** Reads the translation rows for a single gloss group. */ getGroupTranslations: function (group) { var result = []; group.find("li.wiktku-trans-row").each(function () { var lang = $(this).find("select").val(); if (!lang) return; var words = []; $(this).find("ul.wiktku-trans-words textarea").each(function () { var v = $.trim($(this).val()); if (v) words.push(v); }); if (words.length) result.push([lang, words]); }); return result; }, /** * Reads all translation rows from the DOM, grouped by gloss * position — one array of [lang, words] rows per gloss group, in * the same order as the .wiktku-trans-group elements. */ getTranslations: function (stepDiv) { var result = []; stepDiv.find(".wiktku-trans-group").each(function () { result.push(steps.trans.getGroupTranslations($(this))); }); return result; }, /** * Builds the numbered "{ index, gloss }" list — one entry per dfn * sense that has a real mane (skips template senses like Guharto, * which have nothing to caption a translation table with). The * index matches the sense's actual position in the numbered "#" * definition list (1-based), including template senses in the count, * so the number printed next to {{werger-ser}} lines up with the * gloss the reader sees in the entry. * * When nothing has been filled in at all (dfn.getOutput() will emit * {{mane?|lang}} as sense 1), this returns a single placeholder * entry with empty text instead of an empty array, so Werger still * has one group to attach translations to before a gloss exists. * When every filled sense is a template sense instead, this stays * empty — that mirrors trans.visible()'s hidden case, where there's * no group in the DOM for a placeholder to attach to anyway. */ glossList: function () { var dfnSenses = steps.dfn.getSenses($("#wiktku-start-dfn")); var glosses = []; var hasFilledTplSense = false; $.each(dfnSenses, function (i, s) { if (s.tpl) { if (s.tplTitle) hasFilledTplSense = true; return; // template sense — no gloss to caption with } var dfn = s.mane; if (!dfn) { // No mane text, but other fields (etîket/hevmane/nimûne/ // jêder…) are filled — dfn.getOutput() still emits this // sense as a numbered line using {{mane?|lang}}, so it // needs its own gloss group too, just with no caption text. if (senseHasExtraContent(s)) glosses.push({ index: i + 1, text: "" }); return; } if (dfn[0] !== dfn[0].toLowerCase()) dfn = decapitalize(dfn); dfn = stripWikilinks(dfn).replace(/[.…?!)\]،؟]+$/, ""); glosses.push({ index: i + 1, text: dfn }); }); if (!glosses.length && !hasFilledTplSense) { glosses.push({ index: 1, text: "" }); } return glosses; }, output: function (values) { if (values.lang !== "ku") return ""; var stepDiv = $("#wiktku-start-trans"); var glosses = steps.trans.glossList(); // Every sense is a template sense — there's no real gloss // anywhere and no group in the DOM either (glossList() only // returns empty in that case), so skip the section entirely. if (!glosses.length) return ""; // Each gloss now has its own group of translation rows — // attach every gloss's own words under its own werger-ser/-bin // pair instead of dumping everything under the first one. var blocks = $.map(glosses, function (gloss, gi) { var group = stepDiv.find(".wiktku-trans-group[data-gloss-pos='" + gi + "']"); var rows = group.length ? steps.trans.getGroupTranslations(group) : []; // Placeholder gloss (no real mane entered yet) with nothing // translated into it — nothing to output, and gloss.text is // empty so there's no caption to give {{werger-ser}} anyway. if (!gloss.text && !rows.length) return undefined; if (rows.length) { // Sort by Kurdish sort key. rows.sort(function (a, b) { var aLang = langsByCode[a[0]] || []; var bLang = langsByCode[b[0]] || []; return (aLang[2] || "").localeCompare(bLang[2] || "", "ku"); }); } var wordLines = $.map(rows, function (row) { var lang = row[0]; var words = row[1]; var wikiWords = words.map(function (w) { return "{{W|" + lang + "|" + w + "}}"; }).join(", "); return "* {{Z|" + lang + "}}: " + wikiWords; }).join("\n"); var block = "{{werger-ser|" + (gloss.text || "?") + "|" + gloss.index + "}}"; if (wordLines) block += "\n" + wordLines; block += "\n{{werger-bin}}"; return block; }); if (!blocks.length) return ""; return "\n==== Werger ====\n" + blocks.join("\n") + "\n"; } }, }; steps.trans.keys = steps.lang.choices; steps.dunde.keys = steps.lang.choices; steps.zarava.keys = getZaravaKeys(steps.lang.choices); var ordered_steps = [ steps.lang, steps.pron, steps.pos, steps.cinsiyet, steps.lektur, steps.tr, steps.dfn, steps.je, steps.tekildar, steps.etym, steps.dunde, steps.binereherwiha, steps.zarava, steps.trans]; // Step ids that belong to each section (not shared across sections). var PER_SECTION_STEP_IDS = [ "pos", "cinsiyet", "lektur", "tr", "dfn", "je", "tekildar", "etym", "dunde", "binereherwiha", "zarava", "trans" ]; // ── Multi-section state ────────────────────────────────────────────────── // Each entry is a plain snapshot: { pos, cinsiyet, lektur, tr, dfn (senses[]), // je, tekildar, binereherwiha, trans (rows[]) }. var sections = [{}]; // section 0 starts empty (DOM is the truth) var activeSection = 0; function snapshotDfn() { return steps.dfn.getSenses($("#wiktku-start-dfn")); } /** * Rebuild the dfn DOM from a previously snapshotted senses array. */ function restoreDfn(senses) { var stepDiv = $("#wiktku-start-dfn"); // Tear down the existing list so build() recreates it cleanly. stepDiv.find("ol.wiktku-dfn-list").remove(); steps.dfn.build(stepDiv); var list = stepDiv.find("ol.wiktku-dfn-list"); $.each(senses, function (i, sense) { // Ensure enough blocks exist (build() seeds one). var blocks = list.find("li.wiktku-dfn-sense"); var block = blocks.eq(i); if (!block.length) { var nb = steps.dfn.buildSenseBlock(stepDiv); list.append(nb); block = list.find("li.wiktku-dfn-sense").last(); } // Template selector. block.find("select.wiktku-dfn-tpl-select").val(sense.tpl || ""); if (sense.tpl) { block.find("textarea.wiktku-dfn-mane").hide(); block.find("input.wiktku-dfn-tpl-title").val(sense.tplTitle || "").show(); } else { block.find("textarea.wiktku-dfn-mane").val(sense.mane || "").show(); block.find("input.wiktku-dfn-tpl-title").hide().val(""); } // Re-sync the formên alternatîv/hevmane/… hide state now that // tplSelect's value was set programmatically (its own "change" // handler doesn't fire from .val(), so this doesn't happen otherwise). var updateVis = block.data("updateFieldVisibility"); if (updateVis) updateVis(); // Restore a sub-list (etiket, formên alternatîv, hevmane …) from a values array. function restoreSubList(cls, values) { if (!values || !values.length) return; var groupDiv = block.find("." + cls + "-group"); var subList = groupDiv.find("ol, ul").first(); if (!subList.length) return; // group not found // Fill existing items, append new ones as needed. $.each(values, function (j, val) { var items = subList.find("li"); if (j < items.length) { items.eq(j).find("textarea").val(val); } else { var ta = $("<textarea></textarea>") .attr("name", "wiktku-dfn-restore-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 1) .attr("class", "wiktku-dfn-subfield wiktku-start-narrow") .val(val); ta.on("input", function () { steps.dfn.onSubInput(subList, this, 1, true); }); subList.append($("<li></li>").append(ta)); } }); } // Reveal and populate lazy groups that have data. var lazyMap = { "wiktku-dfn-etiket": sense.etiket, "wiktku-dfn-kategori": sense.kategori, "wiktku-dfn-alternativ": sense.alternativ, "wiktku-dfn-hevmane": sense.hevmane, "wiktku-dfn-dijmane": sense.dijmane, "wiktku-dfn-koordine": sense.koordine, "wiktku-dfn-jornav": sense.jornav, "wiktku-dfn-jernav": sense.jernav }; $.each(lazyMap, function (cls, vals) { if (vals && vals.length) restoreSubList(cls, vals); }); // Nimûne items are objects { text, tr?, t? } — restore using the builder. if (sense.nimune && sense.nimune.length) { var nimuneGroupDiv = block.find(".wiktku-dfn-nimune-group"); var nimuneList = nimuneGroupDiv.find("ol.wiktku-dfn-nimune-list"); var buildFn = nimuneGroupDiv.data("buildNimuneLi"); nimuneList.empty(); $.each(sense.nimune, function (_, n) { var text = typeof n === "object" ? (n.text || "") : n; if (!text) return; var li = buildFn ? buildFn() : $("<li class='wiktku-dfn-nimune-li'></li>"); li.find(".wiktku-dfn-nimune-text").val(text); if (n.tr) li.find(".wiktku-dfn-nimune-tr").val(n.tr); if (n.t) li.find(".wiktku-dfn-nimune-t").val(n.t); nimuneList.append(li); }); // Always leave a blank trailing item. if (buildFn) nimuneList.append(buildFn()); } // Restore jêder (quote/citation) entries — a growing list, restored using the // builder just like Nimûne. Accepts either the current array shape or a // single legacy object (from older saved sections) for backwards compatibility. var jederArr = $.isArray(sense.jeder) ? sense.jeder : (sense.jeder ? [sense.jeder] : []); if (jederArr.length) { var jederGroupDiv = block.find(".wiktku-dfn-jeder-group"); var jederList = jederGroupDiv.find("ol.wiktku-dfn-jeder-list"); var buildJederFn = jederGroupDiv.data("buildJederLi"); jederList.empty(); $.each(jederArr, function (_, j) { if (!j || !j.quote) return; var li = buildJederFn ? buildJederFn() : $("<li class='wiktku-dfn-jeder-li'></li>"); li.find(".wiktku-dfn-nimune-quote").val(j.quote); if (j.quoteTr) li.find(".wiktku-dfn-nimune-quote-tr").val(j.quoteTr); if (j.quoteT) li.find(".wiktku-dfn-nimune-quote-t").val(j.quoteT); if (j.jederManual) { var manualSel = li.find(".wiktku-dfn-quote-src-sel"); manualSel.val("__manual__").trigger("change"); li.find(".wiktku-dfn-quote-src-manual").val(j.jederManual); } else if (j.jederTpl) { var srcSel = li.find(".wiktku-dfn-quote-src-sel"); srcSel.val(j.jederTpl).trigger("change"); if (j.jêderFields) { $.each(j.jêderFields, function (key, val) { li.find(".wiktku-dfn-quote-src-input[data-field-key='" + key + "']").val(val); }); } } jederList.append(li); }); // Always leave a blank trailing item, same as Nimûne. if (buildJederFn) jederList.append(buildJederFn()); } }); } /** * Snapshot simple (non-dfn) per-section steps from current DOM into obj. */ function saveCurrentSection() { var snap = {}; $.each(PER_SECTION_STEP_IDS, function (_, id) { if (id === "dfn") { snap.dfn = snapshotDfn(); return; } if (id === "etym") { snap.etym = $.trim($("#wiktku-start-etym .wiktku-etym-text").val()); return; } var step = steps[id]; if (!step) return; var stepDiv = $("#wiktku-start-" + id); if (id === "trans") { snap.trans = steps.trans.getTranslations(stepDiv); return; } if (id === "zarava") { snap.zarava = steps.zarava.getTranslations(stepDiv); return; } if (id === "dunde") { snap.dunde = steps.dunde.getRows(stepDiv); return; } // Generic: read all step fields. var fields = stepDiv.find(".wiktku-start-step-field"); if (step.multiple) { snap[id] = fields.map(function () { return $(this).val(); }).get(); } else { snap[id] = fields.val(); } }); sections[activeSection] = snap; } /** * Restore a previously saved snapshot into the form DOM. */ function restoreSection(snap) { $.each(PER_SECTION_STEP_IDS, function (_, id) { if (id === "dfn") { restoreDfn(snap.dfn || []); return; } if (id === "etym") { $("#wiktku-start-etym .wiktku-etym-wrap").remove(); steps.etym.build($("#wiktku-start-etym")); $("#wiktku-start-etym .wiktku-etym-text").val(snap.etym || ""); return; } if (id === "trans") { // Rebuild trans groups (dfn must already be restored by this // point in the $.each loop, so glossList() reflects it). var transDiv = $("#wiktku-start-trans"); transDiv.find(".wiktku-trans-group").remove(); steps.trans.build(transDiv); var groupsSnap = snap.trans || []; $.each(groupsSnap, function (gi, rows) { var group = transDiv.find(".wiktku-trans-group[data-gloss-pos='" + gi + "']"); if (!group.length) return; // gloss no longer exists — drop its rows var list = group.find("ul.wiktku-trans-list"); $.each(rows, function (j, row) { var lang = row[0], words = row[1]; var lastRow = list.find("li.wiktku-trans-row").last(); lastRow.find("select").val(lang).trigger("change"); var wordList = lastRow.find("ul.wiktku-trans-words"); $.each(words, function (k, word) { var wordItems = wordList.find("li"); if (k < wordItems.length) { wordItems.eq(k).find("textarea").val(word); } else { // .val() below doesn't fire "input", so the normal // auto-grow never runs — append a matching item // ourselves instead of silently dropping the word. var extraInput = steps.trans.makeWordInput(); wordList.append($("<li></li>").append(extraInput)); extraInput.val(word); } }); // Leave one trailing empty field so the row can still grow // when the user types, matching a freshly-built row. if ($.trim(wordList.children("li").last().find("textarea").val())) { wordList.append($("<li></li>").append(steps.trans.makeWordInput())); } }); }); return; } if (id === "zarava") { // Rebuild zarava groups (dfn must already be restored by this // point in the $.each loop, so glossList() reflects it). var zaravaDiv = $("#wiktku-start-zarava"); zaravaDiv.find(".wiktku-zarava-group").remove(); steps.zarava.build(zaravaDiv); var zaravaGroupsSnap = snap.zarava || []; $.each(zaravaGroupsSnap, function (gi, rows) { var group = zaravaDiv.find(".wiktku-zarava-group[data-gloss-pos='" + gi + "']"); if (!group.length) return; // gloss no longer exists — drop its rows var list = group.find("ul.wiktku-zarava-list"); $.each(rows, function (j, row) { var lang = row[0], words = row[1]; var lastRow = list.find("li.wiktku-zarava-row").last(); lastRow.find("select").val(lang).trigger("change"); var wordList = lastRow.find("ul.wiktku-zarava-words"); $.each(words, function (k, word) { var wordItems = wordList.find("li"); if (k < wordItems.length) { wordItems.eq(k).find("textarea").val(word); } else { var extraInput = steps.zarava.makeWordInput(); wordList.append($("<li></li>").append(extraInput)); extraInput.val(word); } }); if ($.trim(wordList.children("li").last().find("textarea").val())) { wordList.append($("<li></li>").append(steps.zarava.makeWordInput())); } }); }); return; } if (id === "dunde") { // Rebuild dunde rows. var dundeDiv = $("#wiktku-start-dunde"); dundeDiv.find("ul.wiktku-dunde-list").remove(); steps.dunde.build(dundeDiv); var dundeRows = snap.dunde || []; $.each(dundeRows, function (i, row) { var lang = row[0], words = row[1]; var list = dundeDiv.find("ul.wiktku-dunde-list"); var lastRow = list.find("li.wiktku-dunde-row").last(); lastRow.find("select").val(lang).trigger("change"); var wordList = lastRow.find("ul.wiktku-dunde-words"); $.each(words, function (j, word) { var wordItems = wordList.find("li"); if (j < wordItems.length) { wordItems.eq(j).find("textarea").val(word); } else { // .val() below doesn't fire "input", so the normal // auto-grow never runs — append a matching item // ourselves instead of silently dropping the word. var extraInput = steps.dunde.makeWordInput(); wordList.append($("<li></li>").append(extraInput)); extraInput.val(word); } }); // Leave one trailing empty field so the row can still grow // when the user types, matching a freshly-built row. if ($.trim(wordList.children("li").last().find("textarea").val())) { wordList.append($("<li></li>").append(steps.dunde.makeWordInput())); } }); return; } var step = steps[id]; if (!step) return; var stepDiv = $("#wiktku-start-" + id); var fields = stepDiv.find(".wiktku-start-step-field"); var val = snap[id]; if (val === undefined || val === null) return; if (step.multiple) { var arr = val; fields.each(function (i) { if (i < arr.length) $(this).val(arr[i]); }); } else { fields.val(val); } // Notify chosen widgets of the programmatic value change. if (!isMobile) fields.filter("select").trigger("chosen:updated"); }); } function getWikitextForCurrentSection(callback) { var values = getValues(); var entry = steps.pos.output(values); steps.dfn.getOutput(values, function (output) { entry += output; entry += steps.je.output(values); entry += steps.tekildar.output(values); entry += steps.etym.output(values); entry += steps.dunde.output(values); entry += steps.binereherwiha.output(values); entry += steps.zarava.output(values); entry += steps.trans.output(values); callback(entry, values); }); } function getWikitextAllSections(callback) { saveCurrentSection(); var results = new Array(sections.length); var sharedValues = getValues(); // lang/pron are shared function processSection(i) { if (i >= sections.length) { // All done — restore original active section. restoreSection(sections[activeSection]); refresh(); callback(results, sharedValues); return; } restoreSection(sections[i]); refresh(); getWikitextForCurrentSection(function (sectionText) { results[i] = sectionText; processSection(i + 1); }); } processSection(0); } /** * Assembles wikitext for all sections plus the shared lang/pron header. */ function getWikitext(callback) { getWikitextAllSections(function (sectionTexts, sharedValues) { var entry = steps.lang.output(sharedValues); entry += steps.pron.output(sharedValues); entry += sectionTexts.join("\n"); // Edit summary uses section 0's values. Read from the saved snapshot // (not the live DOM) so it doesn't mix section 0's pos with whichever // section happens to be active/restored at this point. var dfnSenses = (sections[0] && sections[0].dfn) || []; var dfnSummary = dfnSenses.map(function (s) { return s.mane; }).filter(Boolean).join("; "); var summary = "([[Mediawiki:Gadget-start.js|WF:NÛ]] v.2.0) +" + sharedValues.lang + ":" + sections[0].pos + ":" + dfnSummary; var summaryField = document.getElementById("wpSummary"); if (addLangMode && summaryField.value) { summary = summaryField.value + " " + summary; } summaryField.value = summary; callback(entry); }); } var continueBtn; function getValuesForStep(stepId) { var fields = $("#wiktku-start-" + stepId + " .wiktku-start-step-field"); var step = steps[stepId]; if (step.keys) { var values = {}; fields.each(function (i, field) { var key = $(field).prevAll(".wiktku-start-step-keyfield").val(); if (key) values[key] = $(field).val(); }); return values; } else if (step.multiple) { return fields.map(function () { return $(this).val(); }).get(); } return fields.val(); } function getValues() { var values = {}; $.each(steps, function (stepId) { values[stepId] = getValuesForStep(stepId); }); return values; } function populateMenus(inputs, choices, disabledValues) { if (!disabledValues) disabledValues = {}; var vals = inputs.map(function (i, input) { return $(input).val(); }); inputs.empty(); inputs.append($("<option></option>")); $.each(choices, function (j, choice) { // Append the language code in parentheses so that typing a code // (e.g. "ku") in the search box still finds the language name. var displayText = capitalize(choice[1]); if (choice[2] !== undefined) { // This is a language choice [code, name, sortKey] — show code. displayText = capitalize(choice[1]) + " (" + choice[0] + ")"; } var option = $(mw.html.element("option", { value: choice[0] }, displayText)); if (disabledValues[choice[0]]) option.prop("disabled", true); inputs.append(option); }); inputs.val(function (i) { return vals[i]; }); } /** * Returns a bitmap containing the keys that should be disabled for a key * menu in the given step because they are disabled or already taken by * another key menu. */ function getDisabledKeys(step) { var occupiedKeys = {}; $("#wiktku-start-" + step.id + " .wiktku-start-step-keyfield").each(function () { occupiedKeys[$(this).val()] = true; }); if (step.disabledKeys) $.extend(occupiedKeys, step.disabledKeys); return occupiedKeys; } function buildKeyInput(step) { if (!step.keys) return undefined; var input = $(mw.html.element("select", { "class": "wiktku-start-step-keyfield wiktku-start-narrow" })); input.attr("data-placeholder", "Hilbijêre " + step.keyName); if (isMobile) { populateMenus(input, step.keys, getDisabledKeys(step)); // On mobile return the wrapper; the select is inside it. // Change events still fire on the inner select. return wrapNativeSelect(input); } input.on("chosen:showing_dropdown", function () { $(this).data("wiktku-defaultValue", $(this).val()); }); input.change(function (_, context) { var inputs = $("#wiktku-start-" + step.id + " .wiktku-start-step-keyfield").not(this); var oldValue = $(this).data("wiktku-defaultValue"); var newValue = context.selected; inputs.find("option[value='" + oldValue + "']").prop('disabled', false); inputs.find("option[value='" + newValue + "']").prop('disabled', true); inputs.trigger("chosen:updated"); }); populateMenus(input, step.keys, getDisabledKeys(step)); return input; } /** * If the current text field has text and there are no more text fields after * the current text field in the list, add another text field to the list. */ function refreshForTextField(currentInput, step) { currentInput = $(currentInput); var value = currentInput.val(); var item = currentInput.parent(); if (value && !item.next("li").length) { var nextInput = $("<textarea></textarea>") .attr("name", "wiktku-field-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("class", currentInput.attr("class")) .attr("rows", currentInput.attr("rows") || 1); nextInput.on("input", function (evt) { refreshForTextField(evt.target, step); }); var nextKeyInput = buildKeyInput(step); var nextItem = $("<li></li>").append(nextKeyInput).append(nextInput); item.parent().append(nextItem); if (nextKeyInput) nextKeyInput.chosen(chosenOptions); } var canContinue = !continueBtn.isDisabled(); if ((value && !canContinue) || (!value && canContinue)) { refresh(step); } } function prepareInput(input, step) { if (!input) return; if (step.required) input.prop('required', true); input.change(step, refresh); } /** * Shows and hides all the steps based on whether their prerequisites are met, * and updates placeholders where applicable. */ function refresh(evt) { var values = getValues(); var changedStep = evt && evt.data; var didFocus = false; var canContinue = true; // Re-filter template options in every sense block whenever lang changes. $("#wiktku-start-dfn .wiktku-dfn-tpl-select").each(function () { var fn = $(this).data("updateOptions"); if (typeof fn === "function") fn(); }); // Re-filter pronunciation and etymology template dropdowns when language changes. steps.pron.refreshTplSelect(); steps.etym.refreshTplSelect(); // Sync tr/t sub-fields in every nimûne item to the current language. // tr shown when language needs transliteration; t shown when lang !== "ku". (function () { var lang = values.lang || ""; var showTr = needsTransliteration(lang); var showT = lang && lang !== "ku"; $("#wiktku-start-dfn .wiktku-dfn-nimune-list li.wiktku-dfn-nimune-li").each(function () { var li = $(this); // Ensure the sub-wrapper exists when we need it. var subWrap = li.find(".wiktku-dfn-nimune-sub"); // tr field var trTa = li.find(".wiktku-dfn-nimune-tr"); if (showTr && !trTa.length) { if (!subWrap.length) { subWrap = $("<div></div>").addClass("wiktku-dfn-nimune-sub"); li.append(subWrap); } trTa = $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-tr-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 5) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-tr") .attr("placeholder", "Transkrîpsiyon…"); subWrap.prepend(trTa); } else if (!showTr && trTa.length) { trTa.remove(); } // t field var tTa = li.find(".wiktku-dfn-nimune-t"); if (showT && !tTa.length) { if (!subWrap.length) { subWrap = $("<div></div>").addClass("wiktku-dfn-nimune-sub"); li.append(subWrap); } tTa = $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-t-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 5) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-t") .attr("placeholder", "Tercimeya nimûneyê kurmancî…"); subWrap.append(tTa); } else if (!showT && tTa.length) { tTa.remove(); } // Remove the wrapper if it ended up empty. subWrap = li.find(".wiktku-dfn-nimune-sub"); if (subWrap.length && !subWrap.children().length) subWrap.remove(); }); }()); // Sync tr/t sub-fields in every jêder citation to the current language. // tr shown when language needs transliteration; t shown when lang !== "ku". (function () { var lang = values.lang || ""; var showTr = needsTransliteration(lang); var showT = lang && lang !== "ku"; $("#wiktku-start-dfn .wiktku-dfn-jeder-list li.wiktku-dfn-jeder-li").each(function () { var li = $(this); // Ensure the sub-wrapper exists when we need it. It must sit right // after the quote textarea and before the source selector. var subWrap = li.find(".wiktku-dfn-quote-sub"); // tr field var trTa = li.find(".wiktku-dfn-nimune-quote-tr"); if (showTr && !trTa.length) { if (!subWrap.length) { subWrap = $("<div></div>").addClass("wiktku-dfn-quote-sub"); li.find(".wiktku-dfn-nimune-quote").after(subWrap); } trTa = $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-quote-tr-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 2) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-quote-tr") .attr("placeholder", "Transkrîpsiyona jêgirtinê…"); subWrap.prepend(trTa); } else if (!showTr && trTa.length) { trTa.remove(); } // t field var tTa = li.find(".wiktku-dfn-nimune-quote-t"); if (showT && !tTa.length) { if (!subWrap.length) { subWrap = $("<div></div>").addClass("wiktku-dfn-quote-sub"); li.find(".wiktku-dfn-nimune-quote").after(subWrap); } tTa = $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-quote-t-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 2) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-quote-t") .attr("placeholder", "Tercimeya jêgirtinê ya kurmancî…"); subWrap.append(tTa); } else if (!showT && tTa.length) { tTa.remove(); } // Remove the wrapper if it ended up empty. subWrap = li.find(".wiktku-dfn-quote-sub"); if (subWrap.length && !subWrap.children().length) subWrap.remove(); }); }()); $.each(steps, function (stepId, step) { if (typeof(step.visible) === "function" && !step.visible(values)) { $("#wiktku-start-" + stepId).slideUp(); } else { var stepDiv = $("#wiktku-start-" + stepId); if (changedStep !== step && typeof(step.build) === "function") { prepareInput(step.build(stepDiv, values), step); } var input = stepDiv.find(".wiktku-start-step-field"); if (typeof(step.example) === "function") { // .find() above already reaches nested fields (e.g. the dfn // step's mane textareas inside each sense block), so one // assignment covers every step; dfn keeps its own fallback. var exampleText = step.example(values) || (step.id === "dfn" ? "Mane…" : ""); input.attr("placeholder", exampleText); } var didSlideDown; if (!didFocus && stepDiv.css("display") === "none" && step.required) { didSlideDown = function (evt) { input.focus(); }; didFocus = true; } stepDiv.slideDown(didSlideDown); } if (step.required && (values[stepId] === "" || (step.multiple && values[stepId].join("") === ""))) { canContinue = false; } }); continueBtn.setDisabled(!canContinue); } function destroy() { $("#wiktku-start-form, .noafterwizard").slideUp(function () { $(this).remove(); }); $(".noarticletext .nowizard, #editform").slideDown(); $("#ca-edit").removeClass("selected"); $("#ca-wiktku-nowizard").addClass("selected"); } // Priority order for Kurdish dialects and the navz pseudo-code. // Codes listed here come before all other languages; unlisted codes // are sorted alphabetically by their display name via localeCompare. var LANG_PRIORITY = ["navz", "ku", "hac", "sdh", "lki", "ckb", "zza"]; /** * Inserts a new == {{ziman|code}} == section into existing page wikitext * at the correct sorted position: * 1. Any content before the first language section is preserved at the top. * 2. navz is always first, then ku/hac/sdh/lki/ckb/zza in that order, * then all other languages sorted by display name (localeCompare). */ function insertNewLangSection(existing, wikitext) { var newCodeMatch = wikitext.match(/^== \{\{ziman\|([^}]+)\}\} ==/); var newCode = newCodeMatch ? newCodeMatch[1] : ""; var sections = []; var preamble = ""; var firstMatch = existing.match(/(?:^|\n)== \{\{ziman\|/); if (!firstMatch) { // No existing lang sections at all — just append. var sep = existing && !/\n\s*$/.test(existing) ? "\n\n" : ""; return existing + sep + wikitext; } // Everything before the first == {{ziman|...}} == is the preamble. var firstSectionStart = existing.indexOf("== {{ziman|"); // Walk back to the start of that line. var lineStart = existing.lastIndexOf("\n", firstSectionStart - 1); var preambleEnd = lineStart !== -1 ? lineStart + 1 : 0; preamble = existing.slice(0, preambleEnd); // Parse each language section: header line + everything until the next header. var body = existing.slice(preambleEnd); // NOTE: with the /m flag, a bare "$" matches end-of-*line*, not just // end-of-string — that previously made the non-greedy content group // stop at the section's first line break instead of running to the // next language header (or the real end of the text), silently // dropping the rest of that section's wikitext. (?![\s\S]) matches // only the true end of the string, /m flag or not. var langSectionRe = /^(== \{\{ziman\|([^}]+)\}\} ==\n?)([\s\S]*?)(?=\n== \{\{ziman\||(?![\s\S]))/gm; var m; while ((m = langSectionRe.exec(body)) !== null) { sections.push({ code: m[2], content: m[0] // full text of this section including header }); } // Determine sort rank: priority list first (by index), then alphabetical. function getLangName(code) { var entry = langsByCode[code]; return entry ? entry[1] : code; } function sortRank(code) { var idx = LANG_PRIORITY.indexOf(code); return idx !== -1 ? idx : LANG_PRIORITY.length; } function compareLangs(a, b) { var ra = sortRank(a), rb = sortRank(b); if (ra !== rb) return ra - rb; // Both are outside priority list — sort by display name. return getLangName(a).localeCompare(getLangName(b), userLang); } // Insert the new section into the sorted list. var newSection = { code: newCode, content: wikitext }; var inserted = false; for (var i = 0; i < sections.length; i++) { if (compareLangs(newCode, sections[i].code) < 0) { sections.splice(i, 0, newSection); inserted = true; break; } } if (!inserted) sections.push(newSection); // Re-join: preamble + sections separated by newlines. var joined = sections.map(function (s) { // Ensure each section ends with exactly one newline before the next. return s.content.replace(/\n+$/, ""); }).join("\n"); return preamble + joined + "\n"; } function build() { $(".nowizard, .nowizard .noafterwizard").hide(); var callToAction = $("#wiktku-calltoaction"); var origCallToActionText = callToAction.text(); $(mw.util.addPortletLink("p-views", "#", "Edîtora çavkaniyê veke", "ca-wiktku-nowizard", "Vê rûpelê bi edîtora çavkaniyê çêke", undefined, "#ca-watch")).click(function (evt) { evt.preventDefault(); callToAction.text(origCallToActionText); destroy(); }); if (callToAction.length) { callToAction.text(origCallToActionText + " Forma li jêr ji bo çêkirina madeyeke nû bi kar bîne."); } var startForm = $("<form id='wiktku-start-form'></form>"); var clearPageCheck = null; if (addLangMode) { startForm.append($("<p class='wiktku-addlang-notice'></p>").html( "Bi vê formê tu yê beşeke nû li rûpelê îlawe bikî. Eger ev zimanê ku tu îlawe dikî jixwe di rûpelê de hebe, beşa nû li dawiya vî zimanî dê were îlawekirin. " + "Ji kerema xwe netîceya dawî kontrol bikin, eger problemek derkeve, li <a href='" + mw.util.getUrl('Mediawiki talk:Gadget-start.js') + "'>nîqaşa vê amûrê</a> problemê ragihîne." )); clearPageCheck = $("<input type='checkbox' id='wiktku-clear-page-check'>"); var clearPageLabel = $("<label for='wiktku-clear-page-check'></label>") .text(" Naveroka rûpelê paqij bike (rûpelê ji nû ve binivîse)"); startForm.append( $("<p class='wiktku-addlang-notice'></p>") .append(clearPageCheck) .append(clearPageLabel) ); // Re-evaluate step visibility (e.g. the pron step) whenever this // is toggled, since it changes what counts as "existing content". clearPageCheck.on("change", function () { refresh(); }); } var spinner; // Tab bar for switching between POS sections. var sectionTabsDiv = $("<div id='wiktku-section-tabs'></div>"); startForm.submit(function (evt) { evt.preventDefault(); continueBtn.setDisabled(true); spinner.show(); getWikitext(function (wikitext) { if (addLangMode && clearPageCheck && clearPageCheck.prop("checked")) { // User asked to wipe the page and start fresh — just // write the newly generated wikitext as the full content. $("#wpTextbox1").val(wikitext); } else if (addLangMode) { var textbox = $("#wpTextbox1"); var existing = textbox.val() || ""; // Check whether the generated lang header already exists in the page. // wikitext always starts with "== {{ziman|CODE}} ==\n" (from steps.lang.output). // If that exact section heading is already present in the existing content, // strip it from the new output and insert the remaining content at the end // of that lang section (just before the next == level-2 heading, or at the // very end of the page if there is no following section). var langHeaderMatch = wikitext.match(/^(== \{\{ziman\|[^}]+\}\} ==\n)/); if (langHeaderMatch) { var langHeader = langHeaderMatch[1]; // e.g. "== {{ziman|ku}} ==\n" // Escape for use in RegExp. var escapedHeader = langHeader.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); if (new RegExp(escapedHeader).test(existing)) { // Strip the header from the new output. var newContent = wikitext.slice(langHeader.length); // Find the insertion point: end of the existing lang section. // A new L2 heading marks the start of the next language block. var afterHeader = existing.indexOf(langHeader); var searchFrom = afterHeader + langHeader.length; // Find the next == … == heading after this section's start. var nextL2 = existing.indexOf("\n== ", searchFrom); var insertAt = nextL2 !== -1 ? nextL2 : existing.length; // Ensure there's a blank line before the inserted block. var before = existing.slice(0, insertAt); var after = existing.slice(insertAt); var sep = /\n\s*$/.test(before) ? "" : "\n"; textbox.val(before + sep + newContent + after); } else { // New language — insert at the correct sorted position. textbox.val(insertNewLangSection(existing, wikitext)); } } else { // Unexpected format — insert at sorted position anyway. textbox.val(insertNewLangSection(existing, wikitext)); } } else { $("#wpTextbox1").val(wikitext); } $("html, body").animate({scrollTop: 0}); callToAction.text("Hindik ma!"); $("#wiktku-preview-container").remove(); destroy(); }); }); $.each(ordered_steps, function (i, step) { var stepDiv = $(mw.html.element("div", { "class": "wiktku-start-step", id: "wiktku-start-" + step.id })); var name = capitalize(step.name); stepDiv.append($(mw.html.element("h3", { "class": "wiktku-start-step-name" }, new mw.html.Raw(mw.html.element("label", { "for": "wiktku-start-" + step.id + "-field" }, name))))); if (step.question_fmt) { stepDiv.append($(mw.html.element("label", { "class": "wiktku-start-step-question", "for": "wiktku-start-" + step.id + "-field" }, step.question_fmt))); if (step.question_br) stepDiv.append($("<br>")); } var input; if (step.choices) { input = $(mw.html.element("select", { "class": "wiktku-start-step-field", id: "wiktku-start-" + step.id + "-field" })); input.attr("data-placeholder", capitalize(step.name) + " hilbijêre "); populateMenus(input, step.choices); if (step.multiple) input.attr("multiple", true); if (isMobile) { stepDiv.append(wrapNativeSelect(input)); } else { stepDiv.append(input); } } else if (typeof(step.build) === "function") { input = step.build(stepDiv); } else { input = $("<textarea></textarea>") .attr("class", "wiktku-start-step-field") .attr("id", "wiktku-start-" + step.id + "-field") .attr("rows", step.rows || 2); if (step.narrow) input.addClass("wiktku-start-narrow"); if (step.multiple) { input.on("input", function (evt) { refreshForTextField(evt.target, step); }); var keyInput = buildKeyInput(step); var list = $(step.ordered ? "<ol></ol>" : "<ul></ul>") .append($("<li></li>").append(keyInput).append(input)); stepDiv.append(list); } else stepDiv.append(input); } prepareInput(input, step); stepDiv.hide(); // Insert tab bar just before the first per-section step. if (step.id === "pos") startForm.append(sectionTabsDiv); startForm.append(stepDiv); }); // ── Section tab helpers ────────────────────────────────────────────── // ── Add-section button — lives in the tab bar, disabled until pos chosen ── var addSectionBtn = new OO.ui.ButtonWidget({ label: "+ Beş zêde bike", disabled: true }); addSectionBtn.on("click", function () { saveCurrentSection(); sections.push({}); activeSection = sections.length - 1; $.each(PER_SECTION_STEP_IDS, function (_, id) { if (id === "dfn") { var stepDiv = $("#wiktku-start-dfn"); stepDiv.find("ol.wiktku-dfn-list").remove(); steps.dfn.build(stepDiv); return; } if (id === "etym") { $("#wiktku-start-etym .wiktku-etym-wrap").remove(); steps.etym.build($("#wiktku-start-etym")); return; } if (id === "trans") { var transDiv = $("#wiktku-start-trans"); transDiv.find(".wiktku-trans-group").remove(); return; } if (id === "zarava") { var zaravaDiv = $("#wiktku-start-zarava"); zaravaDiv.find(".wiktku-zarava-group").remove(); return; } if (id === "dunde") { var dundeDiv = $("#wiktku-start-dunde"); dundeDiv.find("ul.wiktku-dunde-list").remove(); return; } var stepDiv = $("#wiktku-start-" + id); stepDiv.find(".wiktku-start-step-field").val(""); if (!isMobile) stepDiv.find("select.wiktku-start-step-field").trigger("chosen:updated"); }); renderSectionTabs(); refresh(); $("html, body").animate({ scrollTop: sectionTabsDiv.offset().top - 20 }, 300); }); /** Re-render the tab bar to reflect current sections[] and activeSection. */ function renderSectionTabs() { // Detach (not remove) the button first: .empty() strips bound // event data from any children left inside it, which would // silently kill addSectionBtn's click handler on every re-render. addSectionBtn.$element.detach(); sectionTabsDiv.empty(); var lang = getValues().lang || ""; if (!lang) { sectionTabsDiv.hide(); return; } sectionTabsDiv.show(); $.each(sections, function (i) { var posVal = sections[i].pos || ""; var tabLabel = posVal ? capitalize(posVal) : ("Beş " + (i + 1)); var tab = $("<span></span>") .addClass("wiktku-section-tab") .text(tabLabel) .toggleClass("wiktku-tab-active", i === activeSection); (function (idx) { tab.on("click", function () { if (idx === activeSection) return; saveCurrentSection(); activeSection = idx; restoreSection(sections[activeSection]); refresh(); renderSectionTabs(); }); }(i)); sectionTabsDiv.append(tab); }); // Enable "Beş zêde bike" only when the active section has a pos chosen. var activePos = sections[activeSection] && sections[activeSection].pos ? sections[activeSection].pos : getValues().pos; addSectionBtn.setDisabled(!activePos); sectionTabsDiv.append(addSectionBtn.$element); } renderSectionTabs(); // Update the active tab's label whenever pos changes. startForm.on("change", "#wiktku-start-pos-field", function () { renderSectionTabs(); }); // Show the tab bar as soon as a language is selected. startForm.on("change", "#wiktku-start-lang-field", function () { renderSectionTabs(); }); var footer = $("<div id='wiktku-start-footer'></div>"); spinner = $(mw.html.element("img", { id: "wiktku-start-spinner", src: "//upload.wikimedia.org/wikipedia/commons/d/de/Ajax-loader.gif", alt: "Tê barkirin…", title: "Tê barkirin…" })); footer.append(spinner.hide()); continueBtn = new OO.ui.ButtonWidget({ id: "wiktku-unhide-editform", label: "Bişîne", flags: [ "primary", "progressive" ] }); continueBtn.on("click", function () { mw.notify("Tê şandin…", { type: "info", tag: "wiktku-submit" }); startForm.trigger("submit"); }); footer.append(continueBtn.$element); // "Edîtora çavkaniyê veke" button — inline fallback for the portlet link // which is invisible on mobile and easy to miss on desktop. var sourceEditorBtn = new OO.ui.ButtonWidget({ label: "Edîtora çavkaniyê veke", framed: false }); sourceEditorBtn.on("click", function () { destroy(); }); footer.append(sourceEditorBtn.$element); // ── Preview checkboxes ─────────────────────────────────────────────── // Wikitext preview (raw text panel) var previewCheck = $("<input type='checkbox' id='wiktku-preview-toggle'>"); var previewLabel = $("<label for='wiktku-preview-toggle'></label>") .text(" Pêşdîtina wîkîtekstê"); var previewPanel = $("<pre id='wiktku-preview-panel'></pre>").hide(); // Live rendered preview (parsed HTML panel, same logic as AjaxEdit). // Not available on mobile — API polling causes too many problems on small screens. var livePreviewCheck = null; var livePreviewPanel = null; if (!isMobile) { livePreviewCheck = $("<input type='checkbox' id='wiktku-live-preview-toggle'>"); livePreviewPanel = $("<div id='wiktku-live-preview-panel'></div>").hide(); } // Container that holds both panels and switches between stacked / side-by-side. var previewContainer = $("<div id='wiktku-preview-container'></div>"); previewContainer.append(previewPanel); if (!isMobile) previewContainer.append(livePreviewPanel); var previewTimer = null; var livePreviewIntervalId = -1; var livePreviewActive = false; // guards in-flight fetches after uncheck /** Rebuilds wikitext preview if its checkbox is checked. */ function schedulePreview() { if (!previewCheck.prop("checked")) return; clearTimeout(previewTimer); // Debounce: wait 400 ms after the last keystroke before rebuilding. previewTimer = setTimeout(function () { getWikitext(function (wikitext) { previewPanel.text(wikitext).show(); updatePanelLayout(); }); }, 400); } /** Fetches parsed HTML and populates the live preview panel. */ function loadLivePreview() { getWikitext(function (wikitext) { new mw.Api().parse(wikitext, { title: mw.config.get("wgPageName") }).done(function (html) { // Discard result if the user unchecked while the fetch was in flight. if (!livePreviewActive) return; livePreviewPanel.html(html).show(); updatePanelLayout(); }); }); } /** Adjusts panel widths depending on which previews are visible. */ function updatePanelLayout() { var wikitextVisible = previewCheck.prop("checked"); var liveVisible = livePreviewCheck && livePreviewCheck.prop("checked"); if (wikitextVisible && liveVisible) { // Side by side — each panel takes roughly half the available width. previewPanel.css({ "flex": "1 1 45%", "min-width": "280px" }); livePreviewPanel.css({ "flex": "1 1 45%", "min-width": "280px" }); } else { // Full width for whichever is visible — only touch panels that are // actually shown so that setting flex doesn't override display:none. if (wikitextVisible) previewPanel.css({ "flex": "1 1 100%", "min-width": "" }); if (liveVisible && livePreviewPanel) livePreviewPanel.css({ "flex": "1 1 100%", "min-width": "" }); } } previewCheck.on("change", function () { if ($(this).prop("checked")) { schedulePreview(); } else { clearTimeout(previewTimer); previewPanel.hide(); updatePanelLayout(); } }); if (!isMobile) { livePreviewCheck.on("change", function () { if ($(this).prop("checked")) { livePreviewActive = true; livePreviewPanel.show(); loadLivePreview(); livePreviewIntervalId = setInterval(loadLivePreview, 500); } else { livePreviewActive = false; clearInterval(livePreviewIntervalId); livePreviewIntervalId = -1; livePreviewPanel.hide().empty(); updatePanelLayout(); } }); } // Listen on all input/change events on the form and update both previews. startForm.on("input change", function () { schedulePreview(); }); footer.append($("<span style='margin-left:1em'></span>") .append(previewCheck).append(previewLabel)); if (!isMobile) { var livePreviewLabel = $("<label for='wiktku-live-preview-toggle'></label>") .text(" Pêşdîtina zindî"); footer.append($("<span style='margin-left:1em'></span>") .append(livePreviewCheck).append(livePreviewLabel)); } startForm.append(footer); $("#editform").hide().before(startForm); // Insert preview container (holds both panels) after the form. startForm.after(previewContainer); if (!isMobile) startForm.find("select").chosen(chosenOptions); refresh(); // Zimanan ji MediaWiki:Gadget-translation_editor.js/ziman.json bar bike. // Kodên ku bi "-pro" diqedin û navên ku "zimanê destan" tê de heye // tên derxistin. Zimanên xardkirî li serî dimînin, yên din // bi alfabeyê li dû wan tên. // Pinned choices come from MediaWiki:Gadget-start.js/data.json (langChoices), // already loaded into steps.lang.choices before build() runs. var pinnedChoices = steps.lang.choices.slice(); var pinnedCodes = $.map(pinnedChoices, function (choice) { return choice[0]; }); new mw.Api().get({ action: "query", prop: "revisions", titles: "MediaWiki:Gadget-translation_editor.js/ziman.json", rvprop: "content", rvslots: "main", formatversion: 2 }).then(function (data) { var page = data.query.pages[0]; var content = page && page.revisions && page.revisions[0].slots.main.content; var zimanData; try { zimanData = JSON.parse(content); } catch (e) { zimanData = {}; } var extraChoices = []; $.each(zimanData, function (code, name) { // Filter: skip proto-language codes and legendary/reconstructed langs. if (/-pro$/i.test(code)) return; if (/ziman[eê]\s+destan/i.test(name)) return; // Skip codes already in the pinned list (they are handled above). if (pinnedCodes.indexOf(code) !== -1) return; // sortKey: bare name without leading "zimanê " for sorting. var sortKey = name.replace(/^ziman[eê]\s+/i, ""); var choice = [code, name, sortKey]; extraChoices.push(choice); langsByCode[code] = choice; }); // Populate langsByCode for pinned choices too. $.each(pinnedChoices, function (i, choice) { // Ensure pinned choices have a sortKey (index 2). if (choice.length < 3) choice[2] = choice[1]; langsByCode[choice[0]] = choice; }); // Sort the extra choices alphabetically by sort key. extraChoices.sort(function (a, b) { return a[2].localeCompare(b[2], userLang); }); // Final list: pinned first, then the rest. var allChoices = pinnedChoices.concat(extraChoices); steps.lang.choices = allChoices; steps.trans.keys = allChoices; steps.dunde.keys = allChoices; steps.zarava.keys = getZaravaKeys(allChoices); var langMenu = $("#wiktku-start-lang-field"); populateMenus(langMenu, steps.lang.choices); langMenu.trigger("chosen:updated"); var transMenus = $("#wiktku-start-trans .wiktku-start-step-keyfield"); populateMenus(transMenus, steps.trans.keys, getDisabledKeys(steps.trans)); transMenus.trigger("chosen:updated"); var dundeMenus = $("#wiktku-start-dunde .wiktku-start-step-keyfield"); populateMenus(dundeMenus, steps.dunde.keys, getDisabledKeys(steps.dunde)); dundeMenus.trigger("chosen:updated"); var zaravaMenus = $("#wiktku-start-zarava .wiktku-start-step-keyfield"); populateMenus(zaravaMenus, steps.zarava.keys, getDisabledKeys(steps.zarava)); }); } mw.loader.using(["jquery.chosen", "mediawiki.api", "oojs-ui-core"], function () { if (!isMobile) { mw.notify( "Amûr dest pê dike, hinek bisekinin. Not: jkx Sentaks (sentaks highlighter) neaktîv bikin", { type: "info", tag: "wiktku-start-notice", autoHide: true, autoHideSeconds: 10 } ); } // Load metadata, langChoices, posChoices and tplDefs from the companion // data page so they can be updated without touching this script. new mw.Api().get({ action: "query", prop: "revisions", titles: "MediaWiki:Gadget-start.js/data.json", rvprop: "content", rvslots: "main", formatversion: 2 }).then(function (data) { var page = data.query.pages[0]; var content = page && page.revisions && page.revisions[0].slots.main.content; var d; try { d = JSON.parse(content); } catch (e) { d = {}; } // Populate metadata. if (d.metadata) $.extend(metadata, d.metadata); // Populate gender labels. if (d.genderLabels) $.extend(GENDER_BASE_LABELS, d.genderLabels); // Populate lang choices (pinned list used by build() → ziman.json loader). if (d.langChoices) steps.lang.choices = d.langChoices; // Populate POS choices. if (d.posChoices) steps.pos.choices = d.posChoices; // Populate template definitions for the dfn sense-block builder. if (d.tplDefs) steps.dfn.tplDefs = d.tplDefs; // Populate pos placeholder examples. if (d.posExamples) steps.dfn.posExamples = d.posExamples; // Populate citation template definitions for the quote widget. if (d.jederDefs) steps.dfn.jederDefs = d.jederDefs; // Populate pronunciation and etymology template insert lists. if (d.pronTpls) { steps.pron.pronTpls = d.pronTpls; steps.pron.refreshTplSelect(); } if (d.etymTpls) { steps.etym.etymTpls = d.etymTpls; steps.etym.refreshTplSelect(); } // Sync trans/dunde/zarava keys with the (now populated) lang choices. steps.trans.keys = steps.lang.choices; steps.dunde.keys = steps.lang.choices; steps.zarava.keys = getZaravaKeys(steps.lang.choices); }).always(build); }); }); //</nowiki> tc3vxm8fsgbo2q3bm3rylfbgdnwdppr 6265580 6265579 2026-07-19T15:00:54Z Wikihez 7344 6265580 javascript text/javascript // Li ser [[vi:MediaWiki:Gadget-start.js]] hatiye refaktorkirin. //<nowiki> $(function () { if (window.location.href.includes("editintro=User:Wikihez/creation/intro")) { return; // Do not run the script wextê WF:Bilez dişuxile } var ns = mw.config.get("wgNamespaceNumber"); if (ns && !(ns === 2 && mw.config.get("wgPageName").match(/\/ceribandin$|\/test$/))) { return; } var action = mw.config.get("wgAction"); var pageExists = !!mw.config.get("wgArticleId"); // "Zimanek lê zêde bike" mode: triggered from the portlet link below. var addLangMode = pageExists && mw.util.getParamValue("wiktkuaddlang") === "1"; // On a normal page view of an existing page, add the portlet link if (action === "view" && pageExists) { var targetContainer; var skin = mw.config.get('skin'); if (skin === 'vector-2022') { targetContainer = 'p-cactions'; } else if (skin === 'vector') { targetContainer = 'p-tb'; } else { targetContainer = 'p-views'; } mw.util.addPortletLink(targetContainer, mw.util.getUrl(mw.config.get("wgPageName"), { action: "submit", wiktkuaddlang: "1" }), "+Ziman/beşeke din", "ca-wiktku-addlang", "Ji vê rûpelê re ziman an jî beşeke nû zêde bike"); return; } if (!(action === "edit" || action === "submit")) { return; } if (!addLangMode && !$(".mw-newarticletext, .mw-newarticletextanon").length) { return; } function capitalize(str) { if (!str) return str; return str[0].toUpperCase() + str.substr(1); } function decapitalize(str) { if (!str) return str; return str[0].toLowerCase() + str.substr(1); } function escapeRegExp(str) { return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); } function stripWikilinks(str) { return str.replace(/\[\[([^\]|]+)(?:\|([^\]]+))?\]\]/g, function (m, target, display) { return display || target; }); } function insertAtCursor(el, text) { var start = el.selectionStart; var end = el.selectionEnd; var val = el.value; el.value = val.slice(0, start) + text + val.slice(end); var pos = start + text.length; el.selectionStart = el.selectionEnd = pos; } var pageName = mw.config.get("wgPageName").replaceAll(/_/g, " "); if (ns) pageName = pageName.replace(/.*\//, ""); var pageNameRe = escapeRegExp(pageName); var userLang = mw.config.get("wgUserLanguage"); // Mobile detection: MobileFrontend sets wgMFMode, or fall back to touch check. var isMobile = !!mw.config.get("wgMFMode") || window.matchMedia("(pointer: coarse)").matches; var chosenOptions = { width: "20em", disable_search_threshold: 0, placeholder_text_single: "Yekî hilbijêre", placeholder_text_multiple: "Hilbijêre", no_results_text: "Nehat dîtin", enable_split_word_search: true, search_contains: true }; function wrapNativeSelect(select) { var placeholder = select.attr("data-placeholder") || "Lê bigere…"; // Hide the native select — we drive it programmatically. select.hide(); var wrapper = $("<span class='wiktku-native-select-wrap'></span>"); var textInput = $("<input type='search' autocomplete='off'>") .attr("placeholder", placeholder) .addClass("wiktku-start-narrow wiktku-ac-input"); var resultsList = $("<ul class='wiktku-ac-results'></ul>").hide(); // Full option cache — rebuilt when chosen:updated fires. var allOptions = []; function cacheOptions() { allOptions = []; select.find("option").each(function () { var v = $(this).val(); if (!v) return; // skip the empty placeholder option allOptions.push({ value: v, text: $(this).text(), disabled: $(this).prop("disabled") }); }); } cacheOptions(); function showResults(query) { var q = query.trim().toLowerCase(); resultsList.empty(); var matched; if (q) { matched = []; $.each(allOptions, function (_, o) { if (o.disabled) return; var codeMatch = o.value.toLowerCase().indexOf(q) !== -1; var nameMatch = o.text.toLowerCase().indexOf(q) !== -1; if (codeMatch || nameMatch) { matched.push({ opt: o, codeMatch: codeMatch }); } }); // Code matches (especially prefix matches) come first. matched.sort(function (a, b) { var aCode = a.opt.value.toLowerCase(); var bCode = b.opt.value.toLowerCase(); var aPrefix = aCode.indexOf(q) === 0; var bPrefix = bCode.indexOf(q) === 0; if (aPrefix !== bPrefix) return aPrefix ? -1 : 1; if (a.codeMatch !== b.codeMatch) return a.codeMatch ? -1 : 1; return 0; }); matched = matched.map(function (item) { return item.opt; }); } else { matched = allOptions.filter(function (o) { return !o.disabled; }); } if (!matched.length) { resultsList.hide(); return; } $.each(matched.slice(0, 50), function (_, opt) { var li = $("<li></li>").text(opt.text).attr("data-value", opt.value); // Use touchend instead of touchstart so that a scroll gesture does // not accidentally select an item. We track whether the finger moved // between touchstart and touchend — if it did, it was a scroll. var touchMoved = false; li.on("touchstart", function () { touchMoved = false; }); li.on("touchmove", function () { touchMoved = true; }); li.on("touchend", function (e) { if (touchMoved) return; // was a scroll, not a tap e.preventDefault(); selectOption(opt.value, opt.text); }); // Keep mousedown for desktop fallback. li.on("mousedown", function (e) { e.preventDefault(); selectOption(opt.value, opt.text); }); resultsList.append(li); }); // Position the list above or below depending on available viewport space. var inputRect = textInput[0].getBoundingClientRect(); var viewportH = window.innerHeight; var spaceBelow = viewportH - inputRect.bottom - 8; var spaceAbove = inputRect.top - 8; var maxH = Math.min(224, Math.max(spaceBelow, spaceAbove)); // 224px ≈ 14em resultsList.css({ "max-height": maxH + "px", "top": spaceBelow >= spaceAbove ? "100%" : "auto", "bottom": spaceBelow >= spaceAbove ? "auto" : "100%" }); resultsList.show(); } function selectOption(value, text) { textInput.val(text); select.val(value); resultsList.hide(); select.trigger("change"); } textInput.on("input focus", function () { showResults($(this).val()); }); textInput.on("blur", function () { // Short delay so a touchstart on a result item fires first. setTimeout(function () { resultsList.hide(); }, 200); }); // chosen:updated → re-cache (called after ziman.json loads). select.on("chosen:updated", function () { cacheOptions(); // If a value is already selected, keep the display text in sync. var cur = select.val(); if (cur) { var match = $.grep(allOptions, function (o) { return o.value === cur; })[0]; if (match) textInput.val(match.text); } }); // No-op .chosen() so desktop call-sites don't need guarding. select.chosen = function () { return select; }; wrapper.append(textInput).append(resultsList).append(select); return wrapper; } var langsByCode = {}; // Populated from [[MediaWiki:Gadget-start.js/data.json]] at runtime. var metadata = {}; // Zaravayên kurdî yên ku di beşa "Bi zaravayên din" de tên pêşkêşkirin — // ev kod ji beşa Werger têne derxistin daku heman zimên du caran neyê xwendin. var ZARAVA_LANG_CODES = ["ckb", "sdh", "lki", "hac", "zza"]; function getZaravaKeys(choices) { var byCode = {}; $.each(choices || [], function (_, c) { byCode[c[0]] = c; }); var result = []; $.each(ZARAVA_LANG_CODES, function (_, code) { if (byCode[code]) result.push(byCode[code]); }); return result; } function needsTransliteration(langCode) { var meta = metadata[langCode]; if (!meta || !meta.sc) return false; var scripts = Array.isArray(meta.sc) ? meta.sc : [meta.sc]; return scripts.length > 0 && scripts[0] !== "Latn"; } // Kodên cinsiyetê yên di metadata.g de — ji data.json tê dagirtin var GENDER_BASE_LABELS = {}; // Sub-lists that only make sense for a plain (non-şablon) sense — hidden // when a şablon (e.g. {{guharto|…}}) is chosen for that sense, since a // template-based sense has no "own" gloss for alternate forms, synonyms, // antonyms, coordinate terms, hypernyms or hyponyms to attach to. Etîket, // Nimûne and Jêgirtin stay visible either way. var HIDDEN_ON_TPL_GROUPS = [ "wiktku-dfn-alternativ", "wiktku-dfn-hevmane", "wiktku-dfn-dijmane", "wiktku-dfn-koordine", "wiktku-dfn-jornav", "wiktku-dfn-jernav" ]; function genderLabel(code) { if (code === "p") return "Pirjimar"; var pluralMatch = code.match(/^(.+)-p$/); if (pluralMatch && GENDER_BASE_LABELS[pluralMatch[1]]) { return GENDER_BASE_LABELS[pluralMatch[1]] + " (pirjimar)"; } return GENDER_BASE_LABELS[code] || code; } /** * True if a sense has any content worth keeping besides its mane text — * etîket, hevmane/dijmane/koordîne/etc. word lists, nimûne, or jêder * (quote). Used so a sense with an empty mane but filled-in extra * fields still gets emitted (with {{mane?}} standing in for the gloss) * instead of being silently dropped. */ function senseHasExtraContent(s) { if (s.etiket && $.grep(s.etiket, function (e) { return $.trim(e) !== ""; }).length) return true; if (s.kategori && $.grep(s.kategori, function (k) { return $.trim(k) !== ""; }).length) return true; if (s.alternativ.length || s.hevmane.length || s.dijmane.length || s.koordine.length || s.jornav.length || s.jernav.length) return true; if (s.nimune && $.grep(s.nimune, function (n) { return (typeof n === "object" ? n.text : n) !== ""; }).length > 0) return true; if (senseHasJeder(s)) return true; return false; } /** * formatNimune: each nimûne item can be { text, tr, t }: * text — example text * tr — transliteration (only when the language needs it) * t — Kurdish translation (third positional param, no key) */ function formatNimune(nimunes, lang, hasJeder) { var hasNimune = nimunes && $.grep(nimunes, function (n) { return (typeof n === "object" ? n.text : n) !== ""; }).length > 0; if (!hasNimune) { return hasJeder ? "" : "\n#* {{bênimûne|" + lang + "}}"; } return $.map(nimunes, function (n) { var text = typeof n === "object" ? n.text : n; if (!text) return undefined; var bolded = text.replace( new RegExp("(" + pageNameRe + "([^( |,|;|\\?|\\.|\\!)]+)?)", "ig"), "'''$1'''"); var tpl = "\n#: {{nm|" + lang + "|" + bolded; if (typeof n === "object") { if (n.tr) tpl += "|tr=" + n.tr; // Translation as third positional param (no key needed). if (n.t) tpl += "|" + n.t; } // Short examples fit on one line together with their translation. // rêz=1 is not used for ku — definitions are shown on separate lines there. if (text.length < 200 && lang !== "ku") tpl += "|rêz=1"; tpl += "}}"; return tpl; }).join(""); } /** * Formats a list of jêder (quote/citation) objects into wikitext lines. * Each entry that has no quote text is skipped. Returns "" when the list * is empty or every entry is blank. * * #* {{jêder-…|lang|jêgirtin=…|tr=…|tercime=…|…fields…}} * * When no template is chosen, the generic {{jêder|…}} template is used * instead. Its 2nd positional param is the user's freeform "bi destê xwe * binivîsim" source text when supplied, or the çavkanî? placeholder otherwise. * If that text contains "=" it is passed as |2=… instead of a bare * positional param, since MediaWiki would otherwise misparse it as its * own key=value pair and break the template: * #* {{jêder|lang|jêgirtin=…|tr=…|tercime=…|<manual source or çavkanî?>}} */ function formatJeder(jederList, lang) { if (!jederList || !jederList.length) return ""; return $.map(jederList, function (jeder) { if (!jeder || !jeder.quote) return undefined; if (jeder.jederTpl) { var cite = "\n#* {{" + jeder.jederTpl + "|" + lang; cite += "|jêgirtin=" + jeder.quote; if (jeder.quoteTr) cite += "|tr=" + jeder.quoteTr; if (jeder.quoteT) cite += "|tercime=" + jeder.quoteT; $.each(jeder.jêderFields || {}, function (key, val) { if (val) cite += "|" + key + "=" + val; }); cite += "}}"; return cite; } var out = "\n#* {{jêder|" + lang + "|jêgirtin=" + jeder.quote; if (jeder.quoteTr) out += "|tr=" + jeder.quoteTr; if (jeder.quoteT) out += "|tercime=" + jeder.quoteT; var srcParam = jeder.jederManual ? jeder.jederManual : "çavkanî?"; // A positional param containing "=" gets parsed as its own key=value // pair by MediaWiki and breaks the template, so force it to be // explicitly named (|2=) whenever that's the case. out += (srcParam.indexOf("=") !== -1 ? "|2=" : "|") + srcParam; out += "}}"; return out; }).join(""); } /** * True if a sense has at least one jêder entry with actual quote text. */ function senseHasJeder(sense) { return !!(sense.jeder && $.grep(sense.jeder, function (j) { return j && j.quote; }).length > 0); } /** * Builds a "{{tplName|lang|part1|part2|…}}" snippet from a sense field * (e.g. kategorî or etîket), wrapped to match how that template is used * inline in the output — or "" if the field has nothing filled in. * * buildSenseTpl(sense, "kategori", lang, "K", "block") * → "\n#: {{K|lang|cat1|cat2|…}}" (its own line, like katTpl) * buildSenseTpl(sense, "etiket", lang, "e", "inline") * → " {{e|lang|label1|label2|…}} " (sits inline, like labelTpl) */ function buildSenseTpl(sense, field, lang, tplName, format) { if (!sense[field] || !sense[field].length) return ""; var parts = sense[field].map(function (p) { return $.trim(p); }) .filter(function (p) { return p !== ""; }); if (!parts.length) return ""; var call = "{{" + tplName + "|" + lang + "|" + parts.join("|") + "}}"; return format === "block" ? "\n#: " + call : " " + call + " "; } /** * Assembles the nimûne + jêder wikitext block for a sense. Shared by * both the template-sense and normal-mane-sense branches below. */ function buildCite(sense, lang) { return formatNimune(sense.nimune, lang, senseHasJeder(sense)) + formatJeder(sense.jeder, lang); } function makeWordListStep(id, name, question_fmt, header, templateName) { return { id: id, name: name, question_fmt: question_fmt, multiple: true, narrow: true, visible: function (values) { return values.lang && values.pos; }, output: function (values) { var words = $.grep(values[id] || [], function (w) { return !!w; }); if (!words.length) return ""; var lang = values.lang; var section = "\n==== " + header + " ====\n"; if (words.length === 1) { // Single word — keep the simple inline template. return section + "* {{" + templateName + "|" + lang + "|" + words[0] + "}}\n"; } // Multiple words — use {{kol3}} with one positional param per word. var params = "cure=" + header + "\n" + $.map(words, function (w) { return "|" + w; }).join("\n"); return section + "{{kol3|" + lang + "|" + params + "\n}}\n"; } }; } var steps = { lang: { id: "lang", required: true, name: "ziman", question_fmt: '"' + pageName + '" bi çi zimanî ye?', question_br: true, // Populated from [[MediaWiki:Gadget-start.js/data.json]] (langChoices). choices: [], output: function (values) { return "== {{ziman|" + values.lang + "}} ==\n"; } }, pron: { id: "pron", name: "bilêvkirin", question_fmt: '"' + pageName + '" çawa tê telafûzkirin?', // pronTpls populated from data.json pronTpls: [], visible: function (values) { if (!values.lang) return false; // In addLangMode, only skip pron when this langcode's section // already exists in the page — if it's a new language, show it. if (addLangMode) { // If the user wants to wipe the page and start over, the // existing content is irrelevant — always show pron. var clearPageCheck = $("#wiktku-clear-page-check"); if (clearPageCheck.length && clearPageCheck.prop("checked")) { return true; } var existing = $("#wpTextbox1").val() || ""; var header = "== {{ziman|" + values.lang + "}} =="; return existing.indexOf(header) === -1; } return true; }, /** Fills (or refills) the insert-dropdown from the current pronTpls array, filtering by language. */ refreshTplSelect: function () { var sel = $("#wiktku-start-pron .wiktku-tpl-insert-select"); if (!sel.length) return; var lang = getValues().lang || ""; sel.find("option[value!='']").remove(); $.each(steps.pron.pronTpls, function (_, tpl) { // Filter: if tpl.langs exists, only show if lang is in that list; otherwise show always var allowed = !tpl.langs || tpl.langs.indexOf(lang) !== -1; if (allowed) { sel.append($("<option></option>") .val(tpl.snippet) .text(tpl.name + " — " + tpl.desc) .attr("data-nolang", tpl.noLang ? "1" : "")); } }); // Notify Chosen that the option list has changed (no-op on mobile). if (!isMobile) sel.trigger("chosen:updated"); }, build: function (stepDiv) { if (stepDiv.find(".wiktku-pron-wrap").length) return null; var wrap = $("<div class='wiktku-pron-wrap'></div>"); var ta = $("<textarea></textarea>") .attr("name", "wiktku-pron-" + $.now()) .attr("class", "wiktku-start-step-field wiktku-pron-text") .attr("rows", 4) .attr("placeholder", "Nimûne: {{IPA|ku|/pɛɪ̯n/}} yan {{kîte|ku|he|ce|ki|rin}}"); // Template insert dropdown — filtered by language. var sel = $("<select class='wiktku-tpl-insert-select'></select>"); sel.append($("<option value=''>— şablonek lê zêde bike —</option>")); var lang = getValues().lang || ""; $.each(steps.pron.pronTpls, function (_, tpl) { // Filter: if tpl.langs exists, only show if lang is in that list; otherwise show always var allowed = !tpl.langs || tpl.langs.indexOf(lang) !== -1; if (allowed) { sel.append($("<option></option>") .val(tpl.snippet) .text(tpl.name + " — " + tpl.desc) .attr("data-nolang", tpl.noLang ? "1" : "")); } }); sel.on("change", function () { var snippet = $(this).val(); if (!snippet) return; var lang = getValues().lang || ""; // Check if the selected option has noLang flag var selectedOption = sel.find("option:selected"); var hasNoLang = selectedOption.attr("data-nolang") === "1"; if (!hasNoLang) { snippet = snippet.replace(/CODE/g, lang).replace(/SOURCELANG/g, "?"); } insertAtCursor(ta[0], snippet); $(this).val(""); ta.focus(); }); wrap.append(sel).append($("<br>")).append(ta); stepDiv.append(wrap); return ta; }, output: function () { var text = $.trim($("#wiktku-start-pron .wiktku-pron-text").val()); if (!text) return ""; var lines = text.split("\n"); var out = $.map(lines, function (line) { line = $.trim(line); if (!line) return undefined; return line.charAt(0) === "*" ? line : "* " + line; }).join("\n"); return "\n=== Bilêvkirin ===\n" + out + "\n"; } }, pos: { id: "pos", required: true, name: "Cureyê rêzimanî", question_fmt: 'Cureyê rêzimanî yê "' + pageName + '" çi ye?', visible: function (values) { return values.lang; }, question_br: true, // Populated from [[MediaWiki:Gadget-start.js/data.json]] (posChoices). choices: [], output: function (values) { var pos = values.pos || ""; var cinsiyet = values.cinsiyet || ""; // from the cinsiyet step var lekTur = values.lektur || ""; // from the lêker transitivity step var capitalizedPos = capitalize(pos); var outputString = "\n=== " + capitalizedPos + " ===\n"; // Add ku-tewîn-nav for single-word navdêr/serenav with known gender. if (!pageName.includes(" ") && cinsiyet && GENDER_BASE_LABELS[cinsiyet] && (pos === "navdêr" || pos === "serenav") && values.lang === "ku") { outputString += "{{ku-tewîn-nav|" + pageName + "|" + GENDER_BASE_LABELS[cinsiyet]; if (pos === "serenav") outputString += "|y"; outputString += "}}\n"; } outputString += "{{" + pos + "|" + values.lang; if (pos === "navdêr" || pos === "serenav") { if (cinsiyet) { outputString += "|c=" + cinsiyet; } else if (values.lang === "ku") { // Unknown gender — prompt editor to fill it in. outputString += "|c=?"; } } else if (/^lêker/.test(pos) && lekTur) { outputString += "|c=" + lekTur; } if (values.tr) { outputString += "|tr=" + values.tr; } outputString += "}}\n"; return outputString; } }, /** * cinsiyet (grammatical gender) — only shown for navdêr/serenav, û * tenê ger metadata ji bo zimanê hilbijartî lîsteyeke "g" (cinsiyet) * were dayîn. Opsiyonên vê gavê ne sabît in — ji metadata[values.lang].g * têne çêkirin, ji ber ku di hemû zimanan de cinsiyet tine. */ cinsiyet: { id: "cinsiyet", name: "cinsiyet", question_fmt: 'Cinsiyeta "' + pageName + '" çi ye?', question_br: true, visible: function (values) { var meta = metadata[values.lang]; return !!(values.lang && (values.pos === "navdêr" || values.pos === "serenav") && meta && meta.g && meta.g.length); }, build: function (stepDiv, values) { var select = stepDiv.find("select.wiktku-start-step-field"); if (!select.length) { select = $(mw.html.element("select", { "class": "wiktku-start-step-field", id: "wiktku-start-cinsiyet-field" })); stepDiv.append(select); } if (!values) return select; var meta = metadata[values.lang]; var codes = (meta && meta.g) || []; var prevVal = select.val(); var choices = $.map(codes, function (code) { return [[code, genderLabel(code)]]; }); populateMenus(select, choices); if ($.grep(choices, function (c) { return c[0] === prevVal; }).length) { select.val(prevVal); } if (!isMobile) select.trigger("chosen:updated"); return select; }, output: function () { return ""; } // consumed by pos.output }, /** * Lêker transitivity — only shown for any lêker variant. */ lektur: { id: "lektur", name: "Cureyê lêkerê (fiîlê)", question_fmt: "Cureyê lêkerê (fiîlê) çi ye?", question_br: true, visible: function (values) { return values.lang && values.pos && /^lêker/.test(values.pos); }, // Dictionary: value → display label. Add new types here. choices: [ ["gh", "gerguhêz"], ['x-gh', 'xwerû-gerguhêz'], ['p-gh', 'pêkhatî-gerguhêz'], ['h-gh', 'hevedudanî-gerguhêz'], ['b-gh', 'biwêjî-gerguhêz'], ["ngh", "negerguhêz"], ['x-ngh', 'xwerû-negerguhêz'], ['p-ngh', 'pêkhatî-negerguhêz'], ['h-ngh', 'hevedudanî-negerguhêz'], ['b-ngh', 'biwêjî-negerguhêz'] ], output: function () { return ""; } // consumed by pos.output }, tr: { id: "tr", name: "transkrîpsiyon", question_fmt: "Transkrîpsiyona kelîmeyê", multiple: false, narrow: true, visible: function (values) { return values.lang && values.pos && needsTransliteration(values.lang); } }, dfn: { id: "dfn", // required: true, ger mane tinebe [[Şablon:mane?]] bi kar bîne name: "Mane", question_fmt: "Maneya kelîmeyê binivîse. Mane otomatîk tê lînkkirin! Ji bo tercimeyan beşa 'Werger' bi kar bîne!", multiple: true, ordered: true, rows: 3, visible: function (values) { return values.lang && values.pos; }, example: function (values) { // posExamples loaded from [[MediaWiki:Gadget-start.js/data.json]]. var examples = steps.dfn.posExamples || {}; var full = values.pos || ""; return examples[full] || ""; }, /** * Builds one sense block (<li>) inside the ordered list. * Each block contains: * - a textarea for the definition * - an expandable nimûne list * - single-row sub-lists for formên alternatîv, hevmane, dijmane */ buildSenseBlock: function (stepDiv) { var block = $("<li class='wiktku-dfn-sense'></li>"); // — Mane textarea (declared first so the template handler can reference it) — var dfnArea = $("<textarea></textarea>") .attr("name", "wiktku-dfn-mane-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("class", "wiktku-start-step-field wiktku-dfn-mane") .attr("rows", 6) .attr("placeholder", "Mane…"); dfnArea.on("input", function () { steps.dfn.onDfnInput(stepDiv, block, this); }); // — Template selector (optional — replaces mane when chosen) — // Template definitions loaded from [[MediaWiki:Gadget-start.js/data.json]]. var tplDefs = steps.dfn.tplDefs || []; // Cache of all non-placeholder option elements — used by updateTplOptions // to remove/re-add options (the only approach compatible with Chosen.js). var _allTplOptions = []; var tplSelect = $(mw.html.element("select", { "class": "wiktku-dfn-tpl-select" })); tplSelect.append($("<option value=''>— yan jî şablonek hilbijêre —</option>")); $.each(tplDefs, function (_, tpl) { var opt = $("<option></option>") .val(tpl.name) .text(tpl.name) .attr("data-langs", tpl.langs ? tpl.langs.join(",") : "") .attr("data-nolang", tpl.noLang ? "1" : ""); tplSelect.append(opt); _allTplOptions.push(opt[0]); }); function updateTplOptions() { var lang = getValues().lang || ""; var currentVal = tplSelect.val(); var currentStillValid = false; // Detach all non-placeholder options, then re-attach only the visible ones. // This is the only approach that works correctly with both native <select> // and Chosen.js on desktop. tplSelect.find("option[value!='']").detach(); $.each(_allTplOptions, function (_, opt) { var allowed = $(opt).attr("data-langs"); var visible = !allowed || allowed.split(",").indexOf(lang) !== -1; if (visible) { tplSelect.append(opt); if ($(opt).val() === currentVal) currentStillValid = true; } }); if (!isMobile) tplSelect.trigger("chosen:updated"); if (currentVal && !currentStillValid) { tplSelect.val(""); dfnArea.show(); tplTitleInput.hide().val(""); } } // Store updater on the element so refresh() can call it for all blocks. tplSelect.data("updateOptions", updateTplOptions); var tplTitleInput = $("<input type='text'>") .addClass("wiktku-dfn-tpl-title wiktku-start-narrow") .attr("placeholder", "Navê rûpelê…") .hide(); // Grow the sense list when the title field of the last block gets content, // mirroring what onDfnInput does for the plain mane textarea. tplTitleInput.on("input", function () { steps.dfn.onDfnInput(stepDiv, block, this); }); /** * When a şablon sense is chosen, formên alternatîv/hevmane/dijmane/ * termên koordîne/jornav/jêrnav don't apply (there's no plain gloss * to hang them off), so hide those subgroups. Etîket, Nimûne and * Jêgirtin stay visible and still usable for a şablon sense. */ function updateFieldVisibility() { var isTpl = !!tplSelect.val(); $.each(HIDDEN_ON_TPL_GROUPS, function (_, cls) { block.find("." + cls + "-group").toggle(!isTpl); }); } // Store on the block so restoreDfn() can re-sync visibility // after programmatically setting tplSelect's value. block.data("updateFieldVisibility", updateFieldVisibility); tplSelect.on("change", function () { var chosen = $(this).val(); if (chosen) { dfnArea.hide(); tplTitleInput.show().focus(); } else { dfnArea.show(); tplTitleInput.hide().val(""); } updateFieldVisibility(); // Re-run refresh so the Werger step visibility updates. refresh(); }); var tplRow = $("<div></div>").addClass("wiktku-dfn-tpl-row") .append(tplSelect).append(" ").append(tplTitleInput); block.append(tplRow); block.append(dfnArea); // Apply lang filter on initial build. updateTplOptions(); // — Sub-field groups — // All groups are always visible with a placeholder textarea. // Nimûne is last in the DOM and last in the output. var allGroups = [ { cls: "wiktku-dfn-etiket", label: "Etîket", rows: 1, narrow: true, izah: "xisûsen, Mêrdîn, anatomî, Badînî" }, { cls: "wiktku-dfn-kategori", label: "Kategorî", rows: 1, narrow: true, izah: "Kategoriya ku ev mane lê tê zêdekirin" }, { cls: "wiktku-dfn-alternativ", label: "Formên alternatîv", rows: 1, narrow: true, izah: "Varyantên vê kelîmeyê" }, { cls: "wiktku-dfn-hevmane", label: "Hevmane", rows: 1, narrow: true, izah: "Spehî hevmaneya Bedew e." }, { cls: "wiktku-dfn-dijmane", label: "Dijmane", rows: 1, narrow: true, izah: "Zengîn dijmaneya feqîr e." }, { cls: "wiktku-dfn-koordine", label: "Termên koordîne", rows: 1, narrow: true, izah: "Pisîk û kûçik termên koordîne ne çunkî Jornavên wan gelek in" }, { cls: "wiktku-dfn-jornav", label: "Jornav", rows: 1, narrow: true, izah: "Heywan jornavê guhandar e" }, { cls: "wiktku-dfn-jernav", label: "Jêrnav", rows: 1, narrow: true, izah: "Guhandar jêrnavê heywan e" }, { cls: "wiktku-dfn-nimune", label: "Nimûne", rows: 2, narrow: false } ]; $.each(allGroups, function (_, g) { var groupDiv = $("<div></div>").addClass("wiktku-dfn-subgroup " + g.cls + "-group"); function buildNimuneLi() { var lang = getValues().lang || ""; var li = $("<li></li>").addClass("wiktku-dfn-nimune-li"); var mainTa = $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-text-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", g.rows) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-text") .attr("placeholder", "Nimûneya emilandina kelîmeyê tu bi xwe binivîse…"); mainTa.on("input", function () { var val = $.trim($(this).val()); var isLast = li.is(list.children("li:last-child")); if (val && isLast) { list.append(buildNimuneLi()); } }); li.append(mainTa); var subWrap = $("<div></div>").addClass("wiktku-dfn-nimune-sub"); if (needsTransliteration(lang)) { subWrap.append( $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-tr-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 5) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-tr") .attr("placeholder", "Transkrîpsiyona bi alfabeya latînî") ); } if (lang && lang !== "ku") { subWrap.append( $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-t-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 5) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-t") .attr("placeholder", "Tercimeya kurmancî") ); } if (subWrap.children().length) li.append(subWrap); return li; } if (g.cls === "wiktku-dfn-nimune") { // Nimûne — compound widget with tr/t sub-fields. var lbl = $("<span></span>").addClass("wiktku-dfn-sublabel").text(g.label + ": "); var list = $("<ol></ol>").addClass("wiktku-dfn-sublist " + g.cls + "-list"); groupDiv.data("buildNimuneLi", buildNimuneLi); list.append(buildNimuneLi()); groupDiv.append(lbl).append(list); block.append(groupDiv); } else { // Regular always-visible group — label + growing textarea list. var lbl = $("<span></span>").addClass("wiktku-dfn-sublabel").text(g.label + ": " + g.izah); var list = $("<ol></ol>").addClass("wiktku-dfn-sublist " + g.cls + "-list"); var firstInput = $("<textarea></textarea>") .attr("name", g.cls + "-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", g.rows) .attr("class", "wiktku-dfn-subfield" + (g.narrow ? " wiktku-start-narrow" : "")) .attr("placeholder", g.label + "…"); firstInput.on("input", function () { steps.dfn.onSubInput(list, this, g.rows, g.narrow); }); list.append($("<li></li>").append(firstInput)); groupDiv.append(lbl).append(list); block.append(groupDiv); } }); // — Jêder (quote / citation) group — a growing list, sibling to Nimûne — // Structured the same way as Nimûne (ol.wiktku-dfn-sublist > li) so it // lines up at the same indentation, and so that typing into the last // citation's Jêgirtin box automatically opens a fresh empty one below it. (function () { var jederGroupDiv = $("<div></div>").addClass("wiktku-dfn-subgroup wiktku-dfn-jeder-group"); var jederLbl = $("<span></span>").addClass("wiktku-dfn-sublabel").text("Jêgirtin: "); var jederList = $("<ol></ol>").addClass("wiktku-dfn-sublist wiktku-dfn-jeder-list"); function buildJederLi() { var lang = getValues().lang || ""; var li = $("<li></li>").addClass("wiktku-dfn-jeder-li"); var dragHandle = $("<span></span>") .addClass("wiktku-jeder-drag-handle") .attr("title", "Bişkûne û bikişîne da ku rêzê biguhezîne"); // Quote text textarea var quoteTa = $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-quote-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 2) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-quote") .attr("placeholder", "Nimûneya emilandinê ji kitêb an çavkaniyeke din binivîse"); quoteTa.on("input", function () { var val = $.trim($(this).val()); var isLast = li.is(jederList.children("li:last-child")); if (val && isLast) { jederList.append(buildJederLi()); } }); li.append(dragHandle).append(quoteTa); // tr/t sub-fields for the quote — shown as needed for the language. var quoteSubWrap = $("<div></div>").addClass("wiktku-dfn-quote-sub"); if (needsTransliteration(lang)) { quoteSubWrap.append( $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-quote-tr-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 2) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-quote-tr") .attr("placeholder", "Transkrîpsiyona jêgirtinê…") ); } if (lang && lang !== "ku") { quoteSubWrap.append( $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-quote-t-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 2) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-quote-t") .attr("placeholder", "Tercimeya jêgirtinê bi kurmancî") ); } if (quoteSubWrap.children().length) li.append(quoteSubWrap); // Citoid auto-fill: fetch citation data from a URL, DOI or ISBN and // prefill the source şablon + fields below (see Gadget-citoid-helper.js). var citoidWrap = $("<div></div>").addClass("wiktku-dfn-quote-citoid"); var citoidInput = $("<input type='text'>") .addClass("wiktku-dfn-quote-citoid-input wiktku-start-narrow") .attr("placeholder", "URL, DOI an ISBN binivîse ku otomatîk were tijekirin…"); var citoidBtn = new OO.ui.ButtonWidget({ label: "Bi Citoid bîne", classes: [ "wiktku-dfn-quote-citoid-btn" ] }); var citoidStatus = $("<span></span>").addClass("wiktku-dfn-quote-citoid-status"); /** * Fetches citation data from Citoid and applies it to this * citation's şablon selector + fields. Mirrors the logic in * Form.prototype._fillFromCitoid (Gadget-wikt.add-examples.js): * - only (re)selects the şablon when it actually differs from * what's already chosen, so a repeat fetch doesn't wipe out * a template the user already picked; * - only fills fields that are currently empty, so it never * overwrites something the user typed by hand; * - falls back to the freeform "bi destê xwe binivîsim" source * only when nothing was typed there yet. */ function runCitoidFetch() { var query = $.trim(citoidInput.val()); if (!query) { mw.notify("Ji kerema xwe re pêşî URL, DOI an ISBNyekê binivîse."); return; } citoidBtn.setDisabled(true); citoidStatus.text("Tê anîn…"); wikt.citoidHelper.ensure().then(function () { return wikt.citoid.fetchJederFields(query); }).then(function (result) { var jederKey = result.jederKey; var hasTpl = !!jederKey && srcSel.find("option[value='" + jederKey + "']").length > 0; var targetVal = hasTpl ? jederKey : "__manual__"; // Only (re)select — and thus rebuild — the field rows if // we're switching to a different şablon than what's // already chosen, so a second fetch doesn't clear fields // the user already filled in by hand. if (srcSel.val() !== targetVal) { srcSel.val(targetVal).trigger("change"); srcSel.trigger("chosen:updated"); } if (hasTpl) { // Tenê qadên vala tijî bike. $.each(result.fields, function (key, val) { var input = srcFields.find("[data-field-key='" + key + "']"); if (input.length && !$.trim(input.val())) { input.val(val); } }); } else { // Şablonek nehat naskirin ji bo vê itemType — rêzikeke // çavkaniyê ya bi destan a ji qadên Citoid tê çêkirin, // lê tenê ger qada destan vala be. var manualField = srcFields.find(".wiktku-dfn-quote-src-manual"); if (!$.trim(manualField.val())) { var parts = []; $.each(["nivîskar", "sernav", "websîte", "kovar", "weşanxane", "sal", "url"], function (_, k) { if (result.fields[k]) parts.push(result.fields[k]); }); manualField.val(parts.join(", ")); } } citoidStatus.text(""); }, function (errorMsg) { citoidStatus.text(typeof errorMsg === "string" ? errorMsg : "Nehat dîtin. Kontrol bike ka URL/DOI/ISBN rast e."); }).always(function () { citoidBtn.setDisabled(false); }); } citoidBtn.on("click", runCitoidFetch); citoidInput.on("keydown", function (e) { if (e.which === 13) { // Enter e.preventDefault(); runCitoidFetch(); } }); citoidWrap.append(citoidInput).append(citoidBtn.$element).append(citoidStatus); // Source template selector, specific to this citation. var srcSel = $("<select></select>").addClass("wiktku-dfn-quote-src-sel"); srcSel.append($("<option value=''>— Çavkaniyê hilbijêre —</option>")); srcSel.append($("<option></option>").val("__manual__").text("Bi destê xwe binivîsim")); var jederDefs = steps.dfn.jederDefs || {}; $.each(jederDefs, function (tplName, def) { srcSel.append($("<option></option>").val(tplName).text(def.label)); }); // Dynamic source fields container. var srcFields = $("<div></div>").addClass("wiktku-dfn-quote-src-fields"); srcSel.on("change", function () { srcFields.empty(); var chosen = $(this).val(); if (!chosen) return; if (chosen === "__manual__") { // Freeform source, written by the user — becomes the 2nd // positional param of {{jêder|lang|…}} instead of çavkanî?. srcFields.append( $("<textarea></textarea>") .attr("rows", 4) .addClass("wiktku-dfn-subfield wiktku-dfn-quote-src-manual") .attr("placeholder", "Çavkaniyê bi destê xwe binivîse…") ); return; } var def = (steps.dfn.jederDefs || {})[chosen]; if (!def) return; $.each(def.fields, function (_, f) { var row = $("<div></div>").addClass("wiktku-dfn-quote-src-row"); var fieldLbl = $("<label></label>").text(f.label + ": "); var inp = $("<textarea></textarea>") .attr("rows", 2) .addClass("wiktku-dfn-quote-src-input wiktku-start-narrow") .attr("data-field-key", f.key) .attr("placeholder", f.label + "…"); row.append(fieldLbl).append(inp); srcFields.append(row); }); }); li.append(citoidWrap).append(srcSel).append(srcFields); return li; } jederGroupDiv.data("buildJederLi", buildJederLi); jederList.append(buildJederLi()); // Make citation rows sortable (drag to reorder). // The last row is always the empty trailing row — cancel its drag. mw.loader.using("jquery.ui.sortable", function () { jederList.sortable({ handle: ".wiktku-jeder-drag-handle", axis: "y", items: "li:not(:last-child)", tolerance: "pointer" }); }); jederGroupDiv.append(jederLbl).append(jederList); block.append(jederGroupDiv); }()); // Apply the initial hide/show state for the sub-groups (matches // tplSelect's starting value, which is normally empty). updateFieldVisibility(); return block; }, /** Grows the sense list when the last mane textarea gets content. */ onDfnInput: function (stepDiv, block, textarea) { var val = $.trim($(textarea).val()); var list = stepDiv.find("ol.wiktku-dfn-list"); var isLast = block.is(list.children("li:last-child")); if (val && isLast) { var newBlock = steps.dfn.buildSenseBlock(stepDiv); list.append(newBlock); // Apply Chosen to the new block's template selector on desktop. if (!isMobile) newBlock.find("select.wiktku-dfn-tpl-select").chosen(chosenOptions); } refresh(); }, /** Grows a sub-list (nimûne/formên alternatîv/hevmane/dijmane/termên koordîne) on input. */ onSubInput: function (list, input, rows, narrow) { var val = $.trim($(input).val()); var item = $(input).parent(); var isLast = item.is(list.children("li:last-child")); if (val && isLast) { var next = $("<textarea></textarea>") .attr("name", "wiktku-dfn-sub-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", rows) .attr("class", "wiktku-dfn-subfield" + (narrow ? " wiktku-start-narrow" : "")); next.on("input", function () { steps.dfn.onSubInput(list, this, rows, narrow); }); list.append($("<li></li>").append(next)); } }, // Populated from [[MediaWiki:Gadget-start.js/data.json]] (tplDefs, posExamples, jederDefs). tplDefs: [], posExamples: {}, jederDefs: {}, build: function (stepDiv) { if (stepDiv.find("ol.wiktku-dfn-list").length) return null; var list = $("<ol class='wiktku-dfn-list'></ol>"); list.append(steps.dfn.buildSenseBlock(stepDiv)); stepDiv.append(list); return null; }, /** Reads all sense blocks from the DOM and returns an array of sense objects. */ getSenses: function (stepDiv) { var senses = []; stepDiv.find("li.wiktku-dfn-sense").each(function () { var block = $(this); var tplSel = block.find("select.wiktku-dfn-tpl-select"); var tpl = tplSel.val() || ""; // noLang: template already encodes the language — don't add |lang| param. var tplNoLang = tpl ? tplSel.find("option[value='" + tpl + "']").attr("data-nolang") === "1" : false; var tplTitle = $.trim(block.find("input.wiktku-dfn-tpl-title").val()); var mane = $.trim(block.find("textarea.wiktku-dfn-mane").val()); var etiket = (function () { var vals = []; block.find(".wiktku-dfn-etiket-list textarea").each(function () { var v = $.trim($(this).val()); if (v) vals.push(v); }); return vals; }()); var kategori = (function () { var vals = []; block.find(".wiktku-dfn-kategori-list textarea").each(function () { var v = $.trim($(this).val()); if (v) vals.push(v); }); return vals; }()); function readList(cls) { var vals = []; block.find("." + cls + "-list textarea").each(function () { var v = $.trim($(this).val()); if (v) vals.push(v); }); return vals; } // Nimûne items are compound: { text, tr?, t? } function readNimuneList() { var items = []; block.find(".wiktku-dfn-nimune-list li.wiktku-dfn-nimune-li").each(function () { var text = $.trim($(this).find(".wiktku-dfn-nimune-text").val()); if (!text) return; var obj = { text: text }; var tr = $.trim($(this).find(".wiktku-dfn-nimune-tr").val()); var t = $.trim($(this).find(".wiktku-dfn-nimune-t").val()); if (tr) obj.tr = tr; if (t) obj.t = t; items.push(obj); }); return items; } // Jêder is a growing list of citations, one per li — mirrors readNimuneList(). function readJederList() { var items = []; block.find(".wiktku-dfn-jeder-list li.wiktku-dfn-jeder-li").each(function () { var li = $(this); var quote = $.trim(li.find(".wiktku-dfn-nimune-quote").val()); if (!quote) return; var obj = { quote: quote }; var qtr = $.trim(li.find(".wiktku-dfn-nimune-quote-tr").val()); var qt = $.trim(li.find(".wiktku-dfn-nimune-quote-t").val()); if (qtr) obj.quoteTr = qtr; if (qt) obj.quoteT = qt; var tplName = li.find(".wiktku-dfn-quote-src-sel").val(); if (tplName === "__manual__") { var manual = $.trim(li.find(".wiktku-dfn-quote-src-manual").val()); if (manual) obj.jederManual = manual; } else if (tplName) { obj.jederTpl = tplName; var fields = {}; li.find(".wiktku-dfn-quote-src-input").each(function () { var k = $(this).attr("data-field-key"); var v = $.trim($(this).val()); if (k && v) fields[k] = v; }); obj.jêderFields = fields; } items.push(obj); }); return items; } senses.push({ tpl: tpl, tplNoLang: tplNoLang, tplTitle: tplTitle, mane: mane, etiket: etiket, kategori: kategori, nimune: readNimuneList(), jeder: readJederList(), alternativ: readList("wiktku-dfn-alternativ"), hevmane: readList("wiktku-dfn-hevmane"), dijmane: readList("wiktku-dfn-dijmane"), koordine: readList("wiktku-dfn-koordine"), jornav: readList("wiktku-dfn-jornav"), jernav: readList("wiktku-dfn-jernav") }); }); return senses; }, getOutput: function (values, callback) { var stepDiv = $("#wiktku-start-dfn"); var senses = steps.dfn.getSenses(stepDiv); var lang = values.lang; // A sense counts as "filled" if it has a mane, a chosen template + title, // or any other content (etîket/hevmane/nimûne/jêder…) worth keeping. var hasMane = senses.some(function (s) { return s.mane !== "" || (s.tpl && s.tplTitle) || senseHasExtraContent(s); }); // True only when at least one sense has a regular mane (needs linkify). var hasRegularMane = senses.some(function (s) { return !s.tpl && s.mane !== ""; }); // nimûne and jêder lines must never pass through linkify — only // the plain mane text should be linkified. We build two parallel // arrays: defLines (sent to linkify) and citeLines (kept aside). // Each entry in citeLines corresponds 1-to-1 with a defLines entry; // a template token {{wiktku-cite-N}} is embedded in defLines so // that after linkify runs we know exactly where to splice them back. // Template-call syntax is guaranteed safe: linkifiers leave {{ }} // tokens completely untouched. var defLines = []; // one entry per kept sense (goes to linkify) var citeLines = []; // parallel — nimûne+jêder for that same sense $.each(senses, function (_, sense) { // — Template sense (e.g. {{guharto|ku|somepage}}) — if (sense.tpl) { if (!sense.tplTitle) return; // skip empty template senses var tplKatTpl = buildSenseTpl(sense, "kategori", lang, "K", "inline"); var tplLabelTpl = buildSenseTpl(sense, "etiket", lang, "e", "inline"); var tplCall = sense.tplNoLang ? "{{" + sense.tpl + "|" + sense.tplTitle + "}}" : "{{" + sense.tpl + "|" + lang + "|" + sense.tplTitle + "}}"; var idx = defLines.length; var cite = buildCite(sense, lang); defLines.push("#" + (tplLabelTpl ? tplLabelTpl : " ") + tplCall + tplKatTpl + (cite ? "{{wiktku-cite-" + idx + "}}" : "")); citeLines.push(cite); return; } // — Normal mane sense — var dfn = sense.mane; if (!dfn && !senseHasExtraContent(sense)) return; // truly empty if (dfn) { dfn = stripWikilinks(dfn); if (dfn[0] !== dfn[0].toUpperCase()) dfn = capitalize(dfn); if (!dfn.match(/[.…?!)\]]$/)) dfn += "."; } else { dfn = "{{mane?|" + lang + "}}"; } var katTpl = buildSenseTpl(sense, "kategori", lang, "K", "inline"); var labelTpl = buildSenseTpl(sense, "etiket", lang, "e", "inline"); var out = "# " + (katTpl ? katTpl : " ") (labelTpl ? labelTpl : "") + dfn; function wordLine(tpl, words) { if (!words.length) return ""; return "\n#: {{" + tpl + "|" + lang + "|" + words.join("|") + "}}"; } out += wordLine("alt-r", sense.alternativ); out += wordLine("hevmane", sense.hevmane); out += wordLine("dijmane", sense.dijmane); out += wordLine("koordîne", sense.koordine); out += wordLine("jornav", sense.jornav); out += wordLine("jêrnav", sense.jernav); var cite = buildCite(sense, lang); var idx = defLines.length; defLines.push(out + (cite ? "{{wiktku-cite-" + idx + "}}" : "")); citeLines.push(cite); }); // Splice citeLines back into a linkified string, replacing each // {{wiktku-cite-N}} token with its stored nimûne/jêder block. function restoreCites(t) { return t.replace(/\{\{wiktku-cite-(\d+)\}\}/g, function (_, n) { return citeLines[parseInt(n, 10)] || ""; }); } var text = defLines.join("\n") + "\n"; if (!hasMane) { // No definitions entered — emit {{mane?}} with bênimûne. text = "# {{mane?|" + lang + "}}\n#* {{bênimûne|" + lang + "}}\n"; callback(text); return; } if (!hasRegularMane) { // All filled senses are template senses — no linkify needed. callback(restoreCites(text)); return; } var didTryToLoad = function () { if (typeof $.wiktviLinkify === "function") { $.wiktviLinkify(text, function (linked) { callback(restoreCites(linked)); }); } else { callback(restoreCites(text)); } }; mw.loader.using("ext.gadget.linkify", didTryToLoad, didTryToLoad); } }, je: makeWordListStep("je", "jê", "Kelîmeyên jê çêbûyî binivîse", "Jê", "g"), tekildar: makeWordListStep("tekildar", "têkildar", "Kelîmeyên ji aliyê etîmolojiyê ve têkildarî vê kelîmeyê binivîse", "Têkildar", "g"), binereherwiha: makeWordListStep("binereherwiha", "binêre herwiha", "Kelîmeyên din ên eleqedar binivîse", "Binêre herwiha", "g"), etym: { id: "etym", name: "etîmolojî", question_fmt: "Etîmolojiya kelîmeyê binivîse", // etymTpls populated from data.json etymTpls: [], visible: function (values) { return values.lang && values.pos; }, /** Fills (or refills) the insert-dropdown from the current etymTpls array. */ refreshTplSelect: function () { var sel = $("#wiktku-start-etym .wiktku-tpl-insert-select"); if (!sel.length) return; sel.find("option[value!='']").remove(); $.each(steps.etym.etymTpls, function (_, tpl) { sel.append($("<option></option>").val(tpl.snippet).text(tpl.name + " — " + tpl.desc)); }); // Notify Chosen that the option list has changed (no-op on mobile). if (!isMobile) sel.trigger("chosen:updated"); }, build: function (stepDiv) { if (stepDiv.find(".wiktku-etym-wrap").length) return null; var wrap = $("<div class='wiktku-etym-wrap'></div>"); var ta = $("<textarea></textarea>") .attr("name", "wiktku-etym-" + $.now()) .attr("class", "wiktku-start-step-field wiktku-etym-text") .attr("rows", 4) .attr("placeholder", "Nimûne: Ji {{ji|en|ku|apple}}. yan rasterast binivîse…"); // Template insert dropdown — options also refreshed after data.json loads. var sel = $("<select class='wiktku-tpl-insert-select'></select>"); sel.append($("<option value=''>— şablonek lê zêde bike —</option>")); $.each(steps.etym.etymTpls, function (_, tpl) { sel.append($("<option></option>").val(tpl.snippet).text(tpl.name + " — " + tpl.desc)); }); sel.on("change", function () { var snippet = $(this).val(); if (!snippet) return; var lang = getValues().lang || ""; snippet = snippet.replace(/CODE/g, lang).replace(/SOURCELANG/g, "?"); insertAtCursor(ta[0], snippet); $(this).val(""); ta.focus(); }); wrap.append(sel).append($("<br>")).append(ta); stepDiv.append(wrap); return ta; }, output: function (values) { var text = $.trim($("#wiktku-start-etym .wiktku-etym-text").val()); if (text) { return "\n==== Etîmolojî ====\n" + text + "\n"; } // No etymology entered — emit {{ji?|lang}} as a placeholder, // but only when the entry has at least one regular (non-şablon) // sense with content — either real mane text, or an empty mane // with other fields filled in (which dfn.getOutput() renders as // {{mane?|lang}} with those fields attached). A şablon sense // like {{guharto|…}} never counts, filled in or not. var dfnSenses = steps.dfn.getSenses($("#wiktku-start-dfn")); var hasRegularMane = dfnSenses.some(function (s) { return !s.tpl && (s.mane !== "" || senseHasExtraContent(s)); }); if (!hasRegularMane) return ""; return "\n==== Etîmolojî ====\n{{ji?|" + values.lang + "}}\n"; } }, dunde: { id: "dunde", name: "dûnde", question_fmt: "Eger ev kelîme ji vî zimanî ketibe zimanekî din, vî zimanî û kelîmeya wî binivîse", visible: function (values) { return !!values.pos; }, disabledKeys: { "navz": true}, /** * Builds one row: a language dropdown + a growing list of word * inputs. When the dropdown gets a value the next empty row is * appended automatically. Mirrors steps.trans's row widget, but * flat (one shared list — dûnde isn't tied to individual senses). */ buildRow: function (stepDiv) { var row = $("<li class='wiktku-dunde-row wiktku-lang-row'></li>"); // Language selector — chosen is applied after insertion into DOM. var langSel = $(mw.html.element("select", { "class": "wiktku-start-step-keyfield wiktku-start-narrow" })); langSel.attr("data-placeholder", "Zimanekî lê bigere"); populateMenus(langSel, steps.dunde.keys || [], steps.dunde.disabledKeys); // When a language is chosen, ensure a next empty row exists. langSel.on("change", function () { steps.dunde.onLangChange(stepDiv, row); }); // Word list for this language. var wordList = $("<ul class='wiktku-dunde-words wiktku-lang-row-words'></ul>"); var firstWord = steps.dunde.makeWordInput(); wordList.append($("<li></li>").append(firstWord)); if (isMobile) { row.append(wrapNativeSelect(langSel)).append(wordList); } else { row.append(langSel).append(wordList); } return row; }, makeWordInput: function () { var input = $("<textarea></textarea>") .attr("name", "wiktku-dunde-word-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 1) .attr("class", "wiktku-dfn-subfield wiktku-start-narrow") .attr("placeholder", "Kelîme…"); input.on("input", function () { var list = $(this).closest("ul.wiktku-dunde-words"); var item = $(this).parent(); var val = $.trim($(this).val()); if (val && item.is(list.children("li:last-child"))) { var next = steps.dunde.makeWordInput(); list.append($("<li></li>").append(next)); } }); return input; }, onLangChange: function (stepDiv, row) { var list = stepDiv.find("ul.wiktku-dunde-list"); var isLast = row.is(list.children("li.wiktku-dunde-row:last-child")); if (isLast) { var newRow = steps.dunde.buildRow(stepDiv); list.append(newRow); // Init chosen after the new row is in the DOM (desktop only). if (!isMobile) newRow.find("select").chosen(chosenOptions); } // Keep disabled keys in sync across all lang selectors. steps.dunde.syncDisabledKeys(stepDiv); }, /** Disables already-selected languages in all other dropdowns. */ syncDisabledKeys: function (stepDiv) { var taken = $.extend({}, steps.dunde.disabledKeys); stepDiv.find("li.wiktku-dunde-row select").each(function () { var v = $(this).val(); if (v) taken[v] = true; }); stepDiv.find("li.wiktku-dunde-row select").each(function () { var self = $(this); var own = self.val(); self.find("option").each(function () { var code = $(this).val(); if (!code) return; $(this).prop("disabled", taken[code] && code !== own); }); self.trigger("chosen:updated"); }); }, build: function (stepDiv) { if (stepDiv.find("ul.wiktku-dunde-list").length) return null; var list = $("<ul class='wiktku-dunde-list wiktku-lang-row-list'></ul>"); list.append(steps.dunde.buildRow(stepDiv)); stepDiv.append(list); // Init chosen after the select is in the DOM (desktop only). if (!isMobile) list.find("select").chosen(chosenOptions); return null; }, /** Reads all [langcode, words[]] rows from the DOM. */ getRows: function (stepDiv) { var result = []; stepDiv.find("li.wiktku-dunde-row").each(function () { var lang = $(this).find("select").val(); if (!lang) return; var words = []; $(this).find("ul.wiktku-dunde-words textarea").each(function () { var v = $.trim($(this).val()); if (v) words.push(v); }); if (words.length) result.push([lang, words]); }); return result; }, output: function () { var stepDiv = $("#wiktku-start-dunde"); var rows = steps.dunde.getRows(stepDiv); if (!rows.length) return ""; var lines = $.map(rows, function (row) { var lang = row[0], words = row[1]; return "* {{dû|" + lang + "|" + words.join("|") + "}}"; }); return "\n==== Dûnde ====\n" + lines.join("\n") + "\n"; } }, zarava: { id: "zarava", name: "bi zaravayên din", visible: function (values) { return steps.trans.visible(values); }, disabledKeys: { "navz": true }, buildRow: function (group) { var row = $("<li class='wiktku-zarava-row wiktku-lang-row'></li>"); var langSel = $(mw.html.element("select", { "class": "wiktku-start-step-keyfield wiktku-start-narrow" })); populateMenus(langSel, steps.zarava.keys || [], steps.zarava.disabledKeys); langSel.on("change", function () { steps.zarava.onLangChange(group, row); }); var wordList = $("<ul class='wiktku-zarava-words wiktku-lang-row-words'></ul>"); var firstWord = steps.zarava.makeWordInput(); wordList.append($("<li></li>").append(firstWord)); row.append(langSel).append(wordList); return row; }, makeWordInput: function () { var input = $("<textarea></textarea>") .attr("name", "wiktku-zarava-word-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 1) .attr("class", "wiktku-dfn-subfield wiktku-start-narrow") .attr("placeholder", "Tercime…"); input.on("input", function () { var list = $(this).closest("ul.wiktku-zarava-words"); var item = $(this).parent(); var val = $.trim($(this).val()); if (val && item.is(list.children("li:last-child"))) { var next = steps.zarava.makeWordInput(); list.append($("<li></li>").append(next)); } }); return input; }, onLangChange: function (group, row) { var list = group.find("ul.wiktku-zarava-list"); var isLast = row.is(list.children("li.wiktku-zarava-row:last-child")); if (isLast) { var newRow = steps.zarava.buildRow(group); list.append(newRow); } steps.zarava.syncDisabledKeys(group); }, /** Disables already-selected dialects in all other dropdowns within one group. */ syncDisabledKeys: function (group) { var taken = $.extend({}, steps.zarava.disabledKeys); group.find("li.wiktku-zarava-row select").each(function () { var v = $(this).val(); if (v) taken[v] = true; }); group.find("li.wiktku-zarava-row select").each(function () { var self = $(this); var own = self.val(); self.find("option").each(function () { var code = $(this).val(); if (!code) return; $(this).prop("disabled", taken[code] && code !== own); }); }); }, /** Builds (or fetches) the .wiktku-zarava-group for one gloss. */ buildGroup: function (stepDiv, gi) { var group = $("<div class='wiktku-zarava-group'></div>").attr("data-gloss-pos", gi); var list = $("<ul class='wiktku-zarava-list wiktku-lang-row-list'></ul>"); list.append(steps.zarava.buildRow(group)); group.append(list); stepDiv.append(group); return group; }, /** Syncs one .wiktku-zarava-group per current gloss (same logic as steps.trans.build). */ build: function (stepDiv) { var glosses = steps.trans.glossList(); if (!glosses.length) { stepDiv.find(".wiktku-zarava-group").remove(); return null; } var existingGroups = stepDiv.find(".wiktku-zarava-group"); if (existingGroups.length > glosses.length) { existingGroups.slice(glosses.length).remove(); } $.each(glosses, function (gi, gloss) { var group = stepDiv.find(".wiktku-zarava-group[data-gloss-pos='" + gi + "']"); if (!group.length) group = steps.zarava.buildGroup(stepDiv, gi); var label = group.find(".wiktku-zarava-group-label"); if (glosses.length > 1) { if (!label.length) { label = $("<div class='wiktku-zarava-group-label'></div>"); group.prepend(label); } label.text(gloss.index + " " + gloss.text); } else if (label.length) { label.remove(); } }); return null; }, /** Reads the dialect rows for a single gloss group. */ getGroupTranslations: function (group) { var result = []; group.find("li.wiktku-zarava-row").each(function () { var lang = $(this).find("select").val(); if (!lang) return; var words = []; $(this).find("ul.wiktku-zarava-words textarea").each(function () { var v = $.trim($(this).val()); if (v) words.push(v); }); if (words.length) result.push([lang, words]); }); return result; }, /** Reads all rows from the DOM, grouped by gloss position. */ getTranslations: function (stepDiv) { var result = []; stepDiv.find(".wiktku-zarava-group").each(function () { result.push(steps.zarava.getGroupTranslations($(this))); }); return result; }, output: function (values) { if (values.lang !== "ku") return ""; var stepDiv = $("#wiktku-start-zarava"); var glosses = steps.trans.glossList(); if (!glosses.length) return ""; var blocks = $.map(glosses, function (gloss, gi) { var group = stepDiv.find(".wiktku-zarava-group[data-gloss-pos='" + gi + "']"); var rows = group.length ? steps.zarava.getGroupTranslations(group) : []; if (!gloss.text && !rows.length) return undefined; if (rows.length) { rows.sort(function (a, b) { var aLang = langsByCode[a[0]] || []; var bLang = langsByCode[b[0]] || []; return (aLang[2] || "").localeCompare(bLang[2] || "", "ku"); }); } var wordLines = $.map(rows, function (row) { var lang = row[0]; var words = row[1]; var wikiWords = words.map(function (w) { return "{{W|" + lang + "|" + w + "}}"; }).join(", "); return "* {{Z|" + lang + "}}: " + wikiWords; }).join("\n"); if (!wordLines) return undefined; var block = "{{werger-ser|" + (gloss.text || "?") + "|" + gloss.index + "}}"; block += "\n" + wordLines; block += "\n{{werger-bin}}"; return block; }); if (!blocks.length) return ""; return "\n==== Bi zaravayên din ====\n" + blocks.join("\n") + "\n"; } }, trans: { id: "trans", name: "werger", visible: function (values) { if (!(values.lang === "ku" && values.pos)) return false; // Hide Werger only when EVERY sense is a template sense (Guharto etc.) // with a title filled in — i.e. there is real content but no plain // gloss to attach a translation table to. A mix of real + template // senses still shows Werger; the template senses are simply skipped // in output(). // // "Real" here means a non-şablon sense with either mane text or // other filled-in fields (etîket/hevmane/nimûne/jêder…), since // dfn.getOutput() renders the latter too, as {{mane?|lang}} plus // whatever else was filled in. // // When nothing has been filled in at all, output() will emit // {{mane?|lang}} instead of a gloss — but Werger should still show, // since the user may want to add translations before they've // settled on a gloss. var dfnSenses = steps.dfn.getSenses($("#wiktku-start-dfn")); var hasRealSense = dfnSenses.some(function (s) { return !s.tpl && (s.mane !== "" || senseHasExtraContent(s)); }); var hasFilledTplSense = dfnSenses.some(function (s) { return s.tpl && s.tplTitle; }); return hasRealSense || !hasFilledTplSense; }, disabledKeys: { "navz": true, "ku": true, "ckb": true, "sdh": true, "lki": true, "hac": true, "zza": true }, /** * Builds one translation row: a language dropdown + a growing list * of word inputs. When the dropdown gets a value the next empty row * is appended automatically. * * @param group the specific .wiktku-trans-group this row belongs to * (each gloss has its own group and its own list of rows, so the * lookups below must stay scoped to that group rather than the * whole step — the step now holds one list per gloss). */ buildRow: function (group) { var row = $("<li class='wiktku-trans-row wiktku-lang-row'></li>"); // Language selector — chosen is applied after insertion into DOM. var langSel = $(mw.html.element("select", { "class": "wiktku-start-step-keyfield wiktku-start-narrow" })); langSel.attr("data-placeholder", "Zimanekî lê bigere"); populateMenus(langSel, steps.trans.keys || [], steps.trans.disabledKeys); // When a language is chosen, ensure a next empty row exists. langSel.on("change", function () { steps.trans.onLangChange(group, row); }); // Word list for this language. var wordList = $("<ul class='wiktku-trans-words wiktku-lang-row-words'></ul>"); var firstWord = steps.trans.makeWordInput(); wordList.append($("<li></li>").append(firstWord)); if (isMobile) { row.append(wrapNativeSelect(langSel)).append(wordList); } else { row.append(langSel).append(wordList); } return row; }, makeWordInput: function () { var input = $("<textarea></textarea>") .attr("name", "wiktku-trans-word-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 1) .attr("class", "wiktku-dfn-subfield wiktku-start-narrow") .attr("placeholder", "Tercime…"); input.on("input", function () { var list = $(this).closest("ul.wiktku-trans-words"); var item = $(this).parent(); var val = $.trim($(this).val()); if (val && item.is(list.children("li:last-child"))) { var next = steps.trans.makeWordInput(); list.append($("<li></li>").append(next)); } }); return input; }, onLangChange: function (group, row) { var list = group.find("ul.wiktku-trans-list"); var isLast = row.is(list.children("li.wiktku-trans-row:last-child")); if (isLast) { var newRow = steps.trans.buildRow(group); list.append(newRow); // Init chosen after the new row is in the DOM (desktop only). if (!isMobile) newRow.find("select").chosen(chosenOptions); } // Keep disabled keys in sync across this gloss's lang selectors // only — the same language can be used for different senses. steps.trans.syncDisabledKeys(group); }, /** Disables already-selected languages in all other dropdowns within one group. */ syncDisabledKeys: function (group) { var taken = $.extend({}, steps.trans.disabledKeys); group.find("li.wiktku-trans-row select").each(function () { var v = $(this).val(); if (v) taken[v] = true; }); group.find("li.wiktku-trans-row select").each(function () { var self = $(this); var own = self.val(); self.find("option").each(function () { var code = $(this).val(); if (!code) return; $(this).prop("disabled", taken[code] && code !== own); }); self.trigger("chosen:updated"); }); }, /** * Builds (or fetches) the .wiktku-trans-group for one gloss, with * its own label and its own list of translation rows. */ buildGroup: function (stepDiv, gi) { var group = $("<div class='wiktku-trans-group'></div>").attr("data-gloss-pos", gi); var list = $("<ul class='wiktku-trans-list wiktku-lang-row-list'></ul>"); list.append(steps.trans.buildRow(group)); group.append(list); stepDiv.append(group); // Init chosen after the select is in the DOM (desktop only). if (!isMobile) list.find("select").chosen(chosenOptions); return group; }, /** * Syncs one .wiktku-trans-group per current gloss, adding new * groups and removing stale ones as senses are added or removed, * while leaving existing groups (and whatever translations the * user has already typed into them) untouched. Groups are keyed * to their gloss's position in glossList() via data-gloss-pos, so * a group always matches the same sense across rebuilds as long * as senses aren't reordered relative to each other. */ build: function (stepDiv) { var glosses = steps.trans.glossList(); if (!glosses.length) { stepDiv.find(".wiktku-trans-group").remove(); return null; } // Drop groups for glosses that no longer exist (always from the // tail — groups are only ever appended in gloss order below). var existingGroups = stepDiv.find(".wiktku-trans-group"); if (existingGroups.length > glosses.length) { existingGroups.slice(glosses.length).remove(); } $.each(glosses, function (gi, gloss) { var group = stepDiv.find(".wiktku-trans-group[data-gloss-pos='" + gi + "']"); if (!group.length) group = steps.trans.buildGroup(stepDiv, gi); // Only label groups when there's more than one gloss to // distinguish between — a single gloss needs no caption. var label = group.find(".wiktku-trans-group-label"); if (glosses.length > 1) { if (!label.length) { label = $("<div class='wiktku-trans-group-label'></div>"); group.prepend(label); } label.text(gloss.index + " " + gloss.text); } else if (label.length) { label.remove(); } }); return null; }, /** Reads the translation rows for a single gloss group. */ getGroupTranslations: function (group) { var result = []; group.find("li.wiktku-trans-row").each(function () { var lang = $(this).find("select").val(); if (!lang) return; var words = []; $(this).find("ul.wiktku-trans-words textarea").each(function () { var v = $.trim($(this).val()); if (v) words.push(v); }); if (words.length) result.push([lang, words]); }); return result; }, /** * Reads all translation rows from the DOM, grouped by gloss * position — one array of [lang, words] rows per gloss group, in * the same order as the .wiktku-trans-group elements. */ getTranslations: function (stepDiv) { var result = []; stepDiv.find(".wiktku-trans-group").each(function () { result.push(steps.trans.getGroupTranslations($(this))); }); return result; }, /** * Builds the numbered "{ index, gloss }" list — one entry per dfn * sense that has a real mane (skips template senses like Guharto, * which have nothing to caption a translation table with). The * index matches the sense's actual position in the numbered "#" * definition list (1-based), including template senses in the count, * so the number printed next to {{werger-ser}} lines up with the * gloss the reader sees in the entry. * * When nothing has been filled in at all (dfn.getOutput() will emit * {{mane?|lang}} as sense 1), this returns a single placeholder * entry with empty text instead of an empty array, so Werger still * has one group to attach translations to before a gloss exists. * When every filled sense is a template sense instead, this stays * empty — that mirrors trans.visible()'s hidden case, where there's * no group in the DOM for a placeholder to attach to anyway. */ glossList: function () { var dfnSenses = steps.dfn.getSenses($("#wiktku-start-dfn")); var glosses = []; var hasFilledTplSense = false; $.each(dfnSenses, function (i, s) { if (s.tpl) { if (s.tplTitle) hasFilledTplSense = true; return; // template sense — no gloss to caption with } var dfn = s.mane; if (!dfn) { // No mane text, but other fields (etîket/hevmane/nimûne/ // jêder…) are filled — dfn.getOutput() still emits this // sense as a numbered line using {{mane?|lang}}, so it // needs its own gloss group too, just with no caption text. if (senseHasExtraContent(s)) glosses.push({ index: i + 1, text: "" }); return; } if (dfn[0] !== dfn[0].toLowerCase()) dfn = decapitalize(dfn); dfn = stripWikilinks(dfn).replace(/[.…?!)\]،؟]+$/, ""); glosses.push({ index: i + 1, text: dfn }); }); if (!glosses.length && !hasFilledTplSense) { glosses.push({ index: 1, text: "" }); } return glosses; }, output: function (values) { if (values.lang !== "ku") return ""; var stepDiv = $("#wiktku-start-trans"); var glosses = steps.trans.glossList(); // Every sense is a template sense — there's no real gloss // anywhere and no group in the DOM either (glossList() only // returns empty in that case), so skip the section entirely. if (!glosses.length) return ""; // Each gloss now has its own group of translation rows — // attach every gloss's own words under its own werger-ser/-bin // pair instead of dumping everything under the first one. var blocks = $.map(glosses, function (gloss, gi) { var group = stepDiv.find(".wiktku-trans-group[data-gloss-pos='" + gi + "']"); var rows = group.length ? steps.trans.getGroupTranslations(group) : []; // Placeholder gloss (no real mane entered yet) with nothing // translated into it — nothing to output, and gloss.text is // empty so there's no caption to give {{werger-ser}} anyway. if (!gloss.text && !rows.length) return undefined; if (rows.length) { // Sort by Kurdish sort key. rows.sort(function (a, b) { var aLang = langsByCode[a[0]] || []; var bLang = langsByCode[b[0]] || []; return (aLang[2] || "").localeCompare(bLang[2] || "", "ku"); }); } var wordLines = $.map(rows, function (row) { var lang = row[0]; var words = row[1]; var wikiWords = words.map(function (w) { return "{{W|" + lang + "|" + w + "}}"; }).join(", "); return "* {{Z|" + lang + "}}: " + wikiWords; }).join("\n"); var block = "{{werger-ser|" + (gloss.text || "?") + "|" + gloss.index + "}}"; if (wordLines) block += "\n" + wordLines; block += "\n{{werger-bin}}"; return block; }); if (!blocks.length) return ""; return "\n==== Werger ====\n" + blocks.join("\n") + "\n"; } }, }; steps.trans.keys = steps.lang.choices; steps.dunde.keys = steps.lang.choices; steps.zarava.keys = getZaravaKeys(steps.lang.choices); var ordered_steps = [ steps.lang, steps.pron, steps.pos, steps.cinsiyet, steps.lektur, steps.tr, steps.dfn, steps.je, steps.tekildar, steps.etym, steps.dunde, steps.binereherwiha, steps.zarava, steps.trans]; // Step ids that belong to each section (not shared across sections). var PER_SECTION_STEP_IDS = [ "pos", "cinsiyet", "lektur", "tr", "dfn", "je", "tekildar", "etym", "dunde", "binereherwiha", "zarava", "trans" ]; // ── Multi-section state ────────────────────────────────────────────────── // Each entry is a plain snapshot: { pos, cinsiyet, lektur, tr, dfn (senses[]), // je, tekildar, binereherwiha, trans (rows[]) }. var sections = [{}]; // section 0 starts empty (DOM is the truth) var activeSection = 0; function snapshotDfn() { return steps.dfn.getSenses($("#wiktku-start-dfn")); } /** * Rebuild the dfn DOM from a previously snapshotted senses array. */ function restoreDfn(senses) { var stepDiv = $("#wiktku-start-dfn"); // Tear down the existing list so build() recreates it cleanly. stepDiv.find("ol.wiktku-dfn-list").remove(); steps.dfn.build(stepDiv); var list = stepDiv.find("ol.wiktku-dfn-list"); $.each(senses, function (i, sense) { // Ensure enough blocks exist (build() seeds one). var blocks = list.find("li.wiktku-dfn-sense"); var block = blocks.eq(i); if (!block.length) { var nb = steps.dfn.buildSenseBlock(stepDiv); list.append(nb); block = list.find("li.wiktku-dfn-sense").last(); } // Template selector. block.find("select.wiktku-dfn-tpl-select").val(sense.tpl || ""); if (sense.tpl) { block.find("textarea.wiktku-dfn-mane").hide(); block.find("input.wiktku-dfn-tpl-title").val(sense.tplTitle || "").show(); } else { block.find("textarea.wiktku-dfn-mane").val(sense.mane || "").show(); block.find("input.wiktku-dfn-tpl-title").hide().val(""); } // Re-sync the formên alternatîv/hevmane/… hide state now that // tplSelect's value was set programmatically (its own "change" // handler doesn't fire from .val(), so this doesn't happen otherwise). var updateVis = block.data("updateFieldVisibility"); if (updateVis) updateVis(); // Restore a sub-list (etiket, formên alternatîv, hevmane …) from a values array. function restoreSubList(cls, values) { if (!values || !values.length) return; var groupDiv = block.find("." + cls + "-group"); var subList = groupDiv.find("ol, ul").first(); if (!subList.length) return; // group not found // Fill existing items, append new ones as needed. $.each(values, function (j, val) { var items = subList.find("li"); if (j < items.length) { items.eq(j).find("textarea").val(val); } else { var ta = $("<textarea></textarea>") .attr("name", "wiktku-dfn-restore-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 1) .attr("class", "wiktku-dfn-subfield wiktku-start-narrow") .val(val); ta.on("input", function () { steps.dfn.onSubInput(subList, this, 1, true); }); subList.append($("<li></li>").append(ta)); } }); } // Reveal and populate lazy groups that have data. var lazyMap = { "wiktku-dfn-etiket": sense.etiket, "wiktku-dfn-kategori": sense.kategori, "wiktku-dfn-alternativ": sense.alternativ, "wiktku-dfn-hevmane": sense.hevmane, "wiktku-dfn-dijmane": sense.dijmane, "wiktku-dfn-koordine": sense.koordine, "wiktku-dfn-jornav": sense.jornav, "wiktku-dfn-jernav": sense.jernav }; $.each(lazyMap, function (cls, vals) { if (vals && vals.length) restoreSubList(cls, vals); }); // Nimûne items are objects { text, tr?, t? } — restore using the builder. if (sense.nimune && sense.nimune.length) { var nimuneGroupDiv = block.find(".wiktku-dfn-nimune-group"); var nimuneList = nimuneGroupDiv.find("ol.wiktku-dfn-nimune-list"); var buildFn = nimuneGroupDiv.data("buildNimuneLi"); nimuneList.empty(); $.each(sense.nimune, function (_, n) { var text = typeof n === "object" ? (n.text || "") : n; if (!text) return; var li = buildFn ? buildFn() : $("<li class='wiktku-dfn-nimune-li'></li>"); li.find(".wiktku-dfn-nimune-text").val(text); if (n.tr) li.find(".wiktku-dfn-nimune-tr").val(n.tr); if (n.t) li.find(".wiktku-dfn-nimune-t").val(n.t); nimuneList.append(li); }); // Always leave a blank trailing item. if (buildFn) nimuneList.append(buildFn()); } // Restore jêder (quote/citation) entries — a growing list, restored using the // builder just like Nimûne. Accepts either the current array shape or a // single legacy object (from older saved sections) for backwards compatibility. var jederArr = $.isArray(sense.jeder) ? sense.jeder : (sense.jeder ? [sense.jeder] : []); if (jederArr.length) { var jederGroupDiv = block.find(".wiktku-dfn-jeder-group"); var jederList = jederGroupDiv.find("ol.wiktku-dfn-jeder-list"); var buildJederFn = jederGroupDiv.data("buildJederLi"); jederList.empty(); $.each(jederArr, function (_, j) { if (!j || !j.quote) return; var li = buildJederFn ? buildJederFn() : $("<li class='wiktku-dfn-jeder-li'></li>"); li.find(".wiktku-dfn-nimune-quote").val(j.quote); if (j.quoteTr) li.find(".wiktku-dfn-nimune-quote-tr").val(j.quoteTr); if (j.quoteT) li.find(".wiktku-dfn-nimune-quote-t").val(j.quoteT); if (j.jederManual) { var manualSel = li.find(".wiktku-dfn-quote-src-sel"); manualSel.val("__manual__").trigger("change"); li.find(".wiktku-dfn-quote-src-manual").val(j.jederManual); } else if (j.jederTpl) { var srcSel = li.find(".wiktku-dfn-quote-src-sel"); srcSel.val(j.jederTpl).trigger("change"); if (j.jêderFields) { $.each(j.jêderFields, function (key, val) { li.find(".wiktku-dfn-quote-src-input[data-field-key='" + key + "']").val(val); }); } } jederList.append(li); }); // Always leave a blank trailing item, same as Nimûne. if (buildJederFn) jederList.append(buildJederFn()); } }); } /** * Snapshot simple (non-dfn) per-section steps from current DOM into obj. */ function saveCurrentSection() { var snap = {}; $.each(PER_SECTION_STEP_IDS, function (_, id) { if (id === "dfn") { snap.dfn = snapshotDfn(); return; } if (id === "etym") { snap.etym = $.trim($("#wiktku-start-etym .wiktku-etym-text").val()); return; } var step = steps[id]; if (!step) return; var stepDiv = $("#wiktku-start-" + id); if (id === "trans") { snap.trans = steps.trans.getTranslations(stepDiv); return; } if (id === "zarava") { snap.zarava = steps.zarava.getTranslations(stepDiv); return; } if (id === "dunde") { snap.dunde = steps.dunde.getRows(stepDiv); return; } // Generic: read all step fields. var fields = stepDiv.find(".wiktku-start-step-field"); if (step.multiple) { snap[id] = fields.map(function () { return $(this).val(); }).get(); } else { snap[id] = fields.val(); } }); sections[activeSection] = snap; } /** * Restore a previously saved snapshot into the form DOM. */ function restoreSection(snap) { $.each(PER_SECTION_STEP_IDS, function (_, id) { if (id === "dfn") { restoreDfn(snap.dfn || []); return; } if (id === "etym") { $("#wiktku-start-etym .wiktku-etym-wrap").remove(); steps.etym.build($("#wiktku-start-etym")); $("#wiktku-start-etym .wiktku-etym-text").val(snap.etym || ""); return; } if (id === "trans") { // Rebuild trans groups (dfn must already be restored by this // point in the $.each loop, so glossList() reflects it). var transDiv = $("#wiktku-start-trans"); transDiv.find(".wiktku-trans-group").remove(); steps.trans.build(transDiv); var groupsSnap = snap.trans || []; $.each(groupsSnap, function (gi, rows) { var group = transDiv.find(".wiktku-trans-group[data-gloss-pos='" + gi + "']"); if (!group.length) return; // gloss no longer exists — drop its rows var list = group.find("ul.wiktku-trans-list"); $.each(rows, function (j, row) { var lang = row[0], words = row[1]; var lastRow = list.find("li.wiktku-trans-row").last(); lastRow.find("select").val(lang).trigger("change"); var wordList = lastRow.find("ul.wiktku-trans-words"); $.each(words, function (k, word) { var wordItems = wordList.find("li"); if (k < wordItems.length) { wordItems.eq(k).find("textarea").val(word); } else { // .val() below doesn't fire "input", so the normal // auto-grow never runs — append a matching item // ourselves instead of silently dropping the word. var extraInput = steps.trans.makeWordInput(); wordList.append($("<li></li>").append(extraInput)); extraInput.val(word); } }); // Leave one trailing empty field so the row can still grow // when the user types, matching a freshly-built row. if ($.trim(wordList.children("li").last().find("textarea").val())) { wordList.append($("<li></li>").append(steps.trans.makeWordInput())); } }); }); return; } if (id === "zarava") { // Rebuild zarava groups (dfn must already be restored by this // point in the $.each loop, so glossList() reflects it). var zaravaDiv = $("#wiktku-start-zarava"); zaravaDiv.find(".wiktku-zarava-group").remove(); steps.zarava.build(zaravaDiv); var zaravaGroupsSnap = snap.zarava || []; $.each(zaravaGroupsSnap, function (gi, rows) { var group = zaravaDiv.find(".wiktku-zarava-group[data-gloss-pos='" + gi + "']"); if (!group.length) return; // gloss no longer exists — drop its rows var list = group.find("ul.wiktku-zarava-list"); $.each(rows, function (j, row) { var lang = row[0], words = row[1]; var lastRow = list.find("li.wiktku-zarava-row").last(); lastRow.find("select").val(lang).trigger("change"); var wordList = lastRow.find("ul.wiktku-zarava-words"); $.each(words, function (k, word) { var wordItems = wordList.find("li"); if (k < wordItems.length) { wordItems.eq(k).find("textarea").val(word); } else { var extraInput = steps.zarava.makeWordInput(); wordList.append($("<li></li>").append(extraInput)); extraInput.val(word); } }); if ($.trim(wordList.children("li").last().find("textarea").val())) { wordList.append($("<li></li>").append(steps.zarava.makeWordInput())); } }); }); return; } if (id === "dunde") { // Rebuild dunde rows. var dundeDiv = $("#wiktku-start-dunde"); dundeDiv.find("ul.wiktku-dunde-list").remove(); steps.dunde.build(dundeDiv); var dundeRows = snap.dunde || []; $.each(dundeRows, function (i, row) { var lang = row[0], words = row[1]; var list = dundeDiv.find("ul.wiktku-dunde-list"); var lastRow = list.find("li.wiktku-dunde-row").last(); lastRow.find("select").val(lang).trigger("change"); var wordList = lastRow.find("ul.wiktku-dunde-words"); $.each(words, function (j, word) { var wordItems = wordList.find("li"); if (j < wordItems.length) { wordItems.eq(j).find("textarea").val(word); } else { // .val() below doesn't fire "input", so the normal // auto-grow never runs — append a matching item // ourselves instead of silently dropping the word. var extraInput = steps.dunde.makeWordInput(); wordList.append($("<li></li>").append(extraInput)); extraInput.val(word); } }); // Leave one trailing empty field so the row can still grow // when the user types, matching a freshly-built row. if ($.trim(wordList.children("li").last().find("textarea").val())) { wordList.append($("<li></li>").append(steps.dunde.makeWordInput())); } }); return; } var step = steps[id]; if (!step) return; var stepDiv = $("#wiktku-start-" + id); var fields = stepDiv.find(".wiktku-start-step-field"); var val = snap[id]; if (val === undefined || val === null) return; if (step.multiple) { var arr = val; fields.each(function (i) { if (i < arr.length) $(this).val(arr[i]); }); } else { fields.val(val); } // Notify chosen widgets of the programmatic value change. if (!isMobile) fields.filter("select").trigger("chosen:updated"); }); } function getWikitextForCurrentSection(callback) { var values = getValues(); var entry = steps.pos.output(values); steps.dfn.getOutput(values, function (output) { entry += output; entry += steps.je.output(values); entry += steps.tekildar.output(values); entry += steps.etym.output(values); entry += steps.dunde.output(values); entry += steps.binereherwiha.output(values); entry += steps.zarava.output(values); entry += steps.trans.output(values); callback(entry, values); }); } function getWikitextAllSections(callback) { saveCurrentSection(); var results = new Array(sections.length); var sharedValues = getValues(); // lang/pron are shared function processSection(i) { if (i >= sections.length) { // All done — restore original active section. restoreSection(sections[activeSection]); refresh(); callback(results, sharedValues); return; } restoreSection(sections[i]); refresh(); getWikitextForCurrentSection(function (sectionText) { results[i] = sectionText; processSection(i + 1); }); } processSection(0); } /** * Assembles wikitext for all sections plus the shared lang/pron header. */ function getWikitext(callback) { getWikitextAllSections(function (sectionTexts, sharedValues) { var entry = steps.lang.output(sharedValues); entry += steps.pron.output(sharedValues); entry += sectionTexts.join("\n"); // Edit summary uses section 0's values. Read from the saved snapshot // (not the live DOM) so it doesn't mix section 0's pos with whichever // section happens to be active/restored at this point. var dfnSenses = (sections[0] && sections[0].dfn) || []; var dfnSummary = dfnSenses.map(function (s) { return s.mane; }).filter(Boolean).join("; "); var summary = "([[Mediawiki:Gadget-start.js|WF:NÛ]] v.2.0) +" + sharedValues.lang + ":" + sections[0].pos + ":" + dfnSummary; var summaryField = document.getElementById("wpSummary"); if (addLangMode && summaryField.value) { summary = summaryField.value + " " + summary; } summaryField.value = summary; callback(entry); }); } var continueBtn; function getValuesForStep(stepId) { var fields = $("#wiktku-start-" + stepId + " .wiktku-start-step-field"); var step = steps[stepId]; if (step.keys) { var values = {}; fields.each(function (i, field) { var key = $(field).prevAll(".wiktku-start-step-keyfield").val(); if (key) values[key] = $(field).val(); }); return values; } else if (step.multiple) { return fields.map(function () { return $(this).val(); }).get(); } return fields.val(); } function getValues() { var values = {}; $.each(steps, function (stepId) { values[stepId] = getValuesForStep(stepId); }); return values; } function populateMenus(inputs, choices, disabledValues) { if (!disabledValues) disabledValues = {}; var vals = inputs.map(function (i, input) { return $(input).val(); }); inputs.empty(); inputs.append($("<option></option>")); $.each(choices, function (j, choice) { // Append the language code in parentheses so that typing a code // (e.g. "ku") in the search box still finds the language name. var displayText = capitalize(choice[1]); if (choice[2] !== undefined) { // This is a language choice [code, name, sortKey] — show code. displayText = capitalize(choice[1]) + " (" + choice[0] + ")"; } var option = $(mw.html.element("option", { value: choice[0] }, displayText)); if (disabledValues[choice[0]]) option.prop("disabled", true); inputs.append(option); }); inputs.val(function (i) { return vals[i]; }); } /** * Returns a bitmap containing the keys that should be disabled for a key * menu in the given step because they are disabled or already taken by * another key menu. */ function getDisabledKeys(step) { var occupiedKeys = {}; $("#wiktku-start-" + step.id + " .wiktku-start-step-keyfield").each(function () { occupiedKeys[$(this).val()] = true; }); if (step.disabledKeys) $.extend(occupiedKeys, step.disabledKeys); return occupiedKeys; } function buildKeyInput(step) { if (!step.keys) return undefined; var input = $(mw.html.element("select", { "class": "wiktku-start-step-keyfield wiktku-start-narrow" })); input.attr("data-placeholder", "Hilbijêre " + step.keyName); if (isMobile) { populateMenus(input, step.keys, getDisabledKeys(step)); // On mobile return the wrapper; the select is inside it. // Change events still fire on the inner select. return wrapNativeSelect(input); } input.on("chosen:showing_dropdown", function () { $(this).data("wiktku-defaultValue", $(this).val()); }); input.change(function (_, context) { var inputs = $("#wiktku-start-" + step.id + " .wiktku-start-step-keyfield").not(this); var oldValue = $(this).data("wiktku-defaultValue"); var newValue = context.selected; inputs.find("option[value='" + oldValue + "']").prop('disabled', false); inputs.find("option[value='" + newValue + "']").prop('disabled', true); inputs.trigger("chosen:updated"); }); populateMenus(input, step.keys, getDisabledKeys(step)); return input; } /** * If the current text field has text and there are no more text fields after * the current text field in the list, add another text field to the list. */ function refreshForTextField(currentInput, step) { currentInput = $(currentInput); var value = currentInput.val(); var item = currentInput.parent(); if (value && !item.next("li").length) { var nextInput = $("<textarea></textarea>") .attr("name", "wiktku-field-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("class", currentInput.attr("class")) .attr("rows", currentInput.attr("rows") || 1); nextInput.on("input", function (evt) { refreshForTextField(evt.target, step); }); var nextKeyInput = buildKeyInput(step); var nextItem = $("<li></li>").append(nextKeyInput).append(nextInput); item.parent().append(nextItem); if (nextKeyInput) nextKeyInput.chosen(chosenOptions); } var canContinue = !continueBtn.isDisabled(); if ((value && !canContinue) || (!value && canContinue)) { refresh(step); } } function prepareInput(input, step) { if (!input) return; if (step.required) input.prop('required', true); input.change(step, refresh); } /** * Shows and hides all the steps based on whether their prerequisites are met, * and updates placeholders where applicable. */ function refresh(evt) { var values = getValues(); var changedStep = evt && evt.data; var didFocus = false; var canContinue = true; // Re-filter template options in every sense block whenever lang changes. $("#wiktku-start-dfn .wiktku-dfn-tpl-select").each(function () { var fn = $(this).data("updateOptions"); if (typeof fn === "function") fn(); }); // Re-filter pronunciation and etymology template dropdowns when language changes. steps.pron.refreshTplSelect(); steps.etym.refreshTplSelect(); // Sync tr/t sub-fields in every nimûne item to the current language. // tr shown when language needs transliteration; t shown when lang !== "ku". (function () { var lang = values.lang || ""; var showTr = needsTransliteration(lang); var showT = lang && lang !== "ku"; $("#wiktku-start-dfn .wiktku-dfn-nimune-list li.wiktku-dfn-nimune-li").each(function () { var li = $(this); // Ensure the sub-wrapper exists when we need it. var subWrap = li.find(".wiktku-dfn-nimune-sub"); // tr field var trTa = li.find(".wiktku-dfn-nimune-tr"); if (showTr && !trTa.length) { if (!subWrap.length) { subWrap = $("<div></div>").addClass("wiktku-dfn-nimune-sub"); li.append(subWrap); } trTa = $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-tr-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 5) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-tr") .attr("placeholder", "Transkrîpsiyon…"); subWrap.prepend(trTa); } else if (!showTr && trTa.length) { trTa.remove(); } // t field var tTa = li.find(".wiktku-dfn-nimune-t"); if (showT && !tTa.length) { if (!subWrap.length) { subWrap = $("<div></div>").addClass("wiktku-dfn-nimune-sub"); li.append(subWrap); } tTa = $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-t-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 5) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-t") .attr("placeholder", "Tercimeya nimûneyê kurmancî…"); subWrap.append(tTa); } else if (!showT && tTa.length) { tTa.remove(); } // Remove the wrapper if it ended up empty. subWrap = li.find(".wiktku-dfn-nimune-sub"); if (subWrap.length && !subWrap.children().length) subWrap.remove(); }); }()); // Sync tr/t sub-fields in every jêder citation to the current language. // tr shown when language needs transliteration; t shown when lang !== "ku". (function () { var lang = values.lang || ""; var showTr = needsTransliteration(lang); var showT = lang && lang !== "ku"; $("#wiktku-start-dfn .wiktku-dfn-jeder-list li.wiktku-dfn-jeder-li").each(function () { var li = $(this); // Ensure the sub-wrapper exists when we need it. It must sit right // after the quote textarea and before the source selector. var subWrap = li.find(".wiktku-dfn-quote-sub"); // tr field var trTa = li.find(".wiktku-dfn-nimune-quote-tr"); if (showTr && !trTa.length) { if (!subWrap.length) { subWrap = $("<div></div>").addClass("wiktku-dfn-quote-sub"); li.find(".wiktku-dfn-nimune-quote").after(subWrap); } trTa = $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-quote-tr-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 2) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-quote-tr") .attr("placeholder", "Transkrîpsiyona jêgirtinê…"); subWrap.prepend(trTa); } else if (!showTr && trTa.length) { trTa.remove(); } // t field var tTa = li.find(".wiktku-dfn-nimune-quote-t"); if (showT && !tTa.length) { if (!subWrap.length) { subWrap = $("<div></div>").addClass("wiktku-dfn-quote-sub"); li.find(".wiktku-dfn-nimune-quote").after(subWrap); } tTa = $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-quote-t-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 2) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-quote-t") .attr("placeholder", "Tercimeya jêgirtinê ya kurmancî…"); subWrap.append(tTa); } else if (!showT && tTa.length) { tTa.remove(); } // Remove the wrapper if it ended up empty. subWrap = li.find(".wiktku-dfn-quote-sub"); if (subWrap.length && !subWrap.children().length) subWrap.remove(); }); }()); $.each(steps, function (stepId, step) { if (typeof(step.visible) === "function" && !step.visible(values)) { $("#wiktku-start-" + stepId).slideUp(); } else { var stepDiv = $("#wiktku-start-" + stepId); if (changedStep !== step && typeof(step.build) === "function") { prepareInput(step.build(stepDiv, values), step); } var input = stepDiv.find(".wiktku-start-step-field"); if (typeof(step.example) === "function") { // .find() above already reaches nested fields (e.g. the dfn // step's mane textareas inside each sense block), so one // assignment covers every step; dfn keeps its own fallback. var exampleText = step.example(values) || (step.id === "dfn" ? "Mane…" : ""); input.attr("placeholder", exampleText); } var didSlideDown; if (!didFocus && stepDiv.css("display") === "none" && step.required) { didSlideDown = function (evt) { input.focus(); }; didFocus = true; } stepDiv.slideDown(didSlideDown); } if (step.required && (values[stepId] === "" || (step.multiple && values[stepId].join("") === ""))) { canContinue = false; } }); continueBtn.setDisabled(!canContinue); } function destroy() { $("#wiktku-start-form, .noafterwizard").slideUp(function () { $(this).remove(); }); $(".noarticletext .nowizard, #editform").slideDown(); $("#ca-edit").removeClass("selected"); $("#ca-wiktku-nowizard").addClass("selected"); } // Priority order for Kurdish dialects and the navz pseudo-code. // Codes listed here come before all other languages; unlisted codes // are sorted alphabetically by their display name via localeCompare. var LANG_PRIORITY = ["navz", "ku", "hac", "sdh", "lki", "ckb", "zza"]; /** * Inserts a new == {{ziman|code}} == section into existing page wikitext * at the correct sorted position: * 1. Any content before the first language section is preserved at the top. * 2. navz is always first, then ku/hac/sdh/lki/ckb/zza in that order, * then all other languages sorted by display name (localeCompare). */ function insertNewLangSection(existing, wikitext) { var newCodeMatch = wikitext.match(/^== \{\{ziman\|([^}]+)\}\} ==/); var newCode = newCodeMatch ? newCodeMatch[1] : ""; var sections = []; var preamble = ""; var firstMatch = existing.match(/(?:^|\n)== \{\{ziman\|/); if (!firstMatch) { // No existing lang sections at all — just append. var sep = existing && !/\n\s*$/.test(existing) ? "\n\n" : ""; return existing + sep + wikitext; } // Everything before the first == {{ziman|...}} == is the preamble. var firstSectionStart = existing.indexOf("== {{ziman|"); // Walk back to the start of that line. var lineStart = existing.lastIndexOf("\n", firstSectionStart - 1); var preambleEnd = lineStart !== -1 ? lineStart + 1 : 0; preamble = existing.slice(0, preambleEnd); // Parse each language section: header line + everything until the next header. var body = existing.slice(preambleEnd); // NOTE: with the /m flag, a bare "$" matches end-of-*line*, not just // end-of-string — that previously made the non-greedy content group // stop at the section's first line break instead of running to the // next language header (or the real end of the text), silently // dropping the rest of that section's wikitext. (?![\s\S]) matches // only the true end of the string, /m flag or not. var langSectionRe = /^(== \{\{ziman\|([^}]+)\}\} ==\n?)([\s\S]*?)(?=\n== \{\{ziman\||(?![\s\S]))/gm; var m; while ((m = langSectionRe.exec(body)) !== null) { sections.push({ code: m[2], content: m[0] // full text of this section including header }); } // Determine sort rank: priority list first (by index), then alphabetical. function getLangName(code) { var entry = langsByCode[code]; return entry ? entry[1] : code; } function sortRank(code) { var idx = LANG_PRIORITY.indexOf(code); return idx !== -1 ? idx : LANG_PRIORITY.length; } function compareLangs(a, b) { var ra = sortRank(a), rb = sortRank(b); if (ra !== rb) return ra - rb; // Both are outside priority list — sort by display name. return getLangName(a).localeCompare(getLangName(b), userLang); } // Insert the new section into the sorted list. var newSection = { code: newCode, content: wikitext }; var inserted = false; for (var i = 0; i < sections.length; i++) { if (compareLangs(newCode, sections[i].code) < 0) { sections.splice(i, 0, newSection); inserted = true; break; } } if (!inserted) sections.push(newSection); // Re-join: preamble + sections separated by newlines. var joined = sections.map(function (s) { // Ensure each section ends with exactly one newline before the next. return s.content.replace(/\n+$/, ""); }).join("\n"); return preamble + joined + "\n"; } function build() { $(".nowizard, .nowizard .noafterwizard").hide(); var callToAction = $("#wiktku-calltoaction"); var origCallToActionText = callToAction.text(); $(mw.util.addPortletLink("p-views", "#", "Edîtora çavkaniyê veke", "ca-wiktku-nowizard", "Vê rûpelê bi edîtora çavkaniyê çêke", undefined, "#ca-watch")).click(function (evt) { evt.preventDefault(); callToAction.text(origCallToActionText); destroy(); }); if (callToAction.length) { callToAction.text(origCallToActionText + " Forma li jêr ji bo çêkirina madeyeke nû bi kar bîne."); } var startForm = $("<form id='wiktku-start-form'></form>"); var clearPageCheck = null; if (addLangMode) { startForm.append($("<p class='wiktku-addlang-notice'></p>").html( "Bi vê formê tu yê beşeke nû li rûpelê îlawe bikî. Eger ev zimanê ku tu îlawe dikî jixwe di rûpelê de hebe, beşa nû li dawiya vî zimanî dê were îlawekirin. " + "Ji kerema xwe netîceya dawî kontrol bikin, eger problemek derkeve, li <a href='" + mw.util.getUrl('Mediawiki talk:Gadget-start.js') + "'>nîqaşa vê amûrê</a> problemê ragihîne." )); clearPageCheck = $("<input type='checkbox' id='wiktku-clear-page-check'>"); var clearPageLabel = $("<label for='wiktku-clear-page-check'></label>") .text(" Naveroka rûpelê paqij bike (rûpelê ji nû ve binivîse)"); startForm.append( $("<p class='wiktku-addlang-notice'></p>") .append(clearPageCheck) .append(clearPageLabel) ); // Re-evaluate step visibility (e.g. the pron step) whenever this // is toggled, since it changes what counts as "existing content". clearPageCheck.on("change", function () { refresh(); }); } var spinner; // Tab bar for switching between POS sections. var sectionTabsDiv = $("<div id='wiktku-section-tabs'></div>"); startForm.submit(function (evt) { evt.preventDefault(); continueBtn.setDisabled(true); spinner.show(); getWikitext(function (wikitext) { if (addLangMode && clearPageCheck && clearPageCheck.prop("checked")) { // User asked to wipe the page and start fresh — just // write the newly generated wikitext as the full content. $("#wpTextbox1").val(wikitext); } else if (addLangMode) { var textbox = $("#wpTextbox1"); var existing = textbox.val() || ""; // Check whether the generated lang header already exists in the page. // wikitext always starts with "== {{ziman|CODE}} ==\n" (from steps.lang.output). // If that exact section heading is already present in the existing content, // strip it from the new output and insert the remaining content at the end // of that lang section (just before the next == level-2 heading, or at the // very end of the page if there is no following section). var langHeaderMatch = wikitext.match(/^(== \{\{ziman\|[^}]+\}\} ==\n)/); if (langHeaderMatch) { var langHeader = langHeaderMatch[1]; // e.g. "== {{ziman|ku}} ==\n" // Escape for use in RegExp. var escapedHeader = langHeader.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); if (new RegExp(escapedHeader).test(existing)) { // Strip the header from the new output. var newContent = wikitext.slice(langHeader.length); // Find the insertion point: end of the existing lang section. // A new L2 heading marks the start of the next language block. var afterHeader = existing.indexOf(langHeader); var searchFrom = afterHeader + langHeader.length; // Find the next == … == heading after this section's start. var nextL2 = existing.indexOf("\n== ", searchFrom); var insertAt = nextL2 !== -1 ? nextL2 : existing.length; // Ensure there's a blank line before the inserted block. var before = existing.slice(0, insertAt); var after = existing.slice(insertAt); var sep = /\n\s*$/.test(before) ? "" : "\n"; textbox.val(before + sep + newContent + after); } else { // New language — insert at the correct sorted position. textbox.val(insertNewLangSection(existing, wikitext)); } } else { // Unexpected format — insert at sorted position anyway. textbox.val(insertNewLangSection(existing, wikitext)); } } else { $("#wpTextbox1").val(wikitext); } $("html, body").animate({scrollTop: 0}); callToAction.text("Hindik ma!"); $("#wiktku-preview-container").remove(); destroy(); }); }); $.each(ordered_steps, function (i, step) { var stepDiv = $(mw.html.element("div", { "class": "wiktku-start-step", id: "wiktku-start-" + step.id })); var name = capitalize(step.name); stepDiv.append($(mw.html.element("h3", { "class": "wiktku-start-step-name" }, new mw.html.Raw(mw.html.element("label", { "for": "wiktku-start-" + step.id + "-field" }, name))))); if (step.question_fmt) { stepDiv.append($(mw.html.element("label", { "class": "wiktku-start-step-question", "for": "wiktku-start-" + step.id + "-field" }, step.question_fmt))); if (step.question_br) stepDiv.append($("<br>")); } var input; if (step.choices) { input = $(mw.html.element("select", { "class": "wiktku-start-step-field", id: "wiktku-start-" + step.id + "-field" })); input.attr("data-placeholder", capitalize(step.name) + " hilbijêre "); populateMenus(input, step.choices); if (step.multiple) input.attr("multiple", true); if (isMobile) { stepDiv.append(wrapNativeSelect(input)); } else { stepDiv.append(input); } } else if (typeof(step.build) === "function") { input = step.build(stepDiv); } else { input = $("<textarea></textarea>") .attr("class", "wiktku-start-step-field") .attr("id", "wiktku-start-" + step.id + "-field") .attr("rows", step.rows || 2); if (step.narrow) input.addClass("wiktku-start-narrow"); if (step.multiple) { input.on("input", function (evt) { refreshForTextField(evt.target, step); }); var keyInput = buildKeyInput(step); var list = $(step.ordered ? "<ol></ol>" : "<ul></ul>") .append($("<li></li>").append(keyInput).append(input)); stepDiv.append(list); } else stepDiv.append(input); } prepareInput(input, step); stepDiv.hide(); // Insert tab bar just before the first per-section step. if (step.id === "pos") startForm.append(sectionTabsDiv); startForm.append(stepDiv); }); // ── Section tab helpers ────────────────────────────────────────────── // ── Add-section button — lives in the tab bar, disabled until pos chosen ── var addSectionBtn = new OO.ui.ButtonWidget({ label: "+ Beş zêde bike", disabled: true }); addSectionBtn.on("click", function () { saveCurrentSection(); sections.push({}); activeSection = sections.length - 1; $.each(PER_SECTION_STEP_IDS, function (_, id) { if (id === "dfn") { var stepDiv = $("#wiktku-start-dfn"); stepDiv.find("ol.wiktku-dfn-list").remove(); steps.dfn.build(stepDiv); return; } if (id === "etym") { $("#wiktku-start-etym .wiktku-etym-wrap").remove(); steps.etym.build($("#wiktku-start-etym")); return; } if (id === "trans") { var transDiv = $("#wiktku-start-trans"); transDiv.find(".wiktku-trans-group").remove(); return; } if (id === "zarava") { var zaravaDiv = $("#wiktku-start-zarava"); zaravaDiv.find(".wiktku-zarava-group").remove(); return; } if (id === "dunde") { var dundeDiv = $("#wiktku-start-dunde"); dundeDiv.find("ul.wiktku-dunde-list").remove(); return; } var stepDiv = $("#wiktku-start-" + id); stepDiv.find(".wiktku-start-step-field").val(""); if (!isMobile) stepDiv.find("select.wiktku-start-step-field").trigger("chosen:updated"); }); renderSectionTabs(); refresh(); $("html, body").animate({ scrollTop: sectionTabsDiv.offset().top - 20 }, 300); }); /** Re-render the tab bar to reflect current sections[] and activeSection. */ function renderSectionTabs() { // Detach (not remove) the button first: .empty() strips bound // event data from any children left inside it, which would // silently kill addSectionBtn's click handler on every re-render. addSectionBtn.$element.detach(); sectionTabsDiv.empty(); var lang = getValues().lang || ""; if (!lang) { sectionTabsDiv.hide(); return; } sectionTabsDiv.show(); $.each(sections, function (i) { var posVal = sections[i].pos || ""; var tabLabel = posVal ? capitalize(posVal) : ("Beş " + (i + 1)); var tab = $("<span></span>") .addClass("wiktku-section-tab") .text(tabLabel) .toggleClass("wiktku-tab-active", i === activeSection); (function (idx) { tab.on("click", function () { if (idx === activeSection) return; saveCurrentSection(); activeSection = idx; restoreSection(sections[activeSection]); refresh(); renderSectionTabs(); }); }(i)); sectionTabsDiv.append(tab); }); // Enable "Beş zêde bike" only when the active section has a pos chosen. var activePos = sections[activeSection] && sections[activeSection].pos ? sections[activeSection].pos : getValues().pos; addSectionBtn.setDisabled(!activePos); sectionTabsDiv.append(addSectionBtn.$element); } renderSectionTabs(); // Update the active tab's label whenever pos changes. startForm.on("change", "#wiktku-start-pos-field", function () { renderSectionTabs(); }); // Show the tab bar as soon as a language is selected. startForm.on("change", "#wiktku-start-lang-field", function () { renderSectionTabs(); }); var footer = $("<div id='wiktku-start-footer'></div>"); spinner = $(mw.html.element("img", { id: "wiktku-start-spinner", src: "//upload.wikimedia.org/wikipedia/commons/d/de/Ajax-loader.gif", alt: "Tê barkirin…", title: "Tê barkirin…" })); footer.append(spinner.hide()); continueBtn = new OO.ui.ButtonWidget({ id: "wiktku-unhide-editform", label: "Bişîne", flags: [ "primary", "progressive" ] }); continueBtn.on("click", function () { mw.notify("Tê şandin…", { type: "info", tag: "wiktku-submit" }); startForm.trigger("submit"); }); footer.append(continueBtn.$element); // "Edîtora çavkaniyê veke" button — inline fallback for the portlet link // which is invisible on mobile and easy to miss on desktop. var sourceEditorBtn = new OO.ui.ButtonWidget({ label: "Edîtora çavkaniyê veke", framed: false }); sourceEditorBtn.on("click", function () { destroy(); }); footer.append(sourceEditorBtn.$element); // ── Preview checkboxes ─────────────────────────────────────────────── // Wikitext preview (raw text panel) var previewCheck = $("<input type='checkbox' id='wiktku-preview-toggle'>"); var previewLabel = $("<label for='wiktku-preview-toggle'></label>") .text(" Pêşdîtina wîkîtekstê"); var previewPanel = $("<pre id='wiktku-preview-panel'></pre>").hide(); // Live rendered preview (parsed HTML panel, same logic as AjaxEdit). // Not available on mobile — API polling causes too many problems on small screens. var livePreviewCheck = null; var livePreviewPanel = null; if (!isMobile) { livePreviewCheck = $("<input type='checkbox' id='wiktku-live-preview-toggle'>"); livePreviewPanel = $("<div id='wiktku-live-preview-panel'></div>").hide(); } // Container that holds both panels and switches between stacked / side-by-side. var previewContainer = $("<div id='wiktku-preview-container'></div>"); previewContainer.append(previewPanel); if (!isMobile) previewContainer.append(livePreviewPanel); var previewTimer = null; var livePreviewIntervalId = -1; var livePreviewActive = false; // guards in-flight fetches after uncheck /** Rebuilds wikitext preview if its checkbox is checked. */ function schedulePreview() { if (!previewCheck.prop("checked")) return; clearTimeout(previewTimer); // Debounce: wait 400 ms after the last keystroke before rebuilding. previewTimer = setTimeout(function () { getWikitext(function (wikitext) { previewPanel.text(wikitext).show(); updatePanelLayout(); }); }, 400); } /** Fetches parsed HTML and populates the live preview panel. */ function loadLivePreview() { getWikitext(function (wikitext) { new mw.Api().parse(wikitext, { title: mw.config.get("wgPageName") }).done(function (html) { // Discard result if the user unchecked while the fetch was in flight. if (!livePreviewActive) return; livePreviewPanel.html(html).show(); updatePanelLayout(); }); }); } /** Adjusts panel widths depending on which previews are visible. */ function updatePanelLayout() { var wikitextVisible = previewCheck.prop("checked"); var liveVisible = livePreviewCheck && livePreviewCheck.prop("checked"); if (wikitextVisible && liveVisible) { // Side by side — each panel takes roughly half the available width. previewPanel.css({ "flex": "1 1 45%", "min-width": "280px" }); livePreviewPanel.css({ "flex": "1 1 45%", "min-width": "280px" }); } else { // Full width for whichever is visible — only touch panels that are // actually shown so that setting flex doesn't override display:none. if (wikitextVisible) previewPanel.css({ "flex": "1 1 100%", "min-width": "" }); if (liveVisible && livePreviewPanel) livePreviewPanel.css({ "flex": "1 1 100%", "min-width": "" }); } } previewCheck.on("change", function () { if ($(this).prop("checked")) { schedulePreview(); } else { clearTimeout(previewTimer); previewPanel.hide(); updatePanelLayout(); } }); if (!isMobile) { livePreviewCheck.on("change", function () { if ($(this).prop("checked")) { livePreviewActive = true; livePreviewPanel.show(); loadLivePreview(); livePreviewIntervalId = setInterval(loadLivePreview, 500); } else { livePreviewActive = false; clearInterval(livePreviewIntervalId); livePreviewIntervalId = -1; livePreviewPanel.hide().empty(); updatePanelLayout(); } }); } // Listen on all input/change events on the form and update both previews. startForm.on("input change", function () { schedulePreview(); }); footer.append($("<span style='margin-left:1em'></span>") .append(previewCheck).append(previewLabel)); if (!isMobile) { var livePreviewLabel = $("<label for='wiktku-live-preview-toggle'></label>") .text(" Pêşdîtina zindî"); footer.append($("<span style='margin-left:1em'></span>") .append(livePreviewCheck).append(livePreviewLabel)); } startForm.append(footer); $("#editform").hide().before(startForm); // Insert preview container (holds both panels) after the form. startForm.after(previewContainer); if (!isMobile) startForm.find("select").chosen(chosenOptions); refresh(); // Zimanan ji MediaWiki:Gadget-translation_editor.js/ziman.json bar bike. // Kodên ku bi "-pro" diqedin û navên ku "zimanê destan" tê de heye // tên derxistin. Zimanên xardkirî li serî dimînin, yên din // bi alfabeyê li dû wan tên. // Pinned choices come from MediaWiki:Gadget-start.js/data.json (langChoices), // already loaded into steps.lang.choices before build() runs. var pinnedChoices = steps.lang.choices.slice(); var pinnedCodes = $.map(pinnedChoices, function (choice) { return choice[0]; }); new mw.Api().get({ action: "query", prop: "revisions", titles: "MediaWiki:Gadget-translation_editor.js/ziman.json", rvprop: "content", rvslots: "main", formatversion: 2 }).then(function (data) { var page = data.query.pages[0]; var content = page && page.revisions && page.revisions[0].slots.main.content; var zimanData; try { zimanData = JSON.parse(content); } catch (e) { zimanData = {}; } var extraChoices = []; $.each(zimanData, function (code, name) { // Filter: skip proto-language codes and legendary/reconstructed langs. if (/-pro$/i.test(code)) return; if (/ziman[eê]\s+destan/i.test(name)) return; // Skip codes already in the pinned list (they are handled above). if (pinnedCodes.indexOf(code) !== -1) return; // sortKey: bare name without leading "zimanê " for sorting. var sortKey = name.replace(/^ziman[eê]\s+/i, ""); var choice = [code, name, sortKey]; extraChoices.push(choice); langsByCode[code] = choice; }); // Populate langsByCode for pinned choices too. $.each(pinnedChoices, function (i, choice) { // Ensure pinned choices have a sortKey (index 2). if (choice.length < 3) choice[2] = choice[1]; langsByCode[choice[0]] = choice; }); // Sort the extra choices alphabetically by sort key. extraChoices.sort(function (a, b) { return a[2].localeCompare(b[2], userLang); }); // Final list: pinned first, then the rest. var allChoices = pinnedChoices.concat(extraChoices); steps.lang.choices = allChoices; steps.trans.keys = allChoices; steps.dunde.keys = allChoices; steps.zarava.keys = getZaravaKeys(allChoices); var langMenu = $("#wiktku-start-lang-field"); populateMenus(langMenu, steps.lang.choices); langMenu.trigger("chosen:updated"); var transMenus = $("#wiktku-start-trans .wiktku-start-step-keyfield"); populateMenus(transMenus, steps.trans.keys, getDisabledKeys(steps.trans)); transMenus.trigger("chosen:updated"); var dundeMenus = $("#wiktku-start-dunde .wiktku-start-step-keyfield"); populateMenus(dundeMenus, steps.dunde.keys, getDisabledKeys(steps.dunde)); dundeMenus.trigger("chosen:updated"); var zaravaMenus = $("#wiktku-start-zarava .wiktku-start-step-keyfield"); populateMenus(zaravaMenus, steps.zarava.keys, getDisabledKeys(steps.zarava)); }); } mw.loader.using(["jquery.chosen", "mediawiki.api", "oojs-ui-core"], function () { if (!isMobile) { mw.notify( "Amûr dest pê dike, hinek bisekinin. Not: jkx Sentaks (sentaks highlighter) neaktîv bikin", { type: "info", tag: "wiktku-start-notice", autoHide: true, autoHideSeconds: 10 } ); } // Load metadata, langChoices, posChoices and tplDefs from the companion // data page so they can be updated without touching this script. new mw.Api().get({ action: "query", prop: "revisions", titles: "MediaWiki:Gadget-start.js/data.json", rvprop: "content", rvslots: "main", formatversion: 2 }).then(function (data) { var page = data.query.pages[0]; var content = page && page.revisions && page.revisions[0].slots.main.content; var d; try { d = JSON.parse(content); } catch (e) { d = {}; } // Populate metadata. if (d.metadata) $.extend(metadata, d.metadata); // Populate gender labels. if (d.genderLabels) $.extend(GENDER_BASE_LABELS, d.genderLabels); // Populate lang choices (pinned list used by build() → ziman.json loader). if (d.langChoices) steps.lang.choices = d.langChoices; // Populate POS choices. if (d.posChoices) steps.pos.choices = d.posChoices; // Populate template definitions for the dfn sense-block builder. if (d.tplDefs) steps.dfn.tplDefs = d.tplDefs; // Populate pos placeholder examples. if (d.posExamples) steps.dfn.posExamples = d.posExamples; // Populate citation template definitions for the quote widget. if (d.jederDefs) steps.dfn.jederDefs = d.jederDefs; // Populate pronunciation and etymology template insert lists. if (d.pronTpls) { steps.pron.pronTpls = d.pronTpls; steps.pron.refreshTplSelect(); } if (d.etymTpls) { steps.etym.etymTpls = d.etymTpls; steps.etym.refreshTplSelect(); } // Sync trans/dunde/zarava keys with the (now populated) lang choices. steps.trans.keys = steps.lang.choices; steps.dunde.keys = steps.lang.choices; steps.zarava.keys = getZaravaKeys(steps.lang.choices); }).always(build); }); }); //</nowiki> 4raxfyfq6hq2i5grtq4vu94vml73qcg 6265594 6265580 2026-07-19T15:30:01Z Wikihez 7344 6265594 javascript text/javascript // Li ser [[vi:MediaWiki:Gadget-start.js]] hatiye refaktorkirin. //<nowiki> $(function () { if (window.location.href.includes("editintro=User:Wikihez/creation/intro")) { return; // Do not run the script wextê WF:Bilez dişuxile } var ns = mw.config.get("wgNamespaceNumber"); if (ns && !(ns === 2 && mw.config.get("wgPageName").match(/\/ceribandin$|\/test$/))) { return; } var action = mw.config.get("wgAction"); var pageExists = !!mw.config.get("wgArticleId"); // "Zimanek lê zêde bike" mode: triggered from the portlet link below. var addLangMode = pageExists && mw.util.getParamValue("wiktkuaddlang") === "1"; // On a normal page view of an existing page, add the portlet link if (action === "view" && pageExists) { var targetContainer; var skin = mw.config.get('skin'); if (skin === 'vector-2022') { targetContainer = 'p-cactions'; } else if (skin === 'vector') { targetContainer = 'p-tb'; } else { targetContainer = 'p-views'; } mw.util.addPortletLink(targetContainer, mw.util.getUrl(mw.config.get("wgPageName"), { action: "submit", wiktkuaddlang: "1" }), "+Ziman/beşeke din", "ca-wiktku-addlang", "Ji vê rûpelê re ziman an jî beşeke nû zêde bike"); return; } if (!(action === "edit" || action === "submit")) { return; } if (!addLangMode && !$(".mw-newarticletext, .mw-newarticletextanon").length) { return; } function capitalize(str) { if (!str) return str; return str[0].toUpperCase() + str.substr(1); } function decapitalize(str) { if (!str) return str; return str[0].toLowerCase() + str.substr(1); } function escapeRegExp(str) { return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); } /** * Regex source (no anchors/flags) for a "== {{ziman|CODE}} ==" section * header. Tolerates any amount of whitespace around the "==" delimiters * and inside the "{{ziman|...}}" call, since hand-edited pages don't * always match the script's own exact single-space formatting. Captures * the langcode as its one group. * * @param {string} codePattern regex source for the langcode: an escaped * literal code (escapeRegExp("ku")) to match one specific language, or * "[^}]+" to match any language header. */ function langHeaderSource(codePattern) { return "==\\s*\\{\\{\\s*ziman\\s*\\|\\s*(" + codePattern + ")\\s*\\}\\}\\s*=="; } /** * Finds a specific language's "== {{ziman|CODE}} ==" header anywhere in * a block of wikitext (see langHeaderSource for the whitespace * tolerance). Returns the match position and full matched text, or null * if that language has no section there. Used everywhere we need to * check whether a lang section already exists on the page, instead of * each call site doing its own ad-hoc (and previously whitespace-picky) * indexOf/regex check. */ function findLangHeader(text, code) { var m = new RegExp(langHeaderSource(escapeRegExp(code))).exec(text); return m ? { index: m.index, match: m[0] } : null; } function stripWikilinks(str) { return str.replace(/\[\[([^\]|]+)(?:\|([^\]]+))?\]\]/g, function (m, target, display) { return display || target; }); } function insertAtCursor(el, text) { var start = el.selectionStart; var end = el.selectionEnd; var val = el.value; el.value = val.slice(0, start) + text + val.slice(end); var pos = start + text.length; el.selectionStart = el.selectionEnd = pos; } var pageName = mw.config.get("wgPageName").replaceAll(/_/g, " "); if (ns) pageName = pageName.replace(/.*\//, ""); var pageNameRe = escapeRegExp(pageName); var userLang = mw.config.get("wgUserLanguage"); // Mobile detection: MobileFrontend sets wgMFMode, or fall back to touch check. var isMobile = !!mw.config.get("wgMFMode") || window.matchMedia("(pointer: coarse)").matches; var chosenOptions = { width: "20em", disable_search_threshold: 0, placeholder_text_single: "Yekî hilbijêre", placeholder_text_multiple: "Hilbijêre", no_results_text: "Nehat dîtin", enable_split_word_search: true, search_contains: true }; function wrapNativeSelect(select) { var placeholder = select.attr("data-placeholder") || "Lê bigere…"; // Hide the native select — we drive it programmatically. select.hide(); var wrapper = $("<span class='wiktku-native-select-wrap'></span>"); var textInput = $("<input type='search' autocomplete='off'>") .attr("placeholder", placeholder) .addClass("wiktku-start-narrow wiktku-ac-input"); var resultsList = $("<ul class='wiktku-ac-results'></ul>").hide(); // Full option cache — rebuilt when chosen:updated fires. var allOptions = []; function cacheOptions() { allOptions = []; select.find("option").each(function () { var v = $(this).val(); if (!v) return; // skip the empty placeholder option allOptions.push({ value: v, text: $(this).text(), disabled: $(this).prop("disabled") }); }); } cacheOptions(); function showResults(query) { var q = query.trim().toLowerCase(); resultsList.empty(); var matched; if (q) { matched = []; $.each(allOptions, function (_, o) { if (o.disabled) return; var codeMatch = o.value.toLowerCase().indexOf(q) !== -1; var nameMatch = o.text.toLowerCase().indexOf(q) !== -1; if (codeMatch || nameMatch) { matched.push({ opt: o, codeMatch: codeMatch }); } }); // Code matches (especially prefix matches) come first. matched.sort(function (a, b) { var aCode = a.opt.value.toLowerCase(); var bCode = b.opt.value.toLowerCase(); var aPrefix = aCode.indexOf(q) === 0; var bPrefix = bCode.indexOf(q) === 0; if (aPrefix !== bPrefix) return aPrefix ? -1 : 1; if (a.codeMatch !== b.codeMatch) return a.codeMatch ? -1 : 1; return 0; }); matched = matched.map(function (item) { return item.opt; }); } else { matched = allOptions.filter(function (o) { return !o.disabled; }); } if (!matched.length) { resultsList.hide(); return; } $.each(matched.slice(0, 50), function (_, opt) { var li = $("<li></li>").text(opt.text).attr("data-value", opt.value); // Use touchend instead of touchstart so that a scroll gesture does // not accidentally select an item. We track whether the finger moved // between touchstart and touchend — if it did, it was a scroll. var touchMoved = false; li.on("touchstart", function () { touchMoved = false; }); li.on("touchmove", function () { touchMoved = true; }); li.on("touchend", function (e) { if (touchMoved) return; // was a scroll, not a tap e.preventDefault(); selectOption(opt.value, opt.text); }); // Keep mousedown for desktop fallback. li.on("mousedown", function (e) { e.preventDefault(); selectOption(opt.value, opt.text); }); resultsList.append(li); }); // Position the list above or below depending on available viewport space. var inputRect = textInput[0].getBoundingClientRect(); var viewportH = window.innerHeight; var spaceBelow = viewportH - inputRect.bottom - 8; var spaceAbove = inputRect.top - 8; var maxH = Math.min(224, Math.max(spaceBelow, spaceAbove)); // 224px ≈ 14em resultsList.css({ "max-height": maxH + "px", "top": spaceBelow >= spaceAbove ? "100%" : "auto", "bottom": spaceBelow >= spaceAbove ? "auto" : "100%" }); resultsList.show(); } function selectOption(value, text) { textInput.val(text); select.val(value); resultsList.hide(); select.trigger("change"); } textInput.on("input focus", function () { showResults($(this).val()); }); textInput.on("blur", function () { // Short delay so a touchstart on a result item fires first. setTimeout(function () { resultsList.hide(); }, 200); }); // chosen:updated → re-cache (called after ziman.json loads). select.on("chosen:updated", function () { cacheOptions(); // If a value is already selected, keep the display text in sync. var cur = select.val(); if (cur) { var match = $.grep(allOptions, function (o) { return o.value === cur; })[0]; if (match) textInput.val(match.text); } }); // No-op .chosen() so desktop call-sites don't need guarding. select.chosen = function () { return select; }; wrapper.append(textInput).append(resultsList).append(select); return wrapper; } var langsByCode = {}; // Populated from [[MediaWiki:Gadget-start.js/data.json]] at runtime. var metadata = {}; // Zaravayên kurdî yên ku di beşa "Bi zaravayên din" de tên pêşkêşkirin — // ev kod ji beşa Werger têne derxistin daku heman zimên du caran neyê xwendin. var ZARAVA_LANG_CODES = ["ckb", "sdh", "lki", "hac", "zza"]; function getZaravaKeys(choices) { var byCode = {}; $.each(choices || [], function (_, c) { byCode[c[0]] = c; }); var result = []; $.each(ZARAVA_LANG_CODES, function (_, code) { if (byCode[code]) result.push(byCode[code]); }); return result; } function needsTransliteration(langCode) { var meta = metadata[langCode]; if (!meta || !meta.sc) return false; var scripts = Array.isArray(meta.sc) ? meta.sc : [meta.sc]; return scripts.length > 0 && scripts[0] !== "Latn"; } // Kodên cinsiyetê yên di metadata.g de — ji data.json tê dagirtin var GENDER_BASE_LABELS = {}; // Sub-lists that only make sense for a plain (non-şablon) sense — hidden // when a şablon (e.g. {{guharto|…}}) is chosen for that sense, since a // template-based sense has no "own" gloss for alternate forms, synonyms, // antonyms, coordinate terms, hypernyms or hyponyms to attach to. Etîket, // Nimûne and Jêgirtin stay visible either way. var HIDDEN_ON_TPL_GROUPS = [ "wiktku-dfn-alternativ", "wiktku-dfn-hevmane", "wiktku-dfn-dijmane", "wiktku-dfn-koordine", "wiktku-dfn-jornav", "wiktku-dfn-jernav" ]; function genderLabel(code) { if (code === "p") return "Pirjimar"; var pluralMatch = code.match(/^(.+)-p$/); if (pluralMatch && GENDER_BASE_LABELS[pluralMatch[1]]) { return GENDER_BASE_LABELS[pluralMatch[1]] + " (pirjimar)"; } return GENDER_BASE_LABELS[code] || code; } /** * True if a sense has any content worth keeping besides its mane text — * etîket, hevmane/dijmane/koordîne/etc. word lists, nimûne, or jêder * (quote). Used so a sense with an empty mane but filled-in extra * fields still gets emitted (with {{mane?}} standing in for the gloss) * instead of being silently dropped. */ function senseHasExtraContent(s) { if (s.etiket && $.grep(s.etiket, function (e) { return $.trim(e) !== ""; }).length) return true; if (s.kategori && $.grep(s.kategori, function (k) { return $.trim(k) !== ""; }).length) return true; if (s.alternativ.length || s.hevmane.length || s.dijmane.length || s.koordine.length || s.jornav.length || s.jernav.length) return true; if (s.nimune && $.grep(s.nimune, function (n) { return (typeof n === "object" ? n.text : n) !== ""; }).length > 0) return true; if (senseHasJeder(s)) return true; return false; } /** * formatNimune: each nimûne item can be { text, tr, t }: * text — example text * tr — transliteration (only when the language needs it) * t — Kurdish translation (third positional param, no key) */ function formatNimune(nimunes, lang, hasJeder) { var hasNimune = nimunes && $.grep(nimunes, function (n) { return (typeof n === "object" ? n.text : n) !== ""; }).length > 0; if (!hasNimune) { return hasJeder ? "" : "\n#* {{bênimûne|" + lang + "}}"; } return $.map(nimunes, function (n) { var text = typeof n === "object" ? n.text : n; if (!text) return undefined; var bolded = text.replace( new RegExp("(" + pageNameRe + "([^( |,|;|\\?|\\.|\\!)]+)?)", "ig"), "'''$1'''"); var tpl = "\n#: {{nm|" + lang + "|" + bolded; if (typeof n === "object") { if (n.tr) tpl += "|tr=" + n.tr; // Translation as third positional param (no key needed). if (n.t) tpl += "|" + n.t; } // Short examples fit on one line together with their translation. // rêz=1 is not used for ku — definitions are shown on separate lines there. if (text.length < 200 && lang !== "ku") tpl += "|rêz=1"; tpl += "}}"; return tpl; }).join(""); } /** * Formats a list of jêder (quote/citation) objects into wikitext lines. * Each entry that has no quote text is skipped. Returns "" when the list * is empty or every entry is blank. * * #* {{jêder-…|lang|jêgirtin=…|tr=…|tercime=…|…fields…}} * * When no template is chosen, the generic {{jêder|…}} template is used * instead. Its 2nd positional param is the user's freeform "bi destê xwe * binivîsim" source text when supplied, or the çavkanî? placeholder otherwise. * If that text contains "=" it is passed as |2=… instead of a bare * positional param, since MediaWiki would otherwise misparse it as its * own key=value pair and break the template: * #* {{jêder|lang|jêgirtin=…|tr=…|tercime=…|<manual source or çavkanî?>}} */ function formatJeder(jederList, lang) { if (!jederList || !jederList.length) return ""; return $.map(jederList, function (jeder) { if (!jeder || !jeder.quote) return undefined; if (jeder.jederTpl) { var cite = "\n#* {{" + jeder.jederTpl + "|" + lang; cite += "|jêgirtin=" + jeder.quote; if (jeder.quoteTr) cite += "|tr=" + jeder.quoteTr; if (jeder.quoteT) cite += "|tercime=" + jeder.quoteT; $.each(jeder.jêderFields || {}, function (key, val) { if (val) cite += "|" + key + "=" + val; }); cite += "}}"; return cite; } var out = "\n#* {{jêder|" + lang + "|jêgirtin=" + jeder.quote; if (jeder.quoteTr) out += "|tr=" + jeder.quoteTr; if (jeder.quoteT) out += "|tercime=" + jeder.quoteT; var srcParam = jeder.jederManual ? jeder.jederManual : "çavkanî?"; // A positional param containing "=" gets parsed as its own key=value // pair by MediaWiki and breaks the template, so force it to be // explicitly named (|2=) whenever that's the case. out += (srcParam.indexOf("=") !== -1 ? "|2=" : "|") + srcParam; out += "}}"; return out; }).join(""); } /** * True if a sense has at least one jêder entry with actual quote text. */ function senseHasJeder(sense) { return !!(sense.jeder && $.grep(sense.jeder, function (j) { return j && j.quote; }).length > 0); } /** * Builds a "{{tplName|lang|part1|part2|…}}" snippet from a sense field * (e.g. kategorî or etîket), wrapped to match how that template is used * inline in the output — or "" if the field has nothing filled in. * * buildSenseTpl(sense, "kategori", lang, "K", "block") * → "\n#: {{K|lang|cat1|cat2|…}}" (its own line, like katTpl) * buildSenseTpl(sense, "etiket", lang, "e", "inline") * → " {{e|lang|label1|label2|…}} " (sits inline, like labelTpl) */ function buildSenseTpl(sense, field, lang, tplName, format) { if (!sense[field] || !sense[field].length) return ""; var parts = sense[field].map(function (p) { return $.trim(p); }) .filter(function (p) { return p !== ""; }); if (!parts.length) return ""; var call = "{{" + tplName + "|" + lang + "|" + parts.join("|") + "}}"; return format === "block" ? "\n#: " + call : " " + call + " "; } /** * Assembles the nimûne + jêder wikitext block for a sense. Shared by * both the template-sense and normal-mane-sense branches below. */ function buildCite(sense, lang) { return formatNimune(sense.nimune, lang, senseHasJeder(sense)) + formatJeder(sense.jeder, lang); } function makeWordListStep(id, name, question_fmt, header, templateName) { return { id: id, name: name, question_fmt: question_fmt, multiple: true, narrow: true, visible: function (values) { return values.lang && values.pos; }, output: function (values) { var words = $.grep(values[id] || [], function (w) { return !!w; }); if (!words.length) return ""; var lang = values.lang; var section = "\n==== " + header + " ====\n"; if (words.length === 1) { // Single word — keep the simple inline template. return section + "* {{" + templateName + "|" + lang + "|" + words[0] + "}}\n"; } // Multiple words — use {{kol3}} with one positional param per word. var params = "cure=" + header + "\n" + $.map(words, function (w) { return "|" + w; }).join("\n"); return section + "{{kol3|" + lang + "|" + params + "\n}}\n"; } }; } var steps = { lang: { id: "lang", required: true, name: "ziman", question_fmt: '"' + pageName + '" bi çi zimanî ye?', question_br: true, // Populated from [[MediaWiki:Gadget-start.js/data.json]] (langChoices). choices: [], output: function (values) { return "== {{ziman|" + values.lang + "}} ==\n"; } }, pron: { id: "pron", name: "bilêvkirin", question_fmt: '"' + pageName + '" çawa tê telafûzkirin?', // pronTpls populated from data.json pronTpls: [], visible: function (values) { if (!values.lang) return false; // In addLangMode, only skip pron when this langcode's section // already exists in the page — if it's a new language, show it. if (addLangMode) { // If the user wants to wipe the page and start over, the // existing content is irrelevant — always show pron. var clearPageCheck = $("#wiktku-clear-page-check"); if (clearPageCheck.length && clearPageCheck.prop("checked")) { return true; } var existing = $("#wpTextbox1").val() || ""; return !findLangHeader(existing, values.lang); } return true; }, /** Fills (or refills) the insert-dropdown from the current pronTpls array, filtering by language. */ refreshTplSelect: function () { var sel = $("#wiktku-start-pron .wiktku-tpl-insert-select"); if (!sel.length) return; var lang = getValues().lang || ""; sel.find("option[value!='']").remove(); $.each(steps.pron.pronTpls, function (_, tpl) { // Filter: if tpl.langs exists, only show if lang is in that list; otherwise show always var allowed = !tpl.langs || tpl.langs.indexOf(lang) !== -1; if (allowed) { sel.append($("<option></option>") .val(tpl.snippet) .text(tpl.name + " — " + tpl.desc) .attr("data-nolang", tpl.noLang ? "1" : "")); } }); // Notify Chosen that the option list has changed (no-op on mobile). if (!isMobile) sel.trigger("chosen:updated"); }, build: function (stepDiv) { if (stepDiv.find(".wiktku-pron-wrap").length) return null; var wrap = $("<div class='wiktku-pron-wrap'></div>"); var ta = $("<textarea></textarea>") .attr("name", "wiktku-pron-" + $.now()) .attr("class", "wiktku-start-step-field wiktku-pron-text") .attr("rows", 4) .attr("placeholder", "Nimûne: {{IPA|ku|/pɛɪ̯n/}} yan {{kîte|ku|he|ce|ki|rin}}"); // Template insert dropdown — filtered by language. var sel = $("<select class='wiktku-tpl-insert-select'></select>"); sel.append($("<option value=''>— şablonek lê zêde bike —</option>")); var lang = getValues().lang || ""; $.each(steps.pron.pronTpls, function (_, tpl) { // Filter: if tpl.langs exists, only show if lang is in that list; otherwise show always var allowed = !tpl.langs || tpl.langs.indexOf(lang) !== -1; if (allowed) { sel.append($("<option></option>") .val(tpl.snippet) .text(tpl.name + " — " + tpl.desc) .attr("data-nolang", tpl.noLang ? "1" : "")); } }); sel.on("change", function () { var snippet = $(this).val(); if (!snippet) return; var lang = getValues().lang || ""; // Check if the selected option has noLang flag var selectedOption = sel.find("option:selected"); var hasNoLang = selectedOption.attr("data-nolang") === "1"; if (!hasNoLang) { snippet = snippet.replace(/CODE/g, lang).replace(/SOURCELANG/g, "?"); } insertAtCursor(ta[0], snippet); $(this).val(""); ta.focus(); }); wrap.append(sel).append($("<br>")).append(ta); stepDiv.append(wrap); return ta; }, output: function () { var text = $.trim($("#wiktku-start-pron .wiktku-pron-text").val()); if (!text) return ""; var lines = text.split("\n"); var out = $.map(lines, function (line) { line = $.trim(line); if (!line) return undefined; return line.charAt(0) === "*" ? line : "* " + line; }).join("\n"); return "\n=== Bilêvkirin ===\n" + out + "\n"; } }, pos: { id: "pos", required: true, name: "Cureyê rêzimanî", question_fmt: 'Cureyê rêzimanî yê "' + pageName + '" çi ye?', visible: function (values) { return values.lang; }, question_br: true, // Populated from [[MediaWiki:Gadget-start.js/data.json]] (posChoices). choices: [], output: function (values) { var pos = values.pos || ""; var cinsiyet = values.cinsiyet || ""; // from the cinsiyet step var lekTur = values.lektur || ""; // from the lêker transitivity step var capitalizedPos = capitalize(pos); var outputString = "\n=== " + capitalizedPos + " ===\n"; // Add ku-tewîn-nav for single-word navdêr/serenav with known gender. if (!pageName.includes(" ") && cinsiyet && GENDER_BASE_LABELS[cinsiyet] && (pos === "navdêr" || pos === "serenav") && values.lang === "ku") { outputString += "{{ku-tewîn-nav|" + pageName + "|" + GENDER_BASE_LABELS[cinsiyet]; if (pos === "serenav") outputString += "|y"; outputString += "}}\n"; } outputString += "{{" + pos + "|" + values.lang; if (pos === "navdêr" || pos === "serenav") { if (cinsiyet) { outputString += "|c=" + cinsiyet; } else if (values.lang === "ku") { // Unknown gender — prompt editor to fill it in. outputString += "|c=?"; } } else if (/^lêker/.test(pos) && lekTur) { outputString += "|c=" + lekTur; } if (values.tr) { outputString += "|tr=" + values.tr; } outputString += "}}\n"; return outputString; } }, /** * cinsiyet (grammatical gender) — only shown for navdêr/serenav, û * tenê ger metadata ji bo zimanê hilbijartî lîsteyeke "g" (cinsiyet) * were dayîn. Opsiyonên vê gavê ne sabît in — ji metadata[values.lang].g * têne çêkirin, ji ber ku di hemû zimanan de cinsiyet tine. */ cinsiyet: { id: "cinsiyet", name: "cinsiyet", question_fmt: 'Cinsiyeta "' + pageName + '" çi ye?', question_br: true, visible: function (values) { var meta = metadata[values.lang]; return !!(values.lang && (values.pos === "navdêr" || values.pos === "serenav") && meta && meta.g && meta.g.length); }, build: function (stepDiv, values) { var select = stepDiv.find("select.wiktku-start-step-field"); if (!select.length) { select = $(mw.html.element("select", { "class": "wiktku-start-step-field", id: "wiktku-start-cinsiyet-field" })); stepDiv.append(select); } if (!values) return select; var meta = metadata[values.lang]; var codes = (meta && meta.g) || []; var prevVal = select.val(); var choices = $.map(codes, function (code) { return [[code, genderLabel(code)]]; }); populateMenus(select, choices); if ($.grep(choices, function (c) { return c[0] === prevVal; }).length) { select.val(prevVal); } if (!isMobile) select.trigger("chosen:updated"); return select; }, output: function () { return ""; } // consumed by pos.output }, /** * Lêker transitivity — only shown for any lêker variant. */ lektur: { id: "lektur", name: "Cureyê lêkerê (fiîlê)", question_fmt: "Cureyê lêkerê (fiîlê) çi ye?", question_br: true, visible: function (values) { return values.lang && values.pos && /^lêker/.test(values.pos); }, // Dictionary: value → display label. Add new types here. choices: [ ["gh", "gerguhêz"], ['x-gh', 'xwerû-gerguhêz'], ['p-gh', 'pêkhatî-gerguhêz'], ['h-gh', 'hevedudanî-gerguhêz'], ['b-gh', 'biwêjî-gerguhêz'], ["ngh", "negerguhêz"], ['x-ngh', 'xwerû-negerguhêz'], ['p-ngh', 'pêkhatî-negerguhêz'], ['h-ngh', 'hevedudanî-negerguhêz'], ['b-ngh', 'biwêjî-negerguhêz'] ], output: function () { return ""; } // consumed by pos.output }, tr: { id: "tr", name: "transkrîpsiyon", question_fmt: "Transkrîpsiyona kelîmeyê", multiple: false, narrow: true, visible: function (values) { return values.lang && values.pos && needsTransliteration(values.lang); } }, dfn: { id: "dfn", // required: true, ger mane tinebe [[Şablon:mane?]] bi kar bîne name: "Mane", question_fmt: "Maneya kelîmeyê binivîse. Mane otomatîk tê lînkkirin! Ji bo tercimeyan beşa 'Werger' bi kar bîne!", multiple: true, ordered: true, rows: 3, visible: function (values) { return values.lang && values.pos; }, example: function (values) { // posExamples loaded from [[MediaWiki:Gadget-start.js/data.json]]. var examples = steps.dfn.posExamples || {}; var full = values.pos || ""; return examples[full] || ""; }, /** * Builds one sense block (<li>) inside the ordered list. * Each block contains: * - a textarea for the definition * - an expandable nimûne list * - single-row sub-lists for formên alternatîv, hevmane, dijmane */ buildSenseBlock: function (stepDiv) { var block = $("<li class='wiktku-dfn-sense'></li>"); // — Mane textarea (declared first so the template handler can reference it) — var dfnArea = $("<textarea></textarea>") .attr("name", "wiktku-dfn-mane-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("class", "wiktku-start-step-field wiktku-dfn-mane") .attr("rows", 6) .attr("placeholder", "Mane…"); dfnArea.on("input", function () { steps.dfn.onDfnInput(stepDiv, block, this); }); // — Template selector (optional — replaces mane when chosen) — // Template definitions loaded from [[MediaWiki:Gadget-start.js/data.json]]. var tplDefs = steps.dfn.tplDefs || []; // Cache of all non-placeholder option elements — used by updateTplOptions // to remove/re-add options (the only approach compatible with Chosen.js). var _allTplOptions = []; var tplSelect = $(mw.html.element("select", { "class": "wiktku-dfn-tpl-select" })); tplSelect.append($("<option value=''>— yan jî şablonek hilbijêre —</option>")); $.each(tplDefs, function (_, tpl) { var opt = $("<option></option>") .val(tpl.name) .text(tpl.name) .attr("data-langs", tpl.langs ? tpl.langs.join(",") : "") .attr("data-nolang", tpl.noLang ? "1" : ""); tplSelect.append(opt); _allTplOptions.push(opt[0]); }); function updateTplOptions() { var lang = getValues().lang || ""; var currentVal = tplSelect.val(); var currentStillValid = false; // Detach all non-placeholder options, then re-attach only the visible ones. // This is the only approach that works correctly with both native <select> // and Chosen.js on desktop. tplSelect.find("option[value!='']").detach(); $.each(_allTplOptions, function (_, opt) { var allowed = $(opt).attr("data-langs"); var visible = !allowed || allowed.split(",").indexOf(lang) !== -1; if (visible) { tplSelect.append(opt); if ($(opt).val() === currentVal) currentStillValid = true; } }); if (!isMobile) tplSelect.trigger("chosen:updated"); if (currentVal && !currentStillValid) { tplSelect.val(""); dfnArea.show(); tplTitleInput.hide().val(""); } } // Store updater on the element so refresh() can call it for all blocks. tplSelect.data("updateOptions", updateTplOptions); var tplTitleInput = $("<input type='text'>") .addClass("wiktku-dfn-tpl-title wiktku-start-narrow") .attr("placeholder", "Navê rûpelê…") .hide(); // Grow the sense list when the title field of the last block gets content, // mirroring what onDfnInput does for the plain mane textarea. tplTitleInput.on("input", function () { steps.dfn.onDfnInput(stepDiv, block, this); }); /** * When a şablon sense is chosen, formên alternatîv/hevmane/dijmane/ * termên koordîne/jornav/jêrnav don't apply (there's no plain gloss * to hang them off), so hide those subgroups. Etîket, Nimûne and * Jêgirtin stay visible and still usable for a şablon sense. */ function updateFieldVisibility() { var isTpl = !!tplSelect.val(); $.each(HIDDEN_ON_TPL_GROUPS, function (_, cls) { block.find("." + cls + "-group").toggle(!isTpl); }); } // Store on the block so restoreDfn() can re-sync visibility // after programmatically setting tplSelect's value. block.data("updateFieldVisibility", updateFieldVisibility); tplSelect.on("change", function () { var chosen = $(this).val(); if (chosen) { dfnArea.hide(); tplTitleInput.show().focus(); } else { dfnArea.show(); tplTitleInput.hide().val(""); } updateFieldVisibility(); // Re-run refresh so the Werger step visibility updates. refresh(); }); var tplRow = $("<div></div>").addClass("wiktku-dfn-tpl-row") .append(tplSelect).append(" ").append(tplTitleInput); block.append(tplRow); block.append(dfnArea); // Apply lang filter on initial build. updateTplOptions(); // — Sub-field groups — // All groups are always visible with a placeholder textarea. // Nimûne is last in the DOM and last in the output. var allGroups = [ { cls: "wiktku-dfn-etiket", label: "Etîket", rows: 1, narrow: true, izah: "xisûsen, Mêrdîn, anatomî, Badînî" }, { cls: "wiktku-dfn-kategori", label: "Kategorî", rows: 1, narrow: true, izah: "Kategoriya ku ev mane lê tê zêdekirin" }, { cls: "wiktku-dfn-alternativ", label: "Formên alternatîv", rows: 1, narrow: true, izah: "Varyantên vê kelîmeyê" }, { cls: "wiktku-dfn-hevmane", label: "Hevmane", rows: 1, narrow: true, izah: "Spehî hevmaneya Bedew e." }, { cls: "wiktku-dfn-dijmane", label: "Dijmane", rows: 1, narrow: true, izah: "Zengîn dijmaneya feqîr e." }, { cls: "wiktku-dfn-koordine", label: "Termên koordîne", rows: 1, narrow: true, izah: "Pisîk û kûçik termên koordîne ne çunkî Jornavên wan gelek in" }, { cls: "wiktku-dfn-jornav", label: "Jornav", rows: 1, narrow: true, izah: "Heywan jornavê guhandar e" }, { cls: "wiktku-dfn-jernav", label: "Jêrnav", rows: 1, narrow: true, izah: "Guhandar jêrnavê heywan e" }, { cls: "wiktku-dfn-nimune", label: "Nimûne", rows: 2, narrow: false } ]; $.each(allGroups, function (_, g) { var groupDiv = $("<div></div>").addClass("wiktku-dfn-subgroup " + g.cls + "-group"); function buildNimuneLi() { var lang = getValues().lang || ""; var li = $("<li></li>").addClass("wiktku-dfn-nimune-li"); var mainTa = $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-text-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", g.rows) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-text") .attr("placeholder", "Nimûneya emilandina kelîmeyê tu bi xwe binivîse…"); mainTa.on("input", function () { var val = $.trim($(this).val()); var isLast = li.is(list.children("li:last-child")); if (val && isLast) { list.append(buildNimuneLi()); } }); li.append(mainTa); var subWrap = $("<div></div>").addClass("wiktku-dfn-nimune-sub"); if (needsTransliteration(lang)) { subWrap.append( $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-tr-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 5) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-tr") .attr("placeholder", "Transkrîpsiyona bi alfabeya latînî") ); } if (lang && lang !== "ku") { subWrap.append( $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-t-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 5) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-t") .attr("placeholder", "Tercimeya kurmancî") ); } if (subWrap.children().length) li.append(subWrap); return li; } if (g.cls === "wiktku-dfn-nimune") { // Nimûne — compound widget with tr/t sub-fields. var lbl = $("<span></span>").addClass("wiktku-dfn-sublabel").text(g.label + ": "); var list = $("<ol></ol>").addClass("wiktku-dfn-sublist " + g.cls + "-list"); groupDiv.data("buildNimuneLi", buildNimuneLi); list.append(buildNimuneLi()); groupDiv.append(lbl).append(list); block.append(groupDiv); } else { // Regular always-visible group — label + growing textarea list. var lbl = $("<span></span>").addClass("wiktku-dfn-sublabel").text(g.label + ": " + g.izah); var list = $("<ol></ol>").addClass("wiktku-dfn-sublist " + g.cls + "-list"); var firstInput = $("<textarea></textarea>") .attr("name", g.cls + "-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", g.rows) .attr("class", "wiktku-dfn-subfield" + (g.narrow ? " wiktku-start-narrow" : "")) .attr("placeholder", g.label + "…"); firstInput.on("input", function () { steps.dfn.onSubInput(list, this, g.rows, g.narrow); }); list.append($("<li></li>").append(firstInput)); groupDiv.append(lbl).append(list); block.append(groupDiv); } }); // — Jêder (quote / citation) group — a growing list, sibling to Nimûne — // Structured the same way as Nimûne (ol.wiktku-dfn-sublist > li) so it // lines up at the same indentation, and so that typing into the last // citation's Jêgirtin box automatically opens a fresh empty one below it. (function () { var jederGroupDiv = $("<div></div>").addClass("wiktku-dfn-subgroup wiktku-dfn-jeder-group"); var jederLbl = $("<span></span>").addClass("wiktku-dfn-sublabel").text("Jêgirtin: "); var jederList = $("<ol></ol>").addClass("wiktku-dfn-sublist wiktku-dfn-jeder-list"); function buildJederLi() { var lang = getValues().lang || ""; var li = $("<li></li>").addClass("wiktku-dfn-jeder-li"); var dragHandle = $("<span></span>") .addClass("wiktku-jeder-drag-handle") .attr("title", "Bişkûne û bikişîne da ku rêzê biguhezîne"); // Quote text textarea var quoteTa = $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-quote-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 2) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-quote") .attr("placeholder", "Nimûneya emilandinê ji kitêb an çavkaniyeke din binivîse"); quoteTa.on("input", function () { var val = $.trim($(this).val()); var isLast = li.is(jederList.children("li:last-child")); if (val && isLast) { jederList.append(buildJederLi()); } }); li.append(dragHandle).append(quoteTa); // tr/t sub-fields for the quote — shown as needed for the language. var quoteSubWrap = $("<div></div>").addClass("wiktku-dfn-quote-sub"); if (needsTransliteration(lang)) { quoteSubWrap.append( $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-quote-tr-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 2) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-quote-tr") .attr("placeholder", "Transkrîpsiyona jêgirtinê…") ); } if (lang && lang !== "ku") { quoteSubWrap.append( $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-quote-t-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 2) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-quote-t") .attr("placeholder", "Tercimeya jêgirtinê bi kurmancî") ); } if (quoteSubWrap.children().length) li.append(quoteSubWrap); // Citoid auto-fill: fetch citation data from a URL, DOI or ISBN and // prefill the source şablon + fields below (see Gadget-citoid-helper.js). var citoidWrap = $("<div></div>").addClass("wiktku-dfn-quote-citoid"); var citoidInput = $("<input type='text'>") .addClass("wiktku-dfn-quote-citoid-input wiktku-start-narrow") .attr("placeholder", "URL, DOI an ISBN binivîse ku otomatîk were tijekirin…"); var citoidBtn = new OO.ui.ButtonWidget({ label: "Bi Citoid bîne", classes: [ "wiktku-dfn-quote-citoid-btn" ] }); var citoidStatus = $("<span></span>").addClass("wiktku-dfn-quote-citoid-status"); /** * Fetches citation data from Citoid and applies it to this * citation's şablon selector + fields. Mirrors the logic in * Form.prototype._fillFromCitoid (Gadget-wikt.add-examples.js): * - only (re)selects the şablon when it actually differs from * what's already chosen, so a repeat fetch doesn't wipe out * a template the user already picked; * - only fills fields that are currently empty, so it never * overwrites something the user typed by hand; * - falls back to the freeform "bi destê xwe binivîsim" source * only when nothing was typed there yet. */ function runCitoidFetch() { var query = $.trim(citoidInput.val()); if (!query) { mw.notify("Ji kerema xwe re pêşî URL, DOI an ISBNyekê binivîse."); return; } citoidBtn.setDisabled(true); citoidStatus.text("Tê anîn…"); wikt.citoidHelper.ensure().then(function () { return wikt.citoid.fetchJederFields(query); }).then(function (result) { var jederKey = result.jederKey; var hasTpl = !!jederKey && srcSel.find("option[value='" + jederKey + "']").length > 0; var targetVal = hasTpl ? jederKey : "__manual__"; // Only (re)select — and thus rebuild — the field rows if // we're switching to a different şablon than what's // already chosen, so a second fetch doesn't clear fields // the user already filled in by hand. if (srcSel.val() !== targetVal) { srcSel.val(targetVal).trigger("change"); srcSel.trigger("chosen:updated"); } if (hasTpl) { // Tenê qadên vala tijî bike. $.each(result.fields, function (key, val) { var input = srcFields.find("[data-field-key='" + key + "']"); if (input.length && !$.trim(input.val())) { input.val(val); } }); } else { // Şablonek nehat naskirin ji bo vê itemType — rêzikeke // çavkaniyê ya bi destan a ji qadên Citoid tê çêkirin, // lê tenê ger qada destan vala be. var manualField = srcFields.find(".wiktku-dfn-quote-src-manual"); if (!$.trim(manualField.val())) { var parts = []; $.each(["nivîskar", "sernav", "websîte", "kovar", "weşanxane", "sal", "url"], function (_, k) { if (result.fields[k]) parts.push(result.fields[k]); }); manualField.val(parts.join(", ")); } } citoidStatus.text(""); }, function (errorMsg) { citoidStatus.text(typeof errorMsg === "string" ? errorMsg : "Nehat dîtin. Kontrol bike ka URL/DOI/ISBN rast e."); }).always(function () { citoidBtn.setDisabled(false); }); } citoidBtn.on("click", runCitoidFetch); citoidInput.on("keydown", function (e) { if (e.which === 13) { // Enter e.preventDefault(); runCitoidFetch(); } }); citoidWrap.append(citoidInput).append(citoidBtn.$element).append(citoidStatus); // Source template selector, specific to this citation. var srcSel = $("<select></select>").addClass("wiktku-dfn-quote-src-sel"); srcSel.append($("<option value=''>— Çavkaniyê hilbijêre —</option>")); srcSel.append($("<option></option>").val("__manual__").text("Bi destê xwe binivîsim")); var jederDefs = steps.dfn.jederDefs || {}; $.each(jederDefs, function (tplName, def) { srcSel.append($("<option></option>").val(tplName).text(def.label)); }); // Dynamic source fields container. var srcFields = $("<div></div>").addClass("wiktku-dfn-quote-src-fields"); srcSel.on("change", function () { srcFields.empty(); var chosen = $(this).val(); if (!chosen) return; if (chosen === "__manual__") { // Freeform source, written by the user — becomes the 2nd // positional param of {{jêder|lang|…}} instead of çavkanî?. srcFields.append( $("<textarea></textarea>") .attr("rows", 4) .addClass("wiktku-dfn-subfield wiktku-dfn-quote-src-manual") .attr("placeholder", "Çavkaniyê bi destê xwe binivîse…") ); return; } var def = (steps.dfn.jederDefs || {})[chosen]; if (!def) return; $.each(def.fields, function (_, f) { var row = $("<div></div>").addClass("wiktku-dfn-quote-src-row"); var fieldLbl = $("<label></label>").text(f.label + ": "); var inp = $("<textarea></textarea>") .attr("rows", 2) .addClass("wiktku-dfn-quote-src-input wiktku-start-narrow") .attr("data-field-key", f.key) .attr("placeholder", f.label + "…"); row.append(fieldLbl).append(inp); srcFields.append(row); }); }); li.append(citoidWrap).append(srcSel).append(srcFields); return li; } jederGroupDiv.data("buildJederLi", buildJederLi); jederList.append(buildJederLi()); // Make citation rows sortable (drag to reorder). // The last row is always the empty trailing row — cancel its drag. mw.loader.using("jquery.ui.sortable", function () { jederList.sortable({ handle: ".wiktku-jeder-drag-handle", axis: "y", items: "li:not(:last-child)", tolerance: "pointer" }); }); jederGroupDiv.append(jederLbl).append(jederList); block.append(jederGroupDiv); }()); // Apply the initial hide/show state for the sub-groups (matches // tplSelect's starting value, which is normally empty). updateFieldVisibility(); return block; }, /** Grows the sense list when the last mane textarea gets content. */ onDfnInput: function (stepDiv, block, textarea) { var val = $.trim($(textarea).val()); var list = stepDiv.find("ol.wiktku-dfn-list"); var isLast = block.is(list.children("li:last-child")); if (val && isLast) { var newBlock = steps.dfn.buildSenseBlock(stepDiv); list.append(newBlock); // Apply Chosen to the new block's template selector on desktop. if (!isMobile) newBlock.find("select.wiktku-dfn-tpl-select").chosen(chosenOptions); } refresh(); }, /** Grows a sub-list (nimûne/formên alternatîv/hevmane/dijmane/termên koordîne) on input. */ onSubInput: function (list, input, rows, narrow) { var val = $.trim($(input).val()); var item = $(input).parent(); var isLast = item.is(list.children("li:last-child")); if (val && isLast) { var next = $("<textarea></textarea>") .attr("name", "wiktku-dfn-sub-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", rows) .attr("class", "wiktku-dfn-subfield" + (narrow ? " wiktku-start-narrow" : "")); next.on("input", function () { steps.dfn.onSubInput(list, this, rows, narrow); }); list.append($("<li></li>").append(next)); } }, // Populated from [[MediaWiki:Gadget-start.js/data.json]] (tplDefs, posExamples, jederDefs). tplDefs: [], posExamples: {}, jederDefs: {}, build: function (stepDiv) { if (stepDiv.find("ol.wiktku-dfn-list").length) return null; var list = $("<ol class='wiktku-dfn-list'></ol>"); list.append(steps.dfn.buildSenseBlock(stepDiv)); stepDiv.append(list); return null; }, /** Reads all sense blocks from the DOM and returns an array of sense objects. */ getSenses: function (stepDiv) { var senses = []; stepDiv.find("li.wiktku-dfn-sense").each(function () { var block = $(this); var tplSel = block.find("select.wiktku-dfn-tpl-select"); var tpl = tplSel.val() || ""; // noLang: template already encodes the language — don't add |lang| param. var tplNoLang = tpl ? tplSel.find("option[value='" + tpl + "']").attr("data-nolang") === "1" : false; var tplTitle = $.trim(block.find("input.wiktku-dfn-tpl-title").val()); var mane = $.trim(block.find("textarea.wiktku-dfn-mane").val()); var etiket = (function () { var vals = []; block.find(".wiktku-dfn-etiket-list textarea").each(function () { var v = $.trim($(this).val()); if (v) vals.push(v); }); return vals; }()); var kategori = (function () { var vals = []; block.find(".wiktku-dfn-kategori-list textarea").each(function () { var v = $.trim($(this).val()); if (v) vals.push(v); }); return vals; }()); function readList(cls) { var vals = []; block.find("." + cls + "-list textarea").each(function () { var v = $.trim($(this).val()); if (v) vals.push(v); }); return vals; } // Nimûne items are compound: { text, tr?, t? } function readNimuneList() { var items = []; block.find(".wiktku-dfn-nimune-list li.wiktku-dfn-nimune-li").each(function () { var text = $.trim($(this).find(".wiktku-dfn-nimune-text").val()); if (!text) return; var obj = { text: text }; var tr = $.trim($(this).find(".wiktku-dfn-nimune-tr").val()); var t = $.trim($(this).find(".wiktku-dfn-nimune-t").val()); if (tr) obj.tr = tr; if (t) obj.t = t; items.push(obj); }); return items; } // Jêder is a growing list of citations, one per li — mirrors readNimuneList(). function readJederList() { var items = []; block.find(".wiktku-dfn-jeder-list li.wiktku-dfn-jeder-li").each(function () { var li = $(this); var quote = $.trim(li.find(".wiktku-dfn-nimune-quote").val()); if (!quote) return; var obj = { quote: quote }; var qtr = $.trim(li.find(".wiktku-dfn-nimune-quote-tr").val()); var qt = $.trim(li.find(".wiktku-dfn-nimune-quote-t").val()); if (qtr) obj.quoteTr = qtr; if (qt) obj.quoteT = qt; var tplName = li.find(".wiktku-dfn-quote-src-sel").val(); if (tplName === "__manual__") { var manual = $.trim(li.find(".wiktku-dfn-quote-src-manual").val()); if (manual) obj.jederManual = manual; } else if (tplName) { obj.jederTpl = tplName; var fields = {}; li.find(".wiktku-dfn-quote-src-input").each(function () { var k = $(this).attr("data-field-key"); var v = $.trim($(this).val()); if (k && v) fields[k] = v; }); obj.jêderFields = fields; } items.push(obj); }); return items; } senses.push({ tpl: tpl, tplNoLang: tplNoLang, tplTitle: tplTitle, mane: mane, etiket: etiket, kategori: kategori, nimune: readNimuneList(), jeder: readJederList(), alternativ: readList("wiktku-dfn-alternativ"), hevmane: readList("wiktku-dfn-hevmane"), dijmane: readList("wiktku-dfn-dijmane"), koordine: readList("wiktku-dfn-koordine"), jornav: readList("wiktku-dfn-jornav"), jernav: readList("wiktku-dfn-jernav") }); }); return senses; }, getOutput: function (values, callback) { var stepDiv = $("#wiktku-start-dfn"); var senses = steps.dfn.getSenses(stepDiv); var lang = values.lang; // A sense counts as "filled" if it has a mane, a chosen template + title, // or any other content (etîket/hevmane/nimûne/jêder…) worth keeping. var hasMane = senses.some(function (s) { return s.mane !== "" || (s.tpl && s.tplTitle) || senseHasExtraContent(s); }); // True only when at least one sense has a regular mane (needs linkify). var hasRegularMane = senses.some(function (s) { return !s.tpl && s.mane !== ""; }); // nimûne and jêder lines must never pass through linkify — only // the plain mane text should be linkified. We build two parallel // arrays: defLines (sent to linkify) and citeLines (kept aside). // Each entry in citeLines corresponds 1-to-1 with a defLines entry; // a template token {{wiktku-cite-N}} is embedded in defLines so // that after linkify runs we know exactly where to splice them back. // Template-call syntax is guaranteed safe: linkifiers leave {{ }} // tokens completely untouched. var defLines = []; // one entry per kept sense (goes to linkify) var citeLines = []; // parallel — nimûne+jêder for that same sense $.each(senses, function (_, sense) { // — Template sense (e.g. {{guharto|ku|somepage}}) — if (sense.tpl) { if (!sense.tplTitle) return; // skip empty template senses var tplKatTpl = buildSenseTpl(sense, "kategori", lang, "K", "inline"); var tplLabelTpl = buildSenseTpl(sense, "etiket", lang, "e", "inline"); var tplCall = sense.tplNoLang ? "{{" + sense.tpl + "|" + sense.tplTitle + "}}" : "{{" + sense.tpl + "|" + lang + "|" + sense.tplTitle + "}}"; var idx = defLines.length; var cite = buildCite(sense, lang); defLines.push("#" + (tplLabelTpl ? tplLabelTpl : " ") + tplCall + tplKatTpl + (cite ? "{{wiktku-cite-" + idx + "}}" : "")); citeLines.push(cite); return; } // — Normal mane sense — var dfn = sense.mane; if (!dfn && !senseHasExtraContent(sense)) return; // truly empty if (dfn) { dfn = stripWikilinks(dfn); if (dfn[0] !== dfn[0].toUpperCase()) dfn = capitalize(dfn); if (!dfn.match(/[.…?!)\]]$/)) dfn += "."; } else { dfn = "{{mane?|" + lang + "}}"; } var katTpl = buildSenseTpl(sense, "kategori", lang, "K", "inline"); var labelTpl = buildSenseTpl(sense, "etiket", lang, "e", "inline"); var out = "# " + (katTpl ? katTpl : " ") (labelTpl ? labelTpl : "") + dfn; function wordLine(tpl, words) { if (!words.length) return ""; return "\n#: {{" + tpl + "|" + lang + "|" + words.join("|") + "}}"; } out += wordLine("alt-r", sense.alternativ); out += wordLine("hevmane", sense.hevmane); out += wordLine("dijmane", sense.dijmane); out += wordLine("koordîne", sense.koordine); out += wordLine("jornav", sense.jornav); out += wordLine("jêrnav", sense.jernav); var cite = buildCite(sense, lang); var idx = defLines.length; defLines.push(out + (cite ? "{{wiktku-cite-" + idx + "}}" : "")); citeLines.push(cite); }); // Splice citeLines back into a linkified string, replacing each // {{wiktku-cite-N}} token with its stored nimûne/jêder block. function restoreCites(t) { return t.replace(/\{\{wiktku-cite-(\d+)\}\}/g, function (_, n) { return citeLines[parseInt(n, 10)] || ""; }); } var text = defLines.join("\n") + "\n"; if (!hasMane) { // No definitions entered — emit {{mane?}} with bênimûne. text = "# {{mane?|" + lang + "}}\n#* {{bênimûne|" + lang + "}}\n"; callback(text); return; } if (!hasRegularMane) { // All filled senses are template senses — no linkify needed. callback(restoreCites(text)); return; } var didTryToLoad = function () { if (typeof $.wiktviLinkify === "function") { $.wiktviLinkify(text, function (linked) { callback(restoreCites(linked)); }); } else { callback(restoreCites(text)); } }; mw.loader.using("ext.gadget.linkify", didTryToLoad, didTryToLoad); } }, je: makeWordListStep("je", "jê", "Kelîmeyên jê çêbûyî binivîse", "Jê", "g"), tekildar: makeWordListStep("tekildar", "têkildar", "Kelîmeyên ji aliyê etîmolojiyê ve têkildarî vê kelîmeyê binivîse", "Têkildar", "g"), binereherwiha: makeWordListStep("binereherwiha", "binêre herwiha", "Kelîmeyên din ên eleqedar binivîse", "Binêre herwiha", "g"), etym: { id: "etym", name: "etîmolojî", question_fmt: "Etîmolojiya kelîmeyê binivîse", // etymTpls populated from data.json etymTpls: [], visible: function (values) { return values.lang && values.pos; }, /** Fills (or refills) the insert-dropdown from the current etymTpls array. */ refreshTplSelect: function () { var sel = $("#wiktku-start-etym .wiktku-tpl-insert-select"); if (!sel.length) return; sel.find("option[value!='']").remove(); $.each(steps.etym.etymTpls, function (_, tpl) { sel.append($("<option></option>").val(tpl.snippet).text(tpl.name + " — " + tpl.desc)); }); // Notify Chosen that the option list has changed (no-op on mobile). if (!isMobile) sel.trigger("chosen:updated"); }, build: function (stepDiv) { if (stepDiv.find(".wiktku-etym-wrap").length) return null; var wrap = $("<div class='wiktku-etym-wrap'></div>"); var ta = $("<textarea></textarea>") .attr("name", "wiktku-etym-" + $.now()) .attr("class", "wiktku-start-step-field wiktku-etym-text") .attr("rows", 4) .attr("placeholder", "Nimûne: Ji {{ji|en|ku|apple}}. yan rasterast binivîse…"); // Template insert dropdown — options also refreshed after data.json loads. var sel = $("<select class='wiktku-tpl-insert-select'></select>"); sel.append($("<option value=''>— şablonek lê zêde bike —</option>")); $.each(steps.etym.etymTpls, function (_, tpl) { sel.append($("<option></option>").val(tpl.snippet).text(tpl.name + " — " + tpl.desc)); }); sel.on("change", function () { var snippet = $(this).val(); if (!snippet) return; var lang = getValues().lang || ""; snippet = snippet.replace(/CODE/g, lang).replace(/SOURCELANG/g, "?"); insertAtCursor(ta[0], snippet); $(this).val(""); ta.focus(); }); wrap.append(sel).append($("<br>")).append(ta); stepDiv.append(wrap); return ta; }, output: function (values) { var text = $.trim($("#wiktku-start-etym .wiktku-etym-text").val()); if (text) { return "\n==== Etîmolojî ====\n" + text + "\n"; } // No etymology entered — emit {{ji?|lang}} as a placeholder, // but only when the entry has at least one regular (non-şablon) // sense with content — either real mane text, or an empty mane // with other fields filled in (which dfn.getOutput() renders as // {{mane?|lang}} with those fields attached). A şablon sense // like {{guharto|…}} never counts, filled in or not. var dfnSenses = steps.dfn.getSenses($("#wiktku-start-dfn")); var hasRegularMane = dfnSenses.some(function (s) { return !s.tpl && (s.mane !== "" || senseHasExtraContent(s)); }); if (!hasRegularMane) return ""; return "\n==== Etîmolojî ====\n{{ji?|" + values.lang + "}}\n"; } }, dunde: { id: "dunde", name: "dûnde", question_fmt: "Eger ev kelîme ji vî zimanî ketibe zimanekî din, vî zimanî û kelîmeya wî binivîse", visible: function (values) { return !!values.pos; }, disabledKeys: { "navz": true}, /** * Builds one row: a language dropdown + a growing list of word * inputs. When the dropdown gets a value the next empty row is * appended automatically. Mirrors steps.trans's row widget, but * flat (one shared list — dûnde isn't tied to individual senses). */ buildRow: function (stepDiv) { var row = $("<li class='wiktku-dunde-row wiktku-lang-row'></li>"); // Language selector — chosen is applied after insertion into DOM. var langSel = $(mw.html.element("select", { "class": "wiktku-start-step-keyfield wiktku-start-narrow" })); langSel.attr("data-placeholder", "Zimanekî lê bigere"); populateMenus(langSel, steps.dunde.keys || [], steps.dunde.disabledKeys); // When a language is chosen, ensure a next empty row exists. langSel.on("change", function () { steps.dunde.onLangChange(stepDiv, row); }); // Word list for this language. var wordList = $("<ul class='wiktku-dunde-words wiktku-lang-row-words'></ul>"); var firstWord = steps.dunde.makeWordInput(); wordList.append($("<li></li>").append(firstWord)); if (isMobile) { row.append(wrapNativeSelect(langSel)).append(wordList); } else { row.append(langSel).append(wordList); } return row; }, makeWordInput: function () { var input = $("<textarea></textarea>") .attr("name", "wiktku-dunde-word-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 1) .attr("class", "wiktku-dfn-subfield wiktku-start-narrow") .attr("placeholder", "Kelîme…"); input.on("input", function () { var list = $(this).closest("ul.wiktku-dunde-words"); var item = $(this).parent(); var val = $.trim($(this).val()); if (val && item.is(list.children("li:last-child"))) { var next = steps.dunde.makeWordInput(); list.append($("<li></li>").append(next)); } }); return input; }, onLangChange: function (stepDiv, row) { var list = stepDiv.find("ul.wiktku-dunde-list"); var isLast = row.is(list.children("li.wiktku-dunde-row:last-child")); if (isLast) { var newRow = steps.dunde.buildRow(stepDiv); list.append(newRow); // Init chosen after the new row is in the DOM (desktop only). if (!isMobile) newRow.find("select").chosen(chosenOptions); } // Keep disabled keys in sync across all lang selectors. steps.dunde.syncDisabledKeys(stepDiv); }, /** Disables already-selected languages in all other dropdowns. */ syncDisabledKeys: function (stepDiv) { var taken = $.extend({}, steps.dunde.disabledKeys); stepDiv.find("li.wiktku-dunde-row select").each(function () { var v = $(this).val(); if (v) taken[v] = true; }); stepDiv.find("li.wiktku-dunde-row select").each(function () { var self = $(this); var own = self.val(); self.find("option").each(function () { var code = $(this).val(); if (!code) return; $(this).prop("disabled", taken[code] && code !== own); }); self.trigger("chosen:updated"); }); }, build: function (stepDiv) { if (stepDiv.find("ul.wiktku-dunde-list").length) return null; var list = $("<ul class='wiktku-dunde-list wiktku-lang-row-list'></ul>"); list.append(steps.dunde.buildRow(stepDiv)); stepDiv.append(list); // Init chosen after the select is in the DOM (desktop only). if (!isMobile) list.find("select").chosen(chosenOptions); return null; }, /** Reads all [langcode, words[]] rows from the DOM. */ getRows: function (stepDiv) { var result = []; stepDiv.find("li.wiktku-dunde-row").each(function () { var lang = $(this).find("select").val(); if (!lang) return; var words = []; $(this).find("ul.wiktku-dunde-words textarea").each(function () { var v = $.trim($(this).val()); if (v) words.push(v); }); if (words.length) result.push([lang, words]); }); return result; }, output: function () { var stepDiv = $("#wiktku-start-dunde"); var rows = steps.dunde.getRows(stepDiv); if (!rows.length) return ""; var lines = $.map(rows, function (row) { var lang = row[0], words = row[1]; return "* {{dû|" + lang + "|" + words.join("|") + "}}"; }); return "\n==== Dûnde ====\n" + lines.join("\n") + "\n"; } }, zarava: { id: "zarava", name: "bi zaravayên din", visible: function (values) { return steps.trans.visible(values); }, disabledKeys: { "navz": true }, buildRow: function (group) { var row = $("<li class='wiktku-zarava-row wiktku-lang-row'></li>"); var langSel = $(mw.html.element("select", { "class": "wiktku-start-step-keyfield wiktku-start-narrow" })); populateMenus(langSel, steps.zarava.keys || [], steps.zarava.disabledKeys); langSel.on("change", function () { steps.zarava.onLangChange(group, row); }); var wordList = $("<ul class='wiktku-zarava-words wiktku-lang-row-words'></ul>"); var firstWord = steps.zarava.makeWordInput(); wordList.append($("<li></li>").append(firstWord)); row.append(langSel).append(wordList); return row; }, makeWordInput: function () { var input = $("<textarea></textarea>") .attr("name", "wiktku-zarava-word-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 1) .attr("class", "wiktku-dfn-subfield wiktku-start-narrow") .attr("placeholder", "Tercime…"); input.on("input", function () { var list = $(this).closest("ul.wiktku-zarava-words"); var item = $(this).parent(); var val = $.trim($(this).val()); if (val && item.is(list.children("li:last-child"))) { var next = steps.zarava.makeWordInput(); list.append($("<li></li>").append(next)); } }); return input; }, onLangChange: function (group, row) { var list = group.find("ul.wiktku-zarava-list"); var isLast = row.is(list.children("li.wiktku-zarava-row:last-child")); if (isLast) { var newRow = steps.zarava.buildRow(group); list.append(newRow); } steps.zarava.syncDisabledKeys(group); }, /** Disables already-selected dialects in all other dropdowns within one group. */ syncDisabledKeys: function (group) { var taken = $.extend({}, steps.zarava.disabledKeys); group.find("li.wiktku-zarava-row select").each(function () { var v = $(this).val(); if (v) taken[v] = true; }); group.find("li.wiktku-zarava-row select").each(function () { var self = $(this); var own = self.val(); self.find("option").each(function () { var code = $(this).val(); if (!code) return; $(this).prop("disabled", taken[code] && code !== own); }); }); }, /** Builds (or fetches) the .wiktku-zarava-group for one gloss. */ buildGroup: function (stepDiv, gi) { var group = $("<div class='wiktku-zarava-group'></div>").attr("data-gloss-pos", gi); var list = $("<ul class='wiktku-zarava-list wiktku-lang-row-list'></ul>"); list.append(steps.zarava.buildRow(group)); group.append(list); stepDiv.append(group); return group; }, /** Syncs one .wiktku-zarava-group per current gloss (same logic as steps.trans.build). */ build: function (stepDiv) { var glosses = steps.trans.glossList(); if (!glosses.length) { stepDiv.find(".wiktku-zarava-group").remove(); return null; } var existingGroups = stepDiv.find(".wiktku-zarava-group"); if (existingGroups.length > glosses.length) { existingGroups.slice(glosses.length).remove(); } $.each(glosses, function (gi, gloss) { var group = stepDiv.find(".wiktku-zarava-group[data-gloss-pos='" + gi + "']"); if (!group.length) group = steps.zarava.buildGroup(stepDiv, gi); var label = group.find(".wiktku-zarava-group-label"); if (glosses.length > 1) { if (!label.length) { label = $("<div class='wiktku-zarava-group-label'></div>"); group.prepend(label); } label.text(gloss.index + " " + gloss.text); } else if (label.length) { label.remove(); } }); return null; }, /** Reads the dialect rows for a single gloss group. */ getGroupTranslations: function (group) { var result = []; group.find("li.wiktku-zarava-row").each(function () { var lang = $(this).find("select").val(); if (!lang) return; var words = []; $(this).find("ul.wiktku-zarava-words textarea").each(function () { var v = $.trim($(this).val()); if (v) words.push(v); }); if (words.length) result.push([lang, words]); }); return result; }, /** Reads all rows from the DOM, grouped by gloss position. */ getTranslations: function (stepDiv) { var result = []; stepDiv.find(".wiktku-zarava-group").each(function () { result.push(steps.zarava.getGroupTranslations($(this))); }); return result; }, output: function (values) { if (values.lang !== "ku") return ""; var stepDiv = $("#wiktku-start-zarava"); var glosses = steps.trans.glossList(); if (!glosses.length) return ""; var blocks = $.map(glosses, function (gloss, gi) { var group = stepDiv.find(".wiktku-zarava-group[data-gloss-pos='" + gi + "']"); var rows = group.length ? steps.zarava.getGroupTranslations(group) : []; if (!gloss.text && !rows.length) return undefined; if (rows.length) { rows.sort(function (a, b) { var aLang = langsByCode[a[0]] || []; var bLang = langsByCode[b[0]] || []; return (aLang[2] || "").localeCompare(bLang[2] || "", "ku"); }); } var wordLines = $.map(rows, function (row) { var lang = row[0]; var words = row[1]; var wikiWords = words.map(function (w) { return "{{W|" + lang + "|" + w + "}}"; }).join(", "); return "* {{Z|" + lang + "}}: " + wikiWords; }).join("\n"); if (!wordLines) return undefined; var block = "{{werger-ser|" + (gloss.text || "?") + "|" + gloss.index + "}}"; block += "\n" + wordLines; block += "\n{{werger-bin}}"; return block; }); if (!blocks.length) return ""; return "\n==== Bi zaravayên din ====\n" + blocks.join("\n") + "\n"; } }, trans: { id: "trans", name: "werger", visible: function (values) { if (!(values.lang === "ku" && values.pos)) return false; // Hide Werger only when EVERY sense is a template sense (Guharto etc.) // with a title filled in — i.e. there is real content but no plain // gloss to attach a translation table to. A mix of real + template // senses still shows Werger; the template senses are simply skipped // in output(). // // "Real" here means a non-şablon sense with either mane text or // other filled-in fields (etîket/hevmane/nimûne/jêder…), since // dfn.getOutput() renders the latter too, as {{mane?|lang}} plus // whatever else was filled in. // // When nothing has been filled in at all, output() will emit // {{mane?|lang}} instead of a gloss — but Werger should still show, // since the user may want to add translations before they've // settled on a gloss. var dfnSenses = steps.dfn.getSenses($("#wiktku-start-dfn")); var hasRealSense = dfnSenses.some(function (s) { return !s.tpl && (s.mane !== "" || senseHasExtraContent(s)); }); var hasFilledTplSense = dfnSenses.some(function (s) { return s.tpl && s.tplTitle; }); return hasRealSense || !hasFilledTplSense; }, disabledKeys: { "navz": true, "ku": true, "ckb": true, "sdh": true, "lki": true, "hac": true, "zza": true }, /** * Builds one translation row: a language dropdown + a growing list * of word inputs. When the dropdown gets a value the next empty row * is appended automatically. * * @param group the specific .wiktku-trans-group this row belongs to * (each gloss has its own group and its own list of rows, so the * lookups below must stay scoped to that group rather than the * whole step — the step now holds one list per gloss). */ buildRow: function (group) { var row = $("<li class='wiktku-trans-row wiktku-lang-row'></li>"); // Language selector — chosen is applied after insertion into DOM. var langSel = $(mw.html.element("select", { "class": "wiktku-start-step-keyfield wiktku-start-narrow" })); langSel.attr("data-placeholder", "Zimanekî lê bigere"); populateMenus(langSel, steps.trans.keys || [], steps.trans.disabledKeys); // When a language is chosen, ensure a next empty row exists. langSel.on("change", function () { steps.trans.onLangChange(group, row); }); // Word list for this language. var wordList = $("<ul class='wiktku-trans-words wiktku-lang-row-words'></ul>"); var firstWord = steps.trans.makeWordInput(); wordList.append($("<li></li>").append(firstWord)); if (isMobile) { row.append(wrapNativeSelect(langSel)).append(wordList); } else { row.append(langSel).append(wordList); } return row; }, makeWordInput: function () { var input = $("<textarea></textarea>") .attr("name", "wiktku-trans-word-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 1) .attr("class", "wiktku-dfn-subfield wiktku-start-narrow") .attr("placeholder", "Tercime…"); input.on("input", function () { var list = $(this).closest("ul.wiktku-trans-words"); var item = $(this).parent(); var val = $.trim($(this).val()); if (val && item.is(list.children("li:last-child"))) { var next = steps.trans.makeWordInput(); list.append($("<li></li>").append(next)); } }); return input; }, onLangChange: function (group, row) { var list = group.find("ul.wiktku-trans-list"); var isLast = row.is(list.children("li.wiktku-trans-row:last-child")); if (isLast) { var newRow = steps.trans.buildRow(group); list.append(newRow); // Init chosen after the new row is in the DOM (desktop only). if (!isMobile) newRow.find("select").chosen(chosenOptions); } // Keep disabled keys in sync across this gloss's lang selectors // only — the same language can be used for different senses. steps.trans.syncDisabledKeys(group); }, /** Disables already-selected languages in all other dropdowns within one group. */ syncDisabledKeys: function (group) { var taken = $.extend({}, steps.trans.disabledKeys); group.find("li.wiktku-trans-row select").each(function () { var v = $(this).val(); if (v) taken[v] = true; }); group.find("li.wiktku-trans-row select").each(function () { var self = $(this); var own = self.val(); self.find("option").each(function () { var code = $(this).val(); if (!code) return; $(this).prop("disabled", taken[code] && code !== own); }); self.trigger("chosen:updated"); }); }, /** * Builds (or fetches) the .wiktku-trans-group for one gloss, with * its own label and its own list of translation rows. */ buildGroup: function (stepDiv, gi) { var group = $("<div class='wiktku-trans-group'></div>").attr("data-gloss-pos", gi); var list = $("<ul class='wiktku-trans-list wiktku-lang-row-list'></ul>"); list.append(steps.trans.buildRow(group)); group.append(list); stepDiv.append(group); // Init chosen after the select is in the DOM (desktop only). if (!isMobile) list.find("select").chosen(chosenOptions); return group; }, /** * Syncs one .wiktku-trans-group per current gloss, adding new * groups and removing stale ones as senses are added or removed, * while leaving existing groups (and whatever translations the * user has already typed into them) untouched. Groups are keyed * to their gloss's position in glossList() via data-gloss-pos, so * a group always matches the same sense across rebuilds as long * as senses aren't reordered relative to each other. */ build: function (stepDiv) { var glosses = steps.trans.glossList(); if (!glosses.length) { stepDiv.find(".wiktku-trans-group").remove(); return null; } // Drop groups for glosses that no longer exist (always from the // tail — groups are only ever appended in gloss order below). var existingGroups = stepDiv.find(".wiktku-trans-group"); if (existingGroups.length > glosses.length) { existingGroups.slice(glosses.length).remove(); } $.each(glosses, function (gi, gloss) { var group = stepDiv.find(".wiktku-trans-group[data-gloss-pos='" + gi + "']"); if (!group.length) group = steps.trans.buildGroup(stepDiv, gi); // Only label groups when there's more than one gloss to // distinguish between — a single gloss needs no caption. var label = group.find(".wiktku-trans-group-label"); if (glosses.length > 1) { if (!label.length) { label = $("<div class='wiktku-trans-group-label'></div>"); group.prepend(label); } label.text(gloss.index + " " + gloss.text); } else if (label.length) { label.remove(); } }); return null; }, /** Reads the translation rows for a single gloss group. */ getGroupTranslations: function (group) { var result = []; group.find("li.wiktku-trans-row").each(function () { var lang = $(this).find("select").val(); if (!lang) return; var words = []; $(this).find("ul.wiktku-trans-words textarea").each(function () { var v = $.trim($(this).val()); if (v) words.push(v); }); if (words.length) result.push([lang, words]); }); return result; }, /** * Reads all translation rows from the DOM, grouped by gloss * position — one array of [lang, words] rows per gloss group, in * the same order as the .wiktku-trans-group elements. */ getTranslations: function (stepDiv) { var result = []; stepDiv.find(".wiktku-trans-group").each(function () { result.push(steps.trans.getGroupTranslations($(this))); }); return result; }, /** * Builds the numbered "{ index, gloss }" list — one entry per dfn * sense that has a real mane (skips template senses like Guharto, * which have nothing to caption a translation table with). The * index matches the sense's actual position in the numbered "#" * definition list (1-based), including template senses in the count, * so the number printed next to {{werger-ser}} lines up with the * gloss the reader sees in the entry. * * When nothing has been filled in at all (dfn.getOutput() will emit * {{mane?|lang}} as sense 1), this returns a single placeholder * entry with empty text instead of an empty array, so Werger still * has one group to attach translations to before a gloss exists. * When every filled sense is a template sense instead, this stays * empty — that mirrors trans.visible()'s hidden case, where there's * no group in the DOM for a placeholder to attach to anyway. */ glossList: function () { var dfnSenses = steps.dfn.getSenses($("#wiktku-start-dfn")); var glosses = []; var hasFilledTplSense = false; $.each(dfnSenses, function (i, s) { if (s.tpl) { if (s.tplTitle) hasFilledTplSense = true; return; // template sense — no gloss to caption with } var dfn = s.mane; if (!dfn) { // No mane text, but other fields (etîket/hevmane/nimûne/ // jêder…) are filled — dfn.getOutput() still emits this // sense as a numbered line using {{mane?|lang}}, so it // needs its own gloss group too, just with no caption text. if (senseHasExtraContent(s)) glosses.push({ index: i + 1, text: "" }); return; } if (dfn[0] !== dfn[0].toLowerCase()) dfn = decapitalize(dfn); dfn = stripWikilinks(dfn).replace(/[.…?!)\]،؟]+$/, ""); glosses.push({ index: i + 1, text: dfn }); }); if (!glosses.length && !hasFilledTplSense) { glosses.push({ index: 1, text: "" }); } return glosses; }, output: function (values) { if (values.lang !== "ku") return ""; var stepDiv = $("#wiktku-start-trans"); var glosses = steps.trans.glossList(); // Every sense is a template sense — there's no real gloss // anywhere and no group in the DOM either (glossList() only // returns empty in that case), so skip the section entirely. if (!glosses.length) return ""; // Each gloss now has its own group of translation rows — // attach every gloss's own words under its own werger-ser/-bin // pair instead of dumping everything under the first one. var blocks = $.map(glosses, function (gloss, gi) { var group = stepDiv.find(".wiktku-trans-group[data-gloss-pos='" + gi + "']"); var rows = group.length ? steps.trans.getGroupTranslations(group) : []; // Placeholder gloss (no real mane entered yet) with nothing // translated into it — nothing to output, and gloss.text is // empty so there's no caption to give {{werger-ser}} anyway. if (!gloss.text && !rows.length) return undefined; if (rows.length) { // Sort by Kurdish sort key. rows.sort(function (a, b) { var aLang = langsByCode[a[0]] || []; var bLang = langsByCode[b[0]] || []; return (aLang[2] || "").localeCompare(bLang[2] || "", "ku"); }); } var wordLines = $.map(rows, function (row) { var lang = row[0]; var words = row[1]; var wikiWords = words.map(function (w) { return "{{W|" + lang + "|" + w + "}}"; }).join(", "); return "* {{Z|" + lang + "}}: " + wikiWords; }).join("\n"); var block = "{{werger-ser|" + (gloss.text || "?") + "|" + gloss.index + "}}"; if (wordLines) block += "\n" + wordLines; block += "\n{{werger-bin}}"; return block; }); if (!blocks.length) return ""; return "\n==== Werger ====\n" + blocks.join("\n") + "\n"; } }, }; steps.trans.keys = steps.lang.choices; steps.dunde.keys = steps.lang.choices; steps.zarava.keys = getZaravaKeys(steps.lang.choices); var ordered_steps = [ steps.lang, steps.pron, steps.pos, steps.cinsiyet, steps.lektur, steps.tr, steps.dfn, steps.je, steps.tekildar, steps.etym, steps.dunde, steps.binereherwiha, steps.zarava, steps.trans]; // Step ids that belong to each section (not shared across sections). var PER_SECTION_STEP_IDS = [ "pos", "cinsiyet", "lektur", "tr", "dfn", "je", "tekildar", "etym", "dunde", "binereherwiha", "zarava", "trans" ]; // ── Multi-section state ────────────────────────────────────────────────── // Each entry is a plain snapshot: { pos, cinsiyet, lektur, tr, dfn (senses[]), // je, tekildar, binereherwiha, trans (rows[]) }. var sections = [{}]; // section 0 starts empty (DOM is the truth) var activeSection = 0; function snapshotDfn() { return steps.dfn.getSenses($("#wiktku-start-dfn")); } /** * Rebuild the dfn DOM from a previously snapshotted senses array. */ function restoreDfn(senses) { var stepDiv = $("#wiktku-start-dfn"); // Tear down the existing list so build() recreates it cleanly. stepDiv.find("ol.wiktku-dfn-list").remove(); steps.dfn.build(stepDiv); var list = stepDiv.find("ol.wiktku-dfn-list"); $.each(senses, function (i, sense) { // Ensure enough blocks exist (build() seeds one). var blocks = list.find("li.wiktku-dfn-sense"); var block = blocks.eq(i); if (!block.length) { var nb = steps.dfn.buildSenseBlock(stepDiv); list.append(nb); block = list.find("li.wiktku-dfn-sense").last(); } // Template selector. block.find("select.wiktku-dfn-tpl-select").val(sense.tpl || ""); if (sense.tpl) { block.find("textarea.wiktku-dfn-mane").hide(); block.find("input.wiktku-dfn-tpl-title").val(sense.tplTitle || "").show(); } else { block.find("textarea.wiktku-dfn-mane").val(sense.mane || "").show(); block.find("input.wiktku-dfn-tpl-title").hide().val(""); } // Re-sync the formên alternatîv/hevmane/… hide state now that // tplSelect's value was set programmatically (its own "change" // handler doesn't fire from .val(), so this doesn't happen otherwise). var updateVis = block.data("updateFieldVisibility"); if (updateVis) updateVis(); // Restore a sub-list (etiket, formên alternatîv, hevmane …) from a values array. function restoreSubList(cls, values) { if (!values || !values.length) return; var groupDiv = block.find("." + cls + "-group"); var subList = groupDiv.find("ol, ul").first(); if (!subList.length) return; // group not found // Fill existing items, append new ones as needed. $.each(values, function (j, val) { var items = subList.find("li"); if (j < items.length) { items.eq(j).find("textarea").val(val); } else { var ta = $("<textarea></textarea>") .attr("name", "wiktku-dfn-restore-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 1) .attr("class", "wiktku-dfn-subfield wiktku-start-narrow") .val(val); ta.on("input", function () { steps.dfn.onSubInput(subList, this, 1, true); }); subList.append($("<li></li>").append(ta)); } }); } // Reveal and populate lazy groups that have data. var lazyMap = { "wiktku-dfn-etiket": sense.etiket, "wiktku-dfn-kategori": sense.kategori, "wiktku-dfn-alternativ": sense.alternativ, "wiktku-dfn-hevmane": sense.hevmane, "wiktku-dfn-dijmane": sense.dijmane, "wiktku-dfn-koordine": sense.koordine, "wiktku-dfn-jornav": sense.jornav, "wiktku-dfn-jernav": sense.jernav }; $.each(lazyMap, function (cls, vals) { if (vals && vals.length) restoreSubList(cls, vals); }); // Nimûne items are objects { text, tr?, t? } — restore using the builder. if (sense.nimune && sense.nimune.length) { var nimuneGroupDiv = block.find(".wiktku-dfn-nimune-group"); var nimuneList = nimuneGroupDiv.find("ol.wiktku-dfn-nimune-list"); var buildFn = nimuneGroupDiv.data("buildNimuneLi"); nimuneList.empty(); $.each(sense.nimune, function (_, n) { var text = typeof n === "object" ? (n.text || "") : n; if (!text) return; var li = buildFn ? buildFn() : $("<li class='wiktku-dfn-nimune-li'></li>"); li.find(".wiktku-dfn-nimune-text").val(text); if (n.tr) li.find(".wiktku-dfn-nimune-tr").val(n.tr); if (n.t) li.find(".wiktku-dfn-nimune-t").val(n.t); nimuneList.append(li); }); // Always leave a blank trailing item. if (buildFn) nimuneList.append(buildFn()); } // Restore jêder (quote/citation) entries — a growing list, restored using the // builder just like Nimûne. Accepts either the current array shape or a // single legacy object (from older saved sections) for backwards compatibility. var jederArr = $.isArray(sense.jeder) ? sense.jeder : (sense.jeder ? [sense.jeder] : []); if (jederArr.length) { var jederGroupDiv = block.find(".wiktku-dfn-jeder-group"); var jederList = jederGroupDiv.find("ol.wiktku-dfn-jeder-list"); var buildJederFn = jederGroupDiv.data("buildJederLi"); jederList.empty(); $.each(jederArr, function (_, j) { if (!j || !j.quote) return; var li = buildJederFn ? buildJederFn() : $("<li class='wiktku-dfn-jeder-li'></li>"); li.find(".wiktku-dfn-nimune-quote").val(j.quote); if (j.quoteTr) li.find(".wiktku-dfn-nimune-quote-tr").val(j.quoteTr); if (j.quoteT) li.find(".wiktku-dfn-nimune-quote-t").val(j.quoteT); if (j.jederManual) { var manualSel = li.find(".wiktku-dfn-quote-src-sel"); manualSel.val("__manual__").trigger("change"); li.find(".wiktku-dfn-quote-src-manual").val(j.jederManual); } else if (j.jederTpl) { var srcSel = li.find(".wiktku-dfn-quote-src-sel"); srcSel.val(j.jederTpl).trigger("change"); if (j.jêderFields) { $.each(j.jêderFields, function (key, val) { li.find(".wiktku-dfn-quote-src-input[data-field-key='" + key + "']").val(val); }); } } jederList.append(li); }); // Always leave a blank trailing item, same as Nimûne. if (buildJederFn) jederList.append(buildJederFn()); } }); } /** * Snapshot simple (non-dfn) per-section steps from current DOM into obj. */ function saveCurrentSection() { var snap = {}; $.each(PER_SECTION_STEP_IDS, function (_, id) { if (id === "dfn") { snap.dfn = snapshotDfn(); return; } if (id === "etym") { snap.etym = $.trim($("#wiktku-start-etym .wiktku-etym-text").val()); return; } var step = steps[id]; if (!step) return; var stepDiv = $("#wiktku-start-" + id); if (id === "trans") { snap.trans = steps.trans.getTranslations(stepDiv); return; } if (id === "zarava") { snap.zarava = steps.zarava.getTranslations(stepDiv); return; } if (id === "dunde") { snap.dunde = steps.dunde.getRows(stepDiv); return; } // Generic: read all step fields. var fields = stepDiv.find(".wiktku-start-step-field"); if (step.multiple) { snap[id] = fields.map(function () { return $(this).val(); }).get(); } else { snap[id] = fields.val(); } }); sections[activeSection] = snap; } /** * Restore a previously saved snapshot into the form DOM. */ function restoreSection(snap) { $.each(PER_SECTION_STEP_IDS, function (_, id) { if (id === "dfn") { restoreDfn(snap.dfn || []); return; } if (id === "etym") { $("#wiktku-start-etym .wiktku-etym-wrap").remove(); steps.etym.build($("#wiktku-start-etym")); $("#wiktku-start-etym .wiktku-etym-text").val(snap.etym || ""); return; } if (id === "trans") { // Rebuild trans groups (dfn must already be restored by this // point in the $.each loop, so glossList() reflects it). var transDiv = $("#wiktku-start-trans"); transDiv.find(".wiktku-trans-group").remove(); steps.trans.build(transDiv); var groupsSnap = snap.trans || []; $.each(groupsSnap, function (gi, rows) { var group = transDiv.find(".wiktku-trans-group[data-gloss-pos='" + gi + "']"); if (!group.length) return; // gloss no longer exists — drop its rows var list = group.find("ul.wiktku-trans-list"); $.each(rows, function (j, row) { var lang = row[0], words = row[1]; var lastRow = list.find("li.wiktku-trans-row").last(); lastRow.find("select").val(lang).trigger("change"); var wordList = lastRow.find("ul.wiktku-trans-words"); $.each(words, function (k, word) { var wordItems = wordList.find("li"); if (k < wordItems.length) { wordItems.eq(k).find("textarea").val(word); } else { // .val() below doesn't fire "input", so the normal // auto-grow never runs — append a matching item // ourselves instead of silently dropping the word. var extraInput = steps.trans.makeWordInput(); wordList.append($("<li></li>").append(extraInput)); extraInput.val(word); } }); // Leave one trailing empty field so the row can still grow // when the user types, matching a freshly-built row. if ($.trim(wordList.children("li").last().find("textarea").val())) { wordList.append($("<li></li>").append(steps.trans.makeWordInput())); } }); }); return; } if (id === "zarava") { // Rebuild zarava groups (dfn must already be restored by this // point in the $.each loop, so glossList() reflects it). var zaravaDiv = $("#wiktku-start-zarava"); zaravaDiv.find(".wiktku-zarava-group").remove(); steps.zarava.build(zaravaDiv); var zaravaGroupsSnap = snap.zarava || []; $.each(zaravaGroupsSnap, function (gi, rows) { var group = zaravaDiv.find(".wiktku-zarava-group[data-gloss-pos='" + gi + "']"); if (!group.length) return; // gloss no longer exists — drop its rows var list = group.find("ul.wiktku-zarava-list"); $.each(rows, function (j, row) { var lang = row[0], words = row[1]; var lastRow = list.find("li.wiktku-zarava-row").last(); lastRow.find("select").val(lang).trigger("change"); var wordList = lastRow.find("ul.wiktku-zarava-words"); $.each(words, function (k, word) { var wordItems = wordList.find("li"); if (k < wordItems.length) { wordItems.eq(k).find("textarea").val(word); } else { var extraInput = steps.zarava.makeWordInput(); wordList.append($("<li></li>").append(extraInput)); extraInput.val(word); } }); if ($.trim(wordList.children("li").last().find("textarea").val())) { wordList.append($("<li></li>").append(steps.zarava.makeWordInput())); } }); }); return; } if (id === "dunde") { // Rebuild dunde rows. var dundeDiv = $("#wiktku-start-dunde"); dundeDiv.find("ul.wiktku-dunde-list").remove(); steps.dunde.build(dundeDiv); var dundeRows = snap.dunde || []; $.each(dundeRows, function (i, row) { var lang = row[0], words = row[1]; var list = dundeDiv.find("ul.wiktku-dunde-list"); var lastRow = list.find("li.wiktku-dunde-row").last(); lastRow.find("select").val(lang).trigger("change"); var wordList = lastRow.find("ul.wiktku-dunde-words"); $.each(words, function (j, word) { var wordItems = wordList.find("li"); if (j < wordItems.length) { wordItems.eq(j).find("textarea").val(word); } else { // .val() below doesn't fire "input", so the normal // auto-grow never runs — append a matching item // ourselves instead of silently dropping the word. var extraInput = steps.dunde.makeWordInput(); wordList.append($("<li></li>").append(extraInput)); extraInput.val(word); } }); // Leave one trailing empty field so the row can still grow // when the user types, matching a freshly-built row. if ($.trim(wordList.children("li").last().find("textarea").val())) { wordList.append($("<li></li>").append(steps.dunde.makeWordInput())); } }); return; } var step = steps[id]; if (!step) return; var stepDiv = $("#wiktku-start-" + id); var fields = stepDiv.find(".wiktku-start-step-field"); var val = snap[id]; if (val === undefined || val === null) return; if (step.multiple) { var arr = val; fields.each(function (i) { if (i < arr.length) $(this).val(arr[i]); }); } else { fields.val(val); } // Notify chosen widgets of the programmatic value change. if (!isMobile) fields.filter("select").trigger("chosen:updated"); }); } function getWikitextForCurrentSection(callback) { var values = getValues(); var entry = steps.pos.output(values); steps.dfn.getOutput(values, function (output) { entry += output; entry += steps.je.output(values); entry += steps.tekildar.output(values); entry += steps.etym.output(values); entry += steps.dunde.output(values); entry += steps.binereherwiha.output(values); entry += steps.zarava.output(values); entry += steps.trans.output(values); callback(entry, values); }); } function getWikitextAllSections(callback) { saveCurrentSection(); var results = new Array(sections.length); var sharedValues = getValues(); // lang/pron are shared function processSection(i) { if (i >= sections.length) { // All done — restore original active section. restoreSection(sections[activeSection]); refresh(); callback(results, sharedValues); return; } restoreSection(sections[i]); refresh(); getWikitextForCurrentSection(function (sectionText) { results[i] = sectionText; processSection(i + 1); }); } processSection(0); } /** * Assembles wikitext for all sections plus the shared lang/pron header. */ function getWikitext(callback) { getWikitextAllSections(function (sectionTexts, sharedValues) { var entry = steps.lang.output(sharedValues); entry += steps.pron.output(sharedValues); entry += sectionTexts.join("\n"); // Edit summary uses section 0's values. Read from the saved snapshot // (not the live DOM) so it doesn't mix section 0's pos with whichever // section happens to be active/restored at this point. var dfnSenses = (sections[0] && sections[0].dfn) || []; var dfnSummary = dfnSenses.map(function (s) { return s.mane; }).filter(Boolean).join("; "); var summary = "([[Mediawiki:Gadget-start.js|WF:NÛ]] v.2.0) +" + sharedValues.lang + ":" + sections[0].pos + ":" + dfnSummary; var summaryField = document.getElementById("wpSummary"); if (addLangMode && summaryField.value) { summary = summaryField.value + " " + summary; } summaryField.value = summary; callback(entry); }); } var continueBtn; function getValuesForStep(stepId) { var fields = $("#wiktku-start-" + stepId + " .wiktku-start-step-field"); var step = steps[stepId]; if (step.keys) { var values = {}; fields.each(function (i, field) { var key = $(field).prevAll(".wiktku-start-step-keyfield").val(); if (key) values[key] = $(field).val(); }); return values; } else if (step.multiple) { return fields.map(function () { return $(this).val(); }).get(); } return fields.val(); } function getValues() { var values = {}; $.each(steps, function (stepId) { values[stepId] = getValuesForStep(stepId); }); return values; } function populateMenus(inputs, choices, disabledValues) { if (!disabledValues) disabledValues = {}; var vals = inputs.map(function (i, input) { return $(input).val(); }); inputs.empty(); inputs.append($("<option></option>")); $.each(choices, function (j, choice) { // Append the language code in parentheses so that typing a code // (e.g. "ku") in the search box still finds the language name. var displayText = capitalize(choice[1]); if (choice[2] !== undefined) { // This is a language choice [code, name, sortKey] — show code. displayText = capitalize(choice[1]) + " (" + choice[0] + ")"; } var option = $(mw.html.element("option", { value: choice[0] }, displayText)); if (disabledValues[choice[0]]) option.prop("disabled", true); inputs.append(option); }); inputs.val(function (i) { return vals[i]; }); } /** * Returns a bitmap containing the keys that should be disabled for a key * menu in the given step because they are disabled or already taken by * another key menu. */ function getDisabledKeys(step) { var occupiedKeys = {}; $("#wiktku-start-" + step.id + " .wiktku-start-step-keyfield").each(function () { occupiedKeys[$(this).val()] = true; }); if (step.disabledKeys) $.extend(occupiedKeys, step.disabledKeys); return occupiedKeys; } function buildKeyInput(step) { if (!step.keys) return undefined; var input = $(mw.html.element("select", { "class": "wiktku-start-step-keyfield wiktku-start-narrow" })); input.attr("data-placeholder", "Hilbijêre " + step.keyName); if (isMobile) { populateMenus(input, step.keys, getDisabledKeys(step)); // On mobile return the wrapper; the select is inside it. // Change events still fire on the inner select. return wrapNativeSelect(input); } input.on("chosen:showing_dropdown", function () { $(this).data("wiktku-defaultValue", $(this).val()); }); input.change(function (_, context) { var inputs = $("#wiktku-start-" + step.id + " .wiktku-start-step-keyfield").not(this); var oldValue = $(this).data("wiktku-defaultValue"); var newValue = context.selected; inputs.find("option[value='" + oldValue + "']").prop('disabled', false); inputs.find("option[value='" + newValue + "']").prop('disabled', true); inputs.trigger("chosen:updated"); }); populateMenus(input, step.keys, getDisabledKeys(step)); return input; } /** * If the current text field has text and there are no more text fields after * the current text field in the list, add another text field to the list. */ function refreshForTextField(currentInput, step) { currentInput = $(currentInput); var value = currentInput.val(); var item = currentInput.parent(); if (value && !item.next("li").length) { var nextInput = $("<textarea></textarea>") .attr("name", "wiktku-field-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("class", currentInput.attr("class")) .attr("rows", currentInput.attr("rows") || 1); nextInput.on("input", function (evt) { refreshForTextField(evt.target, step); }); var nextKeyInput = buildKeyInput(step); var nextItem = $("<li></li>").append(nextKeyInput).append(nextInput); item.parent().append(nextItem); if (nextKeyInput) nextKeyInput.chosen(chosenOptions); } var canContinue = !continueBtn.isDisabled(); if ((value && !canContinue) || (!value && canContinue)) { refresh(step); } } function prepareInput(input, step) { if (!input) return; if (step.required) input.prop('required', true); input.change(step, refresh); } /** * Shows and hides all the steps based on whether their prerequisites are met, * and updates placeholders where applicable. */ function refresh(evt) { var values = getValues(); var changedStep = evt && evt.data; var didFocus = false; var canContinue = true; // Re-filter template options in every sense block whenever lang changes. $("#wiktku-start-dfn .wiktku-dfn-tpl-select").each(function () { var fn = $(this).data("updateOptions"); if (typeof fn === "function") fn(); }); // Re-filter pronunciation and etymology template dropdowns when language changes. steps.pron.refreshTplSelect(); steps.etym.refreshTplSelect(); // Sync tr/t sub-fields in every nimûne item to the current language. // tr shown when language needs transliteration; t shown when lang !== "ku". (function () { var lang = values.lang || ""; var showTr = needsTransliteration(lang); var showT = lang && lang !== "ku"; $("#wiktku-start-dfn .wiktku-dfn-nimune-list li.wiktku-dfn-nimune-li").each(function () { var li = $(this); // Ensure the sub-wrapper exists when we need it. var subWrap = li.find(".wiktku-dfn-nimune-sub"); // tr field var trTa = li.find(".wiktku-dfn-nimune-tr"); if (showTr && !trTa.length) { if (!subWrap.length) { subWrap = $("<div></div>").addClass("wiktku-dfn-nimune-sub"); li.append(subWrap); } trTa = $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-tr-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 5) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-tr") .attr("placeholder", "Transkrîpsiyon…"); subWrap.prepend(trTa); } else if (!showTr && trTa.length) { trTa.remove(); } // t field var tTa = li.find(".wiktku-dfn-nimune-t"); if (showT && !tTa.length) { if (!subWrap.length) { subWrap = $("<div></div>").addClass("wiktku-dfn-nimune-sub"); li.append(subWrap); } tTa = $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-t-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 5) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-t") .attr("placeholder", "Tercimeya nimûneyê kurmancî…"); subWrap.append(tTa); } else if (!showT && tTa.length) { tTa.remove(); } // Remove the wrapper if it ended up empty. subWrap = li.find(".wiktku-dfn-nimune-sub"); if (subWrap.length && !subWrap.children().length) subWrap.remove(); }); }()); // Sync tr/t sub-fields in every jêder citation to the current language. // tr shown when language needs transliteration; t shown when lang !== "ku". (function () { var lang = values.lang || ""; var showTr = needsTransliteration(lang); var showT = lang && lang !== "ku"; $("#wiktku-start-dfn .wiktku-dfn-jeder-list li.wiktku-dfn-jeder-li").each(function () { var li = $(this); // Ensure the sub-wrapper exists when we need it. It must sit right // after the quote textarea and before the source selector. var subWrap = li.find(".wiktku-dfn-quote-sub"); // tr field var trTa = li.find(".wiktku-dfn-nimune-quote-tr"); if (showTr && !trTa.length) { if (!subWrap.length) { subWrap = $("<div></div>").addClass("wiktku-dfn-quote-sub"); li.find(".wiktku-dfn-nimune-quote").after(subWrap); } trTa = $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-quote-tr-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 2) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-quote-tr") .attr("placeholder", "Transkrîpsiyona jêgirtinê…"); subWrap.prepend(trTa); } else if (!showTr && trTa.length) { trTa.remove(); } // t field var tTa = li.find(".wiktku-dfn-nimune-quote-t"); if (showT && !tTa.length) { if (!subWrap.length) { subWrap = $("<div></div>").addClass("wiktku-dfn-quote-sub"); li.find(".wiktku-dfn-nimune-quote").after(subWrap); } tTa = $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-quote-t-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 2) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-quote-t") .attr("placeholder", "Tercimeya jêgirtinê ya kurmancî…"); subWrap.append(tTa); } else if (!showT && tTa.length) { tTa.remove(); } // Remove the wrapper if it ended up empty. subWrap = li.find(".wiktku-dfn-quote-sub"); if (subWrap.length && !subWrap.children().length) subWrap.remove(); }); }()); $.each(steps, function (stepId, step) { if (typeof(step.visible) === "function" && !step.visible(values)) { $("#wiktku-start-" + stepId).slideUp(); } else { var stepDiv = $("#wiktku-start-" + stepId); if (changedStep !== step && typeof(step.build) === "function") { prepareInput(step.build(stepDiv, values), step); } var input = stepDiv.find(".wiktku-start-step-field"); if (typeof(step.example) === "function") { // .find() above already reaches nested fields (e.g. the dfn // step's mane textareas inside each sense block), so one // assignment covers every step; dfn keeps its own fallback. var exampleText = step.example(values) || (step.id === "dfn" ? "Mane…" : ""); input.attr("placeholder", exampleText); } var didSlideDown; if (!didFocus && stepDiv.css("display") === "none" && step.required) { didSlideDown = function (evt) { input.focus(); }; didFocus = true; } stepDiv.slideDown(didSlideDown); } if (step.required && (values[stepId] === "" || (step.multiple && values[stepId].join("") === ""))) { canContinue = false; } }); continueBtn.setDisabled(!canContinue); } function destroy() { $("#wiktku-start-form, .noafterwizard").slideUp(function () { $(this).remove(); }); $(".noarticletext .nowizard, #editform").slideDown(); $("#ca-edit").removeClass("selected"); $("#ca-wiktku-nowizard").addClass("selected"); } // Priority order for Kurdish dialects and the navz pseudo-code. // Codes listed here come before all other languages; unlisted codes // are sorted alphabetically by their display name via localeCompare. var LANG_PRIORITY = ["navz", "ku", "hac", "sdh", "lki", "ckb", "zza"]; /** * Inserts a new == {{ziman|code}} == section into existing page wikitext * at the correct sorted position: * 1. Any content before the first language section is preserved at the top. * 2. navz is always first, then ku/hac/sdh/lki/ckb/zza in that order, * then all other languages sorted by display name (localeCompare). */ function insertNewLangSection(existing, wikitext) { var newCodeMatch = wikitext.match(new RegExp("^" + langHeaderSource("[^}]+"))); var newCode = newCodeMatch ? newCodeMatch[1] : ""; var sections = []; var preamble = ""; var anyHeaderSrc = langHeaderSource("[^}]+"); var firstMatch = new RegExp("^" + anyHeaderSrc, "m").exec(existing); if (!firstMatch) { // No existing lang sections at all — just append. var sep = existing && !/\n\s*$/.test(existing) ? "\n\n" : ""; return existing + sep + wikitext; } // Everything before the first == {{ziman|...}} == is the preamble. var firstSectionStart = firstMatch.index; // Walk back to the start of that line. var lineStart = existing.lastIndexOf("\n", firstSectionStart - 1); var preambleEnd = lineStart !== -1 ? lineStart + 1 : 0; preamble = existing.slice(0, preambleEnd); // Parse each language section: header line + everything until the next header. var body = existing.slice(preambleEnd); // NOTE: with the /m flag, a bare "$" matches end-of-*line*, not just // end-of-string — that previously made the non-greedy content group // stop at the section's first line break instead of running to the // next language header (or the real end of the text), silently // dropping the rest of that section's wikitext. (?![\s\S]) matches // only the true end of the string, /m flag or not. var langSectionRe = new RegExp( "^(" + anyHeaderSrc + "\\n?)([\\s\\S]*?)(?=\\n" + anyHeaderSrc + "|(?![\\s\\S]))", "gm" ); var m; while ((m = langSectionRe.exec(body)) !== null) { sections.push({ code: m[2], content: m[0] // full text of this section including header }); } // Determine sort rank: priority list first (by index), then alphabetical. function getLangName(code) { var entry = langsByCode[code]; return entry ? entry[1] : code; } function sortRank(code) { var idx = LANG_PRIORITY.indexOf(code); return idx !== -1 ? idx : LANG_PRIORITY.length; } function compareLangs(a, b) { var ra = sortRank(a), rb = sortRank(b); if (ra !== rb) return ra - rb; // Both are outside priority list — sort by display name. return getLangName(a).localeCompare(getLangName(b), userLang); } // Insert the new section into the sorted list. var newSection = { code: newCode, content: wikitext }; var inserted = false; for (var i = 0; i < sections.length; i++) { if (compareLangs(newCode, sections[i].code) < 0) { sections.splice(i, 0, newSection); inserted = true; break; } } if (!inserted) sections.push(newSection); // Re-join: preamble + sections separated by newlines. var joined = sections.map(function (s) { // Ensure each section ends with exactly one newline before the next. return s.content.replace(/\n+$/, ""); }).join("\n"); return preamble + joined + "\n"; } function build() { $(".nowizard, .nowizard .noafterwizard").hide(); var callToAction = $("#wiktku-calltoaction"); var origCallToActionText = callToAction.text(); $(mw.util.addPortletLink("p-views", "#", "Edîtora çavkaniyê veke", "ca-wiktku-nowizard", "Vê rûpelê bi edîtora çavkaniyê çêke", undefined, "#ca-watch")).click(function (evt) { evt.preventDefault(); callToAction.text(origCallToActionText); destroy(); }); if (callToAction.length) { callToAction.text(origCallToActionText + " Forma li jêr ji bo çêkirina madeyeke nû bi kar bîne."); } var startForm = $("<form id='wiktku-start-form'></form>"); var clearPageCheck = null; if (addLangMode) { startForm.append($("<p class='wiktku-addlang-notice'></p>").html( "Bi vê formê tu yê beşeke nû li rûpelê îlawe bikî. Eger ev zimanê ku tu îlawe dikî jixwe di rûpelê de hebe, beşa nû li dawiya vî zimanî dê were îlawekirin. " + "Ji kerema xwe netîceya dawî kontrol bikin, eger problemek derkeve, li <a href='" + mw.util.getUrl('Mediawiki talk:Gadget-start.js') + "'>nîqaşa vê amûrê</a> problemê ragihîne." )); clearPageCheck = $("<input type='checkbox' id='wiktku-clear-page-check'>"); var clearPageLabel = $("<label for='wiktku-clear-page-check'></label>") .text(" Naveroka rûpelê paqij bike (rûpelê ji nû ve binivîse)"); startForm.append( $("<p class='wiktku-addlang-notice'></p>") .append(clearPageCheck) .append(clearPageLabel) ); // Re-evaluate step visibility (e.g. the pron step) whenever this // is toggled, since it changes what counts as "existing content". clearPageCheck.on("change", function () { refresh(); }); } var spinner; // Tab bar for switching between POS sections. var sectionTabsDiv = $("<div id='wiktku-section-tabs'></div>"); startForm.submit(function (evt) { evt.preventDefault(); continueBtn.setDisabled(true); spinner.show(); getWikitext(function (wikitext) { if (addLangMode && clearPageCheck && clearPageCheck.prop("checked")) { // User asked to wipe the page and start fresh — just // write the newly generated wikitext as the full content. $("#wpTextbox1").val(wikitext); } else if (addLangMode) { var textbox = $("#wpTextbox1"); var existing = textbox.val() || ""; // Check whether the generated lang header already exists in the page. // wikitext always starts with "== {{ziman|CODE}} ==\n" (from steps.lang.output). // If that language's section is already present in the existing content // (regardless of any whitespace differences from hand-editing), strip the // header from the new output and insert the remaining content at the end // of that lang section (just before the next == level-2 heading, or at the // very end of the page if there is no following section). var langHeaderMatch = wikitext.match(new RegExp("^(" + langHeaderSource("[^}]+") + "\\n)")); if (langHeaderMatch) { var langHeader = langHeaderMatch[1]; // e.g. "== {{ziman|ku}} ==\n" var newCode = langHeaderMatch[2]; var existingHeader = findLangHeader(existing, newCode); if (existingHeader) { // Strip the header from the new output. var newContent = wikitext.slice(langHeader.length); // Find the insertion point: end of the existing lang section. // A new L2 heading marks the start of the next language block. var searchFrom = existingHeader.index + existingHeader.match.length; // Find the next == … == heading after this section's start. var nextL2 = existing.indexOf("\n== ", searchFrom); var insertAt = nextL2 !== -1 ? nextL2 : existing.length; // Ensure there's a blank line before the inserted block. var before = existing.slice(0, insertAt); var after = existing.slice(insertAt); var sep = /\n\s*$/.test(before) ? "" : "\n"; textbox.val(before + sep + newContent + after); } else { // New language — insert at the correct sorted position. textbox.val(insertNewLangSection(existing, wikitext)); } } else { // Unexpected format — insert at sorted position anyway. textbox.val(insertNewLangSection(existing, wikitext)); } } else { $("#wpTextbox1").val(wikitext); } $("html, body").animate({scrollTop: 0}); callToAction.text("Hindik ma!"); $("#wiktku-preview-container").remove(); destroy(); }); }); $.each(ordered_steps, function (i, step) { var stepDiv = $(mw.html.element("div", { "class": "wiktku-start-step", id: "wiktku-start-" + step.id })); var name = capitalize(step.name); stepDiv.append($(mw.html.element("h3", { "class": "wiktku-start-step-name" }, new mw.html.Raw(mw.html.element("label", { "for": "wiktku-start-" + step.id + "-field" }, name))))); if (step.question_fmt) { stepDiv.append($(mw.html.element("label", { "class": "wiktku-start-step-question", "for": "wiktku-start-" + step.id + "-field" }, step.question_fmt))); if (step.question_br) stepDiv.append($("<br>")); } var input; if (step.choices) { input = $(mw.html.element("select", { "class": "wiktku-start-step-field", id: "wiktku-start-" + step.id + "-field" })); input.attr("data-placeholder", capitalize(step.name) + " hilbijêre "); populateMenus(input, step.choices); if (step.multiple) input.attr("multiple", true); if (isMobile) { stepDiv.append(wrapNativeSelect(input)); } else { stepDiv.append(input); } } else if (typeof(step.build) === "function") { input = step.build(stepDiv); } else { input = $("<textarea></textarea>") .attr("class", "wiktku-start-step-field") .attr("id", "wiktku-start-" + step.id + "-field") .attr("rows", step.rows || 2); if (step.narrow) input.addClass("wiktku-start-narrow"); if (step.multiple) { input.on("input", function (evt) { refreshForTextField(evt.target, step); }); var keyInput = buildKeyInput(step); var list = $(step.ordered ? "<ol></ol>" : "<ul></ul>") .append($("<li></li>").append(keyInput).append(input)); stepDiv.append(list); } else stepDiv.append(input); } prepareInput(input, step); stepDiv.hide(); // Insert tab bar just before the first per-section step. if (step.id === "pos") startForm.append(sectionTabsDiv); startForm.append(stepDiv); }); // ── Section tab helpers ────────────────────────────────────────────── // ── Add-section button — lives in the tab bar, disabled until pos chosen ── var addSectionBtn = new OO.ui.ButtonWidget({ label: "+ Beş zêde bike", disabled: true }); addSectionBtn.on("click", function () { saveCurrentSection(); sections.push({}); activeSection = sections.length - 1; $.each(PER_SECTION_STEP_IDS, function (_, id) { if (id === "dfn") { var stepDiv = $("#wiktku-start-dfn"); stepDiv.find("ol.wiktku-dfn-list").remove(); steps.dfn.build(stepDiv); return; } if (id === "etym") { $("#wiktku-start-etym .wiktku-etym-wrap").remove(); steps.etym.build($("#wiktku-start-etym")); return; } if (id === "trans") { var transDiv = $("#wiktku-start-trans"); transDiv.find(".wiktku-trans-group").remove(); return; } if (id === "zarava") { var zaravaDiv = $("#wiktku-start-zarava"); zaravaDiv.find(".wiktku-zarava-group").remove(); return; } if (id === "dunde") { var dundeDiv = $("#wiktku-start-dunde"); dundeDiv.find("ul.wiktku-dunde-list").remove(); return; } var stepDiv = $("#wiktku-start-" + id); stepDiv.find(".wiktku-start-step-field").val(""); if (!isMobile) stepDiv.find("select.wiktku-start-step-field").trigger("chosen:updated"); }); renderSectionTabs(); refresh(); $("html, body").animate({ scrollTop: sectionTabsDiv.offset().top - 20 }, 300); }); /** Re-render the tab bar to reflect current sections[] and activeSection. */ function renderSectionTabs() { // Detach (not remove) the button first: .empty() strips bound // event data from any children left inside it, which would // silently kill addSectionBtn's click handler on every re-render. addSectionBtn.$element.detach(); sectionTabsDiv.empty(); var lang = getValues().lang || ""; if (!lang) { sectionTabsDiv.hide(); return; } sectionTabsDiv.show(); $.each(sections, function (i) { var posVal = sections[i].pos || ""; var tabLabel = posVal ? capitalize(posVal) : ("Beş " + (i + 1)); var tab = $("<span></span>") .addClass("wiktku-section-tab") .text(tabLabel) .toggleClass("wiktku-tab-active", i === activeSection); (function (idx) { tab.on("click", function () { if (idx === activeSection) return; saveCurrentSection(); activeSection = idx; restoreSection(sections[activeSection]); refresh(); renderSectionTabs(); }); }(i)); sectionTabsDiv.append(tab); }); // Enable "Beş zêde bike" only when the active section has a pos chosen. var activePos = sections[activeSection] && sections[activeSection].pos ? sections[activeSection].pos : getValues().pos; addSectionBtn.setDisabled(!activePos); sectionTabsDiv.append(addSectionBtn.$element); } renderSectionTabs(); // Update the active tab's label whenever pos changes. startForm.on("change", "#wiktku-start-pos-field", function () { renderSectionTabs(); }); // Show the tab bar as soon as a language is selected. startForm.on("change", "#wiktku-start-lang-field", function () { renderSectionTabs(); }); var footer = $("<div id='wiktku-start-footer'></div>"); spinner = $(mw.html.element("img", { id: "wiktku-start-spinner", src: "//upload.wikimedia.org/wikipedia/commons/d/de/Ajax-loader.gif", alt: "Tê barkirin…", title: "Tê barkirin…" })); footer.append(spinner.hide()); continueBtn = new OO.ui.ButtonWidget({ id: "wiktku-unhide-editform", label: "Bişîne", flags: [ "primary", "progressive" ] }); continueBtn.on("click", function () { mw.notify("Tê şandin…", { type: "info", tag: "wiktku-submit" }); startForm.trigger("submit"); }); footer.append(continueBtn.$element); // "Edîtora çavkaniyê veke" button — inline fallback for the portlet link // which is invisible on mobile and easy to miss on desktop. var sourceEditorBtn = new OO.ui.ButtonWidget({ label: "Edîtora çavkaniyê veke", framed: false }); sourceEditorBtn.on("click", function () { destroy(); }); footer.append(sourceEditorBtn.$element); // ── Preview checkboxes ─────────────────────────────────────────────── // Wikitext preview (raw text panel) var previewCheck = $("<input type='checkbox' id='wiktku-preview-toggle'>"); var previewLabel = $("<label for='wiktku-preview-toggle'></label>") .text(" Pêşdîtina wîkîtekstê"); var previewPanel = $("<pre id='wiktku-preview-panel'></pre>").hide(); // Live rendered preview (parsed HTML panel, same logic as AjaxEdit). // Not available on mobile — API polling causes too many problems on small screens. var livePreviewCheck = null; var livePreviewPanel = null; if (!isMobile) { livePreviewCheck = $("<input type='checkbox' id='wiktku-live-preview-toggle'>"); livePreviewPanel = $("<div id='wiktku-live-preview-panel'></div>").hide(); } // Container that holds both panels and switches between stacked / side-by-side. var previewContainer = $("<div id='wiktku-preview-container'></div>"); previewContainer.append(previewPanel); if (!isMobile) previewContainer.append(livePreviewPanel); var previewTimer = null; var livePreviewIntervalId = -1; var livePreviewActive = false; // guards in-flight fetches after uncheck /** Rebuilds wikitext preview if its checkbox is checked. */ function schedulePreview() { if (!previewCheck.prop("checked")) return; clearTimeout(previewTimer); // Debounce: wait 400 ms after the last keystroke before rebuilding. previewTimer = setTimeout(function () { getWikitext(function (wikitext) { previewPanel.text(wikitext).show(); updatePanelLayout(); }); }, 400); } /** Fetches parsed HTML and populates the live preview panel. */ function loadLivePreview() { getWikitext(function (wikitext) { new mw.Api().parse(wikitext, { title: mw.config.get("wgPageName") }).done(function (html) { // Discard result if the user unchecked while the fetch was in flight. if (!livePreviewActive) return; livePreviewPanel.html(html).show(); updatePanelLayout(); }); }); } /** Adjusts panel widths depending on which previews are visible. */ function updatePanelLayout() { var wikitextVisible = previewCheck.prop("checked"); var liveVisible = livePreviewCheck && livePreviewCheck.prop("checked"); if (wikitextVisible && liveVisible) { // Side by side — each panel takes roughly half the available width. previewPanel.css({ "flex": "1 1 45%", "min-width": "280px" }); livePreviewPanel.css({ "flex": "1 1 45%", "min-width": "280px" }); } else { // Full width for whichever is visible — only touch panels that are // actually shown so that setting flex doesn't override display:none. if (wikitextVisible) previewPanel.css({ "flex": "1 1 100%", "min-width": "" }); if (liveVisible && livePreviewPanel) livePreviewPanel.css({ "flex": "1 1 100%", "min-width": "" }); } } previewCheck.on("change", function () { if ($(this).prop("checked")) { schedulePreview(); } else { clearTimeout(previewTimer); previewPanel.hide(); updatePanelLayout(); } }); if (!isMobile) { livePreviewCheck.on("change", function () { if ($(this).prop("checked")) { livePreviewActive = true; livePreviewPanel.show(); loadLivePreview(); livePreviewIntervalId = setInterval(loadLivePreview, 500); } else { livePreviewActive = false; clearInterval(livePreviewIntervalId); livePreviewIntervalId = -1; livePreviewPanel.hide().empty(); updatePanelLayout(); } }); } // Listen on all input/change events on the form and update both previews. startForm.on("input change", function () { schedulePreview(); }); footer.append($("<span style='margin-left:1em'></span>") .append(previewCheck).append(previewLabel)); if (!isMobile) { var livePreviewLabel = $("<label for='wiktku-live-preview-toggle'></label>") .text(" Pêşdîtina zindî"); footer.append($("<span style='margin-left:1em'></span>") .append(livePreviewCheck).append(livePreviewLabel)); } startForm.append(footer); $("#editform").hide().before(startForm); // Insert preview container (holds both panels) after the form. startForm.after(previewContainer); if (!isMobile) startForm.find("select").chosen(chosenOptions); refresh(); // Zimanan ji MediaWiki:Gadget-translation_editor.js/ziman.json bar bike. // Kodên ku bi "-pro" diqedin û navên ku "zimanê destan" tê de heye // tên derxistin. Zimanên xardkirî li serî dimînin, yên din // bi alfabeyê li dû wan tên. // Pinned choices come from MediaWiki:Gadget-start.js/data.json (langChoices), // already loaded into steps.lang.choices before build() runs. var pinnedChoices = steps.lang.choices.slice(); var pinnedCodes = $.map(pinnedChoices, function (choice) { return choice[0]; }); new mw.Api().get({ action: "query", prop: "revisions", titles: "MediaWiki:Gadget-translation_editor.js/ziman.json", rvprop: "content", rvslots: "main", formatversion: 2 }).then(function (data) { var page = data.query.pages[0]; var content = page && page.revisions && page.revisions[0].slots.main.content; var zimanData; try { zimanData = JSON.parse(content); } catch (e) { zimanData = {}; } var extraChoices = []; $.each(zimanData, function (code, name) { // Filter: skip proto-language codes and legendary/reconstructed langs. if (/-pro$/i.test(code)) return; if (/ziman[eê]\s+destan/i.test(name)) return; // Skip codes already in the pinned list (they are handled above). if (pinnedCodes.indexOf(code) !== -1) return; // sortKey: bare name without leading "zimanê " for sorting. var sortKey = name.replace(/^ziman[eê]\s+/i, ""); var choice = [code, name, sortKey]; extraChoices.push(choice); langsByCode[code] = choice; }); // Populate langsByCode for pinned choices too. $.each(pinnedChoices, function (i, choice) { // Ensure pinned choices have a sortKey (index 2). if (choice.length < 3) choice[2] = choice[1]; langsByCode[choice[0]] = choice; }); // Sort the extra choices alphabetically by sort key. extraChoices.sort(function (a, b) { return a[2].localeCompare(b[2], userLang); }); // Final list: pinned first, then the rest. var allChoices = pinnedChoices.concat(extraChoices); steps.lang.choices = allChoices; steps.trans.keys = allChoices; steps.dunde.keys = allChoices; steps.zarava.keys = getZaravaKeys(allChoices); var langMenu = $("#wiktku-start-lang-field"); populateMenus(langMenu, steps.lang.choices); langMenu.trigger("chosen:updated"); var transMenus = $("#wiktku-start-trans .wiktku-start-step-keyfield"); populateMenus(transMenus, steps.trans.keys, getDisabledKeys(steps.trans)); transMenus.trigger("chosen:updated"); var dundeMenus = $("#wiktku-start-dunde .wiktku-start-step-keyfield"); populateMenus(dundeMenus, steps.dunde.keys, getDisabledKeys(steps.dunde)); dundeMenus.trigger("chosen:updated"); var zaravaMenus = $("#wiktku-start-zarava .wiktku-start-step-keyfield"); populateMenus(zaravaMenus, steps.zarava.keys, getDisabledKeys(steps.zarava)); }); } mw.loader.using(["jquery.chosen", "mediawiki.api", "oojs-ui-core"], function () { if (!isMobile) { mw.notify( "Amûr dest pê dike, hinek bisekinin. Not: jkx Sentaks (sentaks highlighter) neaktîv bikin", { type: "info", tag: "wiktku-start-notice", autoHide: true, autoHideSeconds: 10 } ); } // Load metadata, langChoices, posChoices and tplDefs from the companion // data page so they can be updated without touching this script. new mw.Api().get({ action: "query", prop: "revisions", titles: "MediaWiki:Gadget-start.js/data.json", rvprop: "content", rvslots: "main", formatversion: 2 }).then(function (data) { var page = data.query.pages[0]; var content = page && page.revisions && page.revisions[0].slots.main.content; var d; try { d = JSON.parse(content); } catch (e) { d = {}; } // Populate metadata. if (d.metadata) $.extend(metadata, d.metadata); // Populate gender labels. if (d.genderLabels) $.extend(GENDER_BASE_LABELS, d.genderLabels); // Populate lang choices (pinned list used by build() → ziman.json loader). if (d.langChoices) steps.lang.choices = d.langChoices; // Populate POS choices. if (d.posChoices) steps.pos.choices = d.posChoices; // Populate template definitions for the dfn sense-block builder. if (d.tplDefs) steps.dfn.tplDefs = d.tplDefs; // Populate pos placeholder examples. if (d.posExamples) steps.dfn.posExamples = d.posExamples; // Populate citation template definitions for the quote widget. if (d.jederDefs) steps.dfn.jederDefs = d.jederDefs; // Populate pronunciation and etymology template insert lists. if (d.pronTpls) { steps.pron.pronTpls = d.pronTpls; steps.pron.refreshTplSelect(); } if (d.etymTpls) { steps.etym.etymTpls = d.etymTpls; steps.etym.refreshTplSelect(); } // Sync trans/dunde/zarava keys with the (now populated) lang choices. steps.trans.keys = steps.lang.choices; steps.dunde.keys = steps.lang.choices; steps.zarava.keys = getZaravaKeys(steps.lang.choices); }).always(build); }); }); //</nowiki> 0mez02a3ogl6qdvcfkc566bz2y8obky 6265595 6265594 2026-07-19T15:44:41Z Wikihez 7344 6265595 javascript text/javascript // Li ser [[vi:MediaWiki:Gadget-start.js]] hatiye refaktorkirin. //<nowiki> $(function () { if (window.location.href.includes("editintro=User:Wikihez/creation/intro")) { return; // Do not run the script wextê WF:Bilez dişuxile } var ns = mw.config.get("wgNamespaceNumber"); if (ns && !(ns === 2 && mw.config.get("wgPageName").match(/\/ceribandin$|\/test$/))) { return; } var action = mw.config.get("wgAction"); var pageExists = !!mw.config.get("wgArticleId"); // "Zimanek lê zêde bike" mode: triggered from the portlet link below. var addLangMode = pageExists && mw.util.getParamValue("wiktkuaddlang") === "1"; // On a normal page view of an existing page, add the portlet link if (action === "view" && pageExists) { var targetContainer; var skin = mw.config.get('skin'); if (skin === 'vector-2022') { targetContainer = 'p-cactions'; } else if (skin === 'vector') { targetContainer = 'p-tb'; } else { targetContainer = 'p-views'; } mw.util.addPortletLink(targetContainer, mw.util.getUrl(mw.config.get("wgPageName"), { action: "submit", wiktkuaddlang: "1" }), "+Ziman/beşeke din", "ca-wiktku-addlang", "Ji vê rûpelê re ziman an jî beşeke nû zêde bike"); return; } if (!(action === "edit" || action === "submit")) { return; } if (!addLangMode && !$(".mw-newarticletext, .mw-newarticletextanon").length) { return; } function capitalize(str) { if (!str) return str; return str[0].toUpperCase() + str.substr(1); } function decapitalize(str) { if (!str) return str; return str[0].toLowerCase() + str.substr(1); } function escapeRegExp(str) { return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); } // Regex source for a "== {{ziman|CODE}} ==" header, tolerant of extra // whitespace. codePattern: escaped code for one language, or "[^}]+" for any. function langHeaderSource(codePattern) { return "==\\s*\\{\\{\\s*ziman\\s*\\|\\s*(" + codePattern + ")\\s*\\}\\}\\s*=="; } // Finds a language's header in wikitext (see langHeaderSource). Returns // { index, match } or null. function findLangHeader(text, code) { var m = new RegExp(langHeaderSource(escapeRegExp(code))).exec(text); return m ? { index: m.index, match: m[0] } : null; } function stripWikilinks(str) { return str.replace(/\[\[([^\]|]+)(?:\|([^\]]+))?\]\]/g, function (m, target, display) { return display || target; }); } function insertAtCursor(el, text) { var start = el.selectionStart; var end = el.selectionEnd; var val = el.value; el.value = val.slice(0, start) + text + val.slice(end); var pos = start + text.length; el.selectionStart = el.selectionEnd = pos; } var pageName = mw.config.get("wgPageName").replaceAll(/_/g, " "); if (ns) pageName = pageName.replace(/.*\//, ""); var pageNameRe = escapeRegExp(pageName); var userLang = mw.config.get("wgUserLanguage"); // Mobile detection: MobileFrontend sets wgMFMode, or fall back to touch check. var isMobile = !!mw.config.get("wgMFMode") || window.matchMedia("(pointer: coarse)").matches; var chosenOptions = { width: "20em", disable_search_threshold: 0, placeholder_text_single: "Yekî hilbijêre", placeholder_text_multiple: "Hilbijêre", no_results_text: "Nehat dîtin", enable_split_word_search: true, search_contains: true }; function wrapNativeSelect(select) { var placeholder = select.attr("data-placeholder") || "Lê bigere…"; // Hide the native select — we drive it programmatically. select.hide(); var wrapper = $("<span class='wiktku-native-select-wrap'></span>"); var textInput = $("<input type='search' autocomplete='off'>") .attr("placeholder", placeholder) .addClass("wiktku-start-narrow wiktku-ac-input"); var resultsList = $("<ul class='wiktku-ac-results'></ul>").hide(); // Full option cache — rebuilt when chosen:updated fires. var allOptions = []; function cacheOptions() { allOptions = []; select.find("option").each(function () { var v = $(this).val(); if (!v) return; // skip the empty placeholder option allOptions.push({ value: v, text: $(this).text(), disabled: $(this).prop("disabled") }); }); } cacheOptions(); function showResults(query) { var q = query.trim().toLowerCase(); resultsList.empty(); var matched; if (q) { matched = []; $.each(allOptions, function (_, o) { if (o.disabled) return; var codeMatch = o.value.toLowerCase().indexOf(q) !== -1; var nameMatch = o.text.toLowerCase().indexOf(q) !== -1; if (codeMatch || nameMatch) { matched.push({ opt: o, codeMatch: codeMatch }); } }); // Code matches (especially prefix matches) come first. matched.sort(function (a, b) { var aCode = a.opt.value.toLowerCase(); var bCode = b.opt.value.toLowerCase(); var aPrefix = aCode.indexOf(q) === 0; var bPrefix = bCode.indexOf(q) === 0; if (aPrefix !== bPrefix) return aPrefix ? -1 : 1; if (a.codeMatch !== b.codeMatch) return a.codeMatch ? -1 : 1; return 0; }); matched = matched.map(function (item) { return item.opt; }); } else { matched = allOptions.filter(function (o) { return !o.disabled; }); } if (!matched.length) { resultsList.hide(); return; } $.each(matched.slice(0, 50), function (_, opt) { var li = $("<li></li>").text(opt.text).attr("data-value", opt.value); // touchend (not touchstart) so a scroll doesn't trigger a select. var touchMoved = false; li.on("touchstart", function () { touchMoved = false; }); li.on("touchmove", function () { touchMoved = true; }); li.on("touchend", function (e) { if (touchMoved) return; // was a scroll, not a tap e.preventDefault(); selectOption(opt.value, opt.text); }); // Keep mousedown for desktop fallback. li.on("mousedown", function (e) { e.preventDefault(); selectOption(opt.value, opt.text); }); resultsList.append(li); }); // Position the list above or below depending on available viewport space. var inputRect = textInput[0].getBoundingClientRect(); var viewportH = window.innerHeight; var spaceBelow = viewportH - inputRect.bottom - 8; var spaceAbove = inputRect.top - 8; var maxH = Math.min(224, Math.max(spaceBelow, spaceAbove)); // 224px ≈ 14em resultsList.css({ "max-height": maxH + "px", "top": spaceBelow >= spaceAbove ? "100%" : "auto", "bottom": spaceBelow >= spaceAbove ? "auto" : "100%" }); resultsList.show(); } function selectOption(value, text) { textInput.val(text); select.val(value); resultsList.hide(); select.trigger("change"); } textInput.on("input focus", function () { showResults($(this).val()); }); textInput.on("blur", function () { // Short delay so a touchstart on a result item fires first. setTimeout(function () { resultsList.hide(); }, 200); }); // chosen:updated → re-cache (called after ziman.json loads). select.on("chosen:updated", function () { cacheOptions(); // If a value is already selected, keep the display text in sync. var cur = select.val(); if (cur) { var match = $.grep(allOptions, function (o) { return o.value === cur; })[0]; if (match) textInput.val(match.text); } }); // No-op .chosen() so desktop call-sites don't need guarding. select.chosen = function () { return select; }; wrapper.append(textInput).append(resultsList).append(select); return wrapper; } var langsByCode = {}; // Populated from [[MediaWiki:Gadget-start.js/data.json]] at runtime. var metadata = {}; // Zaravayên kurdî yên ku di beşa "Bi zaravayên din" de tên pêşkêşkirin — // ev kod ji beşa Werger têne derxistin daku heman zimên du caran neyê xwendin. var ZARAVA_LANG_CODES = ["ckb", "sdh", "lki", "hac", "zza"]; function getZaravaKeys(choices) { var byCode = {}; $.each(choices || [], function (_, c) { byCode[c[0]] = c; }); var result = []; $.each(ZARAVA_LANG_CODES, function (_, code) { if (byCode[code]) result.push(byCode[code]); }); return result; } function needsTransliteration(langCode) { var meta = metadata[langCode]; if (!meta || !meta.sc) return false; var scripts = Array.isArray(meta.sc) ? meta.sc : [meta.sc]; return scripts.length > 0 && scripts[0] !== "Latn"; } // Kodên cinsiyetê yên di metadata.g de — ji data.json tê dagirtin var GENDER_BASE_LABELS = {}; // Sub-lists that only make sense for a plain (non-şablon) sense — hidden // when a şablon (e.g. {{guharto|…}}) is chosen for that sense, since a // template-based sense has no "own" gloss for alternate forms, synonyms, // antonyms, coordinate terms, hypernyms or hyponyms to attach to. Etîket, // Nimûne and Jêgirtin stay visible either way. var HIDDEN_ON_TPL_GROUPS = [ "wiktku-dfn-alternativ", "wiktku-dfn-hevmane", "wiktku-dfn-dijmane", "wiktku-dfn-koordine", "wiktku-dfn-jornav", "wiktku-dfn-jernav" ]; function genderLabel(code) { if (code === "p") return "Pirjimar"; var pluralMatch = code.match(/^(.+)-p$/); if (pluralMatch && GENDER_BASE_LABELS[pluralMatch[1]]) { return GENDER_BASE_LABELS[pluralMatch[1]] + " (pirjimar)"; } return GENDER_BASE_LABELS[code] || code; } // True if a sense has content beyond mane worth keeping (etîket, word // lists, nimûne, jêder) — so it's still emitted with {{mane?}} if empty. function senseHasExtraContent(s) { if (s.etiket && $.grep(s.etiket, function (e) { return $.trim(e) !== ""; }).length) return true; if (s.kategori && $.grep(s.kategori, function (k) { return $.trim(k) !== ""; }).length) return true; if (s.alternativ.length || s.hevmane.length || s.dijmane.length || s.koordine.length || s.jornav.length || s.jernav.length) return true; if (s.nimune && $.grep(s.nimune, function (n) { return (typeof n === "object" ? n.text : n) !== ""; }).length > 0) return true; if (senseHasJeder(s)) return true; return false; } // Each nimûne item can be { text, tr, t }: text, transliteration, translation. function formatNimune(nimunes, lang, hasJeder) { var hasNimune = nimunes && $.grep(nimunes, function (n) { return (typeof n === "object" ? n.text : n) !== ""; }).length > 0; if (!hasNimune) { return hasJeder ? "" : "\n#* {{bênimûne|" + lang + "}}"; } return $.map(nimunes, function (n) { var text = typeof n === "object" ? n.text : n; if (!text) return undefined; var bolded = text.replace( new RegExp("(" + pageNameRe + "([^( |,|;|\\?|\\.|\\!)]+)?)", "ig"), "'''$1'''"); var tpl = "\n#: {{nm|" + lang + "|" + bolded; if (typeof n === "object") { if (n.tr) tpl += "|tr=" + n.tr; // Translation as third positional param (no key needed). if (n.t) tpl += "|" + n.t; } // Short examples fit on one line together with their translation. // rêz=1 is not used for ku — definitions are shown on separate lines there. if (text.length < 200 && lang !== "ku") tpl += "|rêz=1"; tpl += "}}"; return tpl; }).join(""); } // Formats jêder (citation) entries into "#* {{jêder…|…}}" lines; skips // entries with no quote text. Falls back to the generic {{jêder}} // template when no specific template was chosen. function formatJeder(jederList, lang) { if (!jederList || !jederList.length) return ""; return $.map(jederList, function (jeder) { if (!jeder || !jeder.quote) return undefined; if (jeder.jederTpl) { var cite = "\n#* {{" + jeder.jederTpl + "|" + lang; cite += "|jêgirtin=" + jeder.quote; if (jeder.quoteTr) cite += "|tr=" + jeder.quoteTr; if (jeder.quoteT) cite += "|tercime=" + jeder.quoteT; $.each(jeder.jêderFields || {}, function (key, val) { if (val) cite += "|" + key + "=" + val; }); cite += "}}"; return cite; } var out = "\n#* {{jêder|" + lang + "|jêgirtin=" + jeder.quote; if (jeder.quoteTr) out += "|tr=" + jeder.quoteTr; if (jeder.quoteT) out += "|tercime=" + jeder.quoteT; var srcParam = jeder.jederManual ? jeder.jederManual : "çavkanî?"; // A positional param containing "=" gets parsed as its own key=value // pair by MediaWiki and breaks the template, so force it to be // explicitly named (|2=) whenever that's the case. out += (srcParam.indexOf("=") !== -1 ? "|2=" : "|") + srcParam; out += "}}"; return out; }).join(""); } // True if a sense has at least one jêder entry with quote text. function senseHasJeder(sense) { return !!(sense.jeder && $.grep(sense.jeder, function (j) { return j && j.quote; }).length > 0); } // Builds "{{tplName|lang|part1|part2|…}}" from a sense field (kategori, // etiket), wrapped inline (" {{…}} ") or on its own line ("\n#: {{…}}"). function buildSenseTpl(sense, field, lang, tplName, format) { if (!sense[field] || !sense[field].length) return ""; var parts = sense[field].map(function (p) { return $.trim(p); }) .filter(function (p) { return p !== ""; }); if (!parts.length) return ""; var call = "{{" + tplName + "|" + lang + "|" + parts.join("|") + "}} "; return format === "block" ? "\n#: " + call : " " + call + " "; } /** * Assembles the nimûne + jêder wikitext block for a sense. Shared by * both the template-sense and normal-mane-sense branches below. */ function buildCite(sense, lang) { return formatNimune(sense.nimune, lang, senseHasJeder(sense)) + formatJeder(sense.jeder, lang); } function makeWordListStep(id, name, question_fmt, header, templateName) { return { id: id, name: name, question_fmt: question_fmt, multiple: true, narrow: true, visible: function (values) { return values.lang && values.pos; }, output: function (values) { var words = $.grep(values[id] || [], function (w) { return !!w; }); if (!words.length) return ""; var lang = values.lang; var section = "\n==== " + header + " ====\n"; if (words.length === 1) { // Single word — keep the simple inline template. return section + "* {{" + templateName + "|" + lang + "|" + words[0] + "}}\n"; } // Multiple words — use {{kol3}} with one positional param per word. var params = "cure=" + header + "\n" + $.map(words, function (w) { return "|" + w; }).join("\n"); return section + "{{kol3|" + lang + "|" + params + "\n}}\n"; } }; } var steps = { lang: { id: "lang", required: true, name: "ziman", question_fmt: '"' + pageName + '" bi çi zimanî ye?', question_br: true, // Populated from [[MediaWiki:Gadget-start.js/data.json]] (langChoices). choices: [], output: function (values) { return "== {{ziman|" + values.lang + "}} ==\n"; } }, pron: { id: "pron", name: "bilêvkirin", question_fmt: '"' + pageName + '" çawa tê telafûzkirin?', // pronTpls populated from data.json pronTpls: [], visible: function (values) { if (!values.lang) return false; // addLangMode: skip pron only if this lang already has a section. if (addLangMode) { // Clearing the page makes existing content irrelevant. var clearPageCheck = $("#wiktku-clear-page-check"); if (clearPageCheck.length && clearPageCheck.prop("checked")) { return true; } var existing = $("#wpTextbox1").val() || ""; return !findLangHeader(existing, values.lang); } return true; }, // Fills the insert-dropdown from pronTpls, filtered by language. refreshTplSelect: function () { var sel = $("#wiktku-start-pron .wiktku-tpl-insert-select"); if (!sel.length) return; var lang = getValues().lang || ""; sel.find("option[value!='']").remove(); $.each(steps.pron.pronTpls, function (_, tpl) { // Filter: if tpl.langs exists, only show if lang is in that list; otherwise show always var allowed = !tpl.langs || tpl.langs.indexOf(lang) !== -1; if (allowed) { sel.append($("<option></option>") .val(tpl.snippet) .text(tpl.name + " — " + tpl.desc) .attr("data-nolang", tpl.noLang ? "1" : "")); } }); // Notify Chosen that the option list has changed (no-op on mobile). if (!isMobile) sel.trigger("chosen:updated"); }, build: function (stepDiv) { if (stepDiv.find(".wiktku-pron-wrap").length) return null; var wrap = $("<div class='wiktku-pron-wrap'></div>"); var ta = $("<textarea></textarea>") .attr("name", "wiktku-pron-" + $.now()) .attr("class", "wiktku-start-step-field wiktku-pron-text") .attr("rows", 4) .attr("placeholder", "Nimûne: {{IPA|ku|/pɛɪ̯n/}} yan {{kîte|ku|he|ce|ki|rin}}"); // Template insert dropdown — filtered by language. var sel = $("<select class='wiktku-tpl-insert-select'></select>"); sel.append($("<option value=''>— şablonek lê zêde bike —</option>")); var lang = getValues().lang || ""; $.each(steps.pron.pronTpls, function (_, tpl) { // Filter: if tpl.langs exists, only show if lang is in that list; otherwise show always var allowed = !tpl.langs || tpl.langs.indexOf(lang) !== -1; if (allowed) { sel.append($("<option></option>") .val(tpl.snippet) .text(tpl.name + " — " + tpl.desc) .attr("data-nolang", tpl.noLang ? "1" : "")); } }); sel.on("change", function () { var snippet = $(this).val(); if (!snippet) return; var lang = getValues().lang || ""; // Check if the selected option has noLang flag var selectedOption = sel.find("option:selected"); var hasNoLang = selectedOption.attr("data-nolang") === "1"; if (!hasNoLang) { snippet = snippet.replace(/CODE/g, lang).replace(/SOURCELANG/g, "?"); } insertAtCursor(ta[0], snippet); $(this).val(""); ta.focus(); }); wrap.append(sel).append($("<br>")).append(ta); stepDiv.append(wrap); return ta; }, output: function () { var text = $.trim($("#wiktku-start-pron .wiktku-pron-text").val()); if (!text) return ""; var lines = text.split("\n"); var out = $.map(lines, function (line) { line = $.trim(line); if (!line) return undefined; return line.charAt(0) === "*" ? line : "* " + line; }).join("\n"); return "\n=== Bilêvkirin ===\n" + out + "\n"; } }, pos: { id: "pos", required: true, name: "Cureyê rêzimanî", question_fmt: 'Cureyê rêzimanî yê "' + pageName + '" çi ye?', visible: function (values) { return values.lang; }, question_br: true, // Populated from [[MediaWiki:Gadget-start.js/data.json]] (posChoices). choices: [], output: function (values) { var pos = values.pos || ""; var cinsiyet = values.cinsiyet || ""; // from the cinsiyet step var lekTur = values.lektur || ""; // from the lêker transitivity step var capitalizedPos = capitalize(pos); var outputString = "\n=== " + capitalizedPos + " ===\n"; // Add ku-tewîn-nav for single-word navdêr/serenav with known gender. if (!pageName.includes(" ") && cinsiyet && GENDER_BASE_LABELS[cinsiyet] && (pos === "navdêr" || pos === "serenav") && values.lang === "ku") { outputString += "{{ku-tewîn-nav|" + pageName + "|" + GENDER_BASE_LABELS[cinsiyet]; if (pos === "serenav") outputString += "|y"; outputString += "}}\n"; } outputString += "{{" + pos + "|" + values.lang; if (pos === "navdêr" || pos === "serenav") { if (cinsiyet) { outputString += "|c=" + cinsiyet; } else if (values.lang === "ku") { // Unknown gender — prompt editor to fill it in. outputString += "|c=?"; } } else if (/^lêker/.test(pos) && lekTur) { outputString += "|c=" + lekTur; } if (values.tr) { outputString += "|tr=" + values.tr; } outputString += "}}\n"; return outputString; } }, // cinsiyet (gender) — shown for navdêr/serenav only, with choices built // from metadata[lang].g since not every language has grammatical gender. cinsiyet: { id: "cinsiyet", name: "cinsiyet", question_fmt: 'Cinsiyeta "' + pageName + '" çi ye?', question_br: true, visible: function (values) { var meta = metadata[values.lang]; return !!(values.lang && (values.pos === "navdêr" || values.pos === "serenav") && meta && meta.g && meta.g.length); }, build: function (stepDiv, values) { var select = stepDiv.find("select.wiktku-start-step-field"); if (!select.length) { select = $(mw.html.element("select", { "class": "wiktku-start-step-field", id: "wiktku-start-cinsiyet-field" })); stepDiv.append(select); } if (!values) return select; var meta = metadata[values.lang]; var codes = (meta && meta.g) || []; var prevVal = select.val(); var choices = $.map(codes, function (code) { return [[code, genderLabel(code)]]; }); populateMenus(select, choices); if ($.grep(choices, function (c) { return c[0] === prevVal; }).length) { select.val(prevVal); } if (!isMobile) select.trigger("chosen:updated"); return select; }, output: function () { return ""; } // consumed by pos.output }, // Lêker transitivity — shown for any lêker variant. lektur: { id: "lektur", name: "Cureyê lêkerê (fiîlê)", question_fmt: "Cureyê lêkerê (fiîlê) çi ye?", question_br: true, visible: function (values) { return values.lang && values.pos && /^lêker/.test(values.pos); }, // Dictionary: value → display label. Add new types here. choices: [ ["gh", "gerguhêz"], ['x-gh', 'xwerû-gerguhêz'], ['p-gh', 'pêkhatî-gerguhêz'], ['h-gh', 'hevedudanî-gerguhêz'], ['b-gh', 'biwêjî-gerguhêz'], ["ngh", "negerguhêz"], ['x-ngh', 'xwerû-negerguhêz'], ['p-ngh', 'pêkhatî-negerguhêz'], ['h-ngh', 'hevedudanî-negerguhêz'], ['b-ngh', 'biwêjî-negerguhêz'] ], output: function () { return ""; } // consumed by pos.output }, tr: { id: "tr", name: "transkrîpsiyon", question_fmt: "Transkrîpsiyona kelîmeyê", multiple: false, narrow: true, visible: function (values) { return values.lang && values.pos && needsTransliteration(values.lang); } }, dfn: { id: "dfn", // required: true, ger mane tinebe [[Şablon:mane?]] bi kar bîne name: "Mane", question_fmt: "Maneya kelîmeyê binivîse. Mane otomatîk tê lînkkirin! Ji bo tercimeyan beşa 'Werger' bi kar bîne!", multiple: true, ordered: true, rows: 3, visible: function (values) { return values.lang && values.pos; }, example: function (values) { // posExamples loaded from [[MediaWiki:Gadget-start.js/data.json]]. var examples = steps.dfn.posExamples || {}; var full = values.pos || ""; return examples[full] || ""; }, // Builds one sense block (<li>): mane textarea, nimûne list, and // sub-lists for alternatîv/hevmane/dijmane/etc. buildSenseBlock: function (stepDiv) { var block = $("<li class='wiktku-dfn-sense'></li>"); // — Mane textarea (declared first so the template handler can reference it) — var dfnArea = $("<textarea></textarea>") .attr("name", "wiktku-dfn-mane-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("class", "wiktku-start-step-field wiktku-dfn-mane") .attr("rows", 6) .attr("placeholder", "Mane…"); dfnArea.on("input", function () { steps.dfn.onDfnInput(stepDiv, block, this); }); // — Template selector (optional — replaces mane when chosen) — // Template definitions loaded from [[MediaWiki:Gadget-start.js/data.json]]. var tplDefs = steps.dfn.tplDefs || []; // Cache of all non-placeholder option elements — used by updateTplOptions // to remove/re-add options (the only approach compatible with Chosen.js). var _allTplOptions = []; var tplSelect = $(mw.html.element("select", { "class": "wiktku-dfn-tpl-select" })); tplSelect.append($("<option value=''>— yan jî şablonek hilbijêre —</option>")); $.each(tplDefs, function (_, tpl) { var opt = $("<option></option>") .val(tpl.name) .text(tpl.name) .attr("data-langs", tpl.langs ? tpl.langs.join(",") : "") .attr("data-nolang", tpl.noLang ? "1" : ""); tplSelect.append(opt); _allTplOptions.push(opt[0]); }); function updateTplOptions() { var lang = getValues().lang || ""; var currentVal = tplSelect.val(); var currentStillValid = false; // Detach all non-placeholder options, then re-attach only the visible ones. // This is the only approach that works correctly with both native <select> // and Chosen.js on desktop. tplSelect.find("option[value!='']").detach(); $.each(_allTplOptions, function (_, opt) { var allowed = $(opt).attr("data-langs"); var visible = !allowed || allowed.split(",").indexOf(lang) !== -1; if (visible) { tplSelect.append(opt); if ($(opt).val() === currentVal) currentStillValid = true; } }); if (!isMobile) tplSelect.trigger("chosen:updated"); if (currentVal && !currentStillValid) { tplSelect.val(""); dfnArea.show(); tplTitleInput.hide().val(""); } } // Store updater on the element so refresh() can call it for all blocks. tplSelect.data("updateOptions", updateTplOptions); var tplTitleInput = $("<input type='text'>") .addClass("wiktku-dfn-tpl-title wiktku-start-narrow") .attr("placeholder", "Navê rûpelê…") .hide(); // Grow the sense list when the title field of the last block gets content, // mirroring what onDfnInput does for the plain mane textarea. tplTitleInput.on("input", function () { steps.dfn.onDfnInput(stepDiv, block, this); }); // Şablon senses have no plain gloss, so hide alternatîv/hevmane/ // dijmane/etc. Etîket, Nimûne and Jêgirtin stay visible either way. function updateFieldVisibility() { var isTpl = !!tplSelect.val(); $.each(HIDDEN_ON_TPL_GROUPS, function (_, cls) { block.find("." + cls + "-group").toggle(!isTpl); }); } // Store on the block so restoreDfn() can re-sync visibility // after programmatically setting tplSelect's value. block.data("updateFieldVisibility", updateFieldVisibility); tplSelect.on("change", function () { var chosen = $(this).val(); if (chosen) { dfnArea.hide(); tplTitleInput.show().focus(); } else { dfnArea.show(); tplTitleInput.hide().val(""); } updateFieldVisibility(); // Re-run refresh so the Werger step visibility updates. refresh(); }); var tplRow = $("<div></div>").addClass("wiktku-dfn-tpl-row") .append(tplSelect).append(" ").append(tplTitleInput); block.append(tplRow); block.append(dfnArea); // Apply lang filter on initial build. updateTplOptions(); // — Sub-field groups — // All groups are always visible with a placeholder textarea. // Nimûne is last in the DOM and last in the output. var allGroups = [ { cls: "wiktku-dfn-etiket", label: "Etîket", rows: 1, narrow: true, izah: "xisûsen, Mêrdîn, anatomî, Badînî" }, { cls: "wiktku-dfn-kategori", label: "Kategorî", rows: 1, narrow: true, izah: "wekî etîket lê xuya nabe tenê kategorîze dike" }, { cls: "wiktku-dfn-alternativ", label: "Formên alternatîv", rows: 1, narrow: true, izah: "Varyantên vê kelîmeyê" }, { cls: "wiktku-dfn-hevmane", label: "Hevmane", rows: 1, narrow: true, izah: "Spehî hevmaneya Bedew e." }, { cls: "wiktku-dfn-dijmane", label: "Dijmane", rows: 1, narrow: true, izah: "Zengîn dijmaneya feqîr e." }, { cls: "wiktku-dfn-koordine", label: "Termên koordîne", rows: 1, narrow: true, izah: "Pisîk û kûçik termên koordîne ne çunkî Jornavên wan gelek in" }, { cls: "wiktku-dfn-jornav", label: "Jornav", rows: 1, narrow: true, izah: "Heywan jornavê guhandar e" }, { cls: "wiktku-dfn-jernav", label: "Jêrnav", rows: 1, narrow: true, izah: "Guhandar jêrnavê heywan e" }, { cls: "wiktku-dfn-nimune", label: "Nimûne", rows: 2, narrow: false } ]; $.each(allGroups, function (_, g) { var groupDiv = $("<div></div>").addClass("wiktku-dfn-subgroup " + g.cls + "-group"); function buildNimuneLi() { var lang = getValues().lang || ""; var li = $("<li></li>").addClass("wiktku-dfn-nimune-li"); var mainTa = $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-text-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", g.rows) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-text") .attr("placeholder", "Nimûneya emilandina kelîmeyê tu bi xwe binivîse…"); mainTa.on("input", function () { var val = $.trim($(this).val()); var isLast = li.is(list.children("li:last-child")); if (val && isLast) { list.append(buildNimuneLi()); } }); li.append(mainTa); var subWrap = $("<div></div>").addClass("wiktku-dfn-nimune-sub"); if (needsTransliteration(lang)) { subWrap.append( $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-tr-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 5) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-tr") .attr("placeholder", "Transkrîpsiyona bi alfabeya latînî") ); } if (lang && lang !== "ku") { subWrap.append( $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-t-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 5) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-t") .attr("placeholder", "Tercimeya kurmancî") ); } if (subWrap.children().length) li.append(subWrap); return li; } if (g.cls === "wiktku-dfn-nimune") { // Nimûne — compound widget with tr/t sub-fields. var lbl = $("<span></span>").addClass("wiktku-dfn-sublabel").text(g.label + ": "); var list = $("<ol></ol>").addClass("wiktku-dfn-sublist " + g.cls + "-list"); groupDiv.data("buildNimuneLi", buildNimuneLi); list.append(buildNimuneLi()); groupDiv.append(lbl).append(list); block.append(groupDiv); } else { // Regular always-visible group — label + growing textarea list. var lbl = $("<span></span>").addClass("wiktku-dfn-sublabel").text(g.label + ": " + g.izah); var list = $("<ol></ol>").addClass("wiktku-dfn-sublist " + g.cls + "-list"); var firstInput = $("<textarea></textarea>") .attr("name", g.cls + "-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", g.rows) .attr("class", "wiktku-dfn-subfield" + (g.narrow ? " wiktku-start-narrow" : "")) .attr("placeholder", g.label + "…"); firstInput.on("input", function () { steps.dfn.onSubInput(list, this, g.rows, g.narrow); }); list.append($("<li></li>").append(firstInput)); groupDiv.append(lbl).append(list); block.append(groupDiv); } }); // — Jêder (citation) group — growing list, same structure as Nimûne. — (function () { var jederGroupDiv = $("<div></div>").addClass("wiktku-dfn-subgroup wiktku-dfn-jeder-group"); var jederLbl = $("<span></span>").addClass("wiktku-dfn-sublabel").text("Jêgirtin: "); var jederList = $("<ol></ol>").addClass("wiktku-dfn-sublist wiktku-dfn-jeder-list"); function buildJederLi() { var lang = getValues().lang || ""; var li = $("<li></li>").addClass("wiktku-dfn-jeder-li"); var dragHandle = $("<span></span>") .addClass("wiktku-jeder-drag-handle") .attr("title", "Bişkûne û bikişîne da ku rêzê biguhezîne"); // Quote text textarea var quoteTa = $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-quote-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 2) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-quote") .attr("placeholder", "Nimûneya emilandinê ji kitêb an çavkaniyeke din binivîse"); quoteTa.on("input", function () { var val = $.trim($(this).val()); var isLast = li.is(jederList.children("li:last-child")); if (val && isLast) { jederList.append(buildJederLi()); } }); li.append(dragHandle).append(quoteTa); // tr/t sub-fields for the quote — shown as needed for the language. var quoteSubWrap = $("<div></div>").addClass("wiktku-dfn-quote-sub"); if (needsTransliteration(lang)) { quoteSubWrap.append( $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-quote-tr-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 2) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-quote-tr") .attr("placeholder", "Transkrîpsiyona jêgirtinê…") ); } if (lang && lang !== "ku") { quoteSubWrap.append( $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-quote-t-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 2) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-quote-t") .attr("placeholder", "Tercimeya jêgirtinê bi kurmancî") ); } if (quoteSubWrap.children().length) li.append(quoteSubWrap); // Citoid auto-fill: fetch citation data from a URL, DOI or ISBN and // prefill the source şablon + fields below (see Gadget-citoid-helper.js). var citoidWrap = $("<div></div>").addClass("wiktku-dfn-quote-citoid"); var citoidInput = $("<input type='text'>") .addClass("wiktku-dfn-quote-citoid-input wiktku-start-narrow") .attr("placeholder", "URL, DOI an ISBN binivîse ku otomatîk were tijekirin…"); var citoidBtn = new OO.ui.ButtonWidget({ label: "Bi Citoid bîne", classes: [ "wiktku-dfn-quote-citoid-btn" ] }); var citoidStatus = $("<span></span>").addClass("wiktku-dfn-quote-citoid-status"); // Fetches citation data from Citoid and fills this citation's // şablon + fields — only rebuilds fields on template change, // and never overwrites values the user already typed. function runCitoidFetch() { var query = $.trim(citoidInput.val()); if (!query) { mw.notify("Ji kerema xwe re pêşî URL, DOI an ISBNyekê binivîse."); return; } citoidBtn.setDisabled(true); citoidStatus.text("Tê anîn…"); wikt.citoidHelper.ensure().then(function () { return wikt.citoid.fetchJederFields(query); }).then(function (result) { var jederKey = result.jederKey; var hasTpl = !!jederKey && srcSel.find("option[value='" + jederKey + "']").length > 0; var targetVal = hasTpl ? jederKey : "__manual__"; // Only rebuild if switching şablon, so a repeat fetch // doesn't clear fields already filled in by hand. if (srcSel.val() !== targetVal) { srcSel.val(targetVal).trigger("change"); srcSel.trigger("chosen:updated"); } if (hasTpl) { // Tenê qadên vala tijî bike. $.each(result.fields, function (key, val) { var input = srcFields.find("[data-field-key='" + key + "']"); if (input.length && !$.trim(input.val())) { input.val(val); } }); } else { // Şablonek nehat naskirin ji bo vê itemType — rêzikeke // çavkaniyê ya bi destan a ji qadên Citoid tê çêkirin, // lê tenê ger qada destan vala be. var manualField = srcFields.find(".wiktku-dfn-quote-src-manual"); if (!$.trim(manualField.val())) { var parts = []; $.each(["nivîskar", "sernav", "websîte", "kovar", "weşanxane", "sal", "url"], function (_, k) { if (result.fields[k]) parts.push(result.fields[k]); }); manualField.val(parts.join(", ")); } } citoidStatus.text(""); }, function (errorMsg) { citoidStatus.text(typeof errorMsg === "string" ? errorMsg : "Nehat dîtin. Kontrol bike ka URL/DOI/ISBN rast e."); }).always(function () { citoidBtn.setDisabled(false); }); } citoidBtn.on("click", runCitoidFetch); citoidInput.on("keydown", function (e) { if (e.which === 13) { // Enter e.preventDefault(); runCitoidFetch(); } }); citoidWrap.append(citoidInput).append(citoidBtn.$element).append(citoidStatus); // Source template selector, specific to this citation. var srcSel = $("<select></select>").addClass("wiktku-dfn-quote-src-sel"); srcSel.append($("<option value=''>— Çavkaniyê hilbijêre —</option>")); srcSel.append($("<option></option>").val("__manual__").text("Bi destê xwe binivîsim")); var jederDefs = steps.dfn.jederDefs || {}; $.each(jederDefs, function (tplName, def) { srcSel.append($("<option></option>").val(tplName).text(def.label)); }); // Dynamic source fields container. var srcFields = $("<div></div>").addClass("wiktku-dfn-quote-src-fields"); srcSel.on("change", function () { srcFields.empty(); var chosen = $(this).val(); if (!chosen) return; if (chosen === "__manual__") { // Freeform source, written by the user — becomes the 2nd // positional param of {{jêder|lang|…}} instead of çavkanî?. srcFields.append( $("<textarea></textarea>") .attr("rows", 4) .addClass("wiktku-dfn-subfield wiktku-dfn-quote-src-manual") .attr("placeholder", "Çavkaniyê bi destê xwe binivîse…") ); return; } var def = (steps.dfn.jederDefs || {})[chosen]; if (!def) return; $.each(def.fields, function (_, f) { var row = $("<div></div>").addClass("wiktku-dfn-quote-src-row"); var fieldLbl = $("<label></label>").text(f.label + ": "); var inp = $("<textarea></textarea>") .attr("rows", 2) .addClass("wiktku-dfn-quote-src-input wiktku-start-narrow") .attr("data-field-key", f.key) .attr("placeholder", f.label + "…"); row.append(fieldLbl).append(inp); srcFields.append(row); }); }); li.append(citoidWrap).append(srcSel).append(srcFields); return li; } jederGroupDiv.data("buildJederLi", buildJederLi); jederList.append(buildJederLi()); // Make citation rows sortable (drag to reorder). // The last row is always the empty trailing row — cancel its drag. mw.loader.using("jquery.ui.sortable", function () { jederList.sortable({ handle: ".wiktku-jeder-drag-handle", axis: "y", items: "li:not(:last-child)", tolerance: "pointer" }); }); jederGroupDiv.append(jederLbl).append(jederList); block.append(jederGroupDiv); }()); // Apply the initial hide/show state for the sub-groups (matches // tplSelect's starting value, which is normally empty). updateFieldVisibility(); return block; }, /** Grows the sense list when the last mane textarea gets content. */ onDfnInput: function (stepDiv, block, textarea) { var val = $.trim($(textarea).val()); var list = stepDiv.find("ol.wiktku-dfn-list"); var isLast = block.is(list.children("li:last-child")); if (val && isLast) { var newBlock = steps.dfn.buildSenseBlock(stepDiv); list.append(newBlock); // Apply Chosen to the new block's template selector on desktop. if (!isMobile) newBlock.find("select.wiktku-dfn-tpl-select").chosen(chosenOptions); } refresh(); }, /** Grows a sub-list (nimûne/formên alternatîv/hevmane/dijmane/termên koordîne) on input. */ onSubInput: function (list, input, rows, narrow) { var val = $.trim($(input).val()); var item = $(input).parent(); var isLast = item.is(list.children("li:last-child")); if (val && isLast) { var next = $("<textarea></textarea>") .attr("name", "wiktku-dfn-sub-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", rows) .attr("class", "wiktku-dfn-subfield" + (narrow ? " wiktku-start-narrow" : "")); next.on("input", function () { steps.dfn.onSubInput(list, this, rows, narrow); }); list.append($("<li></li>").append(next)); } }, // Populated from [[MediaWiki:Gadget-start.js/data.json]] (tplDefs, posExamples, jederDefs). tplDefs: [], posExamples: {}, jederDefs: {}, build: function (stepDiv) { if (stepDiv.find("ol.wiktku-dfn-list").length) return null; var list = $("<ol class='wiktku-dfn-list'></ol>"); list.append(steps.dfn.buildSenseBlock(stepDiv)); stepDiv.append(list); return null; }, /** Reads all sense blocks from the DOM and returns an array of sense objects. */ getSenses: function (stepDiv) { var senses = []; stepDiv.find("li.wiktku-dfn-sense").each(function () { var block = $(this); var tplSel = block.find("select.wiktku-dfn-tpl-select"); var tpl = tplSel.val() || ""; // noLang: template already encodes the language — don't add |lang| param. var tplNoLang = tpl ? tplSel.find("option[value='" + tpl + "']").attr("data-nolang") === "1" : false; var tplTitle = $.trim(block.find("input.wiktku-dfn-tpl-title").val()); var mane = $.trim(block.find("textarea.wiktku-dfn-mane").val()); function readList(cls) { var vals = []; block.find("." + cls + "-list textarea").each(function () { var v = $.trim($(this).val()); if (v) vals.push(v); }); return vals; } // Nimûne items are compound: { text, tr?, t? } function readNimuneList() { var items = []; block.find(".wiktku-dfn-nimune-list li.wiktku-dfn-nimune-li").each(function () { var text = $.trim($(this).find(".wiktku-dfn-nimune-text").val()); if (!text) return; var obj = { text: text }; var tr = $.trim($(this).find(".wiktku-dfn-nimune-tr").val()); var t = $.trim($(this).find(".wiktku-dfn-nimune-t").val()); if (tr) obj.tr = tr; if (t) obj.t = t; items.push(obj); }); return items; } // Jêder is a growing list of citations, one per li — mirrors readNimuneList(). function readJederList() { var items = []; block.find(".wiktku-dfn-jeder-list li.wiktku-dfn-jeder-li").each(function () { var li = $(this); var quote = $.trim(li.find(".wiktku-dfn-nimune-quote").val()); if (!quote) return; var obj = { quote: quote }; var qtr = $.trim(li.find(".wiktku-dfn-nimune-quote-tr").val()); var qt = $.trim(li.find(".wiktku-dfn-nimune-quote-t").val()); if (qtr) obj.quoteTr = qtr; if (qt) obj.quoteT = qt; var tplName = li.find(".wiktku-dfn-quote-src-sel").val(); if (tplName === "__manual__") { var manual = $.trim(li.find(".wiktku-dfn-quote-src-manual").val()); if (manual) obj.jederManual = manual; } else if (tplName) { obj.jederTpl = tplName; var fields = {}; li.find(".wiktku-dfn-quote-src-input").each(function () { var k = $(this).attr("data-field-key"); var v = $.trim($(this).val()); if (k && v) fields[k] = v; }); obj.jêderFields = fields; } items.push(obj); }); return items; } senses.push({ tpl: tpl, tplNoLang: tplNoLang, tplTitle: tplTitle, mane: mane, etiket: readList("wiktku-dfn-etiket"), kategori: readList("wiktku-dfn-kategori"), nimune: readNimuneList(), jeder: readJederList(), alternativ: readList("wiktku-dfn-alternativ"), hevmane: readList("wiktku-dfn-hevmane"), dijmane: readList("wiktku-dfn-dijmane"), koordine: readList("wiktku-dfn-koordine"), jornav: readList("wiktku-dfn-jornav"), jernav: readList("wiktku-dfn-jernav") }); }); return senses; }, getOutput: function (values, callback) { var stepDiv = $("#wiktku-start-dfn"); var senses = steps.dfn.getSenses(stepDiv); var lang = values.lang; // A sense counts as "filled" if it has a mane, a chosen template + title, // or any other content (etîket/hevmane/nimûne/jêder…) worth keeping. var hasMane = senses.some(function (s) { return s.mane !== "" || (s.tpl && s.tplTitle) || senseHasExtraContent(s); }); // True only when at least one sense has a regular mane (needs linkify). var hasRegularMane = senses.some(function (s) { return !s.tpl && s.mane !== ""; }); // nimûne/jêder must never pass through linkify, only the mane text. // defLines (linkified) and citeLines (kept aside) stay parallel; // a {{wiktku-cite-N}} token in defLines marks where to splice back. var defLines = []; // one entry per kept sense (goes to linkify) var citeLines = []; // parallel — nimûne+jêder for that same sense $.each(senses, function (_, sense) { // — Template sense (e.g. {{guharto|ku|somepage}}) — if (sense.tpl) { if (!sense.tplTitle) return; // skip empty template senses var tplKatTpl = buildSenseTpl(sense, "kategori", lang, "K", "inline"); var tplLabelTpl = buildSenseTpl(sense, "etiket", lang, "e", "inline"); var tplCall = sense.tplNoLang ? "{{" + sense.tpl + "|" + sense.tplTitle + "}}" : "{{" + sense.tpl + "|" + lang + "|" + sense.tplTitle + "}}"; var idx = defLines.length; var cite = buildCite(sense, lang); defLines.push("# " + (tplKatTpl ? tplKatTpl : "") + (tplLabelTpl ? tplLabelTpl : "") + tplCall + (cite ? "{{wiktku-cite-" + idx + "}}" : "")); citeLines.push(cite); return; } // — Normal mane sense — var dfn = sense.mane; if (!dfn && !senseHasExtraContent(sense)) return; // truly empty if (dfn) { dfn = stripWikilinks(dfn); if (dfn[0] !== dfn[0].toUpperCase()) dfn = capitalize(dfn); if (!dfn.match(/[.…?!)\]]$/)) dfn += "."; } else { dfn = "{{mane?|" + lang + "}}"; } var katTpl = buildSenseTpl(sense, "kategori", lang, "K", "inline"); var labelTpl = buildSenseTpl(sense, "etiket", lang, "e", "inline"); var out = "# " + (katTpl ? katTpl : "") + (labelTpl ? labelTpl : "") + dfn; function wordLine(tpl, words) { if (!words.length) return ""; return "\n#: {{" + tpl + "|" + lang + "|" + words.join("|") + "}}"; } out += wordLine("alt-r", sense.alternativ); out += wordLine("hevmane", sense.hevmane); out += wordLine("dijmane", sense.dijmane); out += wordLine("koordîne", sense.koordine); out += wordLine("jornav", sense.jornav); out += wordLine("jêrnav", sense.jernav); var cite = buildCite(sense, lang); var idx = defLines.length; defLines.push(out + (cite ? "{{wiktku-cite-" + idx + "}}" : "")); citeLines.push(cite); }); // Splice citeLines back into a linkified string, replacing each // {{wiktku-cite-N}} token with its stored nimûne/jêder block. function restoreCites(t) { return t.replace(/\{\{wiktku-cite-(\d+)\}\}/g, function (_, n) { return citeLines[parseInt(n, 10)] || ""; }); } var text = defLines.join("\n") + "\n"; if (!hasMane) { // No definitions entered — emit {{mane?}} with bênimûne. text = "# {{mane?|" + lang + "}}\n#* {{bênimûne|" + lang + "}}\n"; callback(text); return; } if (!hasRegularMane) { // All filled senses are template senses — no linkify needed. callback(restoreCites(text)); return; } var didTryToLoad = function () { if (typeof $.wiktviLinkify === "function") { $.wiktviLinkify(text, function (linked) { callback(restoreCites(linked)); }); } else { callback(restoreCites(text)); } }; mw.loader.using("ext.gadget.linkify", didTryToLoad, didTryToLoad); } }, je: makeWordListStep("je", "jê", "Kelîmeyên jê çêbûyî binivîse", "Jê", "g"), tekildar: makeWordListStep("tekildar", "têkildar", "Kelîmeyên ji aliyê etîmolojiyê ve têkildarî vê kelîmeyê binivîse", "Têkildar", "g"), binereherwiha: makeWordListStep("binereherwiha", "binêre herwiha", "Kelîmeyên din ên eleqedar binivîse", "Binêre herwiha", "g"), etym: { id: "etym", name: "etîmolojî", question_fmt: "Etîmolojiya kelîmeyê binivîse", // etymTpls populated from data.json etymTpls: [], visible: function (values) { return values.lang && values.pos; }, // Fills the insert-dropdown from the current etymTpls array. refreshTplSelect: function () { var sel = $("#wiktku-start-etym .wiktku-tpl-insert-select"); if (!sel.length) return; sel.find("option[value!='']").remove(); $.each(steps.etym.etymTpls, function (_, tpl) { sel.append($("<option></option>").val(tpl.snippet).text(tpl.name + " — " + tpl.desc)); }); // Notify Chosen that the option list has changed (no-op on mobile). if (!isMobile) sel.trigger("chosen:updated"); }, build: function (stepDiv) { if (stepDiv.find(".wiktku-etym-wrap").length) return null; var wrap = $("<div class='wiktku-etym-wrap'></div>"); var ta = $("<textarea></textarea>") .attr("name", "wiktku-etym-" + $.now()) .attr("class", "wiktku-start-step-field wiktku-etym-text") .attr("rows", 4) .attr("placeholder", "Nimûne: Ji {{ji|en|ku|apple}}. yan rasterast binivîse…"); // Template insert dropdown — options also refreshed after data.json loads. var sel = $("<select class='wiktku-tpl-insert-select'></select>"); sel.append($("<option value=''>— şablonek lê zêde bike —</option>")); $.each(steps.etym.etymTpls, function (_, tpl) { sel.append($("<option></option>").val(tpl.snippet).text(tpl.name + " — " + tpl.desc)); }); sel.on("change", function () { var snippet = $(this).val(); if (!snippet) return; var lang = getValues().lang || ""; snippet = snippet.replace(/CODE/g, lang).replace(/SOURCELANG/g, "?"); insertAtCursor(ta[0], snippet); $(this).val(""); ta.focus(); }); wrap.append(sel).append($("<br>")).append(ta); stepDiv.append(wrap); return ta; }, output: function (values) { var text = $.trim($("#wiktku-start-etym .wiktku-etym-text").val()); if (text) { return "\n==== Etîmolojî ====\n" + text + "\n"; } // No etymology entered — emit {{ji?|lang}} as a placeholder, // Only when a regular sense has content (real mane, or {{mane?}} // with other fields filled in) — a şablon sense never counts. var dfnSenses = steps.dfn.getSenses($("#wiktku-start-dfn")); var hasRegularMane = dfnSenses.some(function (s) { return !s.tpl && (s.mane !== "" || senseHasExtraContent(s)); }); if (!hasRegularMane) return ""; return "\n==== Etîmolojî ====\n{{ji?|" + values.lang + "}}\n"; } }, dunde: { id: "dunde", name: "dûnde", question_fmt: "Eger ev kelîme ji vî zimanî ketibe zimanekî din, vî zimanî û kelîmeya wî binivîse", visible: function (values) { return !!values.pos; }, disabledKeys: { "navz": true}, // Language dropdown + growing word-input list; a new row appends // when the dropdown gets a value. Mirrors steps.trans, but flat. buildRow: function (stepDiv) { var row = $("<li class='wiktku-dunde-row wiktku-lang-row'></li>"); // Language selector — chosen is applied after insertion into DOM. var langSel = $(mw.html.element("select", { "class": "wiktku-start-step-keyfield wiktku-start-narrow" })); langSel.attr("data-placeholder", "Zimanekî lê bigere"); populateMenus(langSel, steps.dunde.keys || [], steps.dunde.disabledKeys); // When a language is chosen, ensure a next empty row exists. langSel.on("change", function () { steps.dunde.onLangChange(stepDiv, row); }); // Word list for this language. var wordList = $("<ul class='wiktku-dunde-words wiktku-lang-row-words'></ul>"); var firstWord = steps.dunde.makeWordInput(); wordList.append($("<li></li>").append(firstWord)); if (isMobile) { row.append(wrapNativeSelect(langSel)).append(wordList); } else { row.append(langSel).append(wordList); } return row; }, makeWordInput: function () { var input = $("<textarea></textarea>") .attr("name", "wiktku-dunde-word-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 1) .attr("class", "wiktku-dfn-subfield wiktku-start-narrow") .attr("placeholder", "Kelîme…"); input.on("input", function () { var list = $(this).closest("ul.wiktku-dunde-words"); var item = $(this).parent(); var val = $.trim($(this).val()); if (val && item.is(list.children("li:last-child"))) { var next = steps.dunde.makeWordInput(); list.append($("<li></li>").append(next)); } }); return input; }, onLangChange: function (stepDiv, row) { var list = stepDiv.find("ul.wiktku-dunde-list"); var isLast = row.is(list.children("li.wiktku-dunde-row:last-child")); if (isLast) { var newRow = steps.dunde.buildRow(stepDiv); list.append(newRow); // Init chosen after the new row is in the DOM (desktop only). if (!isMobile) newRow.find("select").chosen(chosenOptions); } // Keep disabled keys in sync across all lang selectors. steps.dunde.syncDisabledKeys(stepDiv); }, /** Disables already-selected languages in all other dropdowns. */ syncDisabledKeys: function (stepDiv) { var taken = $.extend({}, steps.dunde.disabledKeys); stepDiv.find("li.wiktku-dunde-row select").each(function () { var v = $(this).val(); if (v) taken[v] = true; }); stepDiv.find("li.wiktku-dunde-row select").each(function () { var self = $(this); var own = self.val(); self.find("option").each(function () { var code = $(this).val(); if (!code) return; $(this).prop("disabled", taken[code] && code !== own); }); self.trigger("chosen:updated"); }); }, build: function (stepDiv) { if (stepDiv.find("ul.wiktku-dunde-list").length) return null; var list = $("<ul class='wiktku-dunde-list wiktku-lang-row-list'></ul>"); list.append(steps.dunde.buildRow(stepDiv)); stepDiv.append(list); // Init chosen after the select is in the DOM (desktop only). if (!isMobile) list.find("select").chosen(chosenOptions); return null; }, /** Reads all [langcode, words[]] rows from the DOM. */ getRows: function (stepDiv) { var result = []; stepDiv.find("li.wiktku-dunde-row").each(function () { var lang = $(this).find("select").val(); if (!lang) return; var words = []; $(this).find("ul.wiktku-dunde-words textarea").each(function () { var v = $.trim($(this).val()); if (v) words.push(v); }); if (words.length) result.push([lang, words]); }); return result; }, output: function () { var stepDiv = $("#wiktku-start-dunde"); var rows = steps.dunde.getRows(stepDiv); if (!rows.length) return ""; var lines = $.map(rows, function (row) { var lang = row[0], words = row[1]; return "* {{dû|" + lang + "|" + words.join("|") + "}}"; }); return "\n==== Dûnde ====\n" + lines.join("\n") + "\n"; } }, zarava: { id: "zarava", name: "bi zaravayên din", visible: function (values) { return steps.trans.visible(values); }, disabledKeys: { "navz": true }, buildRow: function (group) { var row = $("<li class='wiktku-zarava-row wiktku-lang-row'></li>"); var langSel = $(mw.html.element("select", { "class": "wiktku-start-step-keyfield wiktku-start-narrow" })); populateMenus(langSel, steps.zarava.keys || [], steps.zarava.disabledKeys); langSel.on("change", function () { steps.zarava.onLangChange(group, row); }); var wordList = $("<ul class='wiktku-zarava-words wiktku-lang-row-words'></ul>"); var firstWord = steps.zarava.makeWordInput(); wordList.append($("<li></li>").append(firstWord)); row.append(langSel).append(wordList); return row; }, makeWordInput: function () { var input = $("<textarea></textarea>") .attr("name", "wiktku-zarava-word-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 1) .attr("class", "wiktku-dfn-subfield wiktku-start-narrow") .attr("placeholder", "Tercime…"); input.on("input", function () { var list = $(this).closest("ul.wiktku-zarava-words"); var item = $(this).parent(); var val = $.trim($(this).val()); if (val && item.is(list.children("li:last-child"))) { var next = steps.zarava.makeWordInput(); list.append($("<li></li>").append(next)); } }); return input; }, onLangChange: function (group, row) { var list = group.find("ul.wiktku-zarava-list"); var isLast = row.is(list.children("li.wiktku-zarava-row:last-child")); if (isLast) { var newRow = steps.zarava.buildRow(group); list.append(newRow); } steps.zarava.syncDisabledKeys(group); }, /** Disables already-selected dialects in all other dropdowns within one group. */ syncDisabledKeys: function (group) { var taken = $.extend({}, steps.zarava.disabledKeys); group.find("li.wiktku-zarava-row select").each(function () { var v = $(this).val(); if (v) taken[v] = true; }); group.find("li.wiktku-zarava-row select").each(function () { var self = $(this); var own = self.val(); self.find("option").each(function () { var code = $(this).val(); if (!code) return; $(this).prop("disabled", taken[code] && code !== own); }); }); }, /** Builds (or fetches) the .wiktku-zarava-group for one gloss. */ buildGroup: function (stepDiv, gi) { var group = $("<div class='wiktku-zarava-group'></div>").attr("data-gloss-pos", gi); var list = $("<ul class='wiktku-zarava-list wiktku-lang-row-list'></ul>"); list.append(steps.zarava.buildRow(group)); group.append(list); stepDiv.append(group); return group; }, /** Syncs one .wiktku-zarava-group per current gloss (same logic as steps.trans.build). */ build: function (stepDiv) { var glosses = steps.trans.glossList(); if (!glosses.length) { stepDiv.find(".wiktku-zarava-group").remove(); return null; } var existingGroups = stepDiv.find(".wiktku-zarava-group"); if (existingGroups.length > glosses.length) { existingGroups.slice(glosses.length).remove(); } $.each(glosses, function (gi, gloss) { var group = stepDiv.find(".wiktku-zarava-group[data-gloss-pos='" + gi + "']"); if (!group.length) group = steps.zarava.buildGroup(stepDiv, gi); var label = group.find(".wiktku-zarava-group-label"); if (glosses.length > 1) { if (!label.length) { label = $("<div class='wiktku-zarava-group-label'></div>"); group.prepend(label); } label.text(gloss.index + " " + gloss.text); } else if (label.length) { label.remove(); } }); return null; }, /** Reads the dialect rows for a single gloss group. */ getGroupTranslations: function (group) { var result = []; group.find("li.wiktku-zarava-row").each(function () { var lang = $(this).find("select").val(); if (!lang) return; var words = []; $(this).find("ul.wiktku-zarava-words textarea").each(function () { var v = $.trim($(this).val()); if (v) words.push(v); }); if (words.length) result.push([lang, words]); }); return result; }, /** Reads all rows from the DOM, grouped by gloss position. */ getTranslations: function (stepDiv) { var result = []; stepDiv.find(".wiktku-zarava-group").each(function () { result.push(steps.zarava.getGroupTranslations($(this))); }); return result; }, output: function (values) { if (values.lang !== "ku") return ""; var stepDiv = $("#wiktku-start-zarava"); var glosses = steps.trans.glossList(); if (!glosses.length) return ""; var blocks = $.map(glosses, function (gloss, gi) { var group = stepDiv.find(".wiktku-zarava-group[data-gloss-pos='" + gi + "']"); var rows = group.length ? steps.zarava.getGroupTranslations(group) : []; if (!gloss.text && !rows.length) return undefined; if (rows.length) { rows.sort(function (a, b) { var aLang = langsByCode[a[0]] || []; var bLang = langsByCode[b[0]] || []; return (aLang[2] || "").localeCompare(bLang[2] || "", "ku"); }); } var wordLines = $.map(rows, function (row) { var lang = row[0]; var words = row[1]; var wikiWords = words.map(function (w) { return "{{W|" + lang + "|" + w + "}}"; }).join(", "); return "* {{Z|" + lang + "}}: " + wikiWords; }).join("\n"); if (!wordLines) return undefined; var block = "{{werger-ser|" + (gloss.text || "?") + "|" + gloss.index + "}}"; block += "\n" + wordLines; block += "\n{{werger-bin}}"; return block; }); if (!blocks.length) return ""; return "\n==== Bi zaravayên din ====\n" + blocks.join("\n") + "\n"; } }, trans: { id: "trans", name: "werger", visible: function (values) { if (!(values.lang === "ku" && values.pos)) return false; // Hide only when every sense is a filled template sense (no plain // gloss to attach translations to). A mix, or nothing filled in // yet, still shows Werger. var dfnSenses = steps.dfn.getSenses($("#wiktku-start-dfn")); var hasRealSense = dfnSenses.some(function (s) { return !s.tpl && (s.mane !== "" || senseHasExtraContent(s)); }); var hasFilledTplSense = dfnSenses.some(function (s) { return s.tpl && s.tplTitle; }); return hasRealSense || !hasFilledTplSense; }, disabledKeys: { "navz": true, "ku": true, "ckb": true, "sdh": true, "lki": true, "hac": true, "zza": true }, // Language dropdown + growing word-input list, scoped to one gloss's // group (each gloss has its own group and row list). buildRow: function (group) { var row = $("<li class='wiktku-trans-row wiktku-lang-row'></li>"); // Language selector — chosen is applied after insertion into DOM. var langSel = $(mw.html.element("select", { "class": "wiktku-start-step-keyfield wiktku-start-narrow" })); langSel.attr("data-placeholder", "Zimanekî lê bigere"); populateMenus(langSel, steps.trans.keys || [], steps.trans.disabledKeys); // When a language is chosen, ensure a next empty row exists. langSel.on("change", function () { steps.trans.onLangChange(group, row); }); // Word list for this language. var wordList = $("<ul class='wiktku-trans-words wiktku-lang-row-words'></ul>"); var firstWord = steps.trans.makeWordInput(); wordList.append($("<li></li>").append(firstWord)); if (isMobile) { row.append(wrapNativeSelect(langSel)).append(wordList); } else { row.append(langSel).append(wordList); } return row; }, makeWordInput: function () { var input = $("<textarea></textarea>") .attr("name", "wiktku-trans-word-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 1) .attr("class", "wiktku-dfn-subfield wiktku-start-narrow") .attr("placeholder", "Tercime…"); input.on("input", function () { var list = $(this).closest("ul.wiktku-trans-words"); var item = $(this).parent(); var val = $.trim($(this).val()); if (val && item.is(list.children("li:last-child"))) { var next = steps.trans.makeWordInput(); list.append($("<li></li>").append(next)); } }); return input; }, onLangChange: function (group, row) { var list = group.find("ul.wiktku-trans-list"); var isLast = row.is(list.children("li.wiktku-trans-row:last-child")); if (isLast) { var newRow = steps.trans.buildRow(group); list.append(newRow); // Init chosen after the new row is in the DOM (desktop only). if (!isMobile) newRow.find("select").chosen(chosenOptions); } // Keep disabled keys in sync across this gloss's lang selectors // only — the same language can be used for different senses. steps.trans.syncDisabledKeys(group); }, /** Disables already-selected languages in all other dropdowns within one group. */ syncDisabledKeys: function (group) { var taken = $.extend({}, steps.trans.disabledKeys); group.find("li.wiktku-trans-row select").each(function () { var v = $(this).val(); if (v) taken[v] = true; }); group.find("li.wiktku-trans-row select").each(function () { var self = $(this); var own = self.val(); self.find("option").each(function () { var code = $(this).val(); if (!code) return; $(this).prop("disabled", taken[code] && code !== own); }); self.trigger("chosen:updated"); }); }, // Builds (or fetches) the .wiktku-trans-group for one gloss. buildGroup: function (stepDiv, gi) { var group = $("<div class='wiktku-trans-group'></div>").attr("data-gloss-pos", gi); var list = $("<ul class='wiktku-trans-list wiktku-lang-row-list'></ul>"); list.append(steps.trans.buildRow(group)); group.append(list); stepDiv.append(group); // Init chosen after the select is in the DOM (desktop only). if (!isMobile) list.find("select").chosen(chosenOptions); return group; }, // Syncs one .wiktku-trans-group per current gloss, keyed by // data-gloss-pos so groups stay matched across rebuilds. build: function (stepDiv) { var glosses = steps.trans.glossList(); if (!glosses.length) { stepDiv.find(".wiktku-trans-group").remove(); return null; } // Drop groups for glosses that no longer exist (always from the // tail — groups are only ever appended in gloss order below). var existingGroups = stepDiv.find(".wiktku-trans-group"); if (existingGroups.length > glosses.length) { existingGroups.slice(glosses.length).remove(); } $.each(glosses, function (gi, gloss) { var group = stepDiv.find(".wiktku-trans-group[data-gloss-pos='" + gi + "']"); if (!group.length) group = steps.trans.buildGroup(stepDiv, gi); // Only label groups when there's more than one gloss to // distinguish between — a single gloss needs no caption. var label = group.find(".wiktku-trans-group-label"); if (glosses.length > 1) { if (!label.length) { label = $("<div class='wiktku-trans-group-label'></div>"); group.prepend(label); } label.text(gloss.index + " " + gloss.text); } else if (label.length) { label.remove(); } }); return null; }, /** Reads the translation rows for a single gloss group. */ getGroupTranslations: function (group) { var result = []; group.find("li.wiktku-trans-row").each(function () { var lang = $(this).find("select").val(); if (!lang) return; var words = []; $(this).find("ul.wiktku-trans-words textarea").each(function () { var v = $.trim($(this).val()); if (v) words.push(v); }); if (words.length) result.push([lang, words]); }); return result; }, // Reads all translation rows, grouped by gloss position. getTranslations: function (stepDiv) { var result = []; stepDiv.find(".wiktku-trans-group").each(function () { result.push(steps.trans.getGroupTranslations($(this))); }); return result; }, // Builds the numbered "{ index, gloss }" list, one per dfn sense // with a real mane (skips template senses). index is 1-based and // matches the sense's position in the "#" definition list. // When nothing's filled in, returns one placeholder entry so // Werger still has a group to attach to; when every sense is a // filled template sense, stays empty (matches trans.visible()). glossList: function () { var dfnSenses = steps.dfn.getSenses($("#wiktku-start-dfn")); var glosses = []; var hasFilledTplSense = false; $.each(dfnSenses, function (i, s) { if (s.tpl) { if (s.tplTitle) hasFilledTplSense = true; return; // template sense — no gloss to caption with } var dfn = s.mane; if (!dfn) { // No mane, but other fields are filled — still gets a // gloss group since dfn.getOutput() emits {{mane?}} for it. if (senseHasExtraContent(s)) glosses.push({ index: i + 1, text: "" }); return; } if (dfn[0] !== dfn[0].toLowerCase()) dfn = decapitalize(dfn); dfn = stripWikilinks(dfn).replace(/[.…?!)\]،؟]+$/, ""); glosses.push({ index: i + 1, text: dfn }); }); if (!glosses.length && !hasFilledTplSense) { glosses.push({ index: 1, text: "" }); } return glosses; }, output: function (values) { if (values.lang !== "ku") return ""; var stepDiv = $("#wiktku-start-trans"); var glosses = steps.trans.glossList(); // Every sense is a template sense — there's no real gloss // anywhere and no group in the DOM either (glossList() only // returns empty in that case), so skip the section entirely. if (!glosses.length) return ""; // Each gloss now has its own group of translation rows — // attach every gloss's own words under its own werger-ser/-bin // pair instead of dumping everything under the first one. var blocks = $.map(glosses, function (gloss, gi) { var group = stepDiv.find(".wiktku-trans-group[data-gloss-pos='" + gi + "']"); var rows = group.length ? steps.trans.getGroupTranslations(group) : []; // Placeholder gloss (no real mane entered yet) with nothing // translated into it — nothing to output, and gloss.text is // empty so there's no caption to give {{werger-ser}} anyway. if (!gloss.text && !rows.length) return undefined; if (rows.length) { // Sort by Kurdish sort key. rows.sort(function (a, b) { var aLang = langsByCode[a[0]] || []; var bLang = langsByCode[b[0]] || []; return (aLang[2] || "").localeCompare(bLang[2] || "", "ku"); }); } var wordLines = $.map(rows, function (row) { var lang = row[0]; var words = row[1]; var wikiWords = words.map(function (w) { return "{{W|" + lang + "|" + w + "}}"; }).join(", "); return "* {{Z|" + lang + "}}: " + wikiWords; }).join("\n"); var block = "{{werger-ser|" + (gloss.text || "?") + "|" + gloss.index + "}}"; if (wordLines) block += "\n" + wordLines; block += "\n{{werger-bin}}"; return block; }); if (!blocks.length) return ""; return "\n==== Werger ====\n" + blocks.join("\n") + "\n"; } }, }; steps.trans.keys = steps.lang.choices; steps.dunde.keys = steps.lang.choices; steps.zarava.keys = getZaravaKeys(steps.lang.choices); var ordered_steps = [ steps.lang, steps.pron, steps.pos, steps.cinsiyet, steps.lektur, steps.tr, steps.dfn, steps.je, steps.tekildar, steps.etym, steps.dunde, steps.binereherwiha, steps.zarava, steps.trans]; // Step ids that belong to each section (not shared across sections). var PER_SECTION_STEP_IDS = [ "pos", "cinsiyet", "lektur", "tr", "dfn", "je", "tekildar", "etym", "dunde", "binereherwiha", "zarava", "trans" ]; // ── Multi-section state ────────────────────────────────────────────────── // Each entry is a plain snapshot: { pos, cinsiyet, lektur, tr, dfn (senses[]), // je, tekildar, binereherwiha, trans (rows[]) }. var sections = [{}]; // section 0 starts empty (DOM is the truth) var activeSection = 0; function snapshotDfn() { return steps.dfn.getSenses($("#wiktku-start-dfn")); } // Rebuilds the dfn DOM from a previously snapshotted senses array. function restoreDfn(senses) { var stepDiv = $("#wiktku-start-dfn"); // Tear down the existing list so build() recreates it cleanly. stepDiv.find("ol.wiktku-dfn-list").remove(); steps.dfn.build(stepDiv); var list = stepDiv.find("ol.wiktku-dfn-list"); $.each(senses, function (i, sense) { // Ensure enough blocks exist (build() seeds one). var blocks = list.find("li.wiktku-dfn-sense"); var block = blocks.eq(i); if (!block.length) { var nb = steps.dfn.buildSenseBlock(stepDiv); list.append(nb); block = list.find("li.wiktku-dfn-sense").last(); } // Template selector. block.find("select.wiktku-dfn-tpl-select").val(sense.tpl || ""); if (sense.tpl) { block.find("textarea.wiktku-dfn-mane").hide(); block.find("input.wiktku-dfn-tpl-title").val(sense.tplTitle || "").show(); } else { block.find("textarea.wiktku-dfn-mane").val(sense.mane || "").show(); block.find("input.wiktku-dfn-tpl-title").hide().val(""); } // Re-sync the formên alternatîv/hevmane/… hide state now that // tplSelect's value was set programmatically (its own "change" // handler doesn't fire from .val(), so this doesn't happen otherwise). var updateVis = block.data("updateFieldVisibility"); if (updateVis) updateVis(); // Restore a sub-list (etiket, formên alternatîv, hevmane …) from a values array. function restoreSubList(cls, values) { if (!values || !values.length) return; var groupDiv = block.find("." + cls + "-group"); var subList = groupDiv.find("ol, ul").first(); if (!subList.length) return; // group not found // Fill existing items, append new ones as needed. $.each(values, function (j, val) { var items = subList.find("li"); if (j < items.length) { items.eq(j).find("textarea").val(val); } else { var ta = $("<textarea></textarea>") .attr("name", "wiktku-dfn-restore-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 1) .attr("class", "wiktku-dfn-subfield wiktku-start-narrow") .val(val); ta.on("input", function () { steps.dfn.onSubInput(subList, this, 1, true); }); subList.append($("<li></li>").append(ta)); } }); } // Reveal and populate lazy groups that have data. var lazyMap = { "wiktku-dfn-etiket": sense.etiket, "wiktku-dfn-kategori": sense.kategori, "wiktku-dfn-alternativ": sense.alternativ, "wiktku-dfn-hevmane": sense.hevmane, "wiktku-dfn-dijmane": sense.dijmane, "wiktku-dfn-koordine": sense.koordine, "wiktku-dfn-jornav": sense.jornav, "wiktku-dfn-jernav": sense.jernav }; $.each(lazyMap, function (cls, vals) { if (vals && vals.length) restoreSubList(cls, vals); }); // Nimûne items are objects { text, tr?, t? } — restore using the builder. if (sense.nimune && sense.nimune.length) { var nimuneGroupDiv = block.find(".wiktku-dfn-nimune-group"); var nimuneList = nimuneGroupDiv.find("ol.wiktku-dfn-nimune-list"); var buildFn = nimuneGroupDiv.data("buildNimuneLi"); nimuneList.empty(); $.each(sense.nimune, function (_, n) { var text = typeof n === "object" ? (n.text || "") : n; if (!text) return; var li = buildFn ? buildFn() : $("<li class='wiktku-dfn-nimune-li'></li>"); li.find(".wiktku-dfn-nimune-text").val(text); if (n.tr) li.find(".wiktku-dfn-nimune-tr").val(n.tr); if (n.t) li.find(".wiktku-dfn-nimune-t").val(n.t); nimuneList.append(li); }); // Always leave a blank trailing item. if (buildFn) nimuneList.append(buildFn()); } // Restore jêder entries — accepts current array shape or a legacy // single object (older saved sections) for backwards compat. var jederArr = $.isArray(sense.jeder) ? sense.jeder : (sense.jeder ? [sense.jeder] : []); if (jederArr.length) { var jederGroupDiv = block.find(".wiktku-dfn-jeder-group"); var jederList = jederGroupDiv.find("ol.wiktku-dfn-jeder-list"); var buildJederFn = jederGroupDiv.data("buildJederLi"); jederList.empty(); $.each(jederArr, function (_, j) { if (!j || !j.quote) return; var li = buildJederFn ? buildJederFn() : $("<li class='wiktku-dfn-jeder-li'></li>"); li.find(".wiktku-dfn-nimune-quote").val(j.quote); if (j.quoteTr) li.find(".wiktku-dfn-nimune-quote-tr").val(j.quoteTr); if (j.quoteT) li.find(".wiktku-dfn-nimune-quote-t").val(j.quoteT); if (j.jederManual) { var manualSel = li.find(".wiktku-dfn-quote-src-sel"); manualSel.val("__manual__").trigger("change"); li.find(".wiktku-dfn-quote-src-manual").val(j.jederManual); } else if (j.jederTpl) { var srcSel = li.find(".wiktku-dfn-quote-src-sel"); srcSel.val(j.jederTpl).trigger("change"); if (j.jêderFields) { $.each(j.jêderFields, function (key, val) { li.find(".wiktku-dfn-quote-src-input[data-field-key='" + key + "']").val(val); }); } } jederList.append(li); }); // Always leave a blank trailing item, same as Nimûne. if (buildJederFn) jederList.append(buildJederFn()); } }); } // Snapshots simple (non-dfn) per-section steps from the DOM into obj. function saveCurrentSection() { var snap = {}; $.each(PER_SECTION_STEP_IDS, function (_, id) { if (id === "dfn") { snap.dfn = snapshotDfn(); return; } if (id === "etym") { snap.etym = $.trim($("#wiktku-start-etym .wiktku-etym-text").val()); return; } var step = steps[id]; if (!step) return; var stepDiv = $("#wiktku-start-" + id); if (id === "trans") { snap.trans = steps.trans.getTranslations(stepDiv); return; } if (id === "zarava") { snap.zarava = steps.zarava.getTranslations(stepDiv); return; } if (id === "dunde") { snap.dunde = steps.dunde.getRows(stepDiv); return; } // Generic: read all step fields. var fields = stepDiv.find(".wiktku-start-step-field"); if (step.multiple) { snap[id] = fields.map(function () { return $(this).val(); }).get(); } else { snap[id] = fields.val(); } }); sections[activeSection] = snap; } // Restores a previously saved snapshot into the form DOM. function restoreSection(snap) { $.each(PER_SECTION_STEP_IDS, function (_, id) { if (id === "dfn") { restoreDfn(snap.dfn || []); return; } if (id === "etym") { $("#wiktku-start-etym .wiktku-etym-wrap").remove(); steps.etym.build($("#wiktku-start-etym")); $("#wiktku-start-etym .wiktku-etym-text").val(snap.etym || ""); return; } if (id === "trans") { // Rebuild trans groups (dfn must already be restored by this // point in the $.each loop, so glossList() reflects it). var transDiv = $("#wiktku-start-trans"); transDiv.find(".wiktku-trans-group").remove(); steps.trans.build(transDiv); var groupsSnap = snap.trans || []; $.each(groupsSnap, function (gi, rows) { var group = transDiv.find(".wiktku-trans-group[data-gloss-pos='" + gi + "']"); if (!group.length) return; // gloss no longer exists — drop its rows var list = group.find("ul.wiktku-trans-list"); $.each(rows, function (j, row) { var lang = row[0], words = row[1]; var lastRow = list.find("li.wiktku-trans-row").last(); lastRow.find("select").val(lang).trigger("change"); var wordList = lastRow.find("ul.wiktku-trans-words"); $.each(words, function (k, word) { var wordItems = wordList.find("li"); if (k < wordItems.length) { wordItems.eq(k).find("textarea").val(word); } else { // .val() below doesn't fire "input", so the normal // auto-grow never runs — append a matching item // ourselves instead of silently dropping the word. var extraInput = steps.trans.makeWordInput(); wordList.append($("<li></li>").append(extraInput)); extraInput.val(word); } }); // Leave one trailing empty field so the row can still grow // when the user types, matching a freshly-built row. if ($.trim(wordList.children("li").last().find("textarea").val())) { wordList.append($("<li></li>").append(steps.trans.makeWordInput())); } }); }); return; } if (id === "zarava") { // Rebuild zarava groups (dfn must already be restored by this // point in the $.each loop, so glossList() reflects it). var zaravaDiv = $("#wiktku-start-zarava"); zaravaDiv.find(".wiktku-zarava-group").remove(); steps.zarava.build(zaravaDiv); var zaravaGroupsSnap = snap.zarava || []; $.each(zaravaGroupsSnap, function (gi, rows) { var group = zaravaDiv.find(".wiktku-zarava-group[data-gloss-pos='" + gi + "']"); if (!group.length) return; // gloss no longer exists — drop its rows var list = group.find("ul.wiktku-zarava-list"); $.each(rows, function (j, row) { var lang = row[0], words = row[1]; var lastRow = list.find("li.wiktku-zarava-row").last(); lastRow.find("select").val(lang).trigger("change"); var wordList = lastRow.find("ul.wiktku-zarava-words"); $.each(words, function (k, word) { var wordItems = wordList.find("li"); if (k < wordItems.length) { wordItems.eq(k).find("textarea").val(word); } else { var extraInput = steps.zarava.makeWordInput(); wordList.append($("<li></li>").append(extraInput)); extraInput.val(word); } }); if ($.trim(wordList.children("li").last().find("textarea").val())) { wordList.append($("<li></li>").append(steps.zarava.makeWordInput())); } }); }); return; } if (id === "dunde") { // Rebuild dunde rows. var dundeDiv = $("#wiktku-start-dunde"); dundeDiv.find("ul.wiktku-dunde-list").remove(); steps.dunde.build(dundeDiv); var dundeRows = snap.dunde || []; $.each(dundeRows, function (i, row) { var lang = row[0], words = row[1]; var list = dundeDiv.find("ul.wiktku-dunde-list"); var lastRow = list.find("li.wiktku-dunde-row").last(); lastRow.find("select").val(lang).trigger("change"); var wordList = lastRow.find("ul.wiktku-dunde-words"); $.each(words, function (j, word) { var wordItems = wordList.find("li"); if (j < wordItems.length) { wordItems.eq(j).find("textarea").val(word); } else { // .val() below doesn't fire "input", so the normal // auto-grow never runs — append a matching item // ourselves instead of silently dropping the word. var extraInput = steps.dunde.makeWordInput(); wordList.append($("<li></li>").append(extraInput)); extraInput.val(word); } }); // Leave one trailing empty field so the row can still grow // when the user types, matching a freshly-built row. if ($.trim(wordList.children("li").last().find("textarea").val())) { wordList.append($("<li></li>").append(steps.dunde.makeWordInput())); } }); return; } var step = steps[id]; if (!step) return; var stepDiv = $("#wiktku-start-" + id); var fields = stepDiv.find(".wiktku-start-step-field"); var val = snap[id]; if (val === undefined || val === null) return; if (step.multiple) { var arr = val; fields.each(function (i) { if (i < arr.length) $(this).val(arr[i]); }); } else { fields.val(val); } // Notify chosen widgets of the programmatic value change. if (!isMobile) fields.filter("select").trigger("chosen:updated"); }); } function getWikitextForCurrentSection(callback) { var values = getValues(); var entry = steps.pos.output(values); steps.dfn.getOutput(values, function (output) { entry += output; entry += steps.je.output(values); entry += steps.tekildar.output(values); entry += steps.etym.output(values); entry += steps.dunde.output(values); entry += steps.binereherwiha.output(values); entry += steps.zarava.output(values); entry += steps.trans.output(values); callback(entry, values); }); } function getWikitextAllSections(callback) { saveCurrentSection(); var results = new Array(sections.length); var sharedValues = getValues(); // lang/pron are shared function processSection(i) { if (i >= sections.length) { // All done — restore original active section. restoreSection(sections[activeSection]); refresh(); callback(results, sharedValues); return; } restoreSection(sections[i]); refresh(); getWikitextForCurrentSection(function (sectionText) { results[i] = sectionText; processSection(i + 1); }); } processSection(0); } // Assembles wikitext for all sections plus the shared lang/pron header. function getWikitext(callback) { getWikitextAllSections(function (sectionTexts, sharedValues) { var entry = steps.lang.output(sharedValues); entry += steps.pron.output(sharedValues); entry += sectionTexts.join("\n"); // Edit summary uses section 0's values. Read from the saved snapshot // (not the live DOM) so it doesn't mix section 0's pos with whichever // section happens to be active/restored at this point. var dfnSenses = (sections[0] && sections[0].dfn) || []; var dfnSummary = dfnSenses.map(function (s) { return s.mane; }).filter(Boolean).join("; "); var summary = "([[Mediawiki:Gadget-start.js|WF:NÛ]] v.2.0) +" + sharedValues.lang + ":" + sections[0].pos + ":" + dfnSummary; var summaryField = document.getElementById("wpSummary"); if (addLangMode && summaryField.value) { summary = summaryField.value + " " + summary; } summaryField.value = summary; callback(entry); }); } var continueBtn; function getValuesForStep(stepId) { var fields = $("#wiktku-start-" + stepId + " .wiktku-start-step-field"); var step = steps[stepId]; if (step.keys) { var values = {}; fields.each(function (i, field) { var key = $(field).prevAll(".wiktku-start-step-keyfield").val(); if (key) values[key] = $(field).val(); }); return values; } else if (step.multiple) { return fields.map(function () { return $(this).val(); }).get(); } return fields.val(); } function getValues() { var values = {}; $.each(steps, function (stepId) { values[stepId] = getValuesForStep(stepId); }); return values; } function populateMenus(inputs, choices, disabledValues) { if (!disabledValues) disabledValues = {}; var vals = inputs.map(function (i, input) { return $(input).val(); }); inputs.empty(); inputs.append($("<option></option>")); $.each(choices, function (j, choice) { // Append the language code in parentheses so that typing a code // (e.g. "ku") in the search box still finds the language name. var displayText = capitalize(choice[1]); if (choice[2] !== undefined) { // This is a language choice [code, name, sortKey] — show code. displayText = capitalize(choice[1]) + " (" + choice[0] + ")"; } var option = $(mw.html.element("option", { value: choice[0] }, displayText)); if (disabledValues[choice[0]]) option.prop("disabled", true); inputs.append(option); }); inputs.val(function (i) { return vals[i]; }); } // Keys to disable for a key menu: already-taken or explicitly disabled. function getDisabledKeys(step) { var occupiedKeys = {}; $("#wiktku-start-" + step.id + " .wiktku-start-step-keyfield").each(function () { occupiedKeys[$(this).val()] = true; }); if (step.disabledKeys) $.extend(occupiedKeys, step.disabledKeys); return occupiedKeys; } function buildKeyInput(step) { if (!step.keys) return undefined; var input = $(mw.html.element("select", { "class": "wiktku-start-step-keyfield wiktku-start-narrow" })); input.attr("data-placeholder", "Hilbijêre " + step.keyName); if (isMobile) { populateMenus(input, step.keys, getDisabledKeys(step)); // On mobile return the wrapper; the select is inside it. // Change events still fire on the inner select. return wrapNativeSelect(input); } input.on("chosen:showing_dropdown", function () { $(this).data("wiktku-defaultValue", $(this).val()); }); input.change(function (_, context) { var inputs = $("#wiktku-start-" + step.id + " .wiktku-start-step-keyfield").not(this); var oldValue = $(this).data("wiktku-defaultValue"); var newValue = context.selected; inputs.find("option[value='" + oldValue + "']").prop('disabled', false); inputs.find("option[value='" + newValue + "']").prop('disabled', true); inputs.trigger("chosen:updated"); }); populateMenus(input, step.keys, getDisabledKeys(step)); return input; } // Adds another text field to the list if the last one now has text. function refreshForTextField(currentInput, step) { currentInput = $(currentInput); var value = currentInput.val(); var item = currentInput.parent(); if (value && !item.next("li").length) { var nextInput = $("<textarea></textarea>") .attr("name", "wiktku-field-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("class", currentInput.attr("class")) .attr("rows", currentInput.attr("rows") || 1); nextInput.on("input", function (evt) { refreshForTextField(evt.target, step); }); var nextKeyInput = buildKeyInput(step); var nextItem = $("<li></li>").append(nextKeyInput).append(nextInput); item.parent().append(nextItem); if (nextKeyInput) nextKeyInput.chosen(chosenOptions); } var canContinue = !continueBtn.isDisabled(); if ((value && !canContinue) || (!value && canContinue)) { refresh(step); } } function prepareInput(input, step) { if (!input) return; if (step.required) input.prop('required', true); input.change(step, refresh); } // Shows/hides steps based on whether their prerequisites are met, and // updates placeholders where applicable. function refresh(evt) { var values = getValues(); var changedStep = evt && evt.data; var didFocus = false; var canContinue = true; // Re-filter template options in every sense block whenever lang changes. $("#wiktku-start-dfn .wiktku-dfn-tpl-select").each(function () { var fn = $(this).data("updateOptions"); if (typeof fn === "function") fn(); }); // Re-filter pronunciation and etymology template dropdowns when language changes. steps.pron.refreshTplSelect(); steps.etym.refreshTplSelect(); // Sync tr/t sub-fields in every nimûne item to the current language. // tr shown when language needs transliteration; t shown when lang !== "ku". (function () { var lang = values.lang || ""; var showTr = needsTransliteration(lang); var showT = lang && lang !== "ku"; $("#wiktku-start-dfn .wiktku-dfn-nimune-list li.wiktku-dfn-nimune-li").each(function () { var li = $(this); // Ensure the sub-wrapper exists when we need it. var subWrap = li.find(".wiktku-dfn-nimune-sub"); // tr field var trTa = li.find(".wiktku-dfn-nimune-tr"); if (showTr && !trTa.length) { if (!subWrap.length) { subWrap = $("<div></div>").addClass("wiktku-dfn-nimune-sub"); li.append(subWrap); } trTa = $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-tr-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 5) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-tr") .attr("placeholder", "Transkrîpsiyon…"); subWrap.prepend(trTa); } else if (!showTr && trTa.length) { trTa.remove(); } // t field var tTa = li.find(".wiktku-dfn-nimune-t"); if (showT && !tTa.length) { if (!subWrap.length) { subWrap = $("<div></div>").addClass("wiktku-dfn-nimune-sub"); li.append(subWrap); } tTa = $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-t-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 5) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-t") .attr("placeholder", "Tercimeya nimûneyê kurmancî…"); subWrap.append(tTa); } else if (!showT && tTa.length) { tTa.remove(); } // Remove the wrapper if it ended up empty. subWrap = li.find(".wiktku-dfn-nimune-sub"); if (subWrap.length && !subWrap.children().length) subWrap.remove(); }); }()); // Sync tr/t sub-fields in every jêder citation to the current language. // tr shown when language needs transliteration; t shown when lang !== "ku". (function () { var lang = values.lang || ""; var showTr = needsTransliteration(lang); var showT = lang && lang !== "ku"; $("#wiktku-start-dfn .wiktku-dfn-jeder-list li.wiktku-dfn-jeder-li").each(function () { var li = $(this); // Ensure the sub-wrapper exists when we need it. It must sit right // after the quote textarea and before the source selector. var subWrap = li.find(".wiktku-dfn-quote-sub"); // tr field var trTa = li.find(".wiktku-dfn-nimune-quote-tr"); if (showTr && !trTa.length) { if (!subWrap.length) { subWrap = $("<div></div>").addClass("wiktku-dfn-quote-sub"); li.find(".wiktku-dfn-nimune-quote").after(subWrap); } trTa = $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-quote-tr-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 2) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-quote-tr") .attr("placeholder", "Transkrîpsiyona jêgirtinê…"); subWrap.prepend(trTa); } else if (!showTr && trTa.length) { trTa.remove(); } // t field var tTa = li.find(".wiktku-dfn-nimune-quote-t"); if (showT && !tTa.length) { if (!subWrap.length) { subWrap = $("<div></div>").addClass("wiktku-dfn-quote-sub"); li.find(".wiktku-dfn-nimune-quote").after(subWrap); } tTa = $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-quote-t-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 2) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-quote-t") .attr("placeholder", "Tercimeya jêgirtinê ya kurmancî…"); subWrap.append(tTa); } else if (!showT && tTa.length) { tTa.remove(); } // Remove the wrapper if it ended up empty. subWrap = li.find(".wiktku-dfn-quote-sub"); if (subWrap.length && !subWrap.children().length) subWrap.remove(); }); }()); $.each(steps, function (stepId, step) { if (typeof(step.visible) === "function" && !step.visible(values)) { $("#wiktku-start-" + stepId).slideUp(); } else { var stepDiv = $("#wiktku-start-" + stepId); if (changedStep !== step && typeof(step.build) === "function") { prepareInput(step.build(stepDiv, values), step); } var input = stepDiv.find(".wiktku-start-step-field"); if (typeof(step.example) === "function") { // .find() above already reaches nested fields (e.g. the dfn // step's mane textareas inside each sense block), so one // assignment covers every step; dfn keeps its own fallback. var exampleText = step.example(values) || (step.id === "dfn" ? "Mane…" : ""); input.attr("placeholder", exampleText); } var didSlideDown; if (!didFocus && stepDiv.css("display") === "none" && step.required) { didSlideDown = function (evt) { input.focus(); }; didFocus = true; } stepDiv.slideDown(didSlideDown); } if (step.required && (values[stepId] === "" || (step.multiple && values[stepId].join("") === ""))) { canContinue = false; } }); continueBtn.setDisabled(!canContinue); } function destroy() { $("#wiktku-start-form, .noafterwizard").slideUp(function () { $(this).remove(); }); $(".noarticletext .nowizard, #editform").slideDown(); $("#ca-edit").removeClass("selected"); $("#ca-wiktku-nowizard").addClass("selected"); } // Priority order for Kurdish dialects and the navz pseudo-code. // Codes listed here come before all other languages; unlisted codes // are sorted alphabetically by their display name via localeCompare. var LANG_PRIORITY = ["navz", "ku", "hac", "sdh", "lki", "ckb", "zza"]; // Inserts a new "== {{ziman|code}} ==" section at the correct sorted // position: navz, then ku/hac/sdh/lki/ckb/zza, then alphabetical by name. function insertNewLangSection(existing, wikitext) { var newCodeMatch = wikitext.match(new RegExp("^" + langHeaderSource("[^}]+"))); var newCode = newCodeMatch ? newCodeMatch[1] : ""; var sections = []; var preamble = ""; var anyHeaderSrc = langHeaderSource("[^}]+"); var firstMatch = new RegExp("^" + anyHeaderSrc, "m").exec(existing); if (!firstMatch) { // No existing lang sections at all — just append. var sep = existing && !/\n\s*$/.test(existing) ? "\n\n" : ""; return existing + sep + wikitext; } // Everything before the first == {{ziman|...}} == is the preamble. var firstSectionStart = firstMatch.index; // Walk back to the start of that line. var lineStart = existing.lastIndexOf("\n", firstSectionStart - 1); var preambleEnd = lineStart !== -1 ? lineStart + 1 : 0; preamble = existing.slice(0, preambleEnd); // Parse each language section: header line + everything until the next header. var body = existing.slice(preambleEnd); // (?![\s\S]) matches only true end-of-string, since a bare "$" with // /m would stop at the section's first line break instead. var langSectionRe = new RegExp( "^(" + anyHeaderSrc + "\\n?)([\\s\\S]*?)(?=\\n" + anyHeaderSrc + "|(?![\\s\\S]))", "gm" ); var m; while ((m = langSectionRe.exec(body)) !== null) { sections.push({ code: m[2], content: m[0] // full text of this section including header }); } // Determine sort rank: priority list first (by index), then alphabetical. function getLangName(code) { var entry = langsByCode[code]; return entry ? entry[1] : code; } function sortRank(code) { var idx = LANG_PRIORITY.indexOf(code); return idx !== -1 ? idx : LANG_PRIORITY.length; } function compareLangs(a, b) { var ra = sortRank(a), rb = sortRank(b); if (ra !== rb) return ra - rb; // Both are outside priority list — sort by display name. return getLangName(a).localeCompare(getLangName(b), userLang); } // Insert the new section into the sorted list. var newSection = { code: newCode, content: wikitext }; var inserted = false; for (var i = 0; i < sections.length; i++) { if (compareLangs(newCode, sections[i].code) < 0) { sections.splice(i, 0, newSection); inserted = true; break; } } if (!inserted) sections.push(newSection); // Re-join: preamble + sections separated by newlines. var joined = sections.map(function (s) { // Ensure each section ends with exactly one newline before the next. return s.content.replace(/\n+$/, ""); }).join("\n"); return preamble + joined + "\n"; } function build() { $(".nowizard, .nowizard .noafterwizard").hide(); var callToAction = $("#wiktku-calltoaction"); var origCallToActionText = callToAction.text(); $(mw.util.addPortletLink("p-views", "#", "Edîtora çavkaniyê veke", "ca-wiktku-nowizard", "Vê rûpelê bi edîtora çavkaniyê çêke", undefined, "#ca-watch")).click(function (evt) { evt.preventDefault(); callToAction.text(origCallToActionText); destroy(); }); if (callToAction.length) { callToAction.text(origCallToActionText + " Forma li jêr ji bo çêkirina madeyeke nû bi kar bîne."); } var startForm = $("<form id='wiktku-start-form'></form>"); var clearPageCheck = null; if (addLangMode) { startForm.append($("<p class='wiktku-addlang-notice'></p>").html( "Bi vê formê tu yê beşeke nû li rûpelê îlawe bikî. Eger ev zimanê ku tu îlawe dikî jixwe di rûpelê de hebe, beşa nû li dawiya vî zimanî dê were îlawekirin. " + "Ji kerema xwe netîceya dawî kontrol bikin, eger problemek derkeve, li <a href='" + mw.util.getUrl('Mediawiki talk:Gadget-start.js') + "'>nîqaşa vê amûrê</a> problemê ragihîne." )); clearPageCheck = $("<input type='checkbox' id='wiktku-clear-page-check'>"); var clearPageLabel = $("<label for='wiktku-clear-page-check'></label>") .text(" Naveroka rûpelê paqij bike (rûpelê ji nû ve binivîse)"); startForm.append( $("<p class='wiktku-addlang-notice'></p>") .append(clearPageCheck) .append(clearPageLabel) ); // Re-evaluate step visibility (e.g. the pron step) whenever this // is toggled, since it changes what counts as "existing content". clearPageCheck.on("change", function () { refresh(); }); } var spinner; // Tab bar for switching between POS sections. var sectionTabsDiv = $("<div id='wiktku-section-tabs'></div>"); startForm.submit(function (evt) { evt.preventDefault(); continueBtn.setDisabled(true); spinner.show(); getWikitext(function (wikitext) { if (addLangMode && clearPageCheck && clearPageCheck.prop("checked")) { // User asked to wipe the page and start fresh — just // write the newly generated wikitext as the full content. $("#wpTextbox1").val(wikitext); } else if (addLangMode) { var textbox = $("#wpTextbox1"); var existing = textbox.val() || ""; // If this language's section already exists (whitespace // differences aside), merge into it; otherwise insert new. var langHeaderMatch = wikitext.match(new RegExp("^(" + langHeaderSource("[^}]+") + "\\n)")); if (langHeaderMatch) { var langHeader = langHeaderMatch[1]; // e.g. "== {{ziman|ku}} ==\n" var newCode = langHeaderMatch[2]; var existingHeader = findLangHeader(existing, newCode); if (existingHeader) { // Strip the header from the new output. var newContent = wikitext.slice(langHeader.length); // Find the insertion point: end of the existing lang section. // A new L2 heading marks the start of the next language block. var searchFrom = existingHeader.index + existingHeader.match.length; // Find the next == … == heading after this section's start. var nextL2 = existing.indexOf("\n== ", searchFrom); var insertAt = nextL2 !== -1 ? nextL2 : existing.length; // Ensure there's a blank line before the inserted block. var before = existing.slice(0, insertAt); var after = existing.slice(insertAt); var sep = /\n\s*$/.test(before) ? "" : "\n"; textbox.val(before + sep + newContent + after); } else { // New language — insert at the correct sorted position. textbox.val(insertNewLangSection(existing, wikitext)); } } else { // Unexpected format — insert at sorted position anyway. textbox.val(insertNewLangSection(existing, wikitext)); } } else { $("#wpTextbox1").val(wikitext); } $("html, body").animate({scrollTop: 0}); callToAction.text("Hindik ma!"); $("#wiktku-preview-container").remove(); destroy(); }); }); $.each(ordered_steps, function (i, step) { var stepDiv = $(mw.html.element("div", { "class": "wiktku-start-step", id: "wiktku-start-" + step.id })); var name = capitalize(step.name); stepDiv.append($(mw.html.element("h3", { "class": "wiktku-start-step-name" }, new mw.html.Raw(mw.html.element("label", { "for": "wiktku-start-" + step.id + "-field" }, name))))); if (step.question_fmt) { stepDiv.append($(mw.html.element("label", { "class": "wiktku-start-step-question", "for": "wiktku-start-" + step.id + "-field" }, step.question_fmt))); if (step.question_br) stepDiv.append($("<br>")); } var input; if (step.choices) { input = $(mw.html.element("select", { "class": "wiktku-start-step-field", id: "wiktku-start-" + step.id + "-field" })); input.attr("data-placeholder", capitalize(step.name) + " hilbijêre "); populateMenus(input, step.choices); if (step.multiple) input.attr("multiple", true); if (isMobile) { stepDiv.append(wrapNativeSelect(input)); } else { stepDiv.append(input); } } else if (typeof(step.build) === "function") { input = step.build(stepDiv); } else { input = $("<textarea></textarea>") .attr("class", "wiktku-start-step-field") .attr("id", "wiktku-start-" + step.id + "-field") .attr("rows", step.rows || 2); if (step.narrow) input.addClass("wiktku-start-narrow"); if (step.multiple) { input.on("input", function (evt) { refreshForTextField(evt.target, step); }); var keyInput = buildKeyInput(step); var list = $(step.ordered ? "<ol></ol>" : "<ul></ul>") .append($("<li></li>").append(keyInput).append(input)); stepDiv.append(list); } else stepDiv.append(input); } prepareInput(input, step); stepDiv.hide(); // Insert tab bar just before the first per-section step. if (step.id === "pos") startForm.append(sectionTabsDiv); startForm.append(stepDiv); }); // ── Section tab helpers ────────────────────────────────────────────── // ── Add-section button — lives in the tab bar, disabled until pos chosen ── var addSectionBtn = new OO.ui.ButtonWidget({ label: "+ Beş zêde bike", disabled: true }); addSectionBtn.on("click", function () { saveCurrentSection(); sections.push({}); activeSection = sections.length - 1; $.each(PER_SECTION_STEP_IDS, function (_, id) { if (id === "dfn") { var stepDiv = $("#wiktku-start-dfn"); stepDiv.find("ol.wiktku-dfn-list").remove(); steps.dfn.build(stepDiv); return; } if (id === "etym") { $("#wiktku-start-etym .wiktku-etym-wrap").remove(); steps.etym.build($("#wiktku-start-etym")); return; } if (id === "trans") { var transDiv = $("#wiktku-start-trans"); transDiv.find(".wiktku-trans-group").remove(); return; } if (id === "zarava") { var zaravaDiv = $("#wiktku-start-zarava"); zaravaDiv.find(".wiktku-zarava-group").remove(); return; } if (id === "dunde") { var dundeDiv = $("#wiktku-start-dunde"); dundeDiv.find("ul.wiktku-dunde-list").remove(); return; } var stepDiv = $("#wiktku-start-" + id); stepDiv.find(".wiktku-start-step-field").val(""); if (!isMobile) stepDiv.find("select.wiktku-start-step-field").trigger("chosen:updated"); }); renderSectionTabs(); refresh(); $("html, body").animate({ scrollTop: sectionTabsDiv.offset().top - 20 }, 300); }); /** Re-render the tab bar to reflect current sections[] and activeSection. */ function renderSectionTabs() { // Detach (not remove) the button first: .empty() strips bound // event data from any children left inside it, which would // silently kill addSectionBtn's click handler on every re-render. addSectionBtn.$element.detach(); sectionTabsDiv.empty(); var lang = getValues().lang || ""; if (!lang) { sectionTabsDiv.hide(); return; } sectionTabsDiv.show(); $.each(sections, function (i) { var posVal = sections[i].pos || ""; var tabLabel = posVal ? capitalize(posVal) : ("Beş " + (i + 1)); var tab = $("<span></span>") .addClass("wiktku-section-tab") .text(tabLabel) .toggleClass("wiktku-tab-active", i === activeSection); (function (idx) { tab.on("click", function () { if (idx === activeSection) return; saveCurrentSection(); activeSection = idx; restoreSection(sections[activeSection]); refresh(); renderSectionTabs(); }); }(i)); sectionTabsDiv.append(tab); }); // Enable "Beş zêde bike" only when the active section has a pos chosen. var activePos = sections[activeSection] && sections[activeSection].pos ? sections[activeSection].pos : getValues().pos; addSectionBtn.setDisabled(!activePos); sectionTabsDiv.append(addSectionBtn.$element); } renderSectionTabs(); // Update the active tab's label whenever pos changes. startForm.on("change", "#wiktku-start-pos-field", function () { renderSectionTabs(); }); // Show the tab bar as soon as a language is selected. startForm.on("change", "#wiktku-start-lang-field", function () { renderSectionTabs(); }); var footer = $("<div id='wiktku-start-footer'></div>"); spinner = $(mw.html.element("img", { id: "wiktku-start-spinner", src: "//upload.wikimedia.org/wikipedia/commons/d/de/Ajax-loader.gif", alt: "Tê barkirin…", title: "Tê barkirin…" })); footer.append(spinner.hide()); continueBtn = new OO.ui.ButtonWidget({ id: "wiktku-unhide-editform", label: "Bişîne", flags: [ "primary", "progressive" ] }); continueBtn.on("click", function () { mw.notify("Tê şandin…", { type: "info", tag: "wiktku-submit" }); startForm.trigger("submit"); }); footer.append(continueBtn.$element); // "Edîtora çavkaniyê veke" button — inline fallback for the portlet link // which is invisible on mobile and easy to miss on desktop. var sourceEditorBtn = new OO.ui.ButtonWidget({ label: "Edîtora çavkaniyê veke", framed: false }); sourceEditorBtn.on("click", function () { destroy(); }); footer.append(sourceEditorBtn.$element); // ── Preview checkboxes ─────────────────────────────────────────────── // Wikitext preview (raw text panel) var previewCheck = $("<input type='checkbox' id='wiktku-preview-toggle'>"); var previewLabel = $("<label for='wiktku-preview-toggle'></label>") .text(" Pêşdîtina wîkîtekstê"); var previewPanel = $("<pre id='wiktku-preview-panel'></pre>").hide(); // Live rendered preview (parsed HTML panel, same logic as AjaxEdit). // Not available on mobile — API polling causes too many problems on small screens. var livePreviewCheck = null; var livePreviewPanel = null; if (!isMobile) { livePreviewCheck = $("<input type='checkbox' id='wiktku-live-preview-toggle'>"); livePreviewPanel = $("<div id='wiktku-live-preview-panel'></div>").hide(); } // Container that holds both panels and switches between stacked / side-by-side. var previewContainer = $("<div id='wiktku-preview-container'></div>"); previewContainer.append(previewPanel); if (!isMobile) previewContainer.append(livePreviewPanel); var previewTimer = null; var livePreviewIntervalId = -1; var livePreviewActive = false; // guards in-flight fetches after uncheck /** Rebuilds wikitext preview if its checkbox is checked. */ function schedulePreview() { if (!previewCheck.prop("checked")) return; clearTimeout(previewTimer); // Debounce: wait 400 ms after the last keystroke before rebuilding. previewTimer = setTimeout(function () { getWikitext(function (wikitext) { previewPanel.text(wikitext).show(); updatePanelLayout(); }); }, 400); } /** Fetches parsed HTML and populates the live preview panel. */ function loadLivePreview() { getWikitext(function (wikitext) { new mw.Api().parse(wikitext, { title: mw.config.get("wgPageName") }).done(function (html) { // Discard result if the user unchecked while the fetch was in flight. if (!livePreviewActive) return; livePreviewPanel.html(html).show(); updatePanelLayout(); }); }); } /** Adjusts panel widths depending on which previews are visible. */ function updatePanelLayout() { var wikitextVisible = previewCheck.prop("checked"); var liveVisible = livePreviewCheck && livePreviewCheck.prop("checked"); if (wikitextVisible && liveVisible) { // Side by side — each panel takes roughly half the available width. previewPanel.css({ "flex": "1 1 45%", "min-width": "280px" }); livePreviewPanel.css({ "flex": "1 1 45%", "min-width": "280px" }); } else { // Full width for whichever is visible — only touch panels that are // actually shown so that setting flex doesn't override display:none. if (wikitextVisible) previewPanel.css({ "flex": "1 1 100%", "min-width": "" }); if (liveVisible && livePreviewPanel) livePreviewPanel.css({ "flex": "1 1 100%", "min-width": "" }); } } previewCheck.on("change", function () { if ($(this).prop("checked")) { schedulePreview(); } else { clearTimeout(previewTimer); previewPanel.hide(); updatePanelLayout(); } }); if (!isMobile) { livePreviewCheck.on("change", function () { if ($(this).prop("checked")) { livePreviewActive = true; livePreviewPanel.show(); loadLivePreview(); livePreviewIntervalId = setInterval(loadLivePreview, 500); } else { livePreviewActive = false; clearInterval(livePreviewIntervalId); livePreviewIntervalId = -1; livePreviewPanel.hide().empty(); updatePanelLayout(); } }); } // Listen on all input/change events on the form and update both previews. startForm.on("input change", function () { schedulePreview(); }); footer.append($("<span style='margin-left:1em'></span>") .append(previewCheck).append(previewLabel)); if (!isMobile) { var livePreviewLabel = $("<label for='wiktku-live-preview-toggle'></label>") .text(" Pêşdîtina zindî"); footer.append($("<span style='margin-left:1em'></span>") .append(livePreviewCheck).append(livePreviewLabel)); } startForm.append(footer); $("#editform").hide().before(startForm); // Insert preview container (holds both panels) after the form. startForm.after(previewContainer); if (!isMobile) startForm.find("select").chosen(chosenOptions); refresh(); // Zimanan ji MediaWiki:Gadget-translation_editor.js/ziman.json bar bike. // Kodên ku bi "-pro" diqedin û navên ku "zimanê destan" tê de heye // tên derxistin. Zimanên xardkirî li serî dimînin, yên din // bi alfabeyê li dû wan tên. // Pinned choices come from MediaWiki:Gadget-start.js/data.json (langChoices), // already loaded into steps.lang.choices before build() runs. var pinnedChoices = steps.lang.choices.slice(); var pinnedCodes = $.map(pinnedChoices, function (choice) { return choice[0]; }); new mw.Api().get({ action: "query", prop: "revisions", titles: "MediaWiki:Gadget-translation_editor.js/ziman.json", rvprop: "content", rvslots: "main", formatversion: 2 }).then(function (data) { var page = data.query.pages[0]; var content = page && page.revisions && page.revisions[0].slots.main.content; var zimanData; try { zimanData = JSON.parse(content); } catch (e) { zimanData = {}; } var extraChoices = []; $.each(zimanData, function (code, name) { // Filter: skip proto-language codes and legendary/reconstructed langs. if (/-pro$/i.test(code)) return; if (/ziman[eê]\s+destan/i.test(name)) return; // Skip codes already in the pinned list (they are handled above). if (pinnedCodes.indexOf(code) !== -1) return; // sortKey: bare name without leading "zimanê " for sorting. var sortKey = name.replace(/^ziman[eê]\s+/i, ""); var choice = [code, name, sortKey]; extraChoices.push(choice); langsByCode[code] = choice; }); // Populate langsByCode for pinned choices too. $.each(pinnedChoices, function (i, choice) { // Ensure pinned choices have a sortKey (index 2). if (choice.length < 3) choice[2] = choice[1]; langsByCode[choice[0]] = choice; }); // Sort the extra choices alphabetically by sort key. extraChoices.sort(function (a, b) { return a[2].localeCompare(b[2], userLang); }); // Final list: pinned first, then the rest. var allChoices = pinnedChoices.concat(extraChoices); steps.lang.choices = allChoices; steps.trans.keys = allChoices; steps.dunde.keys = allChoices; steps.zarava.keys = getZaravaKeys(allChoices); var langMenu = $("#wiktku-start-lang-field"); populateMenus(langMenu, steps.lang.choices); langMenu.trigger("chosen:updated"); var transMenus = $("#wiktku-start-trans .wiktku-start-step-keyfield"); populateMenus(transMenus, steps.trans.keys, getDisabledKeys(steps.trans)); transMenus.trigger("chosen:updated"); var dundeMenus = $("#wiktku-start-dunde .wiktku-start-step-keyfield"); populateMenus(dundeMenus, steps.dunde.keys, getDisabledKeys(steps.dunde)); dundeMenus.trigger("chosen:updated"); var zaravaMenus = $("#wiktku-start-zarava .wiktku-start-step-keyfield"); populateMenus(zaravaMenus, steps.zarava.keys, getDisabledKeys(steps.zarava)); }); } mw.loader.using(["jquery.chosen", "mediawiki.api", "oojs-ui-core"], function () { if (!isMobile) { mw.notify( "Amûr dest pê dike, hinek bisekinin. Not: jkx Sentaks (sentaks highlighter) neaktîv bikin", { type: "info", tag: "wiktku-start-notice", autoHide: true, autoHideSeconds: 10 } ); } // Load metadata, langChoices, posChoices and tplDefs from the companion // data page so they can be updated without touching this script. new mw.Api().get({ action: "query", prop: "revisions", titles: "MediaWiki:Gadget-start.js/data.json", rvprop: "content", rvslots: "main", formatversion: 2 }).then(function (data) { var page = data.query.pages[0]; var content = page && page.revisions && page.revisions[0].slots.main.content; var d; try { d = JSON.parse(content); } catch (e) { d = {}; } // Populate metadata. if (d.metadata) $.extend(metadata, d.metadata); // Populate gender labels. if (d.genderLabels) $.extend(GENDER_BASE_LABELS, d.genderLabels); // Populate lang choices (pinned list used by build() → ziman.json loader). if (d.langChoices) steps.lang.choices = d.langChoices; // Populate POS choices. if (d.posChoices) steps.pos.choices = d.posChoices; // Populate template definitions for the dfn sense-block builder. if (d.tplDefs) steps.dfn.tplDefs = d.tplDefs; // Populate pos placeholder examples. if (d.posExamples) steps.dfn.posExamples = d.posExamples; // Populate citation template definitions for the quote widget. if (d.jederDefs) steps.dfn.jederDefs = d.jederDefs; // Populate pronunciation and etymology template insert lists. if (d.pronTpls) { steps.pron.pronTpls = d.pronTpls; steps.pron.refreshTplSelect(); } if (d.etymTpls) { steps.etym.etymTpls = d.etymTpls; steps.etym.refreshTplSelect(); } // Sync trans/dunde/zarava keys with the (now populated) lang choices. steps.trans.keys = steps.lang.choices; steps.dunde.keys = steps.lang.choices; steps.zarava.keys = getZaravaKeys(steps.lang.choices); }).always(build); }); }); //</nowiki> dnrqerspgh2760tvl85ud9h6c4wftzs 6265604 6265595 2026-07-19T15:52:14Z Wikihez 7344 6265604 javascript text/javascript // Li ser [[vi:MediaWiki:Gadget-start.js]] hatiye refaktorkirin. //<nowiki> $(function () { if (window.location.href.includes("editintro=User:Wikihez/creation/intro")) { return; // Do not run the script wextê WF:Bilez dişuxile } var ns = mw.config.get("wgNamespaceNumber"); if (ns && !(ns === 2 && mw.config.get("wgPageName").match(/\/ceribandin$|\/test$/))) { return; } var action = mw.config.get("wgAction"); var pageExists = !!mw.config.get("wgArticleId"); // "Zimanek lê zêde bike" mode: triggered from the portlet link below. var addLangMode = pageExists && mw.util.getParamValue("wiktkuaddlang") === "1"; // On a normal page view of an existing page, add the portlet link if (action === "view" && pageExists) { var targetContainer; var skin = mw.config.get('skin'); if (skin === 'vector-2022') { targetContainer = 'p-cactions'; } else if (skin === 'vector') { targetContainer = 'p-tb'; } else { targetContainer = 'p-views'; } mw.util.addPortletLink(targetContainer, mw.util.getUrl(mw.config.get("wgPageName"), { action: "submit", wiktkuaddlang: "1" }), "+Ziman/beşeke din", "ca-wiktku-addlang", "Ji vê rûpelê re ziman an jî beşeke nû zêde bike"); return; } if (!(action === "edit" || action === "submit")) { return; } if (!addLangMode && !$(".mw-newarticletext, .mw-newarticletextanon").length) { return; } function capitalize(str) { if (!str) return str; return str[0].toUpperCase() + str.substr(1); } function decapitalize(str) { if (!str) return str; return str[0].toLowerCase() + str.substr(1); } function escapeRegExp(str) { return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); } // Regex source for a "== {{ziman|CODE}} ==" header, tolerant of extra // whitespace. codePattern: escaped code for one language, or "[^}]+" for any. function langHeaderSource(codePattern) { return "==\\s*\\{\\{\\s*ziman\\s*\\|\\s*(" + codePattern + ")\\s*\\}\\}\\s*=="; } // Finds a language's header in wikitext (see langHeaderSource). Returns // { index, match } or null. function findLangHeader(text, code) { var m = new RegExp(langHeaderSource(escapeRegExp(code))).exec(text); return m ? { index: m.index, match: m[0] } : null; } function stripWikilinks(str) { return str.replace(/\[\[([^\]|]+)(?:\|([^\]]+))?\]\]/g, function (m, target, display) { return display || target; }); } function insertAtCursor(el, text) { var start = el.selectionStart; var end = el.selectionEnd; var val = el.value; el.value = val.slice(0, start) + text + val.slice(end); var pos = start + text.length; el.selectionStart = el.selectionEnd = pos; } var pageName = mw.config.get("wgPageName").replaceAll(/_/g, " "); if (ns) pageName = pageName.replace(/.*\//, ""); var pageNameRe = escapeRegExp(pageName); var userLang = mw.config.get("wgUserLanguage"); // Mobile detection: MobileFrontend sets wgMFMode, or fall back to touch check. var isMobile = !!mw.config.get("wgMFMode") || window.matchMedia("(pointer: coarse)").matches; var chosenOptions = { width: "20em", disable_search_threshold: 0, placeholder_text_single: "Yekî hilbijêre", placeholder_text_multiple: "Hilbijêre", no_results_text: "Nehat dîtin", enable_split_word_search: true, search_contains: true }; function wrapNativeSelect(select) { var placeholder = select.attr("data-placeholder") || "Lê bigere…"; // Hide the native select — we drive it programmatically. select.hide(); var wrapper = $("<span class='wiktku-native-select-wrap'></span>"); var textInput = $("<input type='search' autocomplete='off'>") .attr("placeholder", placeholder) .addClass("wiktku-start-narrow wiktku-ac-input"); var resultsList = $("<ul class='wiktku-ac-results'></ul>").hide(); // Full option cache — rebuilt when chosen:updated fires. var allOptions = []; function cacheOptions() { allOptions = []; select.find("option").each(function () { var v = $(this).val(); if (!v) return; // skip the empty placeholder option allOptions.push({ value: v, text: $(this).text(), disabled: $(this).prop("disabled") }); }); } cacheOptions(); function showResults(query) { var q = query.trim().toLowerCase(); resultsList.empty(); var matched; if (q) { matched = []; $.each(allOptions, function (_, o) { if (o.disabled) return; var codeMatch = o.value.toLowerCase().indexOf(q) !== -1; var nameMatch = o.text.toLowerCase().indexOf(q) !== -1; if (codeMatch || nameMatch) { matched.push({ opt: o, codeMatch: codeMatch }); } }); // Code matches (especially prefix matches) come first. matched.sort(function (a, b) { var aCode = a.opt.value.toLowerCase(); var bCode = b.opt.value.toLowerCase(); var aPrefix = aCode.indexOf(q) === 0; var bPrefix = bCode.indexOf(q) === 0; if (aPrefix !== bPrefix) return aPrefix ? -1 : 1; if (a.codeMatch !== b.codeMatch) return a.codeMatch ? -1 : 1; return 0; }); matched = matched.map(function (item) { return item.opt; }); } else { matched = allOptions.filter(function (o) { return !o.disabled; }); } if (!matched.length) { resultsList.hide(); return; } $.each(matched.slice(0, 50), function (_, opt) { var li = $("<li></li>").text(opt.text).attr("data-value", opt.value); // touchend (not touchstart) so a scroll doesn't trigger a select. var touchMoved = false; li.on("touchstart", function () { touchMoved = false; }); li.on("touchmove", function () { touchMoved = true; }); li.on("touchend", function (e) { if (touchMoved) return; // was a scroll, not a tap e.preventDefault(); selectOption(opt.value, opt.text); }); // Keep mousedown for desktop fallback. li.on("mousedown", function (e) { e.preventDefault(); selectOption(opt.value, opt.text); }); resultsList.append(li); }); // Position the list above or below depending on available viewport space. var inputRect = textInput[0].getBoundingClientRect(); var viewportH = window.innerHeight; var spaceBelow = viewportH - inputRect.bottom - 8; var spaceAbove = inputRect.top - 8; var maxH = Math.min(224, Math.max(spaceBelow, spaceAbove)); // 224px ≈ 14em resultsList.css({ "max-height": maxH + "px", "top": spaceBelow >= spaceAbove ? "100%" : "auto", "bottom": spaceBelow >= spaceAbove ? "auto" : "100%" }); resultsList.show(); } function selectOption(value, text) { textInput.val(text); select.val(value); resultsList.hide(); select.trigger("change"); } textInput.on("input focus", function () { showResults($(this).val()); }); textInput.on("blur", function () { // Short delay so a touchstart on a result item fires first. setTimeout(function () { resultsList.hide(); }, 200); }); // chosen:updated → re-cache (called after ziman.json loads). select.on("chosen:updated", function () { cacheOptions(); // If a value is already selected, keep the display text in sync. var cur = select.val(); if (cur) { var match = $.grep(allOptions, function (o) { return o.value === cur; })[0]; if (match) textInput.val(match.text); } }); // No-op .chosen() so desktop call-sites don't need guarding. select.chosen = function () { return select; }; wrapper.append(textInput).append(resultsList).append(select); return wrapper; } var langsByCode = {}; // Populated from [[MediaWiki:Gadget-start.js/data.json]] at runtime. var metadata = {}; // Zaravayên kurdî yên ku di beşa "Bi zaravayên din" de tên pêşkêşkirin — // ev kod ji beşa Werger têne derxistin daku heman zimên du caran neyê xwendin. var ZARAVA_LANG_CODES = ["ckb", "sdh", "lki", "hac", "zza"]; function getZaravaKeys(choices) { var byCode = {}; $.each(choices || [], function (_, c) { byCode[c[0]] = c; }); var result = []; $.each(ZARAVA_LANG_CODES, function (_, code) { if (byCode[code]) result.push(byCode[code]); }); return result; } function needsTransliteration(langCode) { var meta = metadata[langCode]; if (!meta || !meta.sc) return false; var scripts = Array.isArray(meta.sc) ? meta.sc : [meta.sc]; return scripts.length > 0 && scripts[0] !== "Latn"; } // Kodên cinsiyetê yên di metadata.g de — ji data.json tê dagirtin var GENDER_BASE_LABELS = {}; // Sub-lists that only make sense for a plain (non-şablon) sense — hidden // when a şablon (e.g. {{guharto|…}}) is chosen for that sense, since a // template-based sense has no "own" gloss for alternate forms, synonyms, // antonyms, coordinate terms, hypernyms or hyponyms to attach to. Etîket, // Nimûne and Jêgirtin stay visible either way. var HIDDEN_ON_TPL_GROUPS = [ "wiktku-dfn-alternativ", "wiktku-dfn-hevmane", "wiktku-dfn-dijmane", "wiktku-dfn-koordine", "wiktku-dfn-jornav", "wiktku-dfn-jernav" ]; function genderLabel(code) { if (code === "p") return "Pirjimar"; var pluralMatch = code.match(/^(.+)-p$/); if (pluralMatch && GENDER_BASE_LABELS[pluralMatch[1]]) { return GENDER_BASE_LABELS[pluralMatch[1]] + " (pirjimar)"; } return GENDER_BASE_LABELS[code] || code; } // True if a sense has content beyond mane worth keeping (etîket, word // lists, nimûne, jêder) — so it's still emitted with {{mane?}} if empty. function senseHasExtraContent(s) { if (s.etiket && $.grep(s.etiket, function (e) { return $.trim(e) !== ""; }).length) return true; if (s.kategori && $.grep(s.kategori, function (k) { return $.trim(k) !== ""; }).length) return true; if (s.alternativ.length || s.hevmane.length || s.dijmane.length || s.koordine.length || s.jornav.length || s.jernav.length) return true; if (s.nimune && $.grep(s.nimune, function (n) { return (typeof n === "object" ? n.text : n) !== ""; }).length > 0) return true; if (senseHasJeder(s)) return true; return false; } // Each nimûne item can be { text, tr, t }: text, transliteration, translation. function formatNimune(nimunes, lang, hasJeder) { var hasNimune = nimunes && $.grep(nimunes, function (n) { return (typeof n === "object" ? n.text : n) !== ""; }).length > 0; if (!hasNimune) { return hasJeder ? "" : "\n#* {{bênimûne|" + lang + "}}"; } return $.map(nimunes, function (n) { var text = typeof n === "object" ? n.text : n; if (!text) return undefined; var bolded = text.replace( new RegExp("(" + pageNameRe + "([^( |,|;|\\?|\\.|\\!)]+)?)", "ig"), "'''$1'''"); var tpl = "\n#: {{nm|" + lang + "|" + bolded; if (typeof n === "object") { if (n.tr) tpl += "|tr=" + n.tr; // Translation as third positional param (no key needed). if (n.t) tpl += "|" + n.t; } // Short examples fit on one line together with their translation. // rêz=1 is not used for ku — definitions are shown on separate lines there. if (text.length < 200 && lang !== "ku") tpl += "|rêz=1"; tpl += "}}"; return tpl; }).join(""); } // Formats jêder (citation) entries into "#* {{jêder…|…}}" lines; skips // entries with no quote text. Falls back to the generic {{jêder}} // template when no specific template was chosen. function formatJeder(jederList, lang) { if (!jederList || !jederList.length) return ""; return $.map(jederList, function (jeder) { if (!jeder || !jeder.quote) return undefined; if (jeder.jederTpl) { var cite = "\n#* {{" + jeder.jederTpl + "|" + lang; cite += "|jêgirtin=" + jeder.quote; if (jeder.quoteTr) cite += "|tr=" + jeder.quoteTr; if (jeder.quoteT) cite += "|tercime=" + jeder.quoteT; $.each(jeder.jêderFields || {}, function (key, val) { if (val) cite += "|" + key + "=" + val; }); cite += "}}"; return cite; } var out = "\n#* {{jêder|" + lang + "|jêgirtin=" + jeder.quote; if (jeder.quoteTr) out += "|tr=" + jeder.quoteTr; if (jeder.quoteT) out += "|tercime=" + jeder.quoteT; var srcParam = jeder.jederManual ? jeder.jederManual : "çavkanî?"; // A positional param containing "=" gets parsed as its own key=value // pair by MediaWiki and breaks the template, so force it to be // explicitly named (|2=) whenever that's the case. out += (srcParam.indexOf("=") !== -1 ? "|2=" : "|") + srcParam; out += "}}"; return out; }).join(""); } // True if a sense has at least one jêder entry with quote text. function senseHasJeder(sense) { return !!(sense.jeder && $.grep(sense.jeder, function (j) { return j && j.quote; }).length > 0); } // Builds "{{tplName|lang|part1|part2|…}}" from a sense field (kategori, // etiket), wrapped inline (" {{…}} ") or on its own line ("\n#: {{…}}"). function buildSenseTpl(sense, field, lang, tplName, format) { if (!sense[field] || !sense[field].length) return ""; var parts = sense[field].map(function (p) { return $.trim(p); }) .filter(function (p) { return p !== ""; }); if (!parts.length) return ""; var call = "{{" + tplName + "|" + lang + "|" + parts.join("|") + "}}"; return format === "block" ? "\n#: " + call : " " + call + " "; } /** * Assembles the nimûne + jêder wikitext block for a sense. Shared by * both the template-sense and normal-mane-sense branches below. */ function buildCite(sense, lang) { return formatNimune(sense.nimune, lang, senseHasJeder(sense)) + formatJeder(sense.jeder, lang); } function makeWordListStep(id, name, question_fmt, header, templateName) { return { id: id, name: name, question_fmt: question_fmt, multiple: true, narrow: true, visible: function (values) { return values.lang && values.pos; }, output: function (values) { var words = $.grep(values[id] || [], function (w) { return !!w; }); if (!words.length) return ""; var lang = values.lang; var section = "\n==== " + header + " ====\n"; if (words.length === 1) { // Single word — keep the simple inline template. return section + "* {{" + templateName + "|" + lang + "|" + words[0] + "}}\n"; } // Multiple words — use {{kol3}} with one positional param per word. var params = "cure=" + header + "\n" + $.map(words, function (w) { return "|" + w; }).join("\n"); return section + "{{kol3|" + lang + "|" + params + "\n}}\n"; } }; } var steps = { lang: { id: "lang", required: true, name: "ziman", question_fmt: '"' + pageName + '" bi çi zimanî ye?', question_br: true, // Populated from [[MediaWiki:Gadget-start.js/data.json]] (langChoices). choices: [], output: function (values) { return "== {{ziman|" + values.lang + "}} ==\n"; } }, pron: { id: "pron", name: "bilêvkirin", question_fmt: '"' + pageName + '" çawa tê telafûzkirin?', // pronTpls populated from data.json pronTpls: [], visible: function (values) { if (!values.lang) return false; // addLangMode: skip pron only if this lang already has a section. if (addLangMode) { // Clearing the page makes existing content irrelevant. var clearPageCheck = $("#wiktku-clear-page-check"); if (clearPageCheck.length && clearPageCheck.prop("checked")) { return true; } var existing = $("#wpTextbox1").val() || ""; return !findLangHeader(existing, values.lang); } return true; }, // Fills the insert-dropdown from pronTpls, filtered by language. refreshTplSelect: function () { var sel = $("#wiktku-start-pron .wiktku-tpl-insert-select"); if (!sel.length) return; var lang = getValues().lang || ""; sel.find("option[value!='']").remove(); $.each(steps.pron.pronTpls, function (_, tpl) { // Filter: if tpl.langs exists, only show if lang is in that list; otherwise show always var allowed = !tpl.langs || tpl.langs.indexOf(lang) !== -1; if (allowed) { sel.append($("<option></option>") .val(tpl.snippet) .text(tpl.name + " — " + tpl.desc) .attr("data-nolang", tpl.noLang ? "1" : "")); } }); // Notify Chosen that the option list has changed (no-op on mobile). if (!isMobile) sel.trigger("chosen:updated"); }, build: function (stepDiv) { if (stepDiv.find(".wiktku-pron-wrap").length) return null; var wrap = $("<div class='wiktku-pron-wrap'></div>"); var ta = $("<textarea></textarea>") .attr("name", "wiktku-pron-" + $.now()) .attr("class", "wiktku-start-step-field wiktku-pron-text") .attr("rows", 4) .attr("placeholder", "Nimûne: {{IPA|ku|/pɛɪ̯n/}} yan {{kîte|ku|he|ce|ki|rin}}"); // Template insert dropdown — filtered by language. var sel = $("<select class='wiktku-tpl-insert-select'></select>"); sel.append($("<option value=''>— şablonek lê zêde bike —</option>")); var lang = getValues().lang || ""; $.each(steps.pron.pronTpls, function (_, tpl) { // Filter: if tpl.langs exists, only show if lang is in that list; otherwise show always var allowed = !tpl.langs || tpl.langs.indexOf(lang) !== -1; if (allowed) { sel.append($("<option></option>") .val(tpl.snippet) .text(tpl.name + " — " + tpl.desc) .attr("data-nolang", tpl.noLang ? "1" : "")); } }); sel.on("change", function () { var snippet = $(this).val(); if (!snippet) return; var lang = getValues().lang || ""; // Check if the selected option has noLang flag var selectedOption = sel.find("option:selected"); var hasNoLang = selectedOption.attr("data-nolang") === "1"; if (!hasNoLang) { snippet = snippet.replace(/CODE/g, lang).replace(/SOURCELANG/g, "?"); } insertAtCursor(ta[0], snippet); $(this).val(""); ta.focus(); }); wrap.append(sel).append($("<br>")).append(ta); stepDiv.append(wrap); return ta; }, output: function () { var text = $.trim($("#wiktku-start-pron .wiktku-pron-text").val()); if (!text) return ""; var lines = text.split("\n"); var out = $.map(lines, function (line) { line = $.trim(line); if (!line) return undefined; return line.charAt(0) === "*" ? line : "* " + line; }).join("\n"); return "\n=== Bilêvkirin ===\n" + out + "\n"; } }, pos: { id: "pos", required: true, name: "Cureyê rêzimanî", question_fmt: 'Cureyê rêzimanî yê "' + pageName + '" çi ye?', visible: function (values) { return values.lang; }, question_br: true, // Populated from [[MediaWiki:Gadget-start.js/data.json]] (posChoices). choices: [], output: function (values) { var pos = values.pos || ""; var cinsiyet = values.cinsiyet || ""; // from the cinsiyet step var lekTur = values.lektur || ""; // from the lêker transitivity step var capitalizedPos = capitalize(pos); var outputString = "\n=== " + capitalizedPos + " ===\n"; // Add ku-tewîn-nav for single-word navdêr/serenav with known gender. if (!pageName.includes(" ") && cinsiyet && GENDER_BASE_LABELS[cinsiyet] && (pos === "navdêr" || pos === "serenav") && values.lang === "ku") { outputString += "{{ku-tewîn-nav|" + pageName + "|" + GENDER_BASE_LABELS[cinsiyet]; if (pos === "serenav") outputString += "|y"; outputString += "}}\n"; } outputString += "{{" + pos + "|" + values.lang; if (pos === "navdêr" || pos === "serenav") { if (cinsiyet) { outputString += "|c=" + cinsiyet; } else if (values.lang === "ku") { // Unknown gender — prompt editor to fill it in. outputString += "|c=?"; } } else if (/^lêker/.test(pos) && lekTur) { outputString += "|c=" + lekTur; } if (values.tr) { outputString += "|tr=" + values.tr; } outputString += "}}\n"; return outputString; } }, // cinsiyet (gender) — shown for navdêr/serenav only, with choices built // from metadata[lang].g since not every language has grammatical gender. cinsiyet: { id: "cinsiyet", name: "cinsiyet", question_fmt: 'Cinsiyeta "' + pageName + '" çi ye?', question_br: true, visible: function (values) { var meta = metadata[values.lang]; return !!(values.lang && (values.pos === "navdêr" || values.pos === "serenav") && meta && meta.g && meta.g.length); }, build: function (stepDiv, values) { var select = stepDiv.find("select.wiktku-start-step-field"); if (!select.length) { select = $(mw.html.element("select", { "class": "wiktku-start-step-field", id: "wiktku-start-cinsiyet-field" })); stepDiv.append(select); } if (!values) return select; var meta = metadata[values.lang]; var codes = (meta && meta.g) || []; var prevVal = select.val(); var choices = $.map(codes, function (code) { return [[code, genderLabel(code)]]; }); populateMenus(select, choices); if ($.grep(choices, function (c) { return c[0] === prevVal; }).length) { select.val(prevVal); } if (!isMobile) select.trigger("chosen:updated"); return select; }, output: function () { return ""; } // consumed by pos.output }, // Lêker transitivity — shown for any lêker variant. lektur: { id: "lektur", name: "Cureyê lêkerê (fiîlê)", question_fmt: "Cureyê lêkerê (fiîlê) çi ye?", question_br: true, visible: function (values) { return values.lang && values.pos && /^lêker/.test(values.pos); }, // Dictionary: value → display label. Add new types here. choices: [ ["gh", "gerguhêz"], ['x-gh', 'xwerû-gerguhêz'], ['p-gh', 'pêkhatî-gerguhêz'], ['h-gh', 'hevedudanî-gerguhêz'], ['b-gh', 'biwêjî-gerguhêz'], ["ngh", "negerguhêz"], ['x-ngh', 'xwerû-negerguhêz'], ['p-ngh', 'pêkhatî-negerguhêz'], ['h-ngh', 'hevedudanî-negerguhêz'], ['b-ngh', 'biwêjî-negerguhêz'] ], output: function () { return ""; } // consumed by pos.output }, tr: { id: "tr", name: "transkrîpsiyon", question_fmt: "Transkrîpsiyona kelîmeyê", multiple: false, narrow: true, visible: function (values) { return values.lang && values.pos && needsTransliteration(values.lang); } }, dfn: { id: "dfn", // required: true, ger mane tinebe [[Şablon:mane?]] bi kar bîne name: "Mane", question_fmt: "Maneya kelîmeyê binivîse. Mane otomatîk tê lînkkirin! Ji bo tercimeyan beşa 'Werger' bi kar bîne!", multiple: true, ordered: true, rows: 3, visible: function (values) { return values.lang && values.pos; }, example: function (values) { // posExamples loaded from [[MediaWiki:Gadget-start.js/data.json]]. var examples = steps.dfn.posExamples || {}; var full = values.pos || ""; return examples[full] || ""; }, // Builds one sense block (<li>): mane textarea, nimûne list, and // sub-lists for alternatîv/hevmane/dijmane/etc. buildSenseBlock: function (stepDiv) { var block = $("<li class='wiktku-dfn-sense'></li>"); // — Mane textarea (declared first so the template handler can reference it) — var dfnArea = $("<textarea></textarea>") .attr("name", "wiktku-dfn-mane-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("class", "wiktku-start-step-field wiktku-dfn-mane") .attr("rows", 6) .attr("placeholder", "Mane…"); dfnArea.on("input", function () { steps.dfn.onDfnInput(stepDiv, block, this); }); // — Template selector (optional — replaces mane when chosen) — // Template definitions loaded from [[MediaWiki:Gadget-start.js/data.json]]. var tplDefs = steps.dfn.tplDefs || []; // Cache of all non-placeholder option elements — used by updateTplOptions // to remove/re-add options (the only approach compatible with Chosen.js). var _allTplOptions = []; var tplSelect = $(mw.html.element("select", { "class": "wiktku-dfn-tpl-select" })); tplSelect.append($("<option value=''>— yan jî şablonek hilbijêre —</option>")); $.each(tplDefs, function (_, tpl) { var opt = $("<option></option>") .val(tpl.name) .text(tpl.name) .attr("data-langs", tpl.langs ? tpl.langs.join(",") : "") .attr("data-nolang", tpl.noLang ? "1" : ""); tplSelect.append(opt); _allTplOptions.push(opt[0]); }); function updateTplOptions() { var lang = getValues().lang || ""; var currentVal = tplSelect.val(); var currentStillValid = false; // Detach all non-placeholder options, then re-attach only the visible ones. // This is the only approach that works correctly with both native <select> // and Chosen.js on desktop. tplSelect.find("option[value!='']").detach(); $.each(_allTplOptions, function (_, opt) { var allowed = $(opt).attr("data-langs"); var visible = !allowed || allowed.split(",").indexOf(lang) !== -1; if (visible) { tplSelect.append(opt); if ($(opt).val() === currentVal) currentStillValid = true; } }); if (!isMobile) tplSelect.trigger("chosen:updated"); if (currentVal && !currentStillValid) { tplSelect.val(""); dfnArea.show(); tplTitleInput.hide().val(""); } } // Store updater on the element so refresh() can call it for all blocks. tplSelect.data("updateOptions", updateTplOptions); var tplTitleInput = $("<input type='text'>") .addClass("wiktku-dfn-tpl-title wiktku-start-narrow") .attr("placeholder", "Navê rûpelê…") .hide(); // Grow the sense list when the title field of the last block gets content, // mirroring what onDfnInput does for the plain mane textarea. tplTitleInput.on("input", function () { steps.dfn.onDfnInput(stepDiv, block, this); }); // Şablon senses have no plain gloss, so hide alternatîv/hevmane/ // dijmane/etc. Etîket, Nimûne and Jêgirtin stay visible either way. function updateFieldVisibility() { var isTpl = !!tplSelect.val(); $.each(HIDDEN_ON_TPL_GROUPS, function (_, cls) { block.find("." + cls + "-group").toggle(!isTpl); }); } // Store on the block so restoreDfn() can re-sync visibility // after programmatically setting tplSelect's value. block.data("updateFieldVisibility", updateFieldVisibility); tplSelect.on("change", function () { var chosen = $(this).val(); if (chosen) { dfnArea.hide(); tplTitleInput.show().focus(); } else { dfnArea.show(); tplTitleInput.hide().val(""); } updateFieldVisibility(); // Re-run refresh so the Werger step visibility updates. refresh(); }); var tplRow = $("<div></div>").addClass("wiktku-dfn-tpl-row") .append(tplSelect).append(" ").append(tplTitleInput); block.append(tplRow); block.append(dfnArea); // Apply lang filter on initial build. updateTplOptions(); // — Sub-field groups — // All groups are always visible with a placeholder textarea. // Nimûne is last in the DOM and last in the output. var allGroups = [ { cls: "wiktku-dfn-etiket", label: "Etîket", rows: 1, narrow: true, izah: "xisûsen, Mêrdîn, anatomî, Badînî" }, { cls: "wiktku-dfn-kategori", label: "Kategorî", rows: 1, narrow: true, izah: "wekî etîket lê xuya nabe tenê kategorîze dike" }, { cls: "wiktku-dfn-alternativ", label: "Formên alternatîv", rows: 1, narrow: true, izah: "Varyantên vê kelîmeyê" }, { cls: "wiktku-dfn-hevmane", label: "Hevmane", rows: 1, narrow: true, izah: "Spehî hevmaneya Bedew e." }, { cls: "wiktku-dfn-dijmane", label: "Dijmane", rows: 1, narrow: true, izah: "Zengîn dijmaneya feqîr e." }, { cls: "wiktku-dfn-koordine", label: "Termên koordîne", rows: 1, narrow: true, izah: "Pisîk û kûçik termên koordîne ne çunkî Jornavên wan gelek in" }, { cls: "wiktku-dfn-jornav", label: "Jornav", rows: 1, narrow: true, izah: "Heywan jornavê guhandar e" }, { cls: "wiktku-dfn-jernav", label: "Jêrnav", rows: 1, narrow: true, izah: "Guhandar jêrnavê heywan e" }, { cls: "wiktku-dfn-nimune", label: "Nimûne", rows: 2, narrow: false } ]; $.each(allGroups, function (_, g) { var groupDiv = $("<div></div>").addClass("wiktku-dfn-subgroup " + g.cls + "-group"); function buildNimuneLi() { var lang = getValues().lang || ""; var li = $("<li></li>").addClass("wiktku-dfn-nimune-li"); var mainTa = $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-text-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", g.rows) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-text") .attr("placeholder", "Nimûneya emilandina kelîmeyê tu bi xwe binivîse…"); mainTa.on("input", function () { var val = $.trim($(this).val()); var isLast = li.is(list.children("li:last-child")); if (val && isLast) { list.append(buildNimuneLi()); } }); li.append(mainTa); var subWrap = $("<div></div>").addClass("wiktku-dfn-nimune-sub"); if (needsTransliteration(lang)) { subWrap.append( $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-tr-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 5) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-tr") .attr("placeholder", "Transkrîpsiyona bi alfabeya latînî") ); } if (lang && lang !== "ku") { subWrap.append( $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-t-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 5) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-t") .attr("placeholder", "Tercimeya kurmancî") ); } if (subWrap.children().length) li.append(subWrap); return li; } if (g.cls === "wiktku-dfn-nimune") { // Nimûne — compound widget with tr/t sub-fields. var lbl = $("<span></span>").addClass("wiktku-dfn-sublabel").text(g.label + ": "); var list = $("<ol></ol>").addClass("wiktku-dfn-sublist " + g.cls + "-list"); groupDiv.data("buildNimuneLi", buildNimuneLi); list.append(buildNimuneLi()); groupDiv.append(lbl).append(list); block.append(groupDiv); } else { // Regular always-visible group — label + growing textarea list. var lbl = $("<span></span>").addClass("wiktku-dfn-sublabel").text(g.label + ": " + g.izah); var list = $("<ol></ol>").addClass("wiktku-dfn-sublist " + g.cls + "-list"); var firstInput = $("<textarea></textarea>") .attr("name", g.cls + "-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", g.rows) .attr("class", "wiktku-dfn-subfield" + (g.narrow ? " wiktku-start-narrow" : "")) .attr("placeholder", g.label + "…"); firstInput.on("input", function () { steps.dfn.onSubInput(list, this, g.rows, g.narrow); }); list.append($("<li></li>").append(firstInput)); groupDiv.append(lbl).append(list); block.append(groupDiv); } }); // — Jêder (citation) group — growing list, same structure as Nimûne. — (function () { var jederGroupDiv = $("<div></div>").addClass("wiktku-dfn-subgroup wiktku-dfn-jeder-group"); var jederLbl = $("<span></span>").addClass("wiktku-dfn-sublabel").text("Jêgirtin: "); var jederList = $("<ol></ol>").addClass("wiktku-dfn-sublist wiktku-dfn-jeder-list"); function buildJederLi() { var lang = getValues().lang || ""; var li = $("<li></li>").addClass("wiktku-dfn-jeder-li"); var dragHandle = $("<span></span>") .addClass("wiktku-jeder-drag-handle") .attr("title", "Bişkûne û bikişîne da ku rêzê biguhezîne"); // Quote text textarea var quoteTa = $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-quote-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 2) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-quote") .attr("placeholder", "Nimûneya emilandinê ji kitêb an çavkaniyeke din binivîse"); quoteTa.on("input", function () { var val = $.trim($(this).val()); var isLast = li.is(jederList.children("li:last-child")); if (val && isLast) { jederList.append(buildJederLi()); } }); li.append(dragHandle).append(quoteTa); // tr/t sub-fields for the quote — shown as needed for the language. var quoteSubWrap = $("<div></div>").addClass("wiktku-dfn-quote-sub"); if (needsTransliteration(lang)) { quoteSubWrap.append( $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-quote-tr-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 2) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-quote-tr") .attr("placeholder", "Transkrîpsiyona jêgirtinê…") ); } if (lang && lang !== "ku") { quoteSubWrap.append( $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-quote-t-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 2) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-quote-t") .attr("placeholder", "Tercimeya jêgirtinê bi kurmancî") ); } if (quoteSubWrap.children().length) li.append(quoteSubWrap); // Citoid auto-fill: fetch citation data from a URL, DOI or ISBN and // prefill the source şablon + fields below (see Gadget-citoid-helper.js). var citoidWrap = $("<div></div>").addClass("wiktku-dfn-quote-citoid"); var citoidInput = $("<input type='text'>") .addClass("wiktku-dfn-quote-citoid-input wiktku-start-narrow") .attr("placeholder", "URL, DOI an ISBN binivîse ku otomatîk were tijekirin…"); var citoidBtn = new OO.ui.ButtonWidget({ label: "Bi Citoid bîne", classes: [ "wiktku-dfn-quote-citoid-btn" ] }); var citoidStatus = $("<span></span>").addClass("wiktku-dfn-quote-citoid-status"); // Fetches citation data from Citoid and fills this citation's // şablon + fields — only rebuilds fields on template change, // and never overwrites values the user already typed. function runCitoidFetch() { var query = $.trim(citoidInput.val()); if (!query) { mw.notify("Ji kerema xwe re pêşî URL, DOI an ISBNyekê binivîse."); return; } citoidBtn.setDisabled(true); citoidStatus.text("Tê anîn…"); wikt.citoidHelper.ensure().then(function () { return wikt.citoid.fetchJederFields(query); }).then(function (result) { var jederKey = result.jederKey; var hasTpl = !!jederKey && srcSel.find("option[value='" + jederKey + "']").length > 0; var targetVal = hasTpl ? jederKey : "__manual__"; // Only rebuild if switching şablon, so a repeat fetch // doesn't clear fields already filled in by hand. if (srcSel.val() !== targetVal) { srcSel.val(targetVal).trigger("change"); srcSel.trigger("chosen:updated"); } if (hasTpl) { // Tenê qadên vala tijî bike. $.each(result.fields, function (key, val) { var input = srcFields.find("[data-field-key='" + key + "']"); if (input.length && !$.trim(input.val())) { input.val(val); } }); } else { // Şablonek nehat naskirin ji bo vê itemType — rêzikeke // çavkaniyê ya bi destan a ji qadên Citoid tê çêkirin, // lê tenê ger qada destan vala be. var manualField = srcFields.find(".wiktku-dfn-quote-src-manual"); if (!$.trim(manualField.val())) { var parts = []; $.each(["nivîskar", "sernav", "websîte", "kovar", "weşanxane", "sal", "url"], function (_, k) { if (result.fields[k]) parts.push(result.fields[k]); }); manualField.val(parts.join(", ")); } } citoidStatus.text(""); }, function (errorMsg) { citoidStatus.text(typeof errorMsg === "string" ? errorMsg : "Nehat dîtin. Kontrol bike ka URL/DOI/ISBN rast e."); }).always(function () { citoidBtn.setDisabled(false); }); } citoidBtn.on("click", runCitoidFetch); citoidInput.on("keydown", function (e) { if (e.which === 13) { // Enter e.preventDefault(); runCitoidFetch(); } }); citoidWrap.append(citoidInput).append(citoidBtn.$element).append(citoidStatus); // Source template selector, specific to this citation. var srcSel = $("<select></select>").addClass("wiktku-dfn-quote-src-sel"); srcSel.append($("<option value=''>— Çavkaniyê hilbijêre —</option>")); srcSel.append($("<option></option>").val("__manual__").text("Bi destê xwe binivîsim")); var jederDefs = steps.dfn.jederDefs || {}; $.each(jederDefs, function (tplName, def) { srcSel.append($("<option></option>").val(tplName).text(def.label)); }); // Dynamic source fields container. var srcFields = $("<div></div>").addClass("wiktku-dfn-quote-src-fields"); srcSel.on("change", function () { srcFields.empty(); var chosen = $(this).val(); if (!chosen) return; if (chosen === "__manual__") { // Freeform source, written by the user — becomes the 2nd // positional param of {{jêder|lang|…}} instead of çavkanî?. srcFields.append( $("<textarea></textarea>") .attr("rows", 4) .addClass("wiktku-dfn-subfield wiktku-dfn-quote-src-manual") .attr("placeholder", "Çavkaniyê bi destê xwe binivîse…") ); return; } var def = (steps.dfn.jederDefs || {})[chosen]; if (!def) return; $.each(def.fields, function (_, f) { var row = $("<div></div>").addClass("wiktku-dfn-quote-src-row"); var fieldLbl = $("<label></label>").text(f.label + ": "); var inp = $("<textarea></textarea>") .attr("rows", 2) .addClass("wiktku-dfn-quote-src-input wiktku-start-narrow") .attr("data-field-key", f.key) .attr("placeholder", f.label + "…"); row.append(fieldLbl).append(inp); srcFields.append(row); }); }); li.append(citoidWrap).append(srcSel).append(srcFields); return li; } jederGroupDiv.data("buildJederLi", buildJederLi); jederList.append(buildJederLi()); // Make citation rows sortable (drag to reorder). // The last row is always the empty trailing row — cancel its drag. mw.loader.using("jquery.ui.sortable", function () { jederList.sortable({ handle: ".wiktku-jeder-drag-handle", axis: "y", items: "li:not(:last-child)", tolerance: "pointer" }); }); jederGroupDiv.append(jederLbl).append(jederList); block.append(jederGroupDiv); }()); // Apply the initial hide/show state for the sub-groups (matches // tplSelect's starting value, which is normally empty). updateFieldVisibility(); return block; }, /** Grows the sense list when the last mane textarea gets content. */ onDfnInput: function (stepDiv, block, textarea) { var val = $.trim($(textarea).val()); var list = stepDiv.find("ol.wiktku-dfn-list"); var isLast = block.is(list.children("li:last-child")); if (val && isLast) { var newBlock = steps.dfn.buildSenseBlock(stepDiv); list.append(newBlock); // Apply Chosen to the new block's template selector on desktop. if (!isMobile) newBlock.find("select.wiktku-dfn-tpl-select").chosen(chosenOptions); } refresh(); }, /** Grows a sub-list (nimûne/formên alternatîv/hevmane/dijmane/termên koordîne) on input. */ onSubInput: function (list, input, rows, narrow) { var val = $.trim($(input).val()); var item = $(input).parent(); var isLast = item.is(list.children("li:last-child")); if (val && isLast) { var next = $("<textarea></textarea>") .attr("name", "wiktku-dfn-sub-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", rows) .attr("class", "wiktku-dfn-subfield" + (narrow ? " wiktku-start-narrow" : "")); next.on("input", function () { steps.dfn.onSubInput(list, this, rows, narrow); }); list.append($("<li></li>").append(next)); } }, // Populated from [[MediaWiki:Gadget-start.js/data.json]] (tplDefs, posExamples, jederDefs). tplDefs: [], posExamples: {}, jederDefs: {}, build: function (stepDiv) { if (stepDiv.find("ol.wiktku-dfn-list").length) return null; var list = $("<ol class='wiktku-dfn-list'></ol>"); list.append(steps.dfn.buildSenseBlock(stepDiv)); stepDiv.append(list); return null; }, /** Reads all sense blocks from the DOM and returns an array of sense objects. */ getSenses: function (stepDiv) { var senses = []; stepDiv.find("li.wiktku-dfn-sense").each(function () { var block = $(this); var tplSel = block.find("select.wiktku-dfn-tpl-select"); var tpl = tplSel.val() || ""; // noLang: template already encodes the language — don't add |lang| param. var tplNoLang = tpl ? tplSel.find("option[value='" + tpl + "']").attr("data-nolang") === "1" : false; var tplTitle = $.trim(block.find("input.wiktku-dfn-tpl-title").val()); var mane = $.trim(block.find("textarea.wiktku-dfn-mane").val()); function readList(cls) { var vals = []; block.find("." + cls + "-list textarea").each(function () { var v = $.trim($(this).val()); if (v) vals.push(v); }); return vals; } // Nimûne items are compound: { text, tr?, t? } function readNimuneList() { var items = []; block.find(".wiktku-dfn-nimune-list li.wiktku-dfn-nimune-li").each(function () { var text = $.trim($(this).find(".wiktku-dfn-nimune-text").val()); if (!text) return; var obj = { text: text }; var tr = $.trim($(this).find(".wiktku-dfn-nimune-tr").val()); var t = $.trim($(this).find(".wiktku-dfn-nimune-t").val()); if (tr) obj.tr = tr; if (t) obj.t = t; items.push(obj); }); return items; } // Jêder is a growing list of citations, one per li — mirrors readNimuneList(). function readJederList() { var items = []; block.find(".wiktku-dfn-jeder-list li.wiktku-dfn-jeder-li").each(function () { var li = $(this); var quote = $.trim(li.find(".wiktku-dfn-nimune-quote").val()); if (!quote) return; var obj = { quote: quote }; var qtr = $.trim(li.find(".wiktku-dfn-nimune-quote-tr").val()); var qt = $.trim(li.find(".wiktku-dfn-nimune-quote-t").val()); if (qtr) obj.quoteTr = qtr; if (qt) obj.quoteT = qt; var tplName = li.find(".wiktku-dfn-quote-src-sel").val(); if (tplName === "__manual__") { var manual = $.trim(li.find(".wiktku-dfn-quote-src-manual").val()); if (manual) obj.jederManual = manual; } else if (tplName) { obj.jederTpl = tplName; var fields = {}; li.find(".wiktku-dfn-quote-src-input").each(function () { var k = $(this).attr("data-field-key"); var v = $.trim($(this).val()); if (k && v) fields[k] = v; }); obj.jêderFields = fields; } items.push(obj); }); return items; } senses.push({ tpl: tpl, tplNoLang: tplNoLang, tplTitle: tplTitle, mane: mane, etiket: readList("wiktku-dfn-etiket"), kategori: readList("wiktku-dfn-kategori"), nimune: readNimuneList(), jeder: readJederList(), alternativ: readList("wiktku-dfn-alternativ"), hevmane: readList("wiktku-dfn-hevmane"), dijmane: readList("wiktku-dfn-dijmane"), koordine: readList("wiktku-dfn-koordine"), jornav: readList("wiktku-dfn-jornav"), jernav: readList("wiktku-dfn-jernav") }); }); return senses; }, getOutput: function (values, callback) { var stepDiv = $("#wiktku-start-dfn"); var senses = steps.dfn.getSenses(stepDiv); var lang = values.lang; // A sense counts as "filled" if it has a mane, a chosen template + title, // or any other content (etîket/hevmane/nimûne/jêder…) worth keeping. var hasMane = senses.some(function (s) { return s.mane !== "" || (s.tpl && s.tplTitle) || senseHasExtraContent(s); }); // True only when at least one sense has a regular mane (needs linkify). var hasRegularMane = senses.some(function (s) { return !s.tpl && s.mane !== ""; }); // nimûne/jêder must never pass through linkify, only the mane text. // defLines (linkified) and citeLines (kept aside) stay parallel; // a {{wiktku-cite-N}} token in defLines marks where to splice back. var defLines = []; // one entry per kept sense (goes to linkify) var citeLines = []; // parallel — nimûne+jêder for that same sense $.each(senses, function (_, sense) { // — Template sense (e.g. {{guharto|ku|somepage}}) — if (sense.tpl) { if (!sense.tplTitle) return; // skip empty template senses var tplKatTpl = buildSenseTpl(sense, "kategori", lang, "K", "inline"); var tplLabelTpl = buildSenseTpl(sense, "etiket", lang, "e", "inline"); var tplCall = sense.tplNoLang ? "{{" + sense.tpl + "|" + sense.tplTitle + "}}" : "{{" + sense.tpl + "|" + lang + "|" + sense.tplTitle + "}}"; var idx = defLines.length; var cite = buildCite(sense, lang); defLines.push("# " + (tplKatTpl ? tplKatTpl + " " : "") + (tplLabelTpl ? tplLabelTpl + " " : "") + tplCall + (cite ? "{{wiktku-cite-" + idx + "}}" : "")); citeLines.push(cite); return; } // — Normal mane sense — var dfn = sense.mane; if (!dfn && !senseHasExtraContent(sense)) return; // truly empty if (dfn) { dfn = stripWikilinks(dfn); if (dfn[0] !== dfn[0].toUpperCase()) dfn = capitalize(dfn); if (!dfn.match(/[.…?!)\]]$/)) dfn += "."; } else { dfn = "{{mane?|" + lang + "}}"; } var katTpl = buildSenseTpl(sense, "kategori", lang, "K", "inline"); var labelTpl = buildSenseTpl(sense, "etiket", lang, "e", "inline"); var out = "# " + (katTpl ? katTpl : "") + (labelTpl ? labelTpl : "") + dfn; function wordLine(tpl, words) { if (!words.length) return ""; return "\n#: {{" + tpl + "|" + lang + "|" + words.join("|") + "}}"; } out += wordLine("alt-r", sense.alternativ); out += wordLine("hevmane", sense.hevmane); out += wordLine("dijmane", sense.dijmane); out += wordLine("koordîne", sense.koordine); out += wordLine("jornav", sense.jornav); out += wordLine("jêrnav", sense.jernav); var cite = buildCite(sense, lang); var idx = defLines.length; defLines.push(out + (cite ? "{{wiktku-cite-" + idx + "}}" : "")); citeLines.push(cite); }); // Splice citeLines back into a linkified string, replacing each // {{wiktku-cite-N}} token with its stored nimûne/jêder block. function restoreCites(t) { return t.replace(/\{\{wiktku-cite-(\d+)\}\}/g, function (_, n) { return citeLines[parseInt(n, 10)] || ""; }); } var text = defLines.join("\n") + "\n"; if (!hasMane) { // No definitions entered — emit {{mane?}} with bênimûne. text = "# {{mane?|" + lang + "}}\n#* {{bênimûne|" + lang + "}}\n"; callback(text); return; } if (!hasRegularMane) { // All filled senses are template senses — no linkify needed. callback(restoreCites(text)); return; } var didTryToLoad = function () { if (typeof $.wiktviLinkify === "function") { $.wiktviLinkify(text, function (linked) { callback(restoreCites(linked)); }); } else { callback(restoreCites(text)); } }; mw.loader.using("ext.gadget.linkify", didTryToLoad, didTryToLoad); } }, je: makeWordListStep("je", "jê", "Kelîmeyên jê çêbûyî binivîse", "Jê", "g"), tekildar: makeWordListStep("tekildar", "têkildar", "Kelîmeyên ji aliyê etîmolojiyê ve têkildarî vê kelîmeyê binivîse", "Têkildar", "g"), binereherwiha: makeWordListStep("binereherwiha", "binêre herwiha", "Kelîmeyên din ên eleqedar binivîse", "Binêre herwiha", "g"), etym: { id: "etym", name: "etîmolojî", question_fmt: "Etîmolojiya kelîmeyê binivîse", // etymTpls populated from data.json etymTpls: [], visible: function (values) { return values.lang && values.pos; }, // Fills the insert-dropdown from the current etymTpls array. refreshTplSelect: function () { var sel = $("#wiktku-start-etym .wiktku-tpl-insert-select"); if (!sel.length) return; sel.find("option[value!='']").remove(); $.each(steps.etym.etymTpls, function (_, tpl) { sel.append($("<option></option>").val(tpl.snippet).text(tpl.name + " — " + tpl.desc)); }); // Notify Chosen that the option list has changed (no-op on mobile). if (!isMobile) sel.trigger("chosen:updated"); }, build: function (stepDiv) { if (stepDiv.find(".wiktku-etym-wrap").length) return null; var wrap = $("<div class='wiktku-etym-wrap'></div>"); var ta = $("<textarea></textarea>") .attr("name", "wiktku-etym-" + $.now()) .attr("class", "wiktku-start-step-field wiktku-etym-text") .attr("rows", 4) .attr("placeholder", "Nimûne: Ji {{ji|en|ku|apple}}. yan rasterast binivîse…"); // Template insert dropdown — options also refreshed after data.json loads. var sel = $("<select class='wiktku-tpl-insert-select'></select>"); sel.append($("<option value=''>— şablonek lê zêde bike —</option>")); $.each(steps.etym.etymTpls, function (_, tpl) { sel.append($("<option></option>").val(tpl.snippet).text(tpl.name + " — " + tpl.desc)); }); sel.on("change", function () { var snippet = $(this).val(); if (!snippet) return; var lang = getValues().lang || ""; snippet = snippet.replace(/CODE/g, lang).replace(/SOURCELANG/g, "?"); insertAtCursor(ta[0], snippet); $(this).val(""); ta.focus(); }); wrap.append(sel).append($("<br>")).append(ta); stepDiv.append(wrap); return ta; }, output: function (values) { var text = $.trim($("#wiktku-start-etym .wiktku-etym-text").val()); if (text) { return "\n==== Etîmolojî ====\n" + text + "\n"; } // No etymology entered — emit {{ji?|lang}} as a placeholder, // Only when a regular sense has content (real mane, or {{mane?}} // with other fields filled in) — a şablon sense never counts. var dfnSenses = steps.dfn.getSenses($("#wiktku-start-dfn")); var hasRegularMane = dfnSenses.some(function (s) { return !s.tpl && (s.mane !== "" || senseHasExtraContent(s)); }); if (!hasRegularMane) return ""; return "\n==== Etîmolojî ====\n{{ji?|" + values.lang + "}}\n"; } }, dunde: { id: "dunde", name: "dûnde", question_fmt: "Eger ev kelîme ji vî zimanî ketibe zimanekî din, vî zimanî û kelîmeya wî binivîse", visible: function (values) { return !!values.pos; }, disabledKeys: { "navz": true}, // Language dropdown + growing word-input list; a new row appends // when the dropdown gets a value. Mirrors steps.trans, but flat. buildRow: function (stepDiv) { var row = $("<li class='wiktku-dunde-row wiktku-lang-row'></li>"); // Language selector — chosen is applied after insertion into DOM. var langSel = $(mw.html.element("select", { "class": "wiktku-start-step-keyfield wiktku-start-narrow" })); langSel.attr("data-placeholder", "Zimanekî lê bigere"); populateMenus(langSel, steps.dunde.keys || [], steps.dunde.disabledKeys); // When a language is chosen, ensure a next empty row exists. langSel.on("change", function () { steps.dunde.onLangChange(stepDiv, row); }); // Word list for this language. var wordList = $("<ul class='wiktku-dunde-words wiktku-lang-row-words'></ul>"); var firstWord = steps.dunde.makeWordInput(); wordList.append($("<li></li>").append(firstWord)); if (isMobile) { row.append(wrapNativeSelect(langSel)).append(wordList); } else { row.append(langSel).append(wordList); } return row; }, makeWordInput: function () { var input = $("<textarea></textarea>") .attr("name", "wiktku-dunde-word-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 1) .attr("class", "wiktku-dfn-subfield wiktku-start-narrow") .attr("placeholder", "Kelîme…"); input.on("input", function () { var list = $(this).closest("ul.wiktku-dunde-words"); var item = $(this).parent(); var val = $.trim($(this).val()); if (val && item.is(list.children("li:last-child"))) { var next = steps.dunde.makeWordInput(); list.append($("<li></li>").append(next)); } }); return input; }, onLangChange: function (stepDiv, row) { var list = stepDiv.find("ul.wiktku-dunde-list"); var isLast = row.is(list.children("li.wiktku-dunde-row:last-child")); if (isLast) { var newRow = steps.dunde.buildRow(stepDiv); list.append(newRow); // Init chosen after the new row is in the DOM (desktop only). if (!isMobile) newRow.find("select").chosen(chosenOptions); } // Keep disabled keys in sync across all lang selectors. steps.dunde.syncDisabledKeys(stepDiv); }, /** Disables already-selected languages in all other dropdowns. */ syncDisabledKeys: function (stepDiv) { var taken = $.extend({}, steps.dunde.disabledKeys); stepDiv.find("li.wiktku-dunde-row select").each(function () { var v = $(this).val(); if (v) taken[v] = true; }); stepDiv.find("li.wiktku-dunde-row select").each(function () { var self = $(this); var own = self.val(); self.find("option").each(function () { var code = $(this).val(); if (!code) return; $(this).prop("disabled", taken[code] && code !== own); }); self.trigger("chosen:updated"); }); }, build: function (stepDiv) { if (stepDiv.find("ul.wiktku-dunde-list").length) return null; var list = $("<ul class='wiktku-dunde-list wiktku-lang-row-list'></ul>"); list.append(steps.dunde.buildRow(stepDiv)); stepDiv.append(list); // Init chosen after the select is in the DOM (desktop only). if (!isMobile) list.find("select").chosen(chosenOptions); return null; }, /** Reads all [langcode, words[]] rows from the DOM. */ getRows: function (stepDiv) { var result = []; stepDiv.find("li.wiktku-dunde-row").each(function () { var lang = $(this).find("select").val(); if (!lang) return; var words = []; $(this).find("ul.wiktku-dunde-words textarea").each(function () { var v = $.trim($(this).val()); if (v) words.push(v); }); if (words.length) result.push([lang, words]); }); return result; }, output: function () { var stepDiv = $("#wiktku-start-dunde"); var rows = steps.dunde.getRows(stepDiv); if (!rows.length) return ""; var lines = $.map(rows, function (row) { var lang = row[0], words = row[1]; return "* {{dû|" + lang + "|" + words.join("|") + "}}"; }); return "\n==== Dûnde ====\n" + lines.join("\n") + "\n"; } }, zarava: { id: "zarava", name: "bi zaravayên din", visible: function (values) { return steps.trans.visible(values); }, disabledKeys: { "navz": true }, buildRow: function (group) { var row = $("<li class='wiktku-zarava-row wiktku-lang-row'></li>"); var langSel = $(mw.html.element("select", { "class": "wiktku-start-step-keyfield wiktku-start-narrow" })); populateMenus(langSel, steps.zarava.keys || [], steps.zarava.disabledKeys); langSel.on("change", function () { steps.zarava.onLangChange(group, row); }); var wordList = $("<ul class='wiktku-zarava-words wiktku-lang-row-words'></ul>"); var firstWord = steps.zarava.makeWordInput(); wordList.append($("<li></li>").append(firstWord)); row.append(langSel).append(wordList); return row; }, makeWordInput: function () { var input = $("<textarea></textarea>") .attr("name", "wiktku-zarava-word-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 1) .attr("class", "wiktku-dfn-subfield wiktku-start-narrow") .attr("placeholder", "Tercime…"); input.on("input", function () { var list = $(this).closest("ul.wiktku-zarava-words"); var item = $(this).parent(); var val = $.trim($(this).val()); if (val && item.is(list.children("li:last-child"))) { var next = steps.zarava.makeWordInput(); list.append($("<li></li>").append(next)); } }); return input; }, onLangChange: function (group, row) { var list = group.find("ul.wiktku-zarava-list"); var isLast = row.is(list.children("li.wiktku-zarava-row:last-child")); if (isLast) { var newRow = steps.zarava.buildRow(group); list.append(newRow); } steps.zarava.syncDisabledKeys(group); }, /** Disables already-selected dialects in all other dropdowns within one group. */ syncDisabledKeys: function (group) { var taken = $.extend({}, steps.zarava.disabledKeys); group.find("li.wiktku-zarava-row select").each(function () { var v = $(this).val(); if (v) taken[v] = true; }); group.find("li.wiktku-zarava-row select").each(function () { var self = $(this); var own = self.val(); self.find("option").each(function () { var code = $(this).val(); if (!code) return; $(this).prop("disabled", taken[code] && code !== own); }); }); }, /** Builds (or fetches) the .wiktku-zarava-group for one gloss. */ buildGroup: function (stepDiv, gi) { var group = $("<div class='wiktku-zarava-group'></div>").attr("data-gloss-pos", gi); var list = $("<ul class='wiktku-zarava-list wiktku-lang-row-list'></ul>"); list.append(steps.zarava.buildRow(group)); group.append(list); stepDiv.append(group); return group; }, /** Syncs one .wiktku-zarava-group per current gloss (same logic as steps.trans.build). */ build: function (stepDiv) { var glosses = steps.trans.glossList(); if (!glosses.length) { stepDiv.find(".wiktku-zarava-group").remove(); return null; } var existingGroups = stepDiv.find(".wiktku-zarava-group"); if (existingGroups.length > glosses.length) { existingGroups.slice(glosses.length).remove(); } $.each(glosses, function (gi, gloss) { var group = stepDiv.find(".wiktku-zarava-group[data-gloss-pos='" + gi + "']"); if (!group.length) group = steps.zarava.buildGroup(stepDiv, gi); var label = group.find(".wiktku-zarava-group-label"); if (glosses.length > 1) { if (!label.length) { label = $("<div class='wiktku-zarava-group-label'></div>"); group.prepend(label); } label.text(gloss.index + " " + gloss.text); } else if (label.length) { label.remove(); } }); return null; }, /** Reads the dialect rows for a single gloss group. */ getGroupTranslations: function (group) { var result = []; group.find("li.wiktku-zarava-row").each(function () { var lang = $(this).find("select").val(); if (!lang) return; var words = []; $(this).find("ul.wiktku-zarava-words textarea").each(function () { var v = $.trim($(this).val()); if (v) words.push(v); }); if (words.length) result.push([lang, words]); }); return result; }, /** Reads all rows from the DOM, grouped by gloss position. */ getTranslations: function (stepDiv) { var result = []; stepDiv.find(".wiktku-zarava-group").each(function () { result.push(steps.zarava.getGroupTranslations($(this))); }); return result; }, output: function (values) { if (values.lang !== "ku") return ""; var stepDiv = $("#wiktku-start-zarava"); var glosses = steps.trans.glossList(); if (!glosses.length) return ""; var blocks = $.map(glosses, function (gloss, gi) { var group = stepDiv.find(".wiktku-zarava-group[data-gloss-pos='" + gi + "']"); var rows = group.length ? steps.zarava.getGroupTranslations(group) : []; if (!gloss.text && !rows.length) return undefined; if (rows.length) { rows.sort(function (a, b) { var aLang = langsByCode[a[0]] || []; var bLang = langsByCode[b[0]] || []; return (aLang[2] || "").localeCompare(bLang[2] || "", "ku"); }); } var wordLines = $.map(rows, function (row) { var lang = row[0]; var words = row[1]; var wikiWords = words.map(function (w) { return "{{W|" + lang + "|" + w + "}}"; }).join(", "); return "* {{Z|" + lang + "}}: " + wikiWords; }).join("\n"); if (!wordLines) return undefined; var block = "{{werger-ser|" + (gloss.text || "?") + "|" + gloss.index + "}}"; block += "\n" + wordLines; block += "\n{{werger-bin}}"; return block; }); if (!blocks.length) return ""; return "\n==== Bi zaravayên din ====\n" + blocks.join("\n") + "\n"; } }, trans: { id: "trans", name: "werger", visible: function (values) { if (!(values.lang === "ku" && values.pos)) return false; // Hide only when every sense is a filled template sense (no plain // gloss to attach translations to). A mix, or nothing filled in // yet, still shows Werger. var dfnSenses = steps.dfn.getSenses($("#wiktku-start-dfn")); var hasRealSense = dfnSenses.some(function (s) { return !s.tpl && (s.mane !== "" || senseHasExtraContent(s)); }); var hasFilledTplSense = dfnSenses.some(function (s) { return s.tpl && s.tplTitle; }); return hasRealSense || !hasFilledTplSense; }, disabledKeys: { "navz": true, "ku": true, "ckb": true, "sdh": true, "lki": true, "hac": true, "zza": true }, // Language dropdown + growing word-input list, scoped to one gloss's // group (each gloss has its own group and row list). buildRow: function (group) { var row = $("<li class='wiktku-trans-row wiktku-lang-row'></li>"); // Language selector — chosen is applied after insertion into DOM. var langSel = $(mw.html.element("select", { "class": "wiktku-start-step-keyfield wiktku-start-narrow" })); langSel.attr("data-placeholder", "Zimanekî lê bigere"); populateMenus(langSel, steps.trans.keys || [], steps.trans.disabledKeys); // When a language is chosen, ensure a next empty row exists. langSel.on("change", function () { steps.trans.onLangChange(group, row); }); // Word list for this language. var wordList = $("<ul class='wiktku-trans-words wiktku-lang-row-words'></ul>"); var firstWord = steps.trans.makeWordInput(); wordList.append($("<li></li>").append(firstWord)); if (isMobile) { row.append(wrapNativeSelect(langSel)).append(wordList); } else { row.append(langSel).append(wordList); } return row; }, makeWordInput: function () { var input = $("<textarea></textarea>") .attr("name", "wiktku-trans-word-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 1) .attr("class", "wiktku-dfn-subfield wiktku-start-narrow") .attr("placeholder", "Tercime…"); input.on("input", function () { var list = $(this).closest("ul.wiktku-trans-words"); var item = $(this).parent(); var val = $.trim($(this).val()); if (val && item.is(list.children("li:last-child"))) { var next = steps.trans.makeWordInput(); list.append($("<li></li>").append(next)); } }); return input; }, onLangChange: function (group, row) { var list = group.find("ul.wiktku-trans-list"); var isLast = row.is(list.children("li.wiktku-trans-row:last-child")); if (isLast) { var newRow = steps.trans.buildRow(group); list.append(newRow); // Init chosen after the new row is in the DOM (desktop only). if (!isMobile) newRow.find("select").chosen(chosenOptions); } // Keep disabled keys in sync across this gloss's lang selectors // only — the same language can be used for different senses. steps.trans.syncDisabledKeys(group); }, /** Disables already-selected languages in all other dropdowns within one group. */ syncDisabledKeys: function (group) { var taken = $.extend({}, steps.trans.disabledKeys); group.find("li.wiktku-trans-row select").each(function () { var v = $(this).val(); if (v) taken[v] = true; }); group.find("li.wiktku-trans-row select").each(function () { var self = $(this); var own = self.val(); self.find("option").each(function () { var code = $(this).val(); if (!code) return; $(this).prop("disabled", taken[code] && code !== own); }); self.trigger("chosen:updated"); }); }, // Builds (or fetches) the .wiktku-trans-group for one gloss. buildGroup: function (stepDiv, gi) { var group = $("<div class='wiktku-trans-group'></div>").attr("data-gloss-pos", gi); var list = $("<ul class='wiktku-trans-list wiktku-lang-row-list'></ul>"); list.append(steps.trans.buildRow(group)); group.append(list); stepDiv.append(group); // Init chosen after the select is in the DOM (desktop only). if (!isMobile) list.find("select").chosen(chosenOptions); return group; }, // Syncs one .wiktku-trans-group per current gloss, keyed by // data-gloss-pos so groups stay matched across rebuilds. build: function (stepDiv) { var glosses = steps.trans.glossList(); if (!glosses.length) { stepDiv.find(".wiktku-trans-group").remove(); return null; } // Drop groups for glosses that no longer exist (always from the // tail — groups are only ever appended in gloss order below). var existingGroups = stepDiv.find(".wiktku-trans-group"); if (existingGroups.length > glosses.length) { existingGroups.slice(glosses.length).remove(); } $.each(glosses, function (gi, gloss) { var group = stepDiv.find(".wiktku-trans-group[data-gloss-pos='" + gi + "']"); if (!group.length) group = steps.trans.buildGroup(stepDiv, gi); // Only label groups when there's more than one gloss to // distinguish between — a single gloss needs no caption. var label = group.find(".wiktku-trans-group-label"); if (glosses.length > 1) { if (!label.length) { label = $("<div class='wiktku-trans-group-label'></div>"); group.prepend(label); } label.text(gloss.index + " " + gloss.text); } else if (label.length) { label.remove(); } }); return null; }, /** Reads the translation rows for a single gloss group. */ getGroupTranslations: function (group) { var result = []; group.find("li.wiktku-trans-row").each(function () { var lang = $(this).find("select").val(); if (!lang) return; var words = []; $(this).find("ul.wiktku-trans-words textarea").each(function () { var v = $.trim($(this).val()); if (v) words.push(v); }); if (words.length) result.push([lang, words]); }); return result; }, // Reads all translation rows, grouped by gloss position. getTranslations: function (stepDiv) { var result = []; stepDiv.find(".wiktku-trans-group").each(function () { result.push(steps.trans.getGroupTranslations($(this))); }); return result; }, // Builds the numbered "{ index, gloss }" list, one per dfn sense // with a real mane (skips template senses). index is 1-based and // matches the sense's position in the "#" definition list. // When nothing's filled in, returns one placeholder entry so // Werger still has a group to attach to; when every sense is a // filled template sense, stays empty (matches trans.visible()). glossList: function () { var dfnSenses = steps.dfn.getSenses($("#wiktku-start-dfn")); var glosses = []; var hasFilledTplSense = false; $.each(dfnSenses, function (i, s) { if (s.tpl) { if (s.tplTitle) hasFilledTplSense = true; return; // template sense — no gloss to caption with } var dfn = s.mane; if (!dfn) { // No mane, but other fields are filled — still gets a // gloss group since dfn.getOutput() emits {{mane?}} for it. if (senseHasExtraContent(s)) glosses.push({ index: i + 1, text: "" }); return; } if (dfn[0] !== dfn[0].toLowerCase()) dfn = decapitalize(dfn); dfn = stripWikilinks(dfn).replace(/[.…?!)\]،؟]+$/, ""); glosses.push({ index: i + 1, text: dfn }); }); if (!glosses.length && !hasFilledTplSense) { glosses.push({ index: 1, text: "" }); } return glosses; }, output: function (values) { if (values.lang !== "ku") return ""; var stepDiv = $("#wiktku-start-trans"); var glosses = steps.trans.glossList(); // Every sense is a template sense — there's no real gloss // anywhere and no group in the DOM either (glossList() only // returns empty in that case), so skip the section entirely. if (!glosses.length) return ""; // Each gloss now has its own group of translation rows — // attach every gloss's own words under its own werger-ser/-bin // pair instead of dumping everything under the first one. var blocks = $.map(glosses, function (gloss, gi) { var group = stepDiv.find(".wiktku-trans-group[data-gloss-pos='" + gi + "']"); var rows = group.length ? steps.trans.getGroupTranslations(group) : []; // Placeholder gloss (no real mane entered yet) with nothing // translated into it — nothing to output, and gloss.text is // empty so there's no caption to give {{werger-ser}} anyway. if (!gloss.text && !rows.length) return undefined; if (rows.length) { // Sort by Kurdish sort key. rows.sort(function (a, b) { var aLang = langsByCode[a[0]] || []; var bLang = langsByCode[b[0]] || []; return (aLang[2] || "").localeCompare(bLang[2] || "", "ku"); }); } var wordLines = $.map(rows, function (row) { var lang = row[0]; var words = row[1]; var wikiWords = words.map(function (w) { return "{{W|" + lang + "|" + w + "}}"; }).join(", "); return "* {{Z|" + lang + "}}: " + wikiWords; }).join("\n"); var block = "{{werger-ser|" + (gloss.text || "?") + "|" + gloss.index + "}}"; if (wordLines) block += "\n" + wordLines; block += "\n{{werger-bin}}"; return block; }); if (!blocks.length) return ""; return "\n==== Werger ====\n" + blocks.join("\n") + "\n"; } }, }; steps.trans.keys = steps.lang.choices; steps.dunde.keys = steps.lang.choices; steps.zarava.keys = getZaravaKeys(steps.lang.choices); var ordered_steps = [ steps.lang, steps.pron, steps.pos, steps.cinsiyet, steps.lektur, steps.tr, steps.dfn, steps.je, steps.tekildar, steps.etym, steps.dunde, steps.binereherwiha, steps.zarava, steps.trans]; // Step ids that belong to each section (not shared across sections). var PER_SECTION_STEP_IDS = [ "pos", "cinsiyet", "lektur", "tr", "dfn", "je", "tekildar", "etym", "dunde", "binereherwiha", "zarava", "trans" ]; // ── Multi-section state ────────────────────────────────────────────────── // Each entry is a plain snapshot: { pos, cinsiyet, lektur, tr, dfn (senses[]), // je, tekildar, binereherwiha, trans (rows[]) }. var sections = [{}]; // section 0 starts empty (DOM is the truth) var activeSection = 0; function snapshotDfn() { return steps.dfn.getSenses($("#wiktku-start-dfn")); } // Rebuilds the dfn DOM from a previously snapshotted senses array. function restoreDfn(senses) { var stepDiv = $("#wiktku-start-dfn"); // Tear down the existing list so build() recreates it cleanly. stepDiv.find("ol.wiktku-dfn-list").remove(); steps.dfn.build(stepDiv); var list = stepDiv.find("ol.wiktku-dfn-list"); $.each(senses, function (i, sense) { // Ensure enough blocks exist (build() seeds one). var blocks = list.find("li.wiktku-dfn-sense"); var block = blocks.eq(i); if (!block.length) { var nb = steps.dfn.buildSenseBlock(stepDiv); list.append(nb); block = list.find("li.wiktku-dfn-sense").last(); } // Template selector. block.find("select.wiktku-dfn-tpl-select").val(sense.tpl || ""); if (sense.tpl) { block.find("textarea.wiktku-dfn-mane").hide(); block.find("input.wiktku-dfn-tpl-title").val(sense.tplTitle || "").show(); } else { block.find("textarea.wiktku-dfn-mane").val(sense.mane || "").show(); block.find("input.wiktku-dfn-tpl-title").hide().val(""); } // Re-sync the formên alternatîv/hevmane/… hide state now that // tplSelect's value was set programmatically (its own "change" // handler doesn't fire from .val(), so this doesn't happen otherwise). var updateVis = block.data("updateFieldVisibility"); if (updateVis) updateVis(); // Restore a sub-list (etiket, formên alternatîv, hevmane …) from a values array. function restoreSubList(cls, values) { if (!values || !values.length) return; var groupDiv = block.find("." + cls + "-group"); var subList = groupDiv.find("ol, ul").first(); if (!subList.length) return; // group not found // Fill existing items, append new ones as needed. $.each(values, function (j, val) { var items = subList.find("li"); if (j < items.length) { items.eq(j).find("textarea").val(val); } else { var ta = $("<textarea></textarea>") .attr("name", "wiktku-dfn-restore-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 1) .attr("class", "wiktku-dfn-subfield wiktku-start-narrow") .val(val); ta.on("input", function () { steps.dfn.onSubInput(subList, this, 1, true); }); subList.append($("<li></li>").append(ta)); } }); } // Reveal and populate lazy groups that have data. var lazyMap = { "wiktku-dfn-etiket": sense.etiket, "wiktku-dfn-kategori": sense.kategori, "wiktku-dfn-alternativ": sense.alternativ, "wiktku-dfn-hevmane": sense.hevmane, "wiktku-dfn-dijmane": sense.dijmane, "wiktku-dfn-koordine": sense.koordine, "wiktku-dfn-jornav": sense.jornav, "wiktku-dfn-jernav": sense.jernav }; $.each(lazyMap, function (cls, vals) { if (vals && vals.length) restoreSubList(cls, vals); }); // Nimûne items are objects { text, tr?, t? } — restore using the builder. if (sense.nimune && sense.nimune.length) { var nimuneGroupDiv = block.find(".wiktku-dfn-nimune-group"); var nimuneList = nimuneGroupDiv.find("ol.wiktku-dfn-nimune-list"); var buildFn = nimuneGroupDiv.data("buildNimuneLi"); nimuneList.empty(); $.each(sense.nimune, function (_, n) { var text = typeof n === "object" ? (n.text || "") : n; if (!text) return; var li = buildFn ? buildFn() : $("<li class='wiktku-dfn-nimune-li'></li>"); li.find(".wiktku-dfn-nimune-text").val(text); if (n.tr) li.find(".wiktku-dfn-nimune-tr").val(n.tr); if (n.t) li.find(".wiktku-dfn-nimune-t").val(n.t); nimuneList.append(li); }); // Always leave a blank trailing item. if (buildFn) nimuneList.append(buildFn()); } // Restore jêder entries — accepts current array shape or a legacy // single object (older saved sections) for backwards compat. var jederArr = $.isArray(sense.jeder) ? sense.jeder : (sense.jeder ? [sense.jeder] : []); if (jederArr.length) { var jederGroupDiv = block.find(".wiktku-dfn-jeder-group"); var jederList = jederGroupDiv.find("ol.wiktku-dfn-jeder-list"); var buildJederFn = jederGroupDiv.data("buildJederLi"); jederList.empty(); $.each(jederArr, function (_, j) { if (!j || !j.quote) return; var li = buildJederFn ? buildJederFn() : $("<li class='wiktku-dfn-jeder-li'></li>"); li.find(".wiktku-dfn-nimune-quote").val(j.quote); if (j.quoteTr) li.find(".wiktku-dfn-nimune-quote-tr").val(j.quoteTr); if (j.quoteT) li.find(".wiktku-dfn-nimune-quote-t").val(j.quoteT); if (j.jederManual) { var manualSel = li.find(".wiktku-dfn-quote-src-sel"); manualSel.val("__manual__").trigger("change"); li.find(".wiktku-dfn-quote-src-manual").val(j.jederManual); } else if (j.jederTpl) { var srcSel = li.find(".wiktku-dfn-quote-src-sel"); srcSel.val(j.jederTpl).trigger("change"); if (j.jêderFields) { $.each(j.jêderFields, function (key, val) { li.find(".wiktku-dfn-quote-src-input[data-field-key='" + key + "']").val(val); }); } } jederList.append(li); }); // Always leave a blank trailing item, same as Nimûne. if (buildJederFn) jederList.append(buildJederFn()); } }); } // Snapshots simple (non-dfn) per-section steps from the DOM into obj. function saveCurrentSection() { var snap = {}; $.each(PER_SECTION_STEP_IDS, function (_, id) { if (id === "dfn") { snap.dfn = snapshotDfn(); return; } if (id === "etym") { snap.etym = $.trim($("#wiktku-start-etym .wiktku-etym-text").val()); return; } var step = steps[id]; if (!step) return; var stepDiv = $("#wiktku-start-" + id); if (id === "trans") { snap.trans = steps.trans.getTranslations(stepDiv); return; } if (id === "zarava") { snap.zarava = steps.zarava.getTranslations(stepDiv); return; } if (id === "dunde") { snap.dunde = steps.dunde.getRows(stepDiv); return; } // Generic: read all step fields. var fields = stepDiv.find(".wiktku-start-step-field"); if (step.multiple) { snap[id] = fields.map(function () { return $(this).val(); }).get(); } else { snap[id] = fields.val(); } }); sections[activeSection] = snap; } // Restores a previously saved snapshot into the form DOM. function restoreSection(snap) { $.each(PER_SECTION_STEP_IDS, function (_, id) { if (id === "dfn") { restoreDfn(snap.dfn || []); return; } if (id === "etym") { $("#wiktku-start-etym .wiktku-etym-wrap").remove(); steps.etym.build($("#wiktku-start-etym")); $("#wiktku-start-etym .wiktku-etym-text").val(snap.etym || ""); return; } if (id === "trans") { // Rebuild trans groups (dfn must already be restored by this // point in the $.each loop, so glossList() reflects it). var transDiv = $("#wiktku-start-trans"); transDiv.find(".wiktku-trans-group").remove(); steps.trans.build(transDiv); var groupsSnap = snap.trans || []; $.each(groupsSnap, function (gi, rows) { var group = transDiv.find(".wiktku-trans-group[data-gloss-pos='" + gi + "']"); if (!group.length) return; // gloss no longer exists — drop its rows var list = group.find("ul.wiktku-trans-list"); $.each(rows, function (j, row) { var lang = row[0], words = row[1]; var lastRow = list.find("li.wiktku-trans-row").last(); lastRow.find("select").val(lang).trigger("change"); var wordList = lastRow.find("ul.wiktku-trans-words"); $.each(words, function (k, word) { var wordItems = wordList.find("li"); if (k < wordItems.length) { wordItems.eq(k).find("textarea").val(word); } else { // .val() below doesn't fire "input", so the normal // auto-grow never runs — append a matching item // ourselves instead of silently dropping the word. var extraInput = steps.trans.makeWordInput(); wordList.append($("<li></li>").append(extraInput)); extraInput.val(word); } }); // Leave one trailing empty field so the row can still grow // when the user types, matching a freshly-built row. if ($.trim(wordList.children("li").last().find("textarea").val())) { wordList.append($("<li></li>").append(steps.trans.makeWordInput())); } }); }); return; } if (id === "zarava") { // Rebuild zarava groups (dfn must already be restored by this // point in the $.each loop, so glossList() reflects it). var zaravaDiv = $("#wiktku-start-zarava"); zaravaDiv.find(".wiktku-zarava-group").remove(); steps.zarava.build(zaravaDiv); var zaravaGroupsSnap = snap.zarava || []; $.each(zaravaGroupsSnap, function (gi, rows) { var group = zaravaDiv.find(".wiktku-zarava-group[data-gloss-pos='" + gi + "']"); if (!group.length) return; // gloss no longer exists — drop its rows var list = group.find("ul.wiktku-zarava-list"); $.each(rows, function (j, row) { var lang = row[0], words = row[1]; var lastRow = list.find("li.wiktku-zarava-row").last(); lastRow.find("select").val(lang).trigger("change"); var wordList = lastRow.find("ul.wiktku-zarava-words"); $.each(words, function (k, word) { var wordItems = wordList.find("li"); if (k < wordItems.length) { wordItems.eq(k).find("textarea").val(word); } else { var extraInput = steps.zarava.makeWordInput(); wordList.append($("<li></li>").append(extraInput)); extraInput.val(word); } }); if ($.trim(wordList.children("li").last().find("textarea").val())) { wordList.append($("<li></li>").append(steps.zarava.makeWordInput())); } }); }); return; } if (id === "dunde") { // Rebuild dunde rows. var dundeDiv = $("#wiktku-start-dunde"); dundeDiv.find("ul.wiktku-dunde-list").remove(); steps.dunde.build(dundeDiv); var dundeRows = snap.dunde || []; $.each(dundeRows, function (i, row) { var lang = row[0], words = row[1]; var list = dundeDiv.find("ul.wiktku-dunde-list"); var lastRow = list.find("li.wiktku-dunde-row").last(); lastRow.find("select").val(lang).trigger("change"); var wordList = lastRow.find("ul.wiktku-dunde-words"); $.each(words, function (j, word) { var wordItems = wordList.find("li"); if (j < wordItems.length) { wordItems.eq(j).find("textarea").val(word); } else { // .val() below doesn't fire "input", so the normal // auto-grow never runs — append a matching item // ourselves instead of silently dropping the word. var extraInput = steps.dunde.makeWordInput(); wordList.append($("<li></li>").append(extraInput)); extraInput.val(word); } }); // Leave one trailing empty field so the row can still grow // when the user types, matching a freshly-built row. if ($.trim(wordList.children("li").last().find("textarea").val())) { wordList.append($("<li></li>").append(steps.dunde.makeWordInput())); } }); return; } var step = steps[id]; if (!step) return; var stepDiv = $("#wiktku-start-" + id); var fields = stepDiv.find(".wiktku-start-step-field"); var val = snap[id]; if (val === undefined || val === null) return; if (step.multiple) { var arr = val; fields.each(function (i) { if (i < arr.length) $(this).val(arr[i]); }); } else { fields.val(val); } // Notify chosen widgets of the programmatic value change. if (!isMobile) fields.filter("select").trigger("chosen:updated"); }); } function getWikitextForCurrentSection(callback) { var values = getValues(); var entry = steps.pos.output(values); steps.dfn.getOutput(values, function (output) { entry += output; entry += steps.je.output(values); entry += steps.tekildar.output(values); entry += steps.etym.output(values); entry += steps.dunde.output(values); entry += steps.binereherwiha.output(values); entry += steps.zarava.output(values); entry += steps.trans.output(values); callback(entry, values); }); } function getWikitextAllSections(callback) { saveCurrentSection(); var results = new Array(sections.length); var sharedValues = getValues(); // lang/pron are shared function processSection(i) { if (i >= sections.length) { // All done — restore original active section. restoreSection(sections[activeSection]); refresh(); callback(results, sharedValues); return; } restoreSection(sections[i]); refresh(); getWikitextForCurrentSection(function (sectionText) { results[i] = sectionText; processSection(i + 1); }); } processSection(0); } // Assembles wikitext for all sections plus the shared lang/pron header. function getWikitext(callback) { getWikitextAllSections(function (sectionTexts, sharedValues) { var entry = steps.lang.output(sharedValues); entry += steps.pron.output(sharedValues); entry += sectionTexts.join("\n"); // Edit summary uses section 0's values. Read from the saved snapshot // (not the live DOM) so it doesn't mix section 0's pos with whichever // section happens to be active/restored at this point. var dfnSenses = (sections[0] && sections[0].dfn) || []; var dfnSummary = dfnSenses.map(function (s) { return s.mane; }).filter(Boolean).join("; "); var summary = "([[Mediawiki:Gadget-start.js|WF:NÛ]] v.2.0) +" + sharedValues.lang + ":" + sections[0].pos + ":" + dfnSummary; var summaryField = document.getElementById("wpSummary"); if (addLangMode && summaryField.value) { summary = summaryField.value + " " + summary; } summaryField.value = summary; callback(entry); }); } var continueBtn; function getValuesForStep(stepId) { var fields = $("#wiktku-start-" + stepId + " .wiktku-start-step-field"); var step = steps[stepId]; if (step.keys) { var values = {}; fields.each(function (i, field) { var key = $(field).prevAll(".wiktku-start-step-keyfield").val(); if (key) values[key] = $(field).val(); }); return values; } else if (step.multiple) { return fields.map(function () { return $(this).val(); }).get(); } return fields.val(); } function getValues() { var values = {}; $.each(steps, function (stepId) { values[stepId] = getValuesForStep(stepId); }); return values; } function populateMenus(inputs, choices, disabledValues) { if (!disabledValues) disabledValues = {}; var vals = inputs.map(function (i, input) { return $(input).val(); }); inputs.empty(); inputs.append($("<option></option>")); $.each(choices, function (j, choice) { // Append the language code in parentheses so that typing a code // (e.g. "ku") in the search box still finds the language name. var displayText = capitalize(choice[1]); if (choice[2] !== undefined) { // This is a language choice [code, name, sortKey] — show code. displayText = capitalize(choice[1]) + " (" + choice[0] + ")"; } var option = $(mw.html.element("option", { value: choice[0] }, displayText)); if (disabledValues[choice[0]]) option.prop("disabled", true); inputs.append(option); }); inputs.val(function (i) { return vals[i]; }); } // Keys to disable for a key menu: already-taken or explicitly disabled. function getDisabledKeys(step) { var occupiedKeys = {}; $("#wiktku-start-" + step.id + " .wiktku-start-step-keyfield").each(function () { occupiedKeys[$(this).val()] = true; }); if (step.disabledKeys) $.extend(occupiedKeys, step.disabledKeys); return occupiedKeys; } function buildKeyInput(step) { if (!step.keys) return undefined; var input = $(mw.html.element("select", { "class": "wiktku-start-step-keyfield wiktku-start-narrow" })); input.attr("data-placeholder", "Hilbijêre " + step.keyName); if (isMobile) { populateMenus(input, step.keys, getDisabledKeys(step)); // On mobile return the wrapper; the select is inside it. // Change events still fire on the inner select. return wrapNativeSelect(input); } input.on("chosen:showing_dropdown", function () { $(this).data("wiktku-defaultValue", $(this).val()); }); input.change(function (_, context) { var inputs = $("#wiktku-start-" + step.id + " .wiktku-start-step-keyfield").not(this); var oldValue = $(this).data("wiktku-defaultValue"); var newValue = context.selected; inputs.find("option[value='" + oldValue + "']").prop('disabled', false); inputs.find("option[value='" + newValue + "']").prop('disabled', true); inputs.trigger("chosen:updated"); }); populateMenus(input, step.keys, getDisabledKeys(step)); return input; } // Adds another text field to the list if the last one now has text. function refreshForTextField(currentInput, step) { currentInput = $(currentInput); var value = currentInput.val(); var item = currentInput.parent(); if (value && !item.next("li").length) { var nextInput = $("<textarea></textarea>") .attr("name", "wiktku-field-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("class", currentInput.attr("class")) .attr("rows", currentInput.attr("rows") || 1); nextInput.on("input", function (evt) { refreshForTextField(evt.target, step); }); var nextKeyInput = buildKeyInput(step); var nextItem = $("<li></li>").append(nextKeyInput).append(nextInput); item.parent().append(nextItem); if (nextKeyInput) nextKeyInput.chosen(chosenOptions); } var canContinue = !continueBtn.isDisabled(); if ((value && !canContinue) || (!value && canContinue)) { refresh(step); } } function prepareInput(input, step) { if (!input) return; if (step.required) input.prop('required', true); input.change(step, refresh); } // Shows/hides steps based on whether their prerequisites are met, and // updates placeholders where applicable. function refresh(evt) { var values = getValues(); var changedStep = evt && evt.data; var didFocus = false; var canContinue = true; // Re-filter template options in every sense block whenever lang changes. $("#wiktku-start-dfn .wiktku-dfn-tpl-select").each(function () { var fn = $(this).data("updateOptions"); if (typeof fn === "function") fn(); }); // Re-filter pronunciation and etymology template dropdowns when language changes. steps.pron.refreshTplSelect(); steps.etym.refreshTplSelect(); // Sync tr/t sub-fields in every nimûne item to the current language. // tr shown when language needs transliteration; t shown when lang !== "ku". (function () { var lang = values.lang || ""; var showTr = needsTransliteration(lang); var showT = lang && lang !== "ku"; $("#wiktku-start-dfn .wiktku-dfn-nimune-list li.wiktku-dfn-nimune-li").each(function () { var li = $(this); // Ensure the sub-wrapper exists when we need it. var subWrap = li.find(".wiktku-dfn-nimune-sub"); // tr field var trTa = li.find(".wiktku-dfn-nimune-tr"); if (showTr && !trTa.length) { if (!subWrap.length) { subWrap = $("<div></div>").addClass("wiktku-dfn-nimune-sub"); li.append(subWrap); } trTa = $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-tr-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 5) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-tr") .attr("placeholder", "Transkrîpsiyon…"); subWrap.prepend(trTa); } else if (!showTr && trTa.length) { trTa.remove(); } // t field var tTa = li.find(".wiktku-dfn-nimune-t"); if (showT && !tTa.length) { if (!subWrap.length) { subWrap = $("<div></div>").addClass("wiktku-dfn-nimune-sub"); li.append(subWrap); } tTa = $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-t-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 5) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-t") .attr("placeholder", "Tercimeya nimûneyê kurmancî…"); subWrap.append(tTa); } else if (!showT && tTa.length) { tTa.remove(); } // Remove the wrapper if it ended up empty. subWrap = li.find(".wiktku-dfn-nimune-sub"); if (subWrap.length && !subWrap.children().length) subWrap.remove(); }); }()); // Sync tr/t sub-fields in every jêder citation to the current language. // tr shown when language needs transliteration; t shown when lang !== "ku". (function () { var lang = values.lang || ""; var showTr = needsTransliteration(lang); var showT = lang && lang !== "ku"; $("#wiktku-start-dfn .wiktku-dfn-jeder-list li.wiktku-dfn-jeder-li").each(function () { var li = $(this); // Ensure the sub-wrapper exists when we need it. It must sit right // after the quote textarea and before the source selector. var subWrap = li.find(".wiktku-dfn-quote-sub"); // tr field var trTa = li.find(".wiktku-dfn-nimune-quote-tr"); if (showTr && !trTa.length) { if (!subWrap.length) { subWrap = $("<div></div>").addClass("wiktku-dfn-quote-sub"); li.find(".wiktku-dfn-nimune-quote").after(subWrap); } trTa = $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-quote-tr-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 2) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-quote-tr") .attr("placeholder", "Transkrîpsiyona jêgirtinê…"); subWrap.prepend(trTa); } else if (!showTr && trTa.length) { trTa.remove(); } // t field var tTa = li.find(".wiktku-dfn-nimune-quote-t"); if (showT && !tTa.length) { if (!subWrap.length) { subWrap = $("<div></div>").addClass("wiktku-dfn-quote-sub"); li.find(".wiktku-dfn-nimune-quote").after(subWrap); } tTa = $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-quote-t-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 2) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-quote-t") .attr("placeholder", "Tercimeya jêgirtinê ya kurmancî…"); subWrap.append(tTa); } else if (!showT && tTa.length) { tTa.remove(); } // Remove the wrapper if it ended up empty. subWrap = li.find(".wiktku-dfn-quote-sub"); if (subWrap.length && !subWrap.children().length) subWrap.remove(); }); }()); $.each(steps, function (stepId, step) { if (typeof(step.visible) === "function" && !step.visible(values)) { $("#wiktku-start-" + stepId).slideUp(); } else { var stepDiv = $("#wiktku-start-" + stepId); if (changedStep !== step && typeof(step.build) === "function") { prepareInput(step.build(stepDiv, values), step); } var input = stepDiv.find(".wiktku-start-step-field"); if (typeof(step.example) === "function") { // .find() above already reaches nested fields (e.g. the dfn // step's mane textareas inside each sense block), so one // assignment covers every step; dfn keeps its own fallback. var exampleText = step.example(values) || (step.id === "dfn" ? "Mane…" : ""); input.attr("placeholder", exampleText); } var didSlideDown; if (!didFocus && stepDiv.css("display") === "none" && step.required) { didSlideDown = function (evt) { input.focus(); }; didFocus = true; } stepDiv.slideDown(didSlideDown); } if (step.required && (values[stepId] === "" || (step.multiple && values[stepId].join("") === ""))) { canContinue = false; } }); continueBtn.setDisabled(!canContinue); } function destroy() { $("#wiktku-start-form, .noafterwizard").slideUp(function () { $(this).remove(); }); $(".noarticletext .nowizard, #editform").slideDown(); $("#ca-edit").removeClass("selected"); $("#ca-wiktku-nowizard").addClass("selected"); } // Priority order for Kurdish dialects and the navz pseudo-code. // Codes listed here come before all other languages; unlisted codes // are sorted alphabetically by their display name via localeCompare. var LANG_PRIORITY = ["navz", "ku", "hac", "sdh", "lki", "ckb", "zza"]; // Inserts a new "== {{ziman|code}} ==" section at the correct sorted // position: navz, then ku/hac/sdh/lki/ckb/zza, then alphabetical by name. function insertNewLangSection(existing, wikitext) { var newCodeMatch = wikitext.match(new RegExp("^" + langHeaderSource("[^}]+"))); var newCode = newCodeMatch ? newCodeMatch[1] : ""; var sections = []; var preamble = ""; var anyHeaderSrc = langHeaderSource("[^}]+"); var firstMatch = new RegExp("^" + anyHeaderSrc, "m").exec(existing); if (!firstMatch) { // No existing lang sections at all — just append. var sep = existing && !/\n\s*$/.test(existing) ? "\n\n" : ""; return existing + sep + wikitext; } // Everything before the first == {{ziman|...}} == is the preamble. var firstSectionStart = firstMatch.index; // Walk back to the start of that line. var lineStart = existing.lastIndexOf("\n", firstSectionStart - 1); var preambleEnd = lineStart !== -1 ? lineStart + 1 : 0; preamble = existing.slice(0, preambleEnd); // Parse each language section: header line + everything until the next header. var body = existing.slice(preambleEnd); // (?![\s\S]) matches only true end-of-string, since a bare "$" with // /m would stop at the section's first line break instead. var langSectionRe = new RegExp( "^(" + anyHeaderSrc + "\\n?)([\\s\\S]*?)(?=\\n" + anyHeaderSrc + "|(?![\\s\\S]))", "gm" ); var m; while ((m = langSectionRe.exec(body)) !== null) { sections.push({ code: m[2], content: m[0] // full text of this section including header }); } // Determine sort rank: priority list first (by index), then alphabetical. function getLangName(code) { var entry = langsByCode[code]; return entry ? entry[1] : code; } function sortRank(code) { var idx = LANG_PRIORITY.indexOf(code); return idx !== -1 ? idx : LANG_PRIORITY.length; } function compareLangs(a, b) { var ra = sortRank(a), rb = sortRank(b); if (ra !== rb) return ra - rb; // Both are outside priority list — sort by display name. return getLangName(a).localeCompare(getLangName(b), userLang); } // Insert the new section into the sorted list. var newSection = { code: newCode, content: wikitext }; var inserted = false; for (var i = 0; i < sections.length; i++) { if (compareLangs(newCode, sections[i].code) < 0) { sections.splice(i, 0, newSection); inserted = true; break; } } if (!inserted) sections.push(newSection); // Re-join: preamble + sections separated by newlines. var joined = sections.map(function (s) { // Ensure each section ends with exactly one newline before the next. return s.content.replace(/\n+$/, ""); }).join("\n"); return preamble + joined + "\n"; } function build() { $(".nowizard, .nowizard .noafterwizard").hide(); var callToAction = $("#wiktku-calltoaction"); var origCallToActionText = callToAction.text(); $(mw.util.addPortletLink("p-views", "#", "Edîtora çavkaniyê veke", "ca-wiktku-nowizard", "Vê rûpelê bi edîtora çavkaniyê çêke", undefined, "#ca-watch")).click(function (evt) { evt.preventDefault(); callToAction.text(origCallToActionText); destroy(); }); if (callToAction.length) { callToAction.text(origCallToActionText + " Forma li jêr ji bo çêkirina madeyeke nû bi kar bîne."); } var startForm = $("<form id='wiktku-start-form'></form>"); var clearPageCheck = null; if (addLangMode) { startForm.append($("<p class='wiktku-addlang-notice'></p>").html( "Bi vê formê tu yê beşeke nû li rûpelê îlawe bikî. Eger ev zimanê ku tu îlawe dikî jixwe di rûpelê de hebe, beşa nû li dawiya vî zimanî dê were îlawekirin. " + "Ji kerema xwe netîceya dawî kontrol bikin, eger problemek derkeve, li <a href='" + mw.util.getUrl('Mediawiki talk:Gadget-start.js') + "'>nîqaşa vê amûrê</a> problemê ragihîne." )); clearPageCheck = $("<input type='checkbox' id='wiktku-clear-page-check'>"); var clearPageLabel = $("<label for='wiktku-clear-page-check'></label>") .text(" Naveroka rûpelê paqij bike (rûpelê ji nû ve binivîse)"); startForm.append( $("<p class='wiktku-addlang-notice'></p>") .append(clearPageCheck) .append(clearPageLabel) ); // Re-evaluate step visibility (e.g. the pron step) whenever this // is toggled, since it changes what counts as "existing content". clearPageCheck.on("change", function () { refresh(); }); } var spinner; // Tab bar for switching between POS sections. var sectionTabsDiv = $("<div id='wiktku-section-tabs'></div>"); startForm.submit(function (evt) { evt.preventDefault(); continueBtn.setDisabled(true); spinner.show(); getWikitext(function (wikitext) { if (addLangMode && clearPageCheck && clearPageCheck.prop("checked")) { // User asked to wipe the page and start fresh — just // write the newly generated wikitext as the full content. $("#wpTextbox1").val(wikitext); } else if (addLangMode) { var textbox = $("#wpTextbox1"); var existing = textbox.val() || ""; // If this language's section already exists (whitespace // differences aside), merge into it; otherwise insert new. var langHeaderMatch = wikitext.match(new RegExp("^(" + langHeaderSource("[^}]+") + "\\n)")); if (langHeaderMatch) { var langHeader = langHeaderMatch[1]; // e.g. "== {{ziman|ku}} ==\n" var newCode = langHeaderMatch[2]; var existingHeader = findLangHeader(existing, newCode); if (existingHeader) { // Strip the header from the new output. var newContent = wikitext.slice(langHeader.length); // Find the insertion point: end of the existing lang section. // A new L2 heading marks the start of the next language block. var searchFrom = existingHeader.index + existingHeader.match.length; // Find the next == … == heading after this section's start. var nextL2 = existing.indexOf("\n== ", searchFrom); var insertAt = nextL2 !== -1 ? nextL2 : existing.length; // Ensure there's a blank line before the inserted block. var before = existing.slice(0, insertAt); var after = existing.slice(insertAt); var sep = /\n\s*$/.test(before) ? "" : "\n"; textbox.val(before + sep + newContent + after); } else { // New language — insert at the correct sorted position. textbox.val(insertNewLangSection(existing, wikitext)); } } else { // Unexpected format — insert at sorted position anyway. textbox.val(insertNewLangSection(existing, wikitext)); } } else { $("#wpTextbox1").val(wikitext); } $("html, body").animate({scrollTop: 0}); callToAction.text("Hindik ma!"); $("#wiktku-preview-container").remove(); destroy(); }); }); $.each(ordered_steps, function (i, step) { var stepDiv = $(mw.html.element("div", { "class": "wiktku-start-step", id: "wiktku-start-" + step.id })); var name = capitalize(step.name); stepDiv.append($(mw.html.element("h3", { "class": "wiktku-start-step-name" }, new mw.html.Raw(mw.html.element("label", { "for": "wiktku-start-" + step.id + "-field" }, name))))); if (step.question_fmt) { stepDiv.append($(mw.html.element("label", { "class": "wiktku-start-step-question", "for": "wiktku-start-" + step.id + "-field" }, step.question_fmt))); if (step.question_br) stepDiv.append($("<br>")); } var input; if (step.choices) { input = $(mw.html.element("select", { "class": "wiktku-start-step-field", id: "wiktku-start-" + step.id + "-field" })); input.attr("data-placeholder", capitalize(step.name) + " hilbijêre "); populateMenus(input, step.choices); if (step.multiple) input.attr("multiple", true); if (isMobile) { stepDiv.append(wrapNativeSelect(input)); } else { stepDiv.append(input); } } else if (typeof(step.build) === "function") { input = step.build(stepDiv); } else { input = $("<textarea></textarea>") .attr("class", "wiktku-start-step-field") .attr("id", "wiktku-start-" + step.id + "-field") .attr("rows", step.rows || 2); if (step.narrow) input.addClass("wiktku-start-narrow"); if (step.multiple) { input.on("input", function (evt) { refreshForTextField(evt.target, step); }); var keyInput = buildKeyInput(step); var list = $(step.ordered ? "<ol></ol>" : "<ul></ul>") .append($("<li></li>").append(keyInput).append(input)); stepDiv.append(list); } else stepDiv.append(input); } prepareInput(input, step); stepDiv.hide(); // Insert tab bar just before the first per-section step. if (step.id === "pos") startForm.append(sectionTabsDiv); startForm.append(stepDiv); }); // ── Section tab helpers ────────────────────────────────────────────── // ── Add-section button — lives in the tab bar, disabled until pos chosen ── var addSectionBtn = new OO.ui.ButtonWidget({ label: "+ Beş zêde bike", disabled: true }); addSectionBtn.on("click", function () { saveCurrentSection(); sections.push({}); activeSection = sections.length - 1; $.each(PER_SECTION_STEP_IDS, function (_, id) { if (id === "dfn") { var stepDiv = $("#wiktku-start-dfn"); stepDiv.find("ol.wiktku-dfn-list").remove(); steps.dfn.build(stepDiv); return; } if (id === "etym") { $("#wiktku-start-etym .wiktku-etym-wrap").remove(); steps.etym.build($("#wiktku-start-etym")); return; } if (id === "trans") { var transDiv = $("#wiktku-start-trans"); transDiv.find(".wiktku-trans-group").remove(); return; } if (id === "zarava") { var zaravaDiv = $("#wiktku-start-zarava"); zaravaDiv.find(".wiktku-zarava-group").remove(); return; } if (id === "dunde") { var dundeDiv = $("#wiktku-start-dunde"); dundeDiv.find("ul.wiktku-dunde-list").remove(); return; } var stepDiv = $("#wiktku-start-" + id); stepDiv.find(".wiktku-start-step-field").val(""); if (!isMobile) stepDiv.find("select.wiktku-start-step-field").trigger("chosen:updated"); }); renderSectionTabs(); refresh(); $("html, body").animate({ scrollTop: sectionTabsDiv.offset().top - 20 }, 300); }); /** Re-render the tab bar to reflect current sections[] and activeSection. */ function renderSectionTabs() { // Detach (not remove) the button first: .empty() strips bound // event data from any children left inside it, which would // silently kill addSectionBtn's click handler on every re-render. addSectionBtn.$element.detach(); sectionTabsDiv.empty(); var lang = getValues().lang || ""; if (!lang) { sectionTabsDiv.hide(); return; } sectionTabsDiv.show(); $.each(sections, function (i) { var posVal = sections[i].pos || ""; var tabLabel = posVal ? capitalize(posVal) : ("Beş " + (i + 1)); var tab = $("<span></span>") .addClass("wiktku-section-tab") .text(tabLabel) .toggleClass("wiktku-tab-active", i === activeSection); (function (idx) { tab.on("click", function () { if (idx === activeSection) return; saveCurrentSection(); activeSection = idx; restoreSection(sections[activeSection]); refresh(); renderSectionTabs(); }); }(i)); sectionTabsDiv.append(tab); }); // Enable "Beş zêde bike" only when the active section has a pos chosen. var activePos = sections[activeSection] && sections[activeSection].pos ? sections[activeSection].pos : getValues().pos; addSectionBtn.setDisabled(!activePos); sectionTabsDiv.append(addSectionBtn.$element); } renderSectionTabs(); // Update the active tab's label whenever pos changes. startForm.on("change", "#wiktku-start-pos-field", function () { renderSectionTabs(); }); // Show the tab bar as soon as a language is selected. startForm.on("change", "#wiktku-start-lang-field", function () { renderSectionTabs(); }); var footer = $("<div id='wiktku-start-footer'></div>"); spinner = $(mw.html.element("img", { id: "wiktku-start-spinner", src: "//upload.wikimedia.org/wikipedia/commons/d/de/Ajax-loader.gif", alt: "Tê barkirin…", title: "Tê barkirin…" })); footer.append(spinner.hide()); continueBtn = new OO.ui.ButtonWidget({ id: "wiktku-unhide-editform", label: "Bişîne", flags: [ "primary", "progressive" ] }); continueBtn.on("click", function () { mw.notify("Tê şandin…", { type: "info", tag: "wiktku-submit" }); startForm.trigger("submit"); }); footer.append(continueBtn.$element); // "Edîtora çavkaniyê veke" button — inline fallback for the portlet link // which is invisible on mobile and easy to miss on desktop. var sourceEditorBtn = new OO.ui.ButtonWidget({ label: "Edîtora çavkaniyê veke", framed: false }); sourceEditorBtn.on("click", function () { destroy(); }); footer.append(sourceEditorBtn.$element); // ── Preview checkboxes ─────────────────────────────────────────────── // Wikitext preview (raw text panel) var previewCheck = $("<input type='checkbox' id='wiktku-preview-toggle'>"); var previewLabel = $("<label for='wiktku-preview-toggle'></label>") .text(" Pêşdîtina wîkîtekstê"); var previewPanel = $("<pre id='wiktku-preview-panel'></pre>").hide(); // Live rendered preview (parsed HTML panel, same logic as AjaxEdit). // Not available on mobile — API polling causes too many problems on small screens. var livePreviewCheck = null; var livePreviewPanel = null; if (!isMobile) { livePreviewCheck = $("<input type='checkbox' id='wiktku-live-preview-toggle'>"); livePreviewPanel = $("<div id='wiktku-live-preview-panel'></div>").hide(); } // Container that holds both panels and switches between stacked / side-by-side. var previewContainer = $("<div id='wiktku-preview-container'></div>"); previewContainer.append(previewPanel); if (!isMobile) previewContainer.append(livePreviewPanel); var previewTimer = null; var livePreviewIntervalId = -1; var livePreviewActive = false; // guards in-flight fetches after uncheck /** Rebuilds wikitext preview if its checkbox is checked. */ function schedulePreview() { if (!previewCheck.prop("checked")) return; clearTimeout(previewTimer); // Debounce: wait 400 ms after the last keystroke before rebuilding. previewTimer = setTimeout(function () { getWikitext(function (wikitext) { previewPanel.text(wikitext).show(); updatePanelLayout(); }); }, 400); } /** Fetches parsed HTML and populates the live preview panel. */ function loadLivePreview() { getWikitext(function (wikitext) { new mw.Api().parse(wikitext, { title: mw.config.get("wgPageName") }).done(function (html) { // Discard result if the user unchecked while the fetch was in flight. if (!livePreviewActive) return; livePreviewPanel.html(html).show(); updatePanelLayout(); }); }); } /** Adjusts panel widths depending on which previews are visible. */ function updatePanelLayout() { var wikitextVisible = previewCheck.prop("checked"); var liveVisible = livePreviewCheck && livePreviewCheck.prop("checked"); if (wikitextVisible && liveVisible) { // Side by side — each panel takes roughly half the available width. previewPanel.css({ "flex": "1 1 45%", "min-width": "280px" }); livePreviewPanel.css({ "flex": "1 1 45%", "min-width": "280px" }); } else { // Full width for whichever is visible — only touch panels that are // actually shown so that setting flex doesn't override display:none. if (wikitextVisible) previewPanel.css({ "flex": "1 1 100%", "min-width": "" }); if (liveVisible && livePreviewPanel) livePreviewPanel.css({ "flex": "1 1 100%", "min-width": "" }); } } previewCheck.on("change", function () { if ($(this).prop("checked")) { schedulePreview(); } else { clearTimeout(previewTimer); previewPanel.hide(); updatePanelLayout(); } }); if (!isMobile) { livePreviewCheck.on("change", function () { if ($(this).prop("checked")) { livePreviewActive = true; livePreviewPanel.show(); loadLivePreview(); livePreviewIntervalId = setInterval(loadLivePreview, 500); } else { livePreviewActive = false; clearInterval(livePreviewIntervalId); livePreviewIntervalId = -1; livePreviewPanel.hide().empty(); updatePanelLayout(); } }); } // Listen on all input/change events on the form and update both previews. startForm.on("input change", function () { schedulePreview(); }); footer.append($("<span style='margin-left:1em'></span>") .append(previewCheck).append(previewLabel)); if (!isMobile) { var livePreviewLabel = $("<label for='wiktku-live-preview-toggle'></label>") .text(" Pêşdîtina zindî"); footer.append($("<span style='margin-left:1em'></span>") .append(livePreviewCheck).append(livePreviewLabel)); } startForm.append(footer); $("#editform").hide().before(startForm); // Insert preview container (holds both panels) after the form. startForm.after(previewContainer); if (!isMobile) startForm.find("select").chosen(chosenOptions); refresh(); // Zimanan ji MediaWiki:Gadget-translation_editor.js/ziman.json bar bike. // Kodên ku bi "-pro" diqedin û navên ku "zimanê destan" tê de heye // tên derxistin. Zimanên xardkirî li serî dimînin, yên din // bi alfabeyê li dû wan tên. // Pinned choices come from MediaWiki:Gadget-start.js/data.json (langChoices), // already loaded into steps.lang.choices before build() runs. var pinnedChoices = steps.lang.choices.slice(); var pinnedCodes = $.map(pinnedChoices, function (choice) { return choice[0]; }); new mw.Api().get({ action: "query", prop: "revisions", titles: "MediaWiki:Gadget-translation_editor.js/ziman.json", rvprop: "content", rvslots: "main", formatversion: 2 }).then(function (data) { var page = data.query.pages[0]; var content = page && page.revisions && page.revisions[0].slots.main.content; var zimanData; try { zimanData = JSON.parse(content); } catch (e) { zimanData = {}; } var extraChoices = []; $.each(zimanData, function (code, name) { // Filter: skip proto-language codes and legendary/reconstructed langs. if (/-pro$/i.test(code)) return; if (/ziman[eê]\s+destan/i.test(name)) return; // Skip codes already in the pinned list (they are handled above). if (pinnedCodes.indexOf(code) !== -1) return; // sortKey: bare name without leading "zimanê " for sorting. var sortKey = name.replace(/^ziman[eê]\s+/i, ""); var choice = [code, name, sortKey]; extraChoices.push(choice); langsByCode[code] = choice; }); // Populate langsByCode for pinned choices too. $.each(pinnedChoices, function (i, choice) { // Ensure pinned choices have a sortKey (index 2). if (choice.length < 3) choice[2] = choice[1]; langsByCode[choice[0]] = choice; }); // Sort the extra choices alphabetically by sort key. extraChoices.sort(function (a, b) { return a[2].localeCompare(b[2], userLang); }); // Final list: pinned first, then the rest. var allChoices = pinnedChoices.concat(extraChoices); steps.lang.choices = allChoices; steps.trans.keys = allChoices; steps.dunde.keys = allChoices; steps.zarava.keys = getZaravaKeys(allChoices); var langMenu = $("#wiktku-start-lang-field"); populateMenus(langMenu, steps.lang.choices); langMenu.trigger("chosen:updated"); var transMenus = $("#wiktku-start-trans .wiktku-start-step-keyfield"); populateMenus(transMenus, steps.trans.keys, getDisabledKeys(steps.trans)); transMenus.trigger("chosen:updated"); var dundeMenus = $("#wiktku-start-dunde .wiktku-start-step-keyfield"); populateMenus(dundeMenus, steps.dunde.keys, getDisabledKeys(steps.dunde)); dundeMenus.trigger("chosen:updated"); var zaravaMenus = $("#wiktku-start-zarava .wiktku-start-step-keyfield"); populateMenus(zaravaMenus, steps.zarava.keys, getDisabledKeys(steps.zarava)); }); } mw.loader.using(["jquery.chosen", "mediawiki.api", "oojs-ui-core"], function () { if (!isMobile) { mw.notify( "Amûr dest pê dike, hinek bisekinin. Not: jkx Sentaks (sentaks highlighter) neaktîv bikin", { type: "info", tag: "wiktku-start-notice", autoHide: true, autoHideSeconds: 10 } ); } // Load metadata, langChoices, posChoices and tplDefs from the companion // data page so they can be updated without touching this script. new mw.Api().get({ action: "query", prop: "revisions", titles: "MediaWiki:Gadget-start.js/data.json", rvprop: "content", rvslots: "main", formatversion: 2 }).then(function (data) { var page = data.query.pages[0]; var content = page && page.revisions && page.revisions[0].slots.main.content; var d; try { d = JSON.parse(content); } catch (e) { d = {}; } // Populate metadata. if (d.metadata) $.extend(metadata, d.metadata); // Populate gender labels. if (d.genderLabels) $.extend(GENDER_BASE_LABELS, d.genderLabels); // Populate lang choices (pinned list used by build() → ziman.json loader). if (d.langChoices) steps.lang.choices = d.langChoices; // Populate POS choices. if (d.posChoices) steps.pos.choices = d.posChoices; // Populate template definitions for the dfn sense-block builder. if (d.tplDefs) steps.dfn.tplDefs = d.tplDefs; // Populate pos placeholder examples. if (d.posExamples) steps.dfn.posExamples = d.posExamples; // Populate citation template definitions for the quote widget. if (d.jederDefs) steps.dfn.jederDefs = d.jederDefs; // Populate pronunciation and etymology template insert lists. if (d.pronTpls) { steps.pron.pronTpls = d.pronTpls; steps.pron.refreshTplSelect(); } if (d.etymTpls) { steps.etym.etymTpls = d.etymTpls; steps.etym.refreshTplSelect(); } // Sync trans/dunde/zarava keys with the (now populated) lang choices. steps.trans.keys = steps.lang.choices; steps.dunde.keys = steps.lang.choices; steps.zarava.keys = getZaravaKeys(steps.lang.choices); }).always(build); }); }); //</nowiki> h2xrwf3aoc6saerzvq3ery7a6cpekye 6265606 6265604 2026-07-19T15:56:23Z Wikihez 7344 6265606 javascript text/javascript // Li ser [[vi:MediaWiki:Gadget-start.js]] hatiye refaktorkirin. //<nowiki> $(function () { if (window.location.href.includes("editintro=User:Wikihez/creation/intro")) { return; // Do not run the script wextê WF:Bilez dişuxile } var ns = mw.config.get("wgNamespaceNumber"); if (ns && !(ns === 2 && mw.config.get("wgPageName").match(/\/ceribandin$|\/test$/))) { return; } var action = mw.config.get("wgAction"); var pageExists = !!mw.config.get("wgArticleId"); // "Zimanek lê zêde bike" mode: triggered from the portlet link below. var addLangMode = pageExists && mw.util.getParamValue("wiktkuaddlang") === "1"; // On a normal page view of an existing page, add the portlet link if (action === "view" && pageExists) { var targetContainer; var skin = mw.config.get('skin'); if (skin === 'vector-2022') { targetContainer = 'p-cactions'; } else if (skin === 'vector') { targetContainer = 'p-tb'; } else { targetContainer = 'p-views'; } mw.util.addPortletLink(targetContainer, mw.util.getUrl(mw.config.get("wgPageName"), { action: "submit", wiktkuaddlang: "1" }), "+Ziman/beşeke din", "ca-wiktku-addlang", "Ji vê rûpelê re ziman an jî beşeke nû zêde bike"); return; } if (!(action === "edit" || action === "submit")) { return; } if (!addLangMode && !$(".mw-newarticletext, .mw-newarticletextanon").length) { return; } function capitalize(str) { if (!str) return str; return str[0].toUpperCase() + str.substr(1); } function decapitalize(str) { if (!str) return str; return str[0].toLowerCase() + str.substr(1); } function escapeRegExp(str) { return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); } // Regex source for a "== {{ziman|CODE}} ==" header, tolerant of extra // whitespace. codePattern: escaped code for one language, or "[^}]+" for any. function langHeaderSource(codePattern) { return "==\\s*\\{\\{\\s*ziman\\s*\\|\\s*(" + codePattern + ")\\s*\\}\\}\\s*=="; } // Finds a language's header in wikitext (see langHeaderSource). Returns // { index, match } or null. function findLangHeader(text, code) { var m = new RegExp(langHeaderSource(escapeRegExp(code))).exec(text); return m ? { index: m.index, match: m[0] } : null; } function stripWikilinks(str) { return str.replace(/\[\[([^\]|]+)(?:\|([^\]]+))?\]\]/g, function (m, target, display) { return display || target; }); } function insertAtCursor(el, text) { var start = el.selectionStart; var end = el.selectionEnd; var val = el.value; el.value = val.slice(0, start) + text + val.slice(end); var pos = start + text.length; el.selectionStart = el.selectionEnd = pos; } var pageName = mw.config.get("wgPageName").replaceAll(/_/g, " "); if (ns) pageName = pageName.replace(/.*\//, ""); var pageNameRe = escapeRegExp(pageName); var userLang = mw.config.get("wgUserLanguage"); // Mobile detection: MobileFrontend sets wgMFMode, or fall back to touch check. var isMobile = !!mw.config.get("wgMFMode") || window.matchMedia("(pointer: coarse)").matches; var chosenOptions = { width: "20em", disable_search_threshold: 0, placeholder_text_single: "Yekî hilbijêre", placeholder_text_multiple: "Hilbijêre", no_results_text: "Nehat dîtin", enable_split_word_search: true, search_contains: true }; function wrapNativeSelect(select) { var placeholder = select.attr("data-placeholder") || "Lê bigere…"; // Hide the native select — we drive it programmatically. select.hide(); var wrapper = $("<span class='wiktku-native-select-wrap'></span>"); var textInput = $("<input type='search' autocomplete='off'>") .attr("placeholder", placeholder) .addClass("wiktku-start-narrow wiktku-ac-input"); var resultsList = $("<ul class='wiktku-ac-results'></ul>").hide(); // Full option cache — rebuilt when chosen:updated fires. var allOptions = []; function cacheOptions() { allOptions = []; select.find("option").each(function () { var v = $(this).val(); if (!v) return; // skip the empty placeholder option allOptions.push({ value: v, text: $(this).text(), disabled: $(this).prop("disabled") }); }); } cacheOptions(); function showResults(query) { var q = query.trim().toLowerCase(); resultsList.empty(); var matched; if (q) { matched = []; $.each(allOptions, function (_, o) { if (o.disabled) return; var codeMatch = o.value.toLowerCase().indexOf(q) !== -1; var nameMatch = o.text.toLowerCase().indexOf(q) !== -1; if (codeMatch || nameMatch) { matched.push({ opt: o, codeMatch: codeMatch }); } }); // Code matches (especially prefix matches) come first. matched.sort(function (a, b) { var aCode = a.opt.value.toLowerCase(); var bCode = b.opt.value.toLowerCase(); var aPrefix = aCode.indexOf(q) === 0; var bPrefix = bCode.indexOf(q) === 0; if (aPrefix !== bPrefix) return aPrefix ? -1 : 1; if (a.codeMatch !== b.codeMatch) return a.codeMatch ? -1 : 1; return 0; }); matched = matched.map(function (item) { return item.opt; }); } else { matched = allOptions.filter(function (o) { return !o.disabled; }); } if (!matched.length) { resultsList.hide(); return; } $.each(matched.slice(0, 50), function (_, opt) { var li = $("<li></li>").text(opt.text).attr("data-value", opt.value); // touchend (not touchstart) so a scroll doesn't trigger a select. var touchMoved = false; li.on("touchstart", function () { touchMoved = false; }); li.on("touchmove", function () { touchMoved = true; }); li.on("touchend", function (e) { if (touchMoved) return; // was a scroll, not a tap e.preventDefault(); selectOption(opt.value, opt.text); }); // Keep mousedown for desktop fallback. li.on("mousedown", function (e) { e.preventDefault(); selectOption(opt.value, opt.text); }); resultsList.append(li); }); // Position the list above or below depending on available viewport space. var inputRect = textInput[0].getBoundingClientRect(); var viewportH = window.innerHeight; var spaceBelow = viewportH - inputRect.bottom - 8; var spaceAbove = inputRect.top - 8; var maxH = Math.min(224, Math.max(spaceBelow, spaceAbove)); // 224px ≈ 14em resultsList.css({ "max-height": maxH + "px", "top": spaceBelow >= spaceAbove ? "100%" : "auto", "bottom": spaceBelow >= spaceAbove ? "auto" : "100%" }); resultsList.show(); } function selectOption(value, text) { textInput.val(text); select.val(value); resultsList.hide(); select.trigger("change"); } textInput.on("input focus", function () { showResults($(this).val()); }); textInput.on("blur", function () { // Short delay so a touchstart on a result item fires first. setTimeout(function () { resultsList.hide(); }, 200); }); // chosen:updated → re-cache (called after ziman.json loads). select.on("chosen:updated", function () { cacheOptions(); // If a value is already selected, keep the display text in sync. var cur = select.val(); if (cur) { var match = $.grep(allOptions, function (o) { return o.value === cur; })[0]; if (match) textInput.val(match.text); } }); // No-op .chosen() so desktop call-sites don't need guarding. select.chosen = function () { return select; }; wrapper.append(textInput).append(resultsList).append(select); return wrapper; } var langsByCode = {}; // Populated from [[MediaWiki:Gadget-start.js/data.json]] at runtime. var metadata = {}; // Zaravayên kurdî yên ku di beşa "Bi zaravayên din" de tên pêşkêşkirin — // ev kod ji beşa Werger têne derxistin daku heman zimên du caran neyê xwendin. var ZARAVA_LANG_CODES = ["ckb", "sdh", "lki", "hac", "zza"]; function getZaravaKeys(choices) { var byCode = {}; $.each(choices || [], function (_, c) { byCode[c[0]] = c; }); var result = []; $.each(ZARAVA_LANG_CODES, function (_, code) { if (byCode[code]) result.push(byCode[code]); }); return result; } function needsTransliteration(langCode) { var meta = metadata[langCode]; if (!meta || !meta.sc) return false; var scripts = Array.isArray(meta.sc) ? meta.sc : [meta.sc]; return scripts.length > 0 && scripts[0] !== "Latn"; } // Kodên cinsiyetê yên di metadata.g de — ji data.json tê dagirtin var GENDER_BASE_LABELS = {}; // Sub-lists that only make sense for a plain (non-şablon) sense — hidden // when a şablon (e.g. {{guharto|…}}) is chosen for that sense, since a // template-based sense has no "own" gloss for alternate forms, synonyms, // antonyms, coordinate terms, hypernyms or hyponyms to attach to. Etîket, // Nimûne and Jêgirtin stay visible either way. var HIDDEN_ON_TPL_GROUPS = [ "wiktku-dfn-alternativ", "wiktku-dfn-hevmane", "wiktku-dfn-dijmane", "wiktku-dfn-koordine", "wiktku-dfn-jornav", "wiktku-dfn-jernav" ]; function genderLabel(code) { if (code === "p") return "Pirjimar"; var pluralMatch = code.match(/^(.+)-p$/); if (pluralMatch && GENDER_BASE_LABELS[pluralMatch[1]]) { return GENDER_BASE_LABELS[pluralMatch[1]] + " (pirjimar)"; } return GENDER_BASE_LABELS[code] || code; } // True if a sense has content beyond mane worth keeping (etîket, word // lists, nimûne, jêder) — so it's still emitted with {{mane?}} if empty. function senseHasExtraContent(s) { if (s.etiket && $.grep(s.etiket, function (e) { return $.trim(e) !== ""; }).length) return true; if (s.kategori && $.grep(s.kategori, function (k) { return $.trim(k) !== ""; }).length) return true; if (s.alternativ.length || s.hevmane.length || s.dijmane.length || s.koordine.length || s.jornav.length || s.jernav.length) return true; if (s.nimune && $.grep(s.nimune, function (n) { return (typeof n === "object" ? n.text : n) !== ""; }).length > 0) return true; if (senseHasJeder(s)) return true; return false; } // Each nimûne item can be { text, tr, t }: text, transliteration, translation. function formatNimune(nimunes, lang, hasJeder) { var hasNimune = nimunes && $.grep(nimunes, function (n) { return (typeof n === "object" ? n.text : n) !== ""; }).length > 0; if (!hasNimune) { return hasJeder ? "" : "\n#* {{bênimûne|" + lang + "}}"; } return $.map(nimunes, function (n) { var text = typeof n === "object" ? n.text : n; if (!text) return undefined; var bolded = text.replace( new RegExp("(" + pageNameRe + "([^( |,|;|\\?|\\.|\\!)]+)?)", "ig"), "'''$1'''"); var tpl = "\n#: {{nm|" + lang + "|" + bolded; if (typeof n === "object") { if (n.tr) tpl += "|tr=" + n.tr; // Translation as third positional param (no key needed). if (n.t) tpl += "|" + n.t; } // Short examples fit on one line together with their translation. // rêz=1 is not used for ku — definitions are shown on separate lines there. if (text.length < 200 && lang !== "ku") tpl += "|rêz=1"; tpl += "}}"; return tpl; }).join(""); } // Formats jêder (citation) entries into "#* {{jêder…|…}}" lines; skips // entries with no quote text. Falls back to the generic {{jêder}} // template when no specific template was chosen. function formatJeder(jederList, lang) { if (!jederList || !jederList.length) return ""; return $.map(jederList, function (jeder) { if (!jeder || !jeder.quote) return undefined; if (jeder.jederTpl) { var cite = "\n#* {{" + jeder.jederTpl + "|" + lang; cite += "|jêgirtin=" + jeder.quote; if (jeder.quoteTr) cite += "|tr=" + jeder.quoteTr; if (jeder.quoteT) cite += "|tercime=" + jeder.quoteT; $.each(jeder.jêderFields || {}, function (key, val) { if (val) cite += "|" + key + "=" + val; }); cite += "}}"; return cite; } var out = "\n#* {{jêder|" + lang + "|jêgirtin=" + jeder.quote; if (jeder.quoteTr) out += "|tr=" + jeder.quoteTr; if (jeder.quoteT) out += "|tercime=" + jeder.quoteT; var srcParam = jeder.jederManual ? jeder.jederManual : "çavkanî?"; // A positional param containing "=" gets parsed as its own key=value // pair by MediaWiki and breaks the template, so force it to be // explicitly named (|2=) whenever that's the case. out += (srcParam.indexOf("=") !== -1 ? "|2=" : "|") + srcParam; out += "}}"; return out; }).join(""); } // True if a sense has at least one jêder entry with quote text. function senseHasJeder(sense) { return !!(sense.jeder && $.grep(sense.jeder, function (j) { return j && j.quote; }).length > 0); } // Builds "{{tplName|lang|part1|part2|…}}" from a sense field (kategori, // etiket), wrapped inline (" {{…}} ") or on its own line ("\n#: {{…}}"). function buildSenseTpl(sense, field, lang, tplName) { if (!sense[field] || !sense[field].length) return ""; var parts = sense[field].map(function (p) { return $.trim(p); }) .filter(function (p) { return p !== ""; }); if (!parts.length) return ""; var call = "{{" + tplName + "|" + lang + "|" + parts.join("|") + "}}"; return call } /** * Assembles the nimûne + jêder wikitext block for a sense. Shared by * both the template-sense and normal-mane-sense branches below. */ function buildCite(sense, lang) { return formatNimune(sense.nimune, lang, senseHasJeder(sense)) + formatJeder(sense.jeder, lang); } function makeWordListStep(id, name, question_fmt, header, templateName) { return { id: id, name: name, question_fmt: question_fmt, multiple: true, narrow: true, visible: function (values) { return values.lang && values.pos; }, output: function (values) { var words = $.grep(values[id] || [], function (w) { return !!w; }); if (!words.length) return ""; var lang = values.lang; var section = "\n==== " + header + " ====\n"; if (words.length === 1) { // Single word — keep the simple inline template. return section + "* {{" + templateName + "|" + lang + "|" + words[0] + "}}\n"; } // Multiple words — use {{kol3}} with one positional param per word. var params = "cure=" + header + "\n" + $.map(words, function (w) { return "|" + w; }).join("\n"); return section + "{{kol3|" + lang + "|" + params + "\n}}\n"; } }; } var steps = { lang: { id: "lang", required: true, name: "ziman", question_fmt: '"' + pageName + '" bi çi zimanî ye?', question_br: true, // Populated from [[MediaWiki:Gadget-start.js/data.json]] (langChoices). choices: [], output: function (values) { return "== {{ziman|" + values.lang + "}} ==\n"; } }, pron: { id: "pron", name: "bilêvkirin", question_fmt: '"' + pageName + '" çawa tê telafûzkirin?', // pronTpls populated from data.json pronTpls: [], visible: function (values) { if (!values.lang) return false; // addLangMode: skip pron only if this lang already has a section. if (addLangMode) { // Clearing the page makes existing content irrelevant. var clearPageCheck = $("#wiktku-clear-page-check"); if (clearPageCheck.length && clearPageCheck.prop("checked")) { return true; } var existing = $("#wpTextbox1").val() || ""; return !findLangHeader(existing, values.lang); } return true; }, // Fills the insert-dropdown from pronTpls, filtered by language. refreshTplSelect: function () { var sel = $("#wiktku-start-pron .wiktku-tpl-insert-select"); if (!sel.length) return; var lang = getValues().lang || ""; sel.find("option[value!='']").remove(); $.each(steps.pron.pronTpls, function (_, tpl) { // Filter: if tpl.langs exists, only show if lang is in that list; otherwise show always var allowed = !tpl.langs || tpl.langs.indexOf(lang) !== -1; if (allowed) { sel.append($("<option></option>") .val(tpl.snippet) .text(tpl.name + " — " + tpl.desc) .attr("data-nolang", tpl.noLang ? "1" : "")); } }); // Notify Chosen that the option list has changed (no-op on mobile). if (!isMobile) sel.trigger("chosen:updated"); }, build: function (stepDiv) { if (stepDiv.find(".wiktku-pron-wrap").length) return null; var wrap = $("<div class='wiktku-pron-wrap'></div>"); var ta = $("<textarea></textarea>") .attr("name", "wiktku-pron-" + $.now()) .attr("class", "wiktku-start-step-field wiktku-pron-text") .attr("rows", 4) .attr("placeholder", "Nimûne: {{IPA|ku|/pɛɪ̯n/}} yan {{kîte|ku|he|ce|ki|rin}}"); // Template insert dropdown — filtered by language. var sel = $("<select class='wiktku-tpl-insert-select'></select>"); sel.append($("<option value=''>— şablonek lê zêde bike —</option>")); var lang = getValues().lang || ""; $.each(steps.pron.pronTpls, function (_, tpl) { // Filter: if tpl.langs exists, only show if lang is in that list; otherwise show always var allowed = !tpl.langs || tpl.langs.indexOf(lang) !== -1; if (allowed) { sel.append($("<option></option>") .val(tpl.snippet) .text(tpl.name + " — " + tpl.desc) .attr("data-nolang", tpl.noLang ? "1" : "")); } }); sel.on("change", function () { var snippet = $(this).val(); if (!snippet) return; var lang = getValues().lang || ""; // Check if the selected option has noLang flag var selectedOption = sel.find("option:selected"); var hasNoLang = selectedOption.attr("data-nolang") === "1"; if (!hasNoLang) { snippet = snippet.replace(/CODE/g, lang).replace(/SOURCELANG/g, "?"); } insertAtCursor(ta[0], snippet); $(this).val(""); ta.focus(); }); wrap.append(sel).append($("<br>")).append(ta); stepDiv.append(wrap); return ta; }, output: function () { var text = $.trim($("#wiktku-start-pron .wiktku-pron-text").val()); if (!text) return ""; var lines = text.split("\n"); var out = $.map(lines, function (line) { line = $.trim(line); if (!line) return undefined; return line.charAt(0) === "*" ? line : "* " + line; }).join("\n"); return "\n=== Bilêvkirin ===\n" + out + "\n"; } }, pos: { id: "pos", required: true, name: "Cureyê rêzimanî", question_fmt: 'Cureyê rêzimanî yê "' + pageName + '" çi ye?', visible: function (values) { return values.lang; }, question_br: true, // Populated from [[MediaWiki:Gadget-start.js/data.json]] (posChoices). choices: [], output: function (values) { var pos = values.pos || ""; var cinsiyet = values.cinsiyet || ""; // from the cinsiyet step var lekTur = values.lektur || ""; // from the lêker transitivity step var capitalizedPos = capitalize(pos); var outputString = "\n=== " + capitalizedPos + " ===\n"; // Add ku-tewîn-nav for single-word navdêr/serenav with known gender. if (!pageName.includes(" ") && cinsiyet && GENDER_BASE_LABELS[cinsiyet] && (pos === "navdêr" || pos === "serenav") && values.lang === "ku") { outputString += "{{ku-tewîn-nav|" + pageName + "|" + GENDER_BASE_LABELS[cinsiyet]; if (pos === "serenav") outputString += "|y"; outputString += "}}\n"; } outputString += "{{" + pos + "|" + values.lang; if (pos === "navdêr" || pos === "serenav") { if (cinsiyet) { outputString += "|c=" + cinsiyet; } else if (values.lang === "ku") { // Unknown gender — prompt editor to fill it in. outputString += "|c=?"; } } else if (/^lêker/.test(pos) && lekTur) { outputString += "|c=" + lekTur; } if (values.tr) { outputString += "|tr=" + values.tr; } outputString += "}}\n"; return outputString; } }, // cinsiyet (gender) — shown for navdêr/serenav only, with choices built // from metadata[lang].g since not every language has grammatical gender. cinsiyet: { id: "cinsiyet", name: "cinsiyet", question_fmt: 'Cinsiyeta "' + pageName + '" çi ye?', question_br: true, visible: function (values) { var meta = metadata[values.lang]; return !!(values.lang && (values.pos === "navdêr" || values.pos === "serenav") && meta && meta.g && meta.g.length); }, build: function (stepDiv, values) { var select = stepDiv.find("select.wiktku-start-step-field"); if (!select.length) { select = $(mw.html.element("select", { "class": "wiktku-start-step-field", id: "wiktku-start-cinsiyet-field" })); stepDiv.append(select); } if (!values) return select; var meta = metadata[values.lang]; var codes = (meta && meta.g) || []; var prevVal = select.val(); var choices = $.map(codes, function (code) { return [[code, genderLabel(code)]]; }); populateMenus(select, choices); if ($.grep(choices, function (c) { return c[0] === prevVal; }).length) { select.val(prevVal); } if (!isMobile) select.trigger("chosen:updated"); return select; }, output: function () { return ""; } // consumed by pos.output }, // Lêker transitivity — shown for any lêker variant. lektur: { id: "lektur", name: "Cureyê lêkerê (fiîlê)", question_fmt: "Cureyê lêkerê (fiîlê) çi ye?", question_br: true, visible: function (values) { return values.lang && values.pos && /^lêker/.test(values.pos); }, // Dictionary: value → display label. Add new types here. choices: [ ["gh", "gerguhêz"], ['x-gh', 'xwerû-gerguhêz'], ['p-gh', 'pêkhatî-gerguhêz'], ['h-gh', 'hevedudanî-gerguhêz'], ['b-gh', 'biwêjî-gerguhêz'], ["ngh", "negerguhêz"], ['x-ngh', 'xwerû-negerguhêz'], ['p-ngh', 'pêkhatî-negerguhêz'], ['h-ngh', 'hevedudanî-negerguhêz'], ['b-ngh', 'biwêjî-negerguhêz'] ], output: function () { return ""; } // consumed by pos.output }, tr: { id: "tr", name: "transkrîpsiyon", question_fmt: "Transkrîpsiyona kelîmeyê", multiple: false, narrow: true, visible: function (values) { return values.lang && values.pos && needsTransliteration(values.lang); } }, dfn: { id: "dfn", // required: true, ger mane tinebe [[Şablon:mane?]] bi kar bîne name: "Mane", question_fmt: "Maneya kelîmeyê binivîse. Mane otomatîk tê lînkkirin! Ji bo tercimeyan beşa 'Werger' bi kar bîne!", multiple: true, ordered: true, rows: 3, visible: function (values) { return values.lang && values.pos; }, example: function (values) { // posExamples loaded from [[MediaWiki:Gadget-start.js/data.json]]. var examples = steps.dfn.posExamples || {}; var full = values.pos || ""; return examples[full] || ""; }, // Builds one sense block (<li>): mane textarea, nimûne list, and // sub-lists for alternatîv/hevmane/dijmane/etc. buildSenseBlock: function (stepDiv) { var block = $("<li class='wiktku-dfn-sense'></li>"); // — Mane textarea (declared first so the template handler can reference it) — var dfnArea = $("<textarea></textarea>") .attr("name", "wiktku-dfn-mane-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("class", "wiktku-start-step-field wiktku-dfn-mane") .attr("rows", 6) .attr("placeholder", "Mane…"); dfnArea.on("input", function () { steps.dfn.onDfnInput(stepDiv, block, this); }); // — Template selector (optional — replaces mane when chosen) — // Template definitions loaded from [[MediaWiki:Gadget-start.js/data.json]]. var tplDefs = steps.dfn.tplDefs || []; // Cache of all non-placeholder option elements — used by updateTplOptions // to remove/re-add options (the only approach compatible with Chosen.js). var _allTplOptions = []; var tplSelect = $(mw.html.element("select", { "class": "wiktku-dfn-tpl-select" })); tplSelect.append($("<option value=''>— yan jî şablonek hilbijêre —</option>")); $.each(tplDefs, function (_, tpl) { var opt = $("<option></option>") .val(tpl.name) .text(tpl.name) .attr("data-langs", tpl.langs ? tpl.langs.join(",") : "") .attr("data-nolang", tpl.noLang ? "1" : ""); tplSelect.append(opt); _allTplOptions.push(opt[0]); }); function updateTplOptions() { var lang = getValues().lang || ""; var currentVal = tplSelect.val(); var currentStillValid = false; // Detach all non-placeholder options, then re-attach only the visible ones. // This is the only approach that works correctly with both native <select> // and Chosen.js on desktop. tplSelect.find("option[value!='']").detach(); $.each(_allTplOptions, function (_, opt) { var allowed = $(opt).attr("data-langs"); var visible = !allowed || allowed.split(",").indexOf(lang) !== -1; if (visible) { tplSelect.append(opt); if ($(opt).val() === currentVal) currentStillValid = true; } }); if (!isMobile) tplSelect.trigger("chosen:updated"); if (currentVal && !currentStillValid) { tplSelect.val(""); dfnArea.show(); tplTitleInput.hide().val(""); } } // Store updater on the element so refresh() can call it for all blocks. tplSelect.data("updateOptions", updateTplOptions); var tplTitleInput = $("<input type='text'>") .addClass("wiktku-dfn-tpl-title wiktku-start-narrow") .attr("placeholder", "Navê rûpelê…") .hide(); // Grow the sense list when the title field of the last block gets content, // mirroring what onDfnInput does for the plain mane textarea. tplTitleInput.on("input", function () { steps.dfn.onDfnInput(stepDiv, block, this); }); // Şablon senses have no plain gloss, so hide alternatîv/hevmane/ // dijmane/etc. Etîket, Nimûne and Jêgirtin stay visible either way. function updateFieldVisibility() { var isTpl = !!tplSelect.val(); $.each(HIDDEN_ON_TPL_GROUPS, function (_, cls) { block.find("." + cls + "-group").toggle(!isTpl); }); } // Store on the block so restoreDfn() can re-sync visibility // after programmatically setting tplSelect's value. block.data("updateFieldVisibility", updateFieldVisibility); tplSelect.on("change", function () { var chosen = $(this).val(); if (chosen) { dfnArea.hide(); tplTitleInput.show().focus(); } else { dfnArea.show(); tplTitleInput.hide().val(""); } updateFieldVisibility(); // Re-run refresh so the Werger step visibility updates. refresh(); }); var tplRow = $("<div></div>").addClass("wiktku-dfn-tpl-row") .append(tplSelect).append(" ").append(tplTitleInput); block.append(tplRow); block.append(dfnArea); // Apply lang filter on initial build. updateTplOptions(); // — Sub-field groups — // All groups are always visible with a placeholder textarea. // Nimûne is last in the DOM and last in the output. var allGroups = [ { cls: "wiktku-dfn-etiket", label: "Etîket", rows: 1, narrow: true, izah: "xisûsen, Mêrdîn, anatomî, Badînî" }, { cls: "wiktku-dfn-kategori", label: "Kategorî", rows: 1, narrow: true, izah: "wekî etîket lê xuya nabe tenê kategorîze dike" }, { cls: "wiktku-dfn-alternativ", label: "Formên alternatîv", rows: 1, narrow: true, izah: "Varyantên vê kelîmeyê" }, { cls: "wiktku-dfn-hevmane", label: "Hevmane", rows: 1, narrow: true, izah: "Spehî hevmaneya Bedew e." }, { cls: "wiktku-dfn-dijmane", label: "Dijmane", rows: 1, narrow: true, izah: "Zengîn dijmaneya feqîr e." }, { cls: "wiktku-dfn-koordine", label: "Termên koordîne", rows: 1, narrow: true, izah: "Pisîk û kûçik termên koordîne ne çunkî Jornavên wan gelek in" }, { cls: "wiktku-dfn-jornav", label: "Jornav", rows: 1, narrow: true, izah: "Heywan jornavê guhandar e" }, { cls: "wiktku-dfn-jernav", label: "Jêrnav", rows: 1, narrow: true, izah: "Guhandar jêrnavê heywan e" }, { cls: "wiktku-dfn-nimune", label: "Nimûne", rows: 2, narrow: false } ]; $.each(allGroups, function (_, g) { var groupDiv = $("<div></div>").addClass("wiktku-dfn-subgroup " + g.cls + "-group"); function buildNimuneLi() { var lang = getValues().lang || ""; var li = $("<li></li>").addClass("wiktku-dfn-nimune-li"); var mainTa = $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-text-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", g.rows) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-text") .attr("placeholder", "Nimûneya emilandina kelîmeyê tu bi xwe binivîse…"); mainTa.on("input", function () { var val = $.trim($(this).val()); var isLast = li.is(list.children("li:last-child")); if (val && isLast) { list.append(buildNimuneLi()); } }); li.append(mainTa); var subWrap = $("<div></div>").addClass("wiktku-dfn-nimune-sub"); if (needsTransliteration(lang)) { subWrap.append( $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-tr-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 5) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-tr") .attr("placeholder", "Transkrîpsiyona bi alfabeya latînî") ); } if (lang && lang !== "ku") { subWrap.append( $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-t-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 5) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-t") .attr("placeholder", "Tercimeya kurmancî") ); } if (subWrap.children().length) li.append(subWrap); return li; } if (g.cls === "wiktku-dfn-nimune") { // Nimûne — compound widget with tr/t sub-fields. var lbl = $("<span></span>").addClass("wiktku-dfn-sublabel").text(g.label + ": "); var list = $("<ol></ol>").addClass("wiktku-dfn-sublist " + g.cls + "-list"); groupDiv.data("buildNimuneLi", buildNimuneLi); list.append(buildNimuneLi()); groupDiv.append(lbl).append(list); block.append(groupDiv); } else { // Regular always-visible group — label + growing textarea list. var lbl = $("<span></span>").addClass("wiktku-dfn-sublabel").text(g.label + ": " + g.izah); var list = $("<ol></ol>").addClass("wiktku-dfn-sublist " + g.cls + "-list"); var firstInput = $("<textarea></textarea>") .attr("name", g.cls + "-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", g.rows) .attr("class", "wiktku-dfn-subfield" + (g.narrow ? " wiktku-start-narrow" : "")) .attr("placeholder", g.label + "…"); firstInput.on("input", function () { steps.dfn.onSubInput(list, this, g.rows, g.narrow); }); list.append($("<li></li>").append(firstInput)); groupDiv.append(lbl).append(list); block.append(groupDiv); } }); // — Jêder (citation) group — growing list, same structure as Nimûne. — (function () { var jederGroupDiv = $("<div></div>").addClass("wiktku-dfn-subgroup wiktku-dfn-jeder-group"); var jederLbl = $("<span></span>").addClass("wiktku-dfn-sublabel").text("Jêgirtin: "); var jederList = $("<ol></ol>").addClass("wiktku-dfn-sublist wiktku-dfn-jeder-list"); function buildJederLi() { var lang = getValues().lang || ""; var li = $("<li></li>").addClass("wiktku-dfn-jeder-li"); var dragHandle = $("<span></span>") .addClass("wiktku-jeder-drag-handle") .attr("title", "Bişkûne û bikişîne da ku rêzê biguhezîne"); // Quote text textarea var quoteTa = $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-quote-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 2) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-quote") .attr("placeholder", "Nimûneya emilandinê ji kitêb an çavkaniyeke din binivîse"); quoteTa.on("input", function () { var val = $.trim($(this).val()); var isLast = li.is(jederList.children("li:last-child")); if (val && isLast) { jederList.append(buildJederLi()); } }); li.append(dragHandle).append(quoteTa); // tr/t sub-fields for the quote — shown as needed for the language. var quoteSubWrap = $("<div></div>").addClass("wiktku-dfn-quote-sub"); if (needsTransliteration(lang)) { quoteSubWrap.append( $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-quote-tr-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 2) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-quote-tr") .attr("placeholder", "Transkrîpsiyona jêgirtinê…") ); } if (lang && lang !== "ku") { quoteSubWrap.append( $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-quote-t-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 2) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-quote-t") .attr("placeholder", "Tercimeya jêgirtinê bi kurmancî") ); } if (quoteSubWrap.children().length) li.append(quoteSubWrap); // Citoid auto-fill: fetch citation data from a URL, DOI or ISBN and // prefill the source şablon + fields below (see Gadget-citoid-helper.js). var citoidWrap = $("<div></div>").addClass("wiktku-dfn-quote-citoid"); var citoidInput = $("<input type='text'>") .addClass("wiktku-dfn-quote-citoid-input wiktku-start-narrow") .attr("placeholder", "URL, DOI an ISBN binivîse ku otomatîk were tijekirin…"); var citoidBtn = new OO.ui.ButtonWidget({ label: "Bi Citoid bîne", classes: [ "wiktku-dfn-quote-citoid-btn" ] }); var citoidStatus = $("<span></span>").addClass("wiktku-dfn-quote-citoid-status"); // Fetches citation data from Citoid and fills this citation's // şablon + fields — only rebuilds fields on template change, // and never overwrites values the user already typed. function runCitoidFetch() { var query = $.trim(citoidInput.val()); if (!query) { mw.notify("Ji kerema xwe re pêşî URL, DOI an ISBNyekê binivîse."); return; } citoidBtn.setDisabled(true); citoidStatus.text("Tê anîn…"); wikt.citoidHelper.ensure().then(function () { return wikt.citoid.fetchJederFields(query); }).then(function (result) { var jederKey = result.jederKey; var hasTpl = !!jederKey && srcSel.find("option[value='" + jederKey + "']").length > 0; var targetVal = hasTpl ? jederKey : "__manual__"; // Only rebuild if switching şablon, so a repeat fetch // doesn't clear fields already filled in by hand. if (srcSel.val() !== targetVal) { srcSel.val(targetVal).trigger("change"); srcSel.trigger("chosen:updated"); } if (hasTpl) { // Tenê qadên vala tijî bike. $.each(result.fields, function (key, val) { var input = srcFields.find("[data-field-key='" + key + "']"); if (input.length && !$.trim(input.val())) { input.val(val); } }); } else { // Şablonek nehat naskirin ji bo vê itemType — rêzikeke // çavkaniyê ya bi destan a ji qadên Citoid tê çêkirin, // lê tenê ger qada destan vala be. var manualField = srcFields.find(".wiktku-dfn-quote-src-manual"); if (!$.trim(manualField.val())) { var parts = []; $.each(["nivîskar", "sernav", "websîte", "kovar", "weşanxane", "sal", "url"], function (_, k) { if (result.fields[k]) parts.push(result.fields[k]); }); manualField.val(parts.join(", ")); } } citoidStatus.text(""); }, function (errorMsg) { citoidStatus.text(typeof errorMsg === "string" ? errorMsg : "Nehat dîtin. Kontrol bike ka URL/DOI/ISBN rast e."); }).always(function () { citoidBtn.setDisabled(false); }); } citoidBtn.on("click", runCitoidFetch); citoidInput.on("keydown", function (e) { if (e.which === 13) { // Enter e.preventDefault(); runCitoidFetch(); } }); citoidWrap.append(citoidInput).append(citoidBtn.$element).append(citoidStatus); // Source template selector, specific to this citation. var srcSel = $("<select></select>").addClass("wiktku-dfn-quote-src-sel"); srcSel.append($("<option value=''>— Çavkaniyê hilbijêre —</option>")); srcSel.append($("<option></option>").val("__manual__").text("Bi destê xwe binivîsim")); var jederDefs = steps.dfn.jederDefs || {}; $.each(jederDefs, function (tplName, def) { srcSel.append($("<option></option>").val(tplName).text(def.label)); }); // Dynamic source fields container. var srcFields = $("<div></div>").addClass("wiktku-dfn-quote-src-fields"); srcSel.on("change", function () { srcFields.empty(); var chosen = $(this).val(); if (!chosen) return; if (chosen === "__manual__") { // Freeform source, written by the user — becomes the 2nd // positional param of {{jêder|lang|…}} instead of çavkanî?. srcFields.append( $("<textarea></textarea>") .attr("rows", 4) .addClass("wiktku-dfn-subfield wiktku-dfn-quote-src-manual") .attr("placeholder", "Çavkaniyê bi destê xwe binivîse…") ); return; } var def = (steps.dfn.jederDefs || {})[chosen]; if (!def) return; $.each(def.fields, function (_, f) { var row = $("<div></div>").addClass("wiktku-dfn-quote-src-row"); var fieldLbl = $("<label></label>").text(f.label + ": "); var inp = $("<textarea></textarea>") .attr("rows", 2) .addClass("wiktku-dfn-quote-src-input wiktku-start-narrow") .attr("data-field-key", f.key) .attr("placeholder", f.label + "…"); row.append(fieldLbl).append(inp); srcFields.append(row); }); }); li.append(citoidWrap).append(srcSel).append(srcFields); return li; } jederGroupDiv.data("buildJederLi", buildJederLi); jederList.append(buildJederLi()); // Make citation rows sortable (drag to reorder). // The last row is always the empty trailing row — cancel its drag. mw.loader.using("jquery.ui.sortable", function () { jederList.sortable({ handle: ".wiktku-jeder-drag-handle", axis: "y", items: "li:not(:last-child)", tolerance: "pointer" }); }); jederGroupDiv.append(jederLbl).append(jederList); block.append(jederGroupDiv); }()); // Apply the initial hide/show state for the sub-groups (matches // tplSelect's starting value, which is normally empty). updateFieldVisibility(); return block; }, /** Grows the sense list when the last mane textarea gets content. */ onDfnInput: function (stepDiv, block, textarea) { var val = $.trim($(textarea).val()); var list = stepDiv.find("ol.wiktku-dfn-list"); var isLast = block.is(list.children("li:last-child")); if (val && isLast) { var newBlock = steps.dfn.buildSenseBlock(stepDiv); list.append(newBlock); // Apply Chosen to the new block's template selector on desktop. if (!isMobile) newBlock.find("select.wiktku-dfn-tpl-select").chosen(chosenOptions); } refresh(); }, /** Grows a sub-list (nimûne/formên alternatîv/hevmane/dijmane/termên koordîne) on input. */ onSubInput: function (list, input, rows, narrow) { var val = $.trim($(input).val()); var item = $(input).parent(); var isLast = item.is(list.children("li:last-child")); if (val && isLast) { var next = $("<textarea></textarea>") .attr("name", "wiktku-dfn-sub-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", rows) .attr("class", "wiktku-dfn-subfield" + (narrow ? " wiktku-start-narrow" : "")); next.on("input", function () { steps.dfn.onSubInput(list, this, rows, narrow); }); list.append($("<li></li>").append(next)); } }, // Populated from [[MediaWiki:Gadget-start.js/data.json]] (tplDefs, posExamples, jederDefs). tplDefs: [], posExamples: {}, jederDefs: {}, build: function (stepDiv) { if (stepDiv.find("ol.wiktku-dfn-list").length) return null; var list = $("<ol class='wiktku-dfn-list'></ol>"); list.append(steps.dfn.buildSenseBlock(stepDiv)); stepDiv.append(list); return null; }, /** Reads all sense blocks from the DOM and returns an array of sense objects. */ getSenses: function (stepDiv) { var senses = []; stepDiv.find("li.wiktku-dfn-sense").each(function () { var block = $(this); var tplSel = block.find("select.wiktku-dfn-tpl-select"); var tpl = tplSel.val() || ""; // noLang: template already encodes the language — don't add |lang| param. var tplNoLang = tpl ? tplSel.find("option[value='" + tpl + "']").attr("data-nolang") === "1" : false; var tplTitle = $.trim(block.find("input.wiktku-dfn-tpl-title").val()); var mane = $.trim(block.find("textarea.wiktku-dfn-mane").val()); function readList(cls) { var vals = []; block.find("." + cls + "-list textarea").each(function () { var v = $.trim($(this).val()); if (v) vals.push(v); }); return vals; } // Nimûne items are compound: { text, tr?, t? } function readNimuneList() { var items = []; block.find(".wiktku-dfn-nimune-list li.wiktku-dfn-nimune-li").each(function () { var text = $.trim($(this).find(".wiktku-dfn-nimune-text").val()); if (!text) return; var obj = { text: text }; var tr = $.trim($(this).find(".wiktku-dfn-nimune-tr").val()); var t = $.trim($(this).find(".wiktku-dfn-nimune-t").val()); if (tr) obj.tr = tr; if (t) obj.t = t; items.push(obj); }); return items; } // Jêder is a growing list of citations, one per li — mirrors readNimuneList(). function readJederList() { var items = []; block.find(".wiktku-dfn-jeder-list li.wiktku-dfn-jeder-li").each(function () { var li = $(this); var quote = $.trim(li.find(".wiktku-dfn-nimune-quote").val()); if (!quote) return; var obj = { quote: quote }; var qtr = $.trim(li.find(".wiktku-dfn-nimune-quote-tr").val()); var qt = $.trim(li.find(".wiktku-dfn-nimune-quote-t").val()); if (qtr) obj.quoteTr = qtr; if (qt) obj.quoteT = qt; var tplName = li.find(".wiktku-dfn-quote-src-sel").val(); if (tplName === "__manual__") { var manual = $.trim(li.find(".wiktku-dfn-quote-src-manual").val()); if (manual) obj.jederManual = manual; } else if (tplName) { obj.jederTpl = tplName; var fields = {}; li.find(".wiktku-dfn-quote-src-input").each(function () { var k = $(this).attr("data-field-key"); var v = $.trim($(this).val()); if (k && v) fields[k] = v; }); obj.jêderFields = fields; } items.push(obj); }); return items; } senses.push({ tpl: tpl, tplNoLang: tplNoLang, tplTitle: tplTitle, mane: mane, etiket: readList("wiktku-dfn-etiket"), kategori: readList("wiktku-dfn-kategori"), nimune: readNimuneList(), jeder: readJederList(), alternativ: readList("wiktku-dfn-alternativ"), hevmane: readList("wiktku-dfn-hevmane"), dijmane: readList("wiktku-dfn-dijmane"), koordine: readList("wiktku-dfn-koordine"), jornav: readList("wiktku-dfn-jornav"), jernav: readList("wiktku-dfn-jernav") }); }); return senses; }, getOutput: function (values, callback) { var stepDiv = $("#wiktku-start-dfn"); var senses = steps.dfn.getSenses(stepDiv); var lang = values.lang; // A sense counts as "filled" if it has a mane, a chosen template + title, // or any other content (etîket/hevmane/nimûne/jêder…) worth keeping. var hasMane = senses.some(function (s) { return s.mane !== "" || (s.tpl && s.tplTitle) || senseHasExtraContent(s); }); // True only when at least one sense has a regular mane (needs linkify). var hasRegularMane = senses.some(function (s) { return !s.tpl && s.mane !== ""; }); // nimûne/jêder must never pass through linkify, only the mane text. // defLines (linkified) and citeLines (kept aside) stay parallel; // a {{wiktku-cite-N}} token in defLines marks where to splice back. var defLines = []; // one entry per kept sense (goes to linkify) var citeLines = []; // parallel — nimûne+jêder for that same sense $.each(senses, function (_, sense) { // — Template sense (e.g. {{guharto|ku|somepage}}) — if (sense.tpl) { if (!sense.tplTitle) return; // skip empty template senses var tplKatTpl = buildSenseTpl(sense, "kategori", lang, "K"); var tplLabelTpl = buildSenseTpl(sense, "etiket", lang, "e"); var tplCall = sense.tplNoLang ? "{{" + sense.tpl + "|" + sense.tplTitle + "}}" : "{{" + sense.tpl + "|" + lang + "|" + sense.tplTitle + "}}"; var idx = defLines.length; var cite = buildCite(sense, lang); defLines.push("# " + (tplKatTpl ? tplKatTpl + " " : "") + (tplLabelTpl ? tplLabelTpl + " " : "") + tplCall + (cite ? "{{wiktku-cite-" + idx + "}}" : "")); citeLines.push(cite); return; } // — Normal mane sense — var dfn = sense.mane; if (!dfn && !senseHasExtraContent(sense)) return; // truly empty if (dfn) { dfn = stripWikilinks(dfn); if (dfn[0] !== dfn[0].toUpperCase()) dfn = capitalize(dfn); if (!dfn.match(/[.…?!)\]]$/)) dfn += "."; } else { dfn = "{{mane?|" + lang + "}}"; } var katTpl = buildSenseTpl(sense, "kategori", lang, "K"); var labelTpl = buildSenseTpl(sense, "etiket", lang, "e"); var out = "# " + (katTpl ? katTpl : "") + (labelTpl ? labelTpl : "") + dfn; function wordLine(tpl, words) { if (!words.length) return ""; return "\n#: {{" + tpl + "|" + lang + "|" + words.join("|") + "}}"; } out += wordLine("alt-r", sense.alternativ); out += wordLine("hevmane", sense.hevmane); out += wordLine("dijmane", sense.dijmane); out += wordLine("koordîne", sense.koordine); out += wordLine("jornav", sense.jornav); out += wordLine("jêrnav", sense.jernav); var cite = buildCite(sense, lang); var idx = defLines.length; defLines.push(out + (cite ? "{{wiktku-cite-" + idx + "}}" : "")); citeLines.push(cite); }); // Splice citeLines back into a linkified string, replacing each // {{wiktku-cite-N}} token with its stored nimûne/jêder block. function restoreCites(t) { return t.replace(/\{\{wiktku-cite-(\d+)\}\}/g, function (_, n) { return citeLines[parseInt(n, 10)] || ""; }); } var text = defLines.join("\n") + "\n"; if (!hasMane) { // No definitions entered — emit {{mane?}} with bênimûne. text = "# {{mane?|" + lang + "}}\n#* {{bênimûne|" + lang + "}}\n"; callback(text); return; } if (!hasRegularMane) { // All filled senses are template senses — no linkify needed. callback(restoreCites(text)); return; } var didTryToLoad = function () { if (typeof $.wiktviLinkify === "function") { $.wiktviLinkify(text, function (linked) { callback(restoreCites(linked)); }); } else { callback(restoreCites(text)); } }; mw.loader.using("ext.gadget.linkify", didTryToLoad, didTryToLoad); } }, je: makeWordListStep("je", "jê", "Kelîmeyên jê çêbûyî binivîse", "Jê", "g"), tekildar: makeWordListStep("tekildar", "têkildar", "Kelîmeyên ji aliyê etîmolojiyê ve têkildarî vê kelîmeyê binivîse", "Têkildar", "g"), binereherwiha: makeWordListStep("binereherwiha", "binêre herwiha", "Kelîmeyên din ên eleqedar binivîse", "Binêre herwiha", "g"), etym: { id: "etym", name: "etîmolojî", question_fmt: "Etîmolojiya kelîmeyê binivîse", // etymTpls populated from data.json etymTpls: [], visible: function (values) { return values.lang && values.pos; }, // Fills the insert-dropdown from the current etymTpls array. refreshTplSelect: function () { var sel = $("#wiktku-start-etym .wiktku-tpl-insert-select"); if (!sel.length) return; sel.find("option[value!='']").remove(); $.each(steps.etym.etymTpls, function (_, tpl) { sel.append($("<option></option>").val(tpl.snippet).text(tpl.name + " — " + tpl.desc)); }); // Notify Chosen that the option list has changed (no-op on mobile). if (!isMobile) sel.trigger("chosen:updated"); }, build: function (stepDiv) { if (stepDiv.find(".wiktku-etym-wrap").length) return null; var wrap = $("<div class='wiktku-etym-wrap'></div>"); var ta = $("<textarea></textarea>") .attr("name", "wiktku-etym-" + $.now()) .attr("class", "wiktku-start-step-field wiktku-etym-text") .attr("rows", 4) .attr("placeholder", "Nimûne: Ji {{ji|en|ku|apple}}. yan rasterast binivîse…"); // Template insert dropdown — options also refreshed after data.json loads. var sel = $("<select class='wiktku-tpl-insert-select'></select>"); sel.append($("<option value=''>— şablonek lê zêde bike —</option>")); $.each(steps.etym.etymTpls, function (_, tpl) { sel.append($("<option></option>").val(tpl.snippet).text(tpl.name + " — " + tpl.desc)); }); sel.on("change", function () { var snippet = $(this).val(); if (!snippet) return; var lang = getValues().lang || ""; snippet = snippet.replace(/CODE/g, lang).replace(/SOURCELANG/g, "?"); insertAtCursor(ta[0], snippet); $(this).val(""); ta.focus(); }); wrap.append(sel).append($("<br>")).append(ta); stepDiv.append(wrap); return ta; }, output: function (values) { var text = $.trim($("#wiktku-start-etym .wiktku-etym-text").val()); if (text) { return "\n==== Etîmolojî ====\n" + text + "\n"; } // No etymology entered — emit {{ji?|lang}} as a placeholder, // Only when a regular sense has content (real mane, or {{mane?}} // with other fields filled in) — a şablon sense never counts. var dfnSenses = steps.dfn.getSenses($("#wiktku-start-dfn")); var hasRegularMane = dfnSenses.some(function (s) { return !s.tpl && (s.mane !== "" || senseHasExtraContent(s)); }); if (!hasRegularMane) return ""; return "\n==== Etîmolojî ====\n{{ji?|" + values.lang + "}}\n"; } }, dunde: { id: "dunde", name: "dûnde", question_fmt: "Eger ev kelîme ji vî zimanî ketibe zimanekî din, vî zimanî û kelîmeya wî binivîse", visible: function (values) { return !!values.pos; }, disabledKeys: { "navz": true}, // Language dropdown + growing word-input list; a new row appends // when the dropdown gets a value. Mirrors steps.trans, but flat. buildRow: function (stepDiv) { var row = $("<li class='wiktku-dunde-row wiktku-lang-row'></li>"); // Language selector — chosen is applied after insertion into DOM. var langSel = $(mw.html.element("select", { "class": "wiktku-start-step-keyfield wiktku-start-narrow" })); langSel.attr("data-placeholder", "Zimanekî lê bigere"); populateMenus(langSel, steps.dunde.keys || [], steps.dunde.disabledKeys); // When a language is chosen, ensure a next empty row exists. langSel.on("change", function () { steps.dunde.onLangChange(stepDiv, row); }); // Word list for this language. var wordList = $("<ul class='wiktku-dunde-words wiktku-lang-row-words'></ul>"); var firstWord = steps.dunde.makeWordInput(); wordList.append($("<li></li>").append(firstWord)); if (isMobile) { row.append(wrapNativeSelect(langSel)).append(wordList); } else { row.append(langSel).append(wordList); } return row; }, makeWordInput: function () { var input = $("<textarea></textarea>") .attr("name", "wiktku-dunde-word-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 1) .attr("class", "wiktku-dfn-subfield wiktku-start-narrow") .attr("placeholder", "Kelîme…"); input.on("input", function () { var list = $(this).closest("ul.wiktku-dunde-words"); var item = $(this).parent(); var val = $.trim($(this).val()); if (val && item.is(list.children("li:last-child"))) { var next = steps.dunde.makeWordInput(); list.append($("<li></li>").append(next)); } }); return input; }, onLangChange: function (stepDiv, row) { var list = stepDiv.find("ul.wiktku-dunde-list"); var isLast = row.is(list.children("li.wiktku-dunde-row:last-child")); if (isLast) { var newRow = steps.dunde.buildRow(stepDiv); list.append(newRow); // Init chosen after the new row is in the DOM (desktop only). if (!isMobile) newRow.find("select").chosen(chosenOptions); } // Keep disabled keys in sync across all lang selectors. steps.dunde.syncDisabledKeys(stepDiv); }, /** Disables already-selected languages in all other dropdowns. */ syncDisabledKeys: function (stepDiv) { var taken = $.extend({}, steps.dunde.disabledKeys); stepDiv.find("li.wiktku-dunde-row select").each(function () { var v = $(this).val(); if (v) taken[v] = true; }); stepDiv.find("li.wiktku-dunde-row select").each(function () { var self = $(this); var own = self.val(); self.find("option").each(function () { var code = $(this).val(); if (!code) return; $(this).prop("disabled", taken[code] && code !== own); }); self.trigger("chosen:updated"); }); }, build: function (stepDiv) { if (stepDiv.find("ul.wiktku-dunde-list").length) return null; var list = $("<ul class='wiktku-dunde-list wiktku-lang-row-list'></ul>"); list.append(steps.dunde.buildRow(stepDiv)); stepDiv.append(list); // Init chosen after the select is in the DOM (desktop only). if (!isMobile) list.find("select").chosen(chosenOptions); return null; }, /** Reads all [langcode, words[]] rows from the DOM. */ getRows: function (stepDiv) { var result = []; stepDiv.find("li.wiktku-dunde-row").each(function () { var lang = $(this).find("select").val(); if (!lang) return; var words = []; $(this).find("ul.wiktku-dunde-words textarea").each(function () { var v = $.trim($(this).val()); if (v) words.push(v); }); if (words.length) result.push([lang, words]); }); return result; }, output: function () { var stepDiv = $("#wiktku-start-dunde"); var rows = steps.dunde.getRows(stepDiv); if (!rows.length) return ""; var lines = $.map(rows, function (row) { var lang = row[0], words = row[1]; return "* {{dû|" + lang + "|" + words.join("|") + "}}"; }); return "\n==== Dûnde ====\n" + lines.join("\n") + "\n"; } }, zarava: { id: "zarava", name: "bi zaravayên din", visible: function (values) { return steps.trans.visible(values); }, disabledKeys: { "navz": true }, buildRow: function (group) { var row = $("<li class='wiktku-zarava-row wiktku-lang-row'></li>"); var langSel = $(mw.html.element("select", { "class": "wiktku-start-step-keyfield wiktku-start-narrow" })); populateMenus(langSel, steps.zarava.keys || [], steps.zarava.disabledKeys); langSel.on("change", function () { steps.zarava.onLangChange(group, row); }); var wordList = $("<ul class='wiktku-zarava-words wiktku-lang-row-words'></ul>"); var firstWord = steps.zarava.makeWordInput(); wordList.append($("<li></li>").append(firstWord)); row.append(langSel).append(wordList); return row; }, makeWordInput: function () { var input = $("<textarea></textarea>") .attr("name", "wiktku-zarava-word-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 1) .attr("class", "wiktku-dfn-subfield wiktku-start-narrow") .attr("placeholder", "Tercime…"); input.on("input", function () { var list = $(this).closest("ul.wiktku-zarava-words"); var item = $(this).parent(); var val = $.trim($(this).val()); if (val && item.is(list.children("li:last-child"))) { var next = steps.zarava.makeWordInput(); list.append($("<li></li>").append(next)); } }); return input; }, onLangChange: function (group, row) { var list = group.find("ul.wiktku-zarava-list"); var isLast = row.is(list.children("li.wiktku-zarava-row:last-child")); if (isLast) { var newRow = steps.zarava.buildRow(group); list.append(newRow); } steps.zarava.syncDisabledKeys(group); }, /** Disables already-selected dialects in all other dropdowns within one group. */ syncDisabledKeys: function (group) { var taken = $.extend({}, steps.zarava.disabledKeys); group.find("li.wiktku-zarava-row select").each(function () { var v = $(this).val(); if (v) taken[v] = true; }); group.find("li.wiktku-zarava-row select").each(function () { var self = $(this); var own = self.val(); self.find("option").each(function () { var code = $(this).val(); if (!code) return; $(this).prop("disabled", taken[code] && code !== own); }); }); }, /** Builds (or fetches) the .wiktku-zarava-group for one gloss. */ buildGroup: function (stepDiv, gi) { var group = $("<div class='wiktku-zarava-group'></div>").attr("data-gloss-pos", gi); var list = $("<ul class='wiktku-zarava-list wiktku-lang-row-list'></ul>"); list.append(steps.zarava.buildRow(group)); group.append(list); stepDiv.append(group); return group; }, /** Syncs one .wiktku-zarava-group per current gloss (same logic as steps.trans.build). */ build: function (stepDiv) { var glosses = steps.trans.glossList(); if (!glosses.length) { stepDiv.find(".wiktku-zarava-group").remove(); return null; } var existingGroups = stepDiv.find(".wiktku-zarava-group"); if (existingGroups.length > glosses.length) { existingGroups.slice(glosses.length).remove(); } $.each(glosses, function (gi, gloss) { var group = stepDiv.find(".wiktku-zarava-group[data-gloss-pos='" + gi + "']"); if (!group.length) group = steps.zarava.buildGroup(stepDiv, gi); var label = group.find(".wiktku-zarava-group-label"); if (glosses.length > 1) { if (!label.length) { label = $("<div class='wiktku-zarava-group-label'></div>"); group.prepend(label); } label.text(gloss.index + " " + gloss.text); } else if (label.length) { label.remove(); } }); return null; }, /** Reads the dialect rows for a single gloss group. */ getGroupTranslations: function (group) { var result = []; group.find("li.wiktku-zarava-row").each(function () { var lang = $(this).find("select").val(); if (!lang) return; var words = []; $(this).find("ul.wiktku-zarava-words textarea").each(function () { var v = $.trim($(this).val()); if (v) words.push(v); }); if (words.length) result.push([lang, words]); }); return result; }, /** Reads all rows from the DOM, grouped by gloss position. */ getTranslations: function (stepDiv) { var result = []; stepDiv.find(".wiktku-zarava-group").each(function () { result.push(steps.zarava.getGroupTranslations($(this))); }); return result; }, output: function (values) { if (values.lang !== "ku") return ""; var stepDiv = $("#wiktku-start-zarava"); var glosses = steps.trans.glossList(); if (!glosses.length) return ""; var blocks = $.map(glosses, function (gloss, gi) { var group = stepDiv.find(".wiktku-zarava-group[data-gloss-pos='" + gi + "']"); var rows = group.length ? steps.zarava.getGroupTranslations(group) : []; if (!gloss.text && !rows.length) return undefined; if (rows.length) { rows.sort(function (a, b) { var aLang = langsByCode[a[0]] || []; var bLang = langsByCode[b[0]] || []; return (aLang[2] || "").localeCompare(bLang[2] || "", "ku"); }); } var wordLines = $.map(rows, function (row) { var lang = row[0]; var words = row[1]; var wikiWords = words.map(function (w) { return "{{W|" + lang + "|" + w + "}}"; }).join(", "); return "* {{Z|" + lang + "}}: " + wikiWords; }).join("\n"); if (!wordLines) return undefined; var block = "{{werger-ser|" + (gloss.text || "?") + "|" + gloss.index + "}}"; block += "\n" + wordLines; block += "\n{{werger-bin}}"; return block; }); if (!blocks.length) return ""; return "\n==== Bi zaravayên din ====\n" + blocks.join("\n") + "\n"; } }, trans: { id: "trans", name: "werger", visible: function (values) { if (!(values.lang === "ku" && values.pos)) return false; // Hide only when every sense is a filled template sense (no plain // gloss to attach translations to). A mix, or nothing filled in // yet, still shows Werger. var dfnSenses = steps.dfn.getSenses($("#wiktku-start-dfn")); var hasRealSense = dfnSenses.some(function (s) { return !s.tpl && (s.mane !== "" || senseHasExtraContent(s)); }); var hasFilledTplSense = dfnSenses.some(function (s) { return s.tpl && s.tplTitle; }); return hasRealSense || !hasFilledTplSense; }, disabledKeys: { "navz": true, "ku": true, "ckb": true, "sdh": true, "lki": true, "hac": true, "zza": true }, // Language dropdown + growing word-input list, scoped to one gloss's // group (each gloss has its own group and row list). buildRow: function (group) { var row = $("<li class='wiktku-trans-row wiktku-lang-row'></li>"); // Language selector — chosen is applied after insertion into DOM. var langSel = $(mw.html.element("select", { "class": "wiktku-start-step-keyfield wiktku-start-narrow" })); langSel.attr("data-placeholder", "Zimanekî lê bigere"); populateMenus(langSel, steps.trans.keys || [], steps.trans.disabledKeys); // When a language is chosen, ensure a next empty row exists. langSel.on("change", function () { steps.trans.onLangChange(group, row); }); // Word list for this language. var wordList = $("<ul class='wiktku-trans-words wiktku-lang-row-words'></ul>"); var firstWord = steps.trans.makeWordInput(); wordList.append($("<li></li>").append(firstWord)); if (isMobile) { row.append(wrapNativeSelect(langSel)).append(wordList); } else { row.append(langSel).append(wordList); } return row; }, makeWordInput: function () { var input = $("<textarea></textarea>") .attr("name", "wiktku-trans-word-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 1) .attr("class", "wiktku-dfn-subfield wiktku-start-narrow") .attr("placeholder", "Tercime…"); input.on("input", function () { var list = $(this).closest("ul.wiktku-trans-words"); var item = $(this).parent(); var val = $.trim($(this).val()); if (val && item.is(list.children("li:last-child"))) { var next = steps.trans.makeWordInput(); list.append($("<li></li>").append(next)); } }); return input; }, onLangChange: function (group, row) { var list = group.find("ul.wiktku-trans-list"); var isLast = row.is(list.children("li.wiktku-trans-row:last-child")); if (isLast) { var newRow = steps.trans.buildRow(group); list.append(newRow); // Init chosen after the new row is in the DOM (desktop only). if (!isMobile) newRow.find("select").chosen(chosenOptions); } // Keep disabled keys in sync across this gloss's lang selectors // only — the same language can be used for different senses. steps.trans.syncDisabledKeys(group); }, /** Disables already-selected languages in all other dropdowns within one group. */ syncDisabledKeys: function (group) { var taken = $.extend({}, steps.trans.disabledKeys); group.find("li.wiktku-trans-row select").each(function () { var v = $(this).val(); if (v) taken[v] = true; }); group.find("li.wiktku-trans-row select").each(function () { var self = $(this); var own = self.val(); self.find("option").each(function () { var code = $(this).val(); if (!code) return; $(this).prop("disabled", taken[code] && code !== own); }); self.trigger("chosen:updated"); }); }, // Builds (or fetches) the .wiktku-trans-group for one gloss. buildGroup: function (stepDiv, gi) { var group = $("<div class='wiktku-trans-group'></div>").attr("data-gloss-pos", gi); var list = $("<ul class='wiktku-trans-list wiktku-lang-row-list'></ul>"); list.append(steps.trans.buildRow(group)); group.append(list); stepDiv.append(group); // Init chosen after the select is in the DOM (desktop only). if (!isMobile) list.find("select").chosen(chosenOptions); return group; }, // Syncs one .wiktku-trans-group per current gloss, keyed by // data-gloss-pos so groups stay matched across rebuilds. build: function (stepDiv) { var glosses = steps.trans.glossList(); if (!glosses.length) { stepDiv.find(".wiktku-trans-group").remove(); return null; } // Drop groups for glosses that no longer exist (always from the // tail — groups are only ever appended in gloss order below). var existingGroups = stepDiv.find(".wiktku-trans-group"); if (existingGroups.length > glosses.length) { existingGroups.slice(glosses.length).remove(); } $.each(glosses, function (gi, gloss) { var group = stepDiv.find(".wiktku-trans-group[data-gloss-pos='" + gi + "']"); if (!group.length) group = steps.trans.buildGroup(stepDiv, gi); // Only label groups when there's more than one gloss to // distinguish between — a single gloss needs no caption. var label = group.find(".wiktku-trans-group-label"); if (glosses.length > 1) { if (!label.length) { label = $("<div class='wiktku-trans-group-label'></div>"); group.prepend(label); } label.text(gloss.index + " " + gloss.text); } else if (label.length) { label.remove(); } }); return null; }, /** Reads the translation rows for a single gloss group. */ getGroupTranslations: function (group) { var result = []; group.find("li.wiktku-trans-row").each(function () { var lang = $(this).find("select").val(); if (!lang) return; var words = []; $(this).find("ul.wiktku-trans-words textarea").each(function () { var v = $.trim($(this).val()); if (v) words.push(v); }); if (words.length) result.push([lang, words]); }); return result; }, // Reads all translation rows, grouped by gloss position. getTranslations: function (stepDiv) { var result = []; stepDiv.find(".wiktku-trans-group").each(function () { result.push(steps.trans.getGroupTranslations($(this))); }); return result; }, // Builds the numbered "{ index, gloss }" list, one per dfn sense // with a real mane (skips template senses). index is 1-based and // matches the sense's position in the "#" definition list. // When nothing's filled in, returns one placeholder entry so // Werger still has a group to attach to; when every sense is a // filled template sense, stays empty (matches trans.visible()). glossList: function () { var dfnSenses = steps.dfn.getSenses($("#wiktku-start-dfn")); var glosses = []; var hasFilledTplSense = false; $.each(dfnSenses, function (i, s) { if (s.tpl) { if (s.tplTitle) hasFilledTplSense = true; return; // template sense — no gloss to caption with } var dfn = s.mane; if (!dfn) { // No mane, but other fields are filled — still gets a // gloss group since dfn.getOutput() emits {{mane?}} for it. if (senseHasExtraContent(s)) glosses.push({ index: i + 1, text: "" }); return; } if (dfn[0] !== dfn[0].toLowerCase()) dfn = decapitalize(dfn); dfn = stripWikilinks(dfn).replace(/[.…?!)\]،؟]+$/, ""); glosses.push({ index: i + 1, text: dfn }); }); if (!glosses.length && !hasFilledTplSense) { glosses.push({ index: 1, text: "" }); } return glosses; }, output: function (values) { if (values.lang !== "ku") return ""; var stepDiv = $("#wiktku-start-trans"); var glosses = steps.trans.glossList(); // Every sense is a template sense — there's no real gloss // anywhere and no group in the DOM either (glossList() only // returns empty in that case), so skip the section entirely. if (!glosses.length) return ""; // Each gloss now has its own group of translation rows — // attach every gloss's own words under its own werger-ser/-bin // pair instead of dumping everything under the first one. var blocks = $.map(glosses, function (gloss, gi) { var group = stepDiv.find(".wiktku-trans-group[data-gloss-pos='" + gi + "']"); var rows = group.length ? steps.trans.getGroupTranslations(group) : []; // Placeholder gloss (no real mane entered yet) with nothing // translated into it — nothing to output, and gloss.text is // empty so there's no caption to give {{werger-ser}} anyway. if (!gloss.text && !rows.length) return undefined; if (rows.length) { // Sort by Kurdish sort key. rows.sort(function (a, b) { var aLang = langsByCode[a[0]] || []; var bLang = langsByCode[b[0]] || []; return (aLang[2] || "").localeCompare(bLang[2] || "", "ku"); }); } var wordLines = $.map(rows, function (row) { var lang = row[0]; var words = row[1]; var wikiWords = words.map(function (w) { return "{{W|" + lang + "|" + w + "}}"; }).join(", "); return "* {{Z|" + lang + "}}: " + wikiWords; }).join("\n"); var block = "{{werger-ser|" + (gloss.text || "?") + "|" + gloss.index + "}}"; if (wordLines) block += "\n" + wordLines; block += "\n{{werger-bin}}"; return block; }); if (!blocks.length) return ""; return "\n==== Werger ====\n" + blocks.join("\n") + "\n"; } }, }; steps.trans.keys = steps.lang.choices; steps.dunde.keys = steps.lang.choices; steps.zarava.keys = getZaravaKeys(steps.lang.choices); var ordered_steps = [ steps.lang, steps.pron, steps.pos, steps.cinsiyet, steps.lektur, steps.tr, steps.dfn, steps.je, steps.tekildar, steps.etym, steps.dunde, steps.binereherwiha, steps.zarava, steps.trans]; // Step ids that belong to each section (not shared across sections). var PER_SECTION_STEP_IDS = [ "pos", "cinsiyet", "lektur", "tr", "dfn", "je", "tekildar", "etym", "dunde", "binereherwiha", "zarava", "trans" ]; // ── Multi-section state ────────────────────────────────────────────────── // Each entry is a plain snapshot: { pos, cinsiyet, lektur, tr, dfn (senses[]), // je, tekildar, binereherwiha, trans (rows[]) }. var sections = [{}]; // section 0 starts empty (DOM is the truth) var activeSection = 0; function snapshotDfn() { return steps.dfn.getSenses($("#wiktku-start-dfn")); } // Rebuilds the dfn DOM from a previously snapshotted senses array. function restoreDfn(senses) { var stepDiv = $("#wiktku-start-dfn"); // Tear down the existing list so build() recreates it cleanly. stepDiv.find("ol.wiktku-dfn-list").remove(); steps.dfn.build(stepDiv); var list = stepDiv.find("ol.wiktku-dfn-list"); $.each(senses, function (i, sense) { // Ensure enough blocks exist (build() seeds one). var blocks = list.find("li.wiktku-dfn-sense"); var block = blocks.eq(i); if (!block.length) { var nb = steps.dfn.buildSenseBlock(stepDiv); list.append(nb); block = list.find("li.wiktku-dfn-sense").last(); } // Template selector. block.find("select.wiktku-dfn-tpl-select").val(sense.tpl || ""); if (sense.tpl) { block.find("textarea.wiktku-dfn-mane").hide(); block.find("input.wiktku-dfn-tpl-title").val(sense.tplTitle || "").show(); } else { block.find("textarea.wiktku-dfn-mane").val(sense.mane || "").show(); block.find("input.wiktku-dfn-tpl-title").hide().val(""); } // Re-sync the formên alternatîv/hevmane/… hide state now that // tplSelect's value was set programmatically (its own "change" // handler doesn't fire from .val(), so this doesn't happen otherwise). var updateVis = block.data("updateFieldVisibility"); if (updateVis) updateVis(); // Restore a sub-list (etiket, formên alternatîv, hevmane …) from a values array. function restoreSubList(cls, values) { if (!values || !values.length) return; var groupDiv = block.find("." + cls + "-group"); var subList = groupDiv.find("ol, ul").first(); if (!subList.length) return; // group not found // Fill existing items, append new ones as needed. $.each(values, function (j, val) { var items = subList.find("li"); if (j < items.length) { items.eq(j).find("textarea").val(val); } else { var ta = $("<textarea></textarea>") .attr("name", "wiktku-dfn-restore-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 1) .attr("class", "wiktku-dfn-subfield wiktku-start-narrow") .val(val); ta.on("input", function () { steps.dfn.onSubInput(subList, this, 1, true); }); subList.append($("<li></li>").append(ta)); } }); } // Reveal and populate lazy groups that have data. var lazyMap = { "wiktku-dfn-etiket": sense.etiket, "wiktku-dfn-kategori": sense.kategori, "wiktku-dfn-alternativ": sense.alternativ, "wiktku-dfn-hevmane": sense.hevmane, "wiktku-dfn-dijmane": sense.dijmane, "wiktku-dfn-koordine": sense.koordine, "wiktku-dfn-jornav": sense.jornav, "wiktku-dfn-jernav": sense.jernav }; $.each(lazyMap, function (cls, vals) { if (vals && vals.length) restoreSubList(cls, vals); }); // Nimûne items are objects { text, tr?, t? } — restore using the builder. if (sense.nimune && sense.nimune.length) { var nimuneGroupDiv = block.find(".wiktku-dfn-nimune-group"); var nimuneList = nimuneGroupDiv.find("ol.wiktku-dfn-nimune-list"); var buildFn = nimuneGroupDiv.data("buildNimuneLi"); nimuneList.empty(); $.each(sense.nimune, function (_, n) { var text = typeof n === "object" ? (n.text || "") : n; if (!text) return; var li = buildFn ? buildFn() : $("<li class='wiktku-dfn-nimune-li'></li>"); li.find(".wiktku-dfn-nimune-text").val(text); if (n.tr) li.find(".wiktku-dfn-nimune-tr").val(n.tr); if (n.t) li.find(".wiktku-dfn-nimune-t").val(n.t); nimuneList.append(li); }); // Always leave a blank trailing item. if (buildFn) nimuneList.append(buildFn()); } // Restore jêder entries — accepts current array shape or a legacy // single object (older saved sections) for backwards compat. var jederArr = $.isArray(sense.jeder) ? sense.jeder : (sense.jeder ? [sense.jeder] : []); if (jederArr.length) { var jederGroupDiv = block.find(".wiktku-dfn-jeder-group"); var jederList = jederGroupDiv.find("ol.wiktku-dfn-jeder-list"); var buildJederFn = jederGroupDiv.data("buildJederLi"); jederList.empty(); $.each(jederArr, function (_, j) { if (!j || !j.quote) return; var li = buildJederFn ? buildJederFn() : $("<li class='wiktku-dfn-jeder-li'></li>"); li.find(".wiktku-dfn-nimune-quote").val(j.quote); if (j.quoteTr) li.find(".wiktku-dfn-nimune-quote-tr").val(j.quoteTr); if (j.quoteT) li.find(".wiktku-dfn-nimune-quote-t").val(j.quoteT); if (j.jederManual) { var manualSel = li.find(".wiktku-dfn-quote-src-sel"); manualSel.val("__manual__").trigger("change"); li.find(".wiktku-dfn-quote-src-manual").val(j.jederManual); } else if (j.jederTpl) { var srcSel = li.find(".wiktku-dfn-quote-src-sel"); srcSel.val(j.jederTpl).trigger("change"); if (j.jêderFields) { $.each(j.jêderFields, function (key, val) { li.find(".wiktku-dfn-quote-src-input[data-field-key='" + key + "']").val(val); }); } } jederList.append(li); }); // Always leave a blank trailing item, same as Nimûne. if (buildJederFn) jederList.append(buildJederFn()); } }); } // Snapshots simple (non-dfn) per-section steps from the DOM into obj. function saveCurrentSection() { var snap = {}; $.each(PER_SECTION_STEP_IDS, function (_, id) { if (id === "dfn") { snap.dfn = snapshotDfn(); return; } if (id === "etym") { snap.etym = $.trim($("#wiktku-start-etym .wiktku-etym-text").val()); return; } var step = steps[id]; if (!step) return; var stepDiv = $("#wiktku-start-" + id); if (id === "trans") { snap.trans = steps.trans.getTranslations(stepDiv); return; } if (id === "zarava") { snap.zarava = steps.zarava.getTranslations(stepDiv); return; } if (id === "dunde") { snap.dunde = steps.dunde.getRows(stepDiv); return; } // Generic: read all step fields. var fields = stepDiv.find(".wiktku-start-step-field"); if (step.multiple) { snap[id] = fields.map(function () { return $(this).val(); }).get(); } else { snap[id] = fields.val(); } }); sections[activeSection] = snap; } // Restores a previously saved snapshot into the form DOM. function restoreSection(snap) { $.each(PER_SECTION_STEP_IDS, function (_, id) { if (id === "dfn") { restoreDfn(snap.dfn || []); return; } if (id === "etym") { $("#wiktku-start-etym .wiktku-etym-wrap").remove(); steps.etym.build($("#wiktku-start-etym")); $("#wiktku-start-etym .wiktku-etym-text").val(snap.etym || ""); return; } if (id === "trans") { // Rebuild trans groups (dfn must already be restored by this // point in the $.each loop, so glossList() reflects it). var transDiv = $("#wiktku-start-trans"); transDiv.find(".wiktku-trans-group").remove(); steps.trans.build(transDiv); var groupsSnap = snap.trans || []; $.each(groupsSnap, function (gi, rows) { var group = transDiv.find(".wiktku-trans-group[data-gloss-pos='" + gi + "']"); if (!group.length) return; // gloss no longer exists — drop its rows var list = group.find("ul.wiktku-trans-list"); $.each(rows, function (j, row) { var lang = row[0], words = row[1]; var lastRow = list.find("li.wiktku-trans-row").last(); lastRow.find("select").val(lang).trigger("change"); var wordList = lastRow.find("ul.wiktku-trans-words"); $.each(words, function (k, word) { var wordItems = wordList.find("li"); if (k < wordItems.length) { wordItems.eq(k).find("textarea").val(word); } else { // .val() below doesn't fire "input", so the normal // auto-grow never runs — append a matching item // ourselves instead of silently dropping the word. var extraInput = steps.trans.makeWordInput(); wordList.append($("<li></li>").append(extraInput)); extraInput.val(word); } }); // Leave one trailing empty field so the row can still grow // when the user types, matching a freshly-built row. if ($.trim(wordList.children("li").last().find("textarea").val())) { wordList.append($("<li></li>").append(steps.trans.makeWordInput())); } }); }); return; } if (id === "zarava") { // Rebuild zarava groups (dfn must already be restored by this // point in the $.each loop, so glossList() reflects it). var zaravaDiv = $("#wiktku-start-zarava"); zaravaDiv.find(".wiktku-zarava-group").remove(); steps.zarava.build(zaravaDiv); var zaravaGroupsSnap = snap.zarava || []; $.each(zaravaGroupsSnap, function (gi, rows) { var group = zaravaDiv.find(".wiktku-zarava-group[data-gloss-pos='" + gi + "']"); if (!group.length) return; // gloss no longer exists — drop its rows var list = group.find("ul.wiktku-zarava-list"); $.each(rows, function (j, row) { var lang = row[0], words = row[1]; var lastRow = list.find("li.wiktku-zarava-row").last(); lastRow.find("select").val(lang).trigger("change"); var wordList = lastRow.find("ul.wiktku-zarava-words"); $.each(words, function (k, word) { var wordItems = wordList.find("li"); if (k < wordItems.length) { wordItems.eq(k).find("textarea").val(word); } else { var extraInput = steps.zarava.makeWordInput(); wordList.append($("<li></li>").append(extraInput)); extraInput.val(word); } }); if ($.trim(wordList.children("li").last().find("textarea").val())) { wordList.append($("<li></li>").append(steps.zarava.makeWordInput())); } }); }); return; } if (id === "dunde") { // Rebuild dunde rows. var dundeDiv = $("#wiktku-start-dunde"); dundeDiv.find("ul.wiktku-dunde-list").remove(); steps.dunde.build(dundeDiv); var dundeRows = snap.dunde || []; $.each(dundeRows, function (i, row) { var lang = row[0], words = row[1]; var list = dundeDiv.find("ul.wiktku-dunde-list"); var lastRow = list.find("li.wiktku-dunde-row").last(); lastRow.find("select").val(lang).trigger("change"); var wordList = lastRow.find("ul.wiktku-dunde-words"); $.each(words, function (j, word) { var wordItems = wordList.find("li"); if (j < wordItems.length) { wordItems.eq(j).find("textarea").val(word); } else { // .val() below doesn't fire "input", so the normal // auto-grow never runs — append a matching item // ourselves instead of silently dropping the word. var extraInput = steps.dunde.makeWordInput(); wordList.append($("<li></li>").append(extraInput)); extraInput.val(word); } }); // Leave one trailing empty field so the row can still grow // when the user types, matching a freshly-built row. if ($.trim(wordList.children("li").last().find("textarea").val())) { wordList.append($("<li></li>").append(steps.dunde.makeWordInput())); } }); return; } var step = steps[id]; if (!step) return; var stepDiv = $("#wiktku-start-" + id); var fields = stepDiv.find(".wiktku-start-step-field"); var val = snap[id]; if (val === undefined || val === null) return; if (step.multiple) { var arr = val; fields.each(function (i) { if (i < arr.length) $(this).val(arr[i]); }); } else { fields.val(val); } // Notify chosen widgets of the programmatic value change. if (!isMobile) fields.filter("select").trigger("chosen:updated"); }); } function getWikitextForCurrentSection(callback) { var values = getValues(); var entry = steps.pos.output(values); steps.dfn.getOutput(values, function (output) { entry += output; entry += steps.je.output(values); entry += steps.tekildar.output(values); entry += steps.etym.output(values); entry += steps.dunde.output(values); entry += steps.binereherwiha.output(values); entry += steps.zarava.output(values); entry += steps.trans.output(values); callback(entry, values); }); } function getWikitextAllSections(callback) { saveCurrentSection(); var results = new Array(sections.length); var sharedValues = getValues(); // lang/pron are shared function processSection(i) { if (i >= sections.length) { // All done — restore original active section. restoreSection(sections[activeSection]); refresh(); callback(results, sharedValues); return; } restoreSection(sections[i]); refresh(); getWikitextForCurrentSection(function (sectionText) { results[i] = sectionText; processSection(i + 1); }); } processSection(0); } // Assembles wikitext for all sections plus the shared lang/pron header. function getWikitext(callback) { getWikitextAllSections(function (sectionTexts, sharedValues) { var entry = steps.lang.output(sharedValues); entry += steps.pron.output(sharedValues); entry += sectionTexts.join("\n"); // Edit summary uses section 0's values. Read from the saved snapshot // (not the live DOM) so it doesn't mix section 0's pos with whichever // section happens to be active/restored at this point. var dfnSenses = (sections[0] && sections[0].dfn) || []; var dfnSummary = dfnSenses.map(function (s) { return s.mane; }).filter(Boolean).join("; "); var summary = "([[Mediawiki:Gadget-start.js|WF:NÛ]] v.2.0) +" + sharedValues.lang + ":" + sections[0].pos + ":" + dfnSummary; var summaryField = document.getElementById("wpSummary"); if (addLangMode && summaryField.value) { summary = summaryField.value + " " + summary; } summaryField.value = summary; callback(entry); }); } var continueBtn; function getValuesForStep(stepId) { var fields = $("#wiktku-start-" + stepId + " .wiktku-start-step-field"); var step = steps[stepId]; if (step.keys) { var values = {}; fields.each(function (i, field) { var key = $(field).prevAll(".wiktku-start-step-keyfield").val(); if (key) values[key] = $(field).val(); }); return values; } else if (step.multiple) { return fields.map(function () { return $(this).val(); }).get(); } return fields.val(); } function getValues() { var values = {}; $.each(steps, function (stepId) { values[stepId] = getValuesForStep(stepId); }); return values; } function populateMenus(inputs, choices, disabledValues) { if (!disabledValues) disabledValues = {}; var vals = inputs.map(function (i, input) { return $(input).val(); }); inputs.empty(); inputs.append($("<option></option>")); $.each(choices, function (j, choice) { // Append the language code in parentheses so that typing a code // (e.g. "ku") in the search box still finds the language name. var displayText = capitalize(choice[1]); if (choice[2] !== undefined) { // This is a language choice [code, name, sortKey] — show code. displayText = capitalize(choice[1]) + " (" + choice[0] + ")"; } var option = $(mw.html.element("option", { value: choice[0] }, displayText)); if (disabledValues[choice[0]]) option.prop("disabled", true); inputs.append(option); }); inputs.val(function (i) { return vals[i]; }); } // Keys to disable for a key menu: already-taken or explicitly disabled. function getDisabledKeys(step) { var occupiedKeys = {}; $("#wiktku-start-" + step.id + " .wiktku-start-step-keyfield").each(function () { occupiedKeys[$(this).val()] = true; }); if (step.disabledKeys) $.extend(occupiedKeys, step.disabledKeys); return occupiedKeys; } function buildKeyInput(step) { if (!step.keys) return undefined; var input = $(mw.html.element("select", { "class": "wiktku-start-step-keyfield wiktku-start-narrow" })); input.attr("data-placeholder", "Hilbijêre " + step.keyName); if (isMobile) { populateMenus(input, step.keys, getDisabledKeys(step)); // On mobile return the wrapper; the select is inside it. // Change events still fire on the inner select. return wrapNativeSelect(input); } input.on("chosen:showing_dropdown", function () { $(this).data("wiktku-defaultValue", $(this).val()); }); input.change(function (_, context) { var inputs = $("#wiktku-start-" + step.id + " .wiktku-start-step-keyfield").not(this); var oldValue = $(this).data("wiktku-defaultValue"); var newValue = context.selected; inputs.find("option[value='" + oldValue + "']").prop('disabled', false); inputs.find("option[value='" + newValue + "']").prop('disabled', true); inputs.trigger("chosen:updated"); }); populateMenus(input, step.keys, getDisabledKeys(step)); return input; } // Adds another text field to the list if the last one now has text. function refreshForTextField(currentInput, step) { currentInput = $(currentInput); var value = currentInput.val(); var item = currentInput.parent(); if (value && !item.next("li").length) { var nextInput = $("<textarea></textarea>") .attr("name", "wiktku-field-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("class", currentInput.attr("class")) .attr("rows", currentInput.attr("rows") || 1); nextInput.on("input", function (evt) { refreshForTextField(evt.target, step); }); var nextKeyInput = buildKeyInput(step); var nextItem = $("<li></li>").append(nextKeyInput).append(nextInput); item.parent().append(nextItem); if (nextKeyInput) nextKeyInput.chosen(chosenOptions); } var canContinue = !continueBtn.isDisabled(); if ((value && !canContinue) || (!value && canContinue)) { refresh(step); } } function prepareInput(input, step) { if (!input) return; if (step.required) input.prop('required', true); input.change(step, refresh); } // Shows/hides steps based on whether their prerequisites are met, and // updates placeholders where applicable. function refresh(evt) { var values = getValues(); var changedStep = evt && evt.data; var didFocus = false; var canContinue = true; // Re-filter template options in every sense block whenever lang changes. $("#wiktku-start-dfn .wiktku-dfn-tpl-select").each(function () { var fn = $(this).data("updateOptions"); if (typeof fn === "function") fn(); }); // Re-filter pronunciation and etymology template dropdowns when language changes. steps.pron.refreshTplSelect(); steps.etym.refreshTplSelect(); // Sync tr/t sub-fields in every nimûne item to the current language. // tr shown when language needs transliteration; t shown when lang !== "ku". (function () { var lang = values.lang || ""; var showTr = needsTransliteration(lang); var showT = lang && lang !== "ku"; $("#wiktku-start-dfn .wiktku-dfn-nimune-list li.wiktku-dfn-nimune-li").each(function () { var li = $(this); // Ensure the sub-wrapper exists when we need it. var subWrap = li.find(".wiktku-dfn-nimune-sub"); // tr field var trTa = li.find(".wiktku-dfn-nimune-tr"); if (showTr && !trTa.length) { if (!subWrap.length) { subWrap = $("<div></div>").addClass("wiktku-dfn-nimune-sub"); li.append(subWrap); } trTa = $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-tr-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 5) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-tr") .attr("placeholder", "Transkrîpsiyon…"); subWrap.prepend(trTa); } else if (!showTr && trTa.length) { trTa.remove(); } // t field var tTa = li.find(".wiktku-dfn-nimune-t"); if (showT && !tTa.length) { if (!subWrap.length) { subWrap = $("<div></div>").addClass("wiktku-dfn-nimune-sub"); li.append(subWrap); } tTa = $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-t-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 5) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-t") .attr("placeholder", "Tercimeya nimûneyê kurmancî…"); subWrap.append(tTa); } else if (!showT && tTa.length) { tTa.remove(); } // Remove the wrapper if it ended up empty. subWrap = li.find(".wiktku-dfn-nimune-sub"); if (subWrap.length && !subWrap.children().length) subWrap.remove(); }); }()); // Sync tr/t sub-fields in every jêder citation to the current language. // tr shown when language needs transliteration; t shown when lang !== "ku". (function () { var lang = values.lang || ""; var showTr = needsTransliteration(lang); var showT = lang && lang !== "ku"; $("#wiktku-start-dfn .wiktku-dfn-jeder-list li.wiktku-dfn-jeder-li").each(function () { var li = $(this); // Ensure the sub-wrapper exists when we need it. It must sit right // after the quote textarea and before the source selector. var subWrap = li.find(".wiktku-dfn-quote-sub"); // tr field var trTa = li.find(".wiktku-dfn-nimune-quote-tr"); if (showTr && !trTa.length) { if (!subWrap.length) { subWrap = $("<div></div>").addClass("wiktku-dfn-quote-sub"); li.find(".wiktku-dfn-nimune-quote").after(subWrap); } trTa = $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-quote-tr-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 2) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-quote-tr") .attr("placeholder", "Transkrîpsiyona jêgirtinê…"); subWrap.prepend(trTa); } else if (!showTr && trTa.length) { trTa.remove(); } // t field var tTa = li.find(".wiktku-dfn-nimune-quote-t"); if (showT && !tTa.length) { if (!subWrap.length) { subWrap = $("<div></div>").addClass("wiktku-dfn-quote-sub"); li.find(".wiktku-dfn-nimune-quote").after(subWrap); } tTa = $("<textarea></textarea>") .attr("name", "wiktku-dfn-nimune-quote-t-" + $.now() + "-" + Math.random().toString(36).substr(2, 9)) .attr("rows", 2) .attr("class", "wiktku-dfn-subfield wiktku-dfn-nimune-quote-t") .attr("placeholder", "Tercimeya jêgirtinê ya kurmancî…"); subWrap.append(tTa); } else if (!showT && tTa.length) { tTa.remove(); } // Remove the wrapper if it ended up empty. subWrap = li.find(".wiktku-dfn-quote-sub"); if (subWrap.length && !subWrap.children().length) subWrap.remove(); }); }()); $.each(steps, function (stepId, step) { if (typeof(step.visible) === "function" && !step.visible(values)) { $("#wiktku-start-" + stepId).slideUp(); } else { var stepDiv = $("#wiktku-start-" + stepId); if (changedStep !== step && typeof(step.build) === "function") { prepareInput(step.build(stepDiv, values), step); } var input = stepDiv.find(".wiktku-start-step-field"); if (typeof(step.example) === "function") { // .find() above already reaches nested fields (e.g. the dfn // step's mane textareas inside each sense block), so one // assignment covers every step; dfn keeps its own fallback. var exampleText = step.example(values) || (step.id === "dfn" ? "Mane…" : ""); input.attr("placeholder", exampleText); } var didSlideDown; if (!didFocus && stepDiv.css("display") === "none" && step.required) { didSlideDown = function (evt) { input.focus(); }; didFocus = true; } stepDiv.slideDown(didSlideDown); } if (step.required && (values[stepId] === "" || (step.multiple && values[stepId].join("") === ""))) { canContinue = false; } }); continueBtn.setDisabled(!canContinue); } function destroy() { $("#wiktku-start-form, .noafterwizard").slideUp(function () { $(this).remove(); }); $(".noarticletext .nowizard, #editform").slideDown(); $("#ca-edit").removeClass("selected"); $("#ca-wiktku-nowizard").addClass("selected"); } // Priority order for Kurdish dialects and the navz pseudo-code. // Codes listed here come before all other languages; unlisted codes // are sorted alphabetically by their display name via localeCompare. var LANG_PRIORITY = ["navz", "ku", "hac", "sdh", "lki", "ckb", "zza"]; // Inserts a new "== {{ziman|code}} ==" section at the correct sorted // position: navz, then ku/hac/sdh/lki/ckb/zza, then alphabetical by name. function insertNewLangSection(existing, wikitext) { var newCodeMatch = wikitext.match(new RegExp("^" + langHeaderSource("[^}]+"))); var newCode = newCodeMatch ? newCodeMatch[1] : ""; var sections = []; var preamble = ""; var anyHeaderSrc = langHeaderSource("[^}]+"); var firstMatch = new RegExp("^" + anyHeaderSrc, "m").exec(existing); if (!firstMatch) { // No existing lang sections at all — just append. var sep = existing && !/\n\s*$/.test(existing) ? "\n\n" : ""; return existing + sep + wikitext; } // Everything before the first == {{ziman|...}} == is the preamble. var firstSectionStart = firstMatch.index; // Walk back to the start of that line. var lineStart = existing.lastIndexOf("\n", firstSectionStart - 1); var preambleEnd = lineStart !== -1 ? lineStart + 1 : 0; preamble = existing.slice(0, preambleEnd); // Parse each language section: header line + everything until the next header. var body = existing.slice(preambleEnd); // (?![\s\S]) matches only true end-of-string, since a bare "$" with // /m would stop at the section's first line break instead. var langSectionRe = new RegExp( "^(" + anyHeaderSrc + "\\n?)([\\s\\S]*?)(?=\\n" + anyHeaderSrc + "|(?![\\s\\S]))", "gm" ); var m; while ((m = langSectionRe.exec(body)) !== null) { sections.push({ code: m[2], content: m[0] // full text of this section including header }); } // Determine sort rank: priority list first (by index), then alphabetical. function getLangName(code) { var entry = langsByCode[code]; return entry ? entry[1] : code; } function sortRank(code) { var idx = LANG_PRIORITY.indexOf(code); return idx !== -1 ? idx : LANG_PRIORITY.length; } function compareLangs(a, b) { var ra = sortRank(a), rb = sortRank(b); if (ra !== rb) return ra - rb; // Both are outside priority list — sort by display name. return getLangName(a).localeCompare(getLangName(b), userLang); } // Insert the new section into the sorted list. var newSection = { code: newCode, content: wikitext }; var inserted = false; for (var i = 0; i < sections.length; i++) { if (compareLangs(newCode, sections[i].code) < 0) { sections.splice(i, 0, newSection); inserted = true; break; } } if (!inserted) sections.push(newSection); // Re-join: preamble + sections separated by newlines. var joined = sections.map(function (s) { // Ensure each section ends with exactly one newline before the next. return s.content.replace(/\n+$/, ""); }).join("\n"); return preamble + joined + "\n"; } function build() { $(".nowizard, .nowizard .noafterwizard").hide(); var callToAction = $("#wiktku-calltoaction"); var origCallToActionText = callToAction.text(); $(mw.util.addPortletLink("p-views", "#", "Edîtora çavkaniyê veke", "ca-wiktku-nowizard", "Vê rûpelê bi edîtora çavkaniyê çêke", undefined, "#ca-watch")).click(function (evt) { evt.preventDefault(); callToAction.text(origCallToActionText); destroy(); }); if (callToAction.length) { callToAction.text(origCallToActionText + " Forma li jêr ji bo çêkirina madeyeke nû bi kar bîne."); } var startForm = $("<form id='wiktku-start-form'></form>"); var clearPageCheck = null; if (addLangMode) { startForm.append($("<p class='wiktku-addlang-notice'></p>").html( "Bi vê formê tu yê beşeke nû li rûpelê îlawe bikî. Eger ev zimanê ku tu îlawe dikî jixwe di rûpelê de hebe, beşa nû li dawiya vî zimanî dê were îlawekirin. " + "Ji kerema xwe netîceya dawî kontrol bikin, eger problemek derkeve, li <a href='" + mw.util.getUrl('Mediawiki talk:Gadget-start.js') + "'>nîqaşa vê amûrê</a> problemê ragihîne." )); clearPageCheck = $("<input type='checkbox' id='wiktku-clear-page-check'>"); var clearPageLabel = $("<label for='wiktku-clear-page-check'></label>") .text(" Naveroka rûpelê paqij bike (rûpelê ji nû ve binivîse)"); startForm.append( $("<p class='wiktku-addlang-notice'></p>") .append(clearPageCheck) .append(clearPageLabel) ); // Re-evaluate step visibility (e.g. the pron step) whenever this // is toggled, since it changes what counts as "existing content". clearPageCheck.on("change", function () { refresh(); }); } var spinner; // Tab bar for switching between POS sections. var sectionTabsDiv = $("<div id='wiktku-section-tabs'></div>"); startForm.submit(function (evt) { evt.preventDefault(); continueBtn.setDisabled(true); spinner.show(); getWikitext(function (wikitext) { if (addLangMode && clearPageCheck && clearPageCheck.prop("checked")) { // User asked to wipe the page and start fresh — just // write the newly generated wikitext as the full content. $("#wpTextbox1").val(wikitext); } else if (addLangMode) { var textbox = $("#wpTextbox1"); var existing = textbox.val() || ""; // If this language's section already exists (whitespace // differences aside), merge into it; otherwise insert new. var langHeaderMatch = wikitext.match(new RegExp("^(" + langHeaderSource("[^}]+") + "\\n)")); if (langHeaderMatch) { var langHeader = langHeaderMatch[1]; // e.g. "== {{ziman|ku}} ==\n" var newCode = langHeaderMatch[2]; var existingHeader = findLangHeader(existing, newCode); if (existingHeader) { // Strip the header from the new output. var newContent = wikitext.slice(langHeader.length); // Find the insertion point: end of the existing lang section. // A new L2 heading marks the start of the next language block. var searchFrom = existingHeader.index + existingHeader.match.length; // Find the next == … == heading after this section's start. var nextL2 = existing.indexOf("\n== ", searchFrom); var insertAt = nextL2 !== -1 ? nextL2 : existing.length; // Ensure there's a blank line before the inserted block. var before = existing.slice(0, insertAt); var after = existing.slice(insertAt); var sep = /\n\s*$/.test(before) ? "" : "\n"; textbox.val(before + sep + newContent + after); } else { // New language — insert at the correct sorted position. textbox.val(insertNewLangSection(existing, wikitext)); } } else { // Unexpected format — insert at sorted position anyway. textbox.val(insertNewLangSection(existing, wikitext)); } } else { $("#wpTextbox1").val(wikitext); } $("html, body").animate({scrollTop: 0}); callToAction.text("Hindik ma!"); $("#wiktku-preview-container").remove(); destroy(); }); }); $.each(ordered_steps, function (i, step) { var stepDiv = $(mw.html.element("div", { "class": "wiktku-start-step", id: "wiktku-start-" + step.id })); var name = capitalize(step.name); stepDiv.append($(mw.html.element("h3", { "class": "wiktku-start-step-name" }, new mw.html.Raw(mw.html.element("label", { "for": "wiktku-start-" + step.id + "-field" }, name))))); if (step.question_fmt) { stepDiv.append($(mw.html.element("label", { "class": "wiktku-start-step-question", "for": "wiktku-start-" + step.id + "-field" }, step.question_fmt))); if (step.question_br) stepDiv.append($("<br>")); } var input; if (step.choices) { input = $(mw.html.element("select", { "class": "wiktku-start-step-field", id: "wiktku-start-" + step.id + "-field" })); input.attr("data-placeholder", capitalize(step.name) + " hilbijêre "); populateMenus(input, step.choices); if (step.multiple) input.attr("multiple", true); if (isMobile) { stepDiv.append(wrapNativeSelect(input)); } else { stepDiv.append(input); } } else if (typeof(step.build) === "function") { input = step.build(stepDiv); } else { input = $("<textarea></textarea>") .attr("class", "wiktku-start-step-field") .attr("id", "wiktku-start-" + step.id + "-field") .attr("rows", step.rows || 2); if (step.narrow) input.addClass("wiktku-start-narrow"); if (step.multiple) { input.on("input", function (evt) { refreshForTextField(evt.target, step); }); var keyInput = buildKeyInput(step); var list = $(step.ordered ? "<ol></ol>" : "<ul></ul>") .append($("<li></li>").append(keyInput).append(input)); stepDiv.append(list); } else stepDiv.append(input); } prepareInput(input, step); stepDiv.hide(); // Insert tab bar just before the first per-section step. if (step.id === "pos") startForm.append(sectionTabsDiv); startForm.append(stepDiv); }); // ── Section tab helpers ────────────────────────────────────────────── // ── Add-section button — lives in the tab bar, disabled until pos chosen ── var addSectionBtn = new OO.ui.ButtonWidget({ label: "+ Beş zêde bike", disabled: true }); addSectionBtn.on("click", function () { saveCurrentSection(); sections.push({}); activeSection = sections.length - 1; $.each(PER_SECTION_STEP_IDS, function (_, id) { if (id === "dfn") { var stepDiv = $("#wiktku-start-dfn"); stepDiv.find("ol.wiktku-dfn-list").remove(); steps.dfn.build(stepDiv); return; } if (id === "etym") { $("#wiktku-start-etym .wiktku-etym-wrap").remove(); steps.etym.build($("#wiktku-start-etym")); return; } if (id === "trans") { var transDiv = $("#wiktku-start-trans"); transDiv.find(".wiktku-trans-group").remove(); return; } if (id === "zarava") { var zaravaDiv = $("#wiktku-start-zarava"); zaravaDiv.find(".wiktku-zarava-group").remove(); return; } if (id === "dunde") { var dundeDiv = $("#wiktku-start-dunde"); dundeDiv.find("ul.wiktku-dunde-list").remove(); return; } var stepDiv = $("#wiktku-start-" + id); stepDiv.find(".wiktku-start-step-field").val(""); if (!isMobile) stepDiv.find("select.wiktku-start-step-field").trigger("chosen:updated"); }); renderSectionTabs(); refresh(); $("html, body").animate({ scrollTop: sectionTabsDiv.offset().top - 20 }, 300); }); /** Re-render the tab bar to reflect current sections[] and activeSection. */ function renderSectionTabs() { // Detach (not remove) the button first: .empty() strips bound // event data from any children left inside it, which would // silently kill addSectionBtn's click handler on every re-render. addSectionBtn.$element.detach(); sectionTabsDiv.empty(); var lang = getValues().lang || ""; if (!lang) { sectionTabsDiv.hide(); return; } sectionTabsDiv.show(); $.each(sections, function (i) { var posVal = sections[i].pos || ""; var tabLabel = posVal ? capitalize(posVal) : ("Beş " + (i + 1)); var tab = $("<span></span>") .addClass("wiktku-section-tab") .text(tabLabel) .toggleClass("wiktku-tab-active", i === activeSection); (function (idx) { tab.on("click", function () { if (idx === activeSection) return; saveCurrentSection(); activeSection = idx; restoreSection(sections[activeSection]); refresh(); renderSectionTabs(); }); }(i)); sectionTabsDiv.append(tab); }); // Enable "Beş zêde bike" only when the active section has a pos chosen. var activePos = sections[activeSection] && sections[activeSection].pos ? sections[activeSection].pos : getValues().pos; addSectionBtn.setDisabled(!activePos); sectionTabsDiv.append(addSectionBtn.$element); } renderSectionTabs(); // Update the active tab's label whenever pos changes. startForm.on("change", "#wiktku-start-pos-field", function () { renderSectionTabs(); }); // Show the tab bar as soon as a language is selected. startForm.on("change", "#wiktku-start-lang-field", function () { renderSectionTabs(); }); var footer = $("<div id='wiktku-start-footer'></div>"); spinner = $(mw.html.element("img", { id: "wiktku-start-spinner", src: "//upload.wikimedia.org/wikipedia/commons/d/de/Ajax-loader.gif", alt: "Tê barkirin…", title: "Tê barkirin…" })); footer.append(spinner.hide()); continueBtn = new OO.ui.ButtonWidget({ id: "wiktku-unhide-editform", label: "Bişîne", flags: [ "primary", "progressive" ] }); continueBtn.on("click", function () { mw.notify("Tê şandin…", { type: "info", tag: "wiktku-submit" }); startForm.trigger("submit"); }); footer.append(continueBtn.$element); // "Edîtora çavkaniyê veke" button — inline fallback for the portlet link // which is invisible on mobile and easy to miss on desktop. var sourceEditorBtn = new OO.ui.ButtonWidget({ label: "Edîtora çavkaniyê veke", framed: false }); sourceEditorBtn.on("click", function () { destroy(); }); footer.append(sourceEditorBtn.$element); // ── Preview checkboxes ─────────────────────────────────────────────── // Wikitext preview (raw text panel) var previewCheck = $("<input type='checkbox' id='wiktku-preview-toggle'>"); var previewLabel = $("<label for='wiktku-preview-toggle'></label>") .text(" Pêşdîtina wîkîtekstê"); var previewPanel = $("<pre id='wiktku-preview-panel'></pre>").hide(); // Live rendered preview (parsed HTML panel, same logic as AjaxEdit). // Not available on mobile — API polling causes too many problems on small screens. var livePreviewCheck = null; var livePreviewPanel = null; if (!isMobile) { livePreviewCheck = $("<input type='checkbox' id='wiktku-live-preview-toggle'>"); livePreviewPanel = $("<div id='wiktku-live-preview-panel'></div>").hide(); } // Container that holds both panels and switches between stacked / side-by-side. var previewContainer = $("<div id='wiktku-preview-container'></div>"); previewContainer.append(previewPanel); if (!isMobile) previewContainer.append(livePreviewPanel); var previewTimer = null; var livePreviewIntervalId = -1; var livePreviewActive = false; // guards in-flight fetches after uncheck /** Rebuilds wikitext preview if its checkbox is checked. */ function schedulePreview() { if (!previewCheck.prop("checked")) return; clearTimeout(previewTimer); // Debounce: wait 400 ms after the last keystroke before rebuilding. previewTimer = setTimeout(function () { getWikitext(function (wikitext) { previewPanel.text(wikitext).show(); updatePanelLayout(); }); }, 400); } /** Fetches parsed HTML and populates the live preview panel. */ function loadLivePreview() { getWikitext(function (wikitext) { new mw.Api().parse(wikitext, { title: mw.config.get("wgPageName") }).done(function (html) { // Discard result if the user unchecked while the fetch was in flight. if (!livePreviewActive) return; livePreviewPanel.html(html).show(); updatePanelLayout(); }); }); } /** Adjusts panel widths depending on which previews are visible. */ function updatePanelLayout() { var wikitextVisible = previewCheck.prop("checked"); var liveVisible = livePreviewCheck && livePreviewCheck.prop("checked"); if (wikitextVisible && liveVisible) { // Side by side — each panel takes roughly half the available width. previewPanel.css({ "flex": "1 1 45%", "min-width": "280px" }); livePreviewPanel.css({ "flex": "1 1 45%", "min-width": "280px" }); } else { // Full width for whichever is visible — only touch panels that are // actually shown so that setting flex doesn't override display:none. if (wikitextVisible) previewPanel.css({ "flex": "1 1 100%", "min-width": "" }); if (liveVisible && livePreviewPanel) livePreviewPanel.css({ "flex": "1 1 100%", "min-width": "" }); } } previewCheck.on("change", function () { if ($(this).prop("checked")) { schedulePreview(); } else { clearTimeout(previewTimer); previewPanel.hide(); updatePanelLayout(); } }); if (!isMobile) { livePreviewCheck.on("change", function () { if ($(this).prop("checked")) { livePreviewActive = true; livePreviewPanel.show(); loadLivePreview(); livePreviewIntervalId = setInterval(loadLivePreview, 500); } else { livePreviewActive = false; clearInterval(livePreviewIntervalId); livePreviewIntervalId = -1; livePreviewPanel.hide().empty(); updatePanelLayout(); } }); } // Listen on all input/change events on the form and update both previews. startForm.on("input change", function () { schedulePreview(); }); footer.append($("<span style='margin-left:1em'></span>") .append(previewCheck).append(previewLabel)); if (!isMobile) { var livePreviewLabel = $("<label for='wiktku-live-preview-toggle'></label>") .text(" Pêşdîtina zindî"); footer.append($("<span style='margin-left:1em'></span>") .append(livePreviewCheck).append(livePreviewLabel)); } startForm.append(footer); $("#editform").hide().before(startForm); // Insert preview container (holds both panels) after the form. startForm.after(previewContainer); if (!isMobile) startForm.find("select").chosen(chosenOptions); refresh(); // Zimanan ji MediaWiki:Gadget-translation_editor.js/ziman.json bar bike. // Kodên ku bi "-pro" diqedin û navên ku "zimanê destan" tê de heye // tên derxistin. Zimanên xardkirî li serî dimînin, yên din // bi alfabeyê li dû wan tên. // Pinned choices come from MediaWiki:Gadget-start.js/data.json (langChoices), // already loaded into steps.lang.choices before build() runs. var pinnedChoices = steps.lang.choices.slice(); var pinnedCodes = $.map(pinnedChoices, function (choice) { return choice[0]; }); new mw.Api().get({ action: "query", prop: "revisions", titles: "MediaWiki:Gadget-translation_editor.js/ziman.json", rvprop: "content", rvslots: "main", formatversion: 2 }).then(function (data) { var page = data.query.pages[0]; var content = page && page.revisions && page.revisions[0].slots.main.content; var zimanData; try { zimanData = JSON.parse(content); } catch (e) { zimanData = {}; } var extraChoices = []; $.each(zimanData, function (code, name) { // Filter: skip proto-language codes and legendary/reconstructed langs. if (/-pro$/i.test(code)) return; if (/ziman[eê]\s+destan/i.test(name)) return; // Skip codes already in the pinned list (they are handled above). if (pinnedCodes.indexOf(code) !== -1) return; // sortKey: bare name without leading "zimanê " for sorting. var sortKey = name.replace(/^ziman[eê]\s+/i, ""); var choice = [code, name, sortKey]; extraChoices.push(choice); langsByCode[code] = choice; }); // Populate langsByCode for pinned choices too. $.each(pinnedChoices, function (i, choice) { // Ensure pinned choices have a sortKey (index 2). if (choice.length < 3) choice[2] = choice[1]; langsByCode[choice[0]] = choice; }); // Sort the extra choices alphabetically by sort key. extraChoices.sort(function (a, b) { return a[2].localeCompare(b[2], userLang); }); // Final list: pinned first, then the rest. var allChoices = pinnedChoices.concat(extraChoices); steps.lang.choices = allChoices; steps.trans.keys = allChoices; steps.dunde.keys = allChoices; steps.zarava.keys = getZaravaKeys(allChoices); var langMenu = $("#wiktku-start-lang-field"); populateMenus(langMenu, steps.lang.choices); langMenu.trigger("chosen:updated"); var transMenus = $("#wiktku-start-trans .wiktku-start-step-keyfield"); populateMenus(transMenus, steps.trans.keys, getDisabledKeys(steps.trans)); transMenus.trigger("chosen:updated"); var dundeMenus = $("#wiktku-start-dunde .wiktku-start-step-keyfield"); populateMenus(dundeMenus, steps.dunde.keys, getDisabledKeys(steps.dunde)); dundeMenus.trigger("chosen:updated"); var zaravaMenus = $("#wiktku-start-zarava .wiktku-start-step-keyfield"); populateMenus(zaravaMenus, steps.zarava.keys, getDisabledKeys(steps.zarava)); }); } mw.loader.using(["jquery.chosen", "mediawiki.api", "oojs-ui-core"], function () { if (!isMobile) { mw.notify( "Amûr dest pê dike, hinek bisekinin. Not: jkx Sentaks (sentaks highlighter) neaktîv bikin", { type: "info", tag: "wiktku-start-notice", autoHide: true, autoHideSeconds: 10 } ); } // Load metadata, langChoices, posChoices and tplDefs from the companion // data page so they can be updated without touching this script. new mw.Api().get({ action: "query", prop: "revisions", titles: "MediaWiki:Gadget-start.js/data.json", rvprop: "content", rvslots: "main", formatversion: 2 }).then(function (data) { var page = data.query.pages[0]; var content = page && page.revisions && page.revisions[0].slots.main.content; var d; try { d = JSON.parse(content); } catch (e) { d = {}; } // Populate metadata. if (d.metadata) $.extend(metadata, d.metadata); // Populate gender labels. if (d.genderLabels) $.extend(GENDER_BASE_LABELS, d.genderLabels); // Populate lang choices (pinned list used by build() → ziman.json loader). if (d.langChoices) steps.lang.choices = d.langChoices; // Populate POS choices. if (d.posChoices) steps.pos.choices = d.posChoices; // Populate template definitions for the dfn sense-block builder. if (d.tplDefs) steps.dfn.tplDefs = d.tplDefs; // Populate pos placeholder examples. if (d.posExamples) steps.dfn.posExamples = d.posExamples; // Populate citation template definitions for the quote widget. if (d.jederDefs) steps.dfn.jederDefs = d.jederDefs; // Populate pronunciation and etymology template insert lists. if (d.pronTpls) { steps.pron.pronTpls = d.pronTpls; steps.pron.refreshTplSelect(); } if (d.etymTpls) { steps.etym.etymTpls = d.etymTpls; steps.etym.refreshTplSelect(); } // Sync trans/dunde/zarava keys with the (now populated) lang choices. steps.trans.keys = steps.lang.choices; steps.dunde.keys = steps.lang.choices; steps.zarava.keys = getZaravaKeys(steps.lang.choices); }).always(build); }); }); //</nowiki> sod7igh751g5umen6lhqadaqjt49urx dilevîn 0 977616 6265791 5840868 2026-07-20T08:16:31Z Wikihez 7344 /* */ bi [[MediaWiki:Gadget-AjaxEdit.js|AjaxEdit]]ê re 6265791 wikitext text/x-wiki == {{ziman|ku}} == === Bilêvkirin === * {{ku-IPA}} * {{deng|ku|LL-Q36163 (kmr)-Ebulfîda-dilevîn.wav|Deng|Bidlîs}} * {{ku-kîte}} === Rengdêr === {{rengdêr|ku}} # [[rehîm]], [[birehm]] #* {{Jêgirtin/Mela Hisênê Bateyî/Mewlûda Kurdî|jêgirtin=Rehîm û Rehman, letîf û mihriban<br />Bi navê Xwedayê dilnerm û '''dilovan'''}} ==== Bi alfabeyên din ==== * {{ku-ar|دلەڤین}} ==== Etîmolojî ==== Ji {{pêk|ku|dil|evîn}}. ==== Werger ==== {{werger-ser}} * {{Z|ar}}: {{W+|ar|رَحِيم‎}} * {{Z|en}}: {{W+|en|gracious}} * {{Z|tr}}: {{W+|tr|rahim}} {{werger-bin}} 1qpxhbcmts77mpfdriwue7j6ywko4ih Wîkîferheng:Ferexetnameya giştî 4 977734 6265659 5138559 2026-07-19T20:29:11Z Wikihez 7344 6265659 wikitext text/x-wiki {{softredirect|en:Wiktionary:General disclaimer}} k66362agoedjnjwvkpn235509t8u5ty Gotûbêja Wîkîferhengê:IPA kurmancî 5 979898 6265549 6123446 2026-07-19T12:15:34Z Ghybu 1393 Ghybuî/ê navê [[Gotûbêja Wîkîferhengê:IPA kurdî]] weke [[Gotûbêja Wîkîferhengê:IPA kurmancî]] guhart: şaş tê fêm kirin 6123446 wikitext text/x-wiki == Parastin == {{silav|Balyozxane}} Tu dikarî parastina rûpelê rakî :) Spas --[[Bikarhêner:Ghybu|Ghybu]] ([[Gotûbêja bikarhêner:Ghybu|gotûbêj]]) 19:40, 24 hezîran 2023 (UTC) == SPRACHENSTECKBRIEF == Kitêbeke bi nav SPRACHENSTECKBRIEF heye ku tê de tabloyeke IPAyê dide. [https://www.schule-mehrsprachig.at/fileadmin/Redaktion/Sprachensteckbriefe/PDF/kurdisch.pdf] [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 14:03, 23 sibat 2025 (UTC) == Bilêvkirina Tîpa "i" == Ma bilêvkirina tîpa "i" bi rastî [ɪ] ye? Ez û malbata min [ɪ] nabêjin; em tîpa "i" wek tîpa "ı" ya tirkî bi lêv dikin, yanî [ɯ]. Li gorî hin çavkaniyan jî [ɨ] yan [ə] ye. Jê cuda, ma dengê [ŋ] li kurmancî tune? Li gorî wîkîferheng, bo nimûne, di peyva "ferheng" de [ŋ] heye. Û ev her tişt nebû jî. Va tablo bi rastî min şaş dike! :( [[Bikarhêner:Joriyan|Joriyan]] ([[Gotûbêja bikarhêner:Joriyan|gotûbêj]]) 00:53, 26 tebax 2025 (UTC) :@[[Bikarhêner:Joriyan|Joriyan]] Herfa kurmancî ya "i" weke ya tirkî "ı" [ɯ] nayê gotin ji xeynî hin îstisnayan. Piştî herfeke qalin/qelew [ɯ] ye (weke "ı"ya tirkî), lê wekî dî ne wilo ye. Endamekî dî jî gotibû [ɪ] ne rast e lê ti guhertin nehatin kirin. IPAya li vê websîtê gelekî xelet e. Dengê "i" belkî li gora devokan tê guhertin, lê ne [ɪ] ye. "i", axlebe [ɘ] ye. [[Bikarhêner:Guherto|Guherto]] ([[Gotûbêja bikarhêner:Guherto|gotûbêj]]) 21:40, 7 îlon 2025 (UTC) ::Dengê [ŋ] di kurmancî de heye. Wextê ko "ng" ye, ew "n" li wir [ŋ] ye. Di hinek devokan de di xeberên ko di axlebê devokan de "ng" tê gotin, ew tenê "ŋ" dibêjin (g-yê nabêjin). [[Bikarhêner:Guherto|Guherto]] ([[Gotûbêja bikarhêner:Guherto|gotûbêj]]) 21:43, 7 îlon 2025 (UTC) :::Li ser vê meseleyê ev meqale jî heye, hûn karin li vî jî binêrin: [https://nevgur.net/meqale/12-Deng Deng] [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 21:52, 7 îlon 2025 (UTC) :::: Ev jî heye: [https://nevgur.net/meqale/16 meqaleyeke din] -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 22:38, 7 îlon 2025 (UTC) ::Ji bo bersiva te spas dikim. Ma ji bo [ɘ]'yê hin çavkaniyên vekolînên zimannasiyî hene? Ez dibêjim ku gereke mirov li axaftina kurdan guhdarî ke û loma analîzên fonetîk bike, ji ber ku bi vî awayî em dikarin dengê(-n) rast bibînin. Bi diristî, dengên [ɘ], [ɯ], [​ə], [ɨ] ji min re pir wekhev xuya dikin û herkes li xebatê xwe tiştekî din dibêje. [[Bikarhêner:Joriyan|Joriyan]] ([[Gotûbêja bikarhêner:Joriyan|gotûbêj]]) 14:15, 9 îlon 2025 (UTC) e28wbmuxpcfv2wfafammvcctchyezce Tewandin:hebûn 106 1036591 6265596 6238344 2026-07-19T15:45:43Z Ghybu 1393 6265596 wikitext text/x-wiki {{vegere|hebûn}} {{ku-tewandin-tablo | lêker = hebûn | form = negerguhêz | cure = pêkhatî | rehNiha = he-b- {{i|erênî, têne formên dema niha cuda ne}} | rehBorî = he-bû- {{i|erênî}} <!-- Raweya fermanî - Imperative --> | imp.s2 = hebe | imp.p2 = hebin | negImp.s2 = nebe, mebe | negImp.p2 = nebin, mebin <!-- Raweya pêşkerî - Indicative --> <!-- Dema niha - Present --> | indPresent.s1 = heme | indPresent.s2 = heyî | indPresent.s3 = heye | indPresent.p1 = hene | indPresent.p2 = hene | indPresent.p3 = hene | negIndPresent.s1 = nînim — tine/tune me | negIndPresent.s2 = nînî — tine/tune yî | negIndPresent.s3 = nîne — tine/tune ye | negIndPresent.p1 = nînin — tine/tune ne | negIndPresent.p2 = nînin — tine/tune ne | negIndPresent.p3 = nînin — tine/tune ne <!-- Raboriya sade - Simple past --> | indPreterite.s1 = hebûm | indPreterite.s2 = hebûyî | indPreterite.s3 = hebû | indPreterite.p1 = hebûn | indPreterite.p2 = hebûn | indPreterite.p3 = hebûn | negIndPreterite.s1 = nebûm — tine/tune bûm | negIndPreterite.s2 = nebûyî — tine/tune bûyî | negIndPreterite.s3 = nebû — tine/tune bû | negIndPreterite.p1 = nebûn — tine/tune bûn | negIndPreterite.p2 = nebûn — tine/tune bûn | negIndPreterite.p3 = nebûn — tine/tune bûn <!-- Raboriya berdest - Imperfect --> | indImperfect.s1 = — | indImperfect.s2 = — | indImperfect.s3 = — | indImperfect.p1 = — | indImperfect.p2 = — | indImperfect.p3 = — | negIndImperfect.s1 = — | negIndImperfect.s2 = — | negIndImperfect.s3 = — | negIndImperfect.p1 = — | negIndImperfect.p2 = — | negIndImperfect.p3 = — <!-- Raboriya dûr - Pluperfect --> | indPluperfect.s1 = — | indPluperfect.s2 = — | indPluperfect.s3 = — | indPluperfect.p1 = — | indPluperfect.p2 = — | indPluperfect.p3 = — | negIndPluperfect.s1 = — | negIndPluperfect.s2 = — | negIndPluperfect.s3 = — | negIndPluperfect.p1 = — | negIndPluperfect.p2 = — | negIndPluperfect.p3 = — <!-- Dema bê - Future --> | indFuture.s1 = hebim | indFuture.s2 = hebî | indFuture.s3 = hebe | indFuture.p1 = hebin | indFuture.p2 = hebin | indFuture.p3 = hebin | negIndFuture.s1 = nebim — tine/tune bim | negIndFuture.s2 = nebî — tine/tune bî | negIndFuture.s3 = nebe — tine/tune be | negIndFuture.p1 = nebin — tine/tune bin | negIndFuture.p2 = nebin — tine/tune bin | negIndFuture.p3 = nebin — tine/tune bin <!-- Dahatiya pêş - Future perfect --> | indFuturePerfect.s1 = hebûbim | indFuturePerfect.s2 = hebûbî | indFuturePerfect.s3 = hebûbe | indFuturePerfect.p1 = hebûbin | indFuturePerfect.p2 = hebûbin | indFuturePerfect.p3 = hebûbin | negIndFuturePerfect.s1 = nebûbim — tine/tune bûbim | negIndFuturePerfect.s2 = nebûbî — tine/tune bûbî | negIndFuturePerfect.s3 = nebûbe — tine/tune bûbe | negIndFuturePerfect.p1 = nebûbin — tine/tune bûbin | negIndFuturePerfect.p2 = nebûbin — tine/tune bûbin | negIndFuturePerfect.p3 = nebûbin — tine/tune bûbin <!-- Raboriya dûdar - Perfect --> | indPerfect.s1 = hebûme | indPerfect.s2 = hebûyî | indPerfect.s3 = hebûye | indPerfect.p1 = hebûne | indPerfect.p2 = hebûne | indPerfect.p3 = hebûne | negIndPerfect.s1 = nebûme — tine/tune bûme | negIndPerfect.s2 = nebûyî — tine/tune bûyî | negIndPerfect.s3 = nebûye — tine/tune bûye | negIndPerfect.p1 = nebûne — tine/tune bûne | negIndPerfect.p2 = nebûne — tine/tune bûne | negIndPerfect.p3 = nebûne — tine/tune bûne <!-- Çîrokiya boriya dûdar - Non-witnessed pluperfect --> | indNwPluperfect.s1 = — | indNwPluperfect.s2 = — | indNwPluperfect.s3 = — | indNwPluperfect.p1 = — | indNwPluperfect.p2 = — | indNwPluperfect.p3 = — | negIndNwPluperfect.s1 = — | negIndNwPluperfect.s2 = — | negIndNwPluperfect.s3 = — | negIndNwPluperfect.p1 = — | negIndNwPluperfect.p2 = — | negIndNwPluperfect.p3 = — <!-- Raweya xwestekî - Subjunctive --> <!-- Dema nihaya xwestekî - Present subjunctive: bnr. "indFuture" --> <!-- Dema boriya xwestekî - Preterite subjunctive: bnr. "indFuturePerfect" --> <!-- Raboriya bilaniyê - Imperfect subjunctive --> | subjImperfect.s1 = hebûma | subjImperfect.s2 = hebûya/hebûyayî | subjImperfect.s3 = hebûya | subjImperfect.p1 = hebûna | subjImperfect.p2 = hebûna | subjImperfect.p3 = hebûna | negSubjImperfect.s1 = nebûma — tine/tune bûma | negSubjImperfect.s2 = nebûya/nebûyayî — tine/tune bûya/bûyayî | negSubjImperfect.s3 = nebûya — tine/tune bûya | negSubjImperfect.p1 = nebûna — tine/tune bûna | negSubjImperfect.p2 = nebûna — tine/tune bûna | negSubjImperfect.p3 = nebûna — tine/tune bûna <!-- Raboriya dûr a bilaniyê - Pluperfect subjunctive --> | subjPluperfect.s1 = — | subjPluperfect.s2 = — | subjPluperfect.s3 = — | subjPluperfect.p1 = — | subjPluperfect.p2 = — | subjPluperfect.p3 = — | negSubjPluperfect.s1 = — | negSubjPluperfect.s2 = — | negSubjPluperfect.s3 = — | negSubjPluperfect.p1 = — | negSubjPluperfect.p2 = — | negSubjPluperfect.p3 = — <!-- Raweya mercî - Conditional --> <!-- Çîrokiya dema nihaya mercî - Present conditional: bnr. "subjImperfect" --> <!-- Dema boriya mercî - Preterite conditional: bnr. "subjPluperfect" --> }} ==== Binêre herwiha ==== {| class="wikitable" |- ! Dema niha ! Dema borî ! Dema bê |- | <span style="color:green">min, te, wê, wî, me, we, wan</span> tişt'''ek''' heye | <span style="color:green">min, te, wê, wî, me, we, wan</span> tişt'''ek''' hebû | <span style="color:green">min, te, wê, wî, me, we, wan</span> tişt'''ek''' hebe |- | <span style="color:green">min, te, wê, wî, me, we, wan</span> '''çend''' tişt hene | <span style="color:green">min, te, wê, wî, me, we, wan</span> '''çend''' tişt hebûn | <span style="color:green">min, te, wê, wî, me, we, wan</span> '''çend''' tişt hebin |} 1w1kb0824kp5rnti1imxqjndrtkw71c 6265610 6265596 2026-07-19T16:07:51Z Ghybu 1393 6265610 wikitext text/x-wiki {{vegere|hebûn}} {{ku-tewandin-tablo | lêker = hebûn | form = negerguhêz | cure = pêkhatî | rehNiha = he-b- {{i|erênî, têne formên dema niha cuda ne}} | rehBorî = he-bû- {{i|erênî}} <!-- Raweya fermanî - Imperative --> | imp.s2 = {{g|ku|hebe}} | imp.p2 = {{g|ku|hebin}} | negImp.s2 = {{g|ku|nebe}}, {{g|ku|mebe}} | negImp.p2 = {{g|ku|nebin}}, {{g|ku|mebin}} <!-- Raweya pêşkerî - Indicative --> <!-- Dema niha - Present --> | indPresent.s1 = {{g|ku|heme}} | indPresent.s2 = {{g|ku|heyî}} | indPresent.s3 = {{g|ku|heye}} | indPresent.p1 = {{g|ku|hene}} | indPresent.p2 = {{g|ku|hene}} | indPresent.p3 = {{g|ku|hene}} | negIndPresent.s1 = {{g|ku|nînim}} — {{g|ku|tine}}/{{g|ku|tune}} me | negIndPresent.s2 = {{g|ku|nînî}} — tine/tune yî | negIndPresent.s3 = {{g|ku|nîne}} — tine/tune ye | negIndPresent.p1 = {{g|ku|nînin}} — tine/tune ne | negIndPresent.p2 = {{g|ku|nînin}} — tine/tune ne | negIndPresent.p3 = {{g|ku|nînin}} — tine/tune ne <!-- Raboriya sade - Simple past --> | indPreterite.s1 = {{g|ku|hebûm}} | indPreterite.s2 = {{g|ku|hebûyî}} | indPreterite.s3 = {{g|ku|hebû}} | indPreterite.p1 = {{g|ku|hebûn}} | indPreterite.p2 = {{g|ku|hebûn}} | indPreterite.p3 = {{g|ku|hebûn}} | negIndPreterite.s1 = nebûm — {{g|ku|tine}}/{{g|ku|tune}} bûm | negIndPreterite.s2 = nebûyî — tine/tune bûyî | negIndPreterite.s3 = nebû — tine/tune bû | negIndPreterite.p1 = nebûn — tine/tune bûn | negIndPreterite.p2 = nebûn — tine/tune bûn | negIndPreterite.p3 = nebûn — tine/tune bûn <!-- Raboriya berdest - Imperfect --> | indImperfect.s1 = — | indImperfect.s2 = — | indImperfect.s3 = — | indImperfect.p1 = — | indImperfect.p2 = — | indImperfect.p3 = — | negIndImperfect.s1 = — | negIndImperfect.s2 = — | negIndImperfect.s3 = — | negIndImperfect.p1 = — | negIndImperfect.p2 = — | negIndImperfect.p3 = — <!-- Raboriya dûr - Pluperfect --> | indPluperfect.s1 = — | indPluperfect.s2 = — | indPluperfect.s3 = — | indPluperfect.p1 = — | indPluperfect.p2 = — | indPluperfect.p3 = — | negIndPluperfect.s1 = — | negIndPluperfect.s2 = — | negIndPluperfect.s3 = — | negIndPluperfect.p1 = — | negIndPluperfect.p2 = — | negIndPluperfect.p3 = — <!-- Dema bê - Future --> | indFuture.s1 = {{g|ku|hebim}} | indFuture.s2 = {{g|ku|hebî}} | indFuture.s3 = {{g|ku|hebe}} | indFuture.p1 = {{g|ku|hebin}} | indFuture.p2 = {{g|ku|hebin}} | indFuture.p3 = {{g|ku|hebin}} | negIndFuture.s1 = nebim — {{g|ku|tine}}/{{g|ku|tune}} bim | negIndFuture.s2 = nebî — tine/tune bî | negIndFuture.s3 = nebe — tine/tune be | negIndFuture.p1 = nebin — tine/tune bin | negIndFuture.p2 = nebin — tine/tune bin | negIndFuture.p3 = nebin — tine/tune bin <!-- Dahatiya pêş - Future perfect --> | indFuturePerfect.s1 = hebûbim | indFuturePerfect.s2 = hebûbî | indFuturePerfect.s3 = hebûbe | indFuturePerfect.p1 = hebûbin | indFuturePerfect.p2 = hebûbin | indFuturePerfect.p3 = hebûbin | negIndFuturePerfect.s1 = nebûbim — tine/tune bûbim | negIndFuturePerfect.s2 = nebûbî — tine/tune bûbî | negIndFuturePerfect.s3 = nebûbe — tine/tune bûbe | negIndFuturePerfect.p1 = nebûbin — tine/tune bûbin | negIndFuturePerfect.p2 = nebûbin — tine/tune bûbin | negIndFuturePerfect.p3 = nebûbin — tine/tune bûbin <!-- Raboriya dûdar - Perfect --> | indPerfect.s1 = hebûme | indPerfect.s2 = hebûyî | indPerfect.s3 = hebûye | indPerfect.p1 = hebûne | indPerfect.p2 = hebûne | indPerfect.p3 = hebûne | negIndPerfect.s1 = nebûme — tine/tune bûme | negIndPerfect.s2 = nebûyî — tine/tune bûyî | negIndPerfect.s3 = nebûye — tine/tune bûye | negIndPerfect.p1 = nebûne — tine/tune bûne | negIndPerfect.p2 = nebûne — tine/tune bûne | negIndPerfect.p3 = nebûne — tine/tune bûne <!-- Çîrokiya boriya dûdar - Non-witnessed pluperfect --> | indNwPluperfect.s1 = — | indNwPluperfect.s2 = — | indNwPluperfect.s3 = — | indNwPluperfect.p1 = — | indNwPluperfect.p2 = — | indNwPluperfect.p3 = — | negIndNwPluperfect.s1 = — | negIndNwPluperfect.s2 = — | negIndNwPluperfect.s3 = — | negIndNwPluperfect.p1 = — | negIndNwPluperfect.p2 = — | negIndNwPluperfect.p3 = — <!-- Raweya xwestekî - Subjunctive --> <!-- Dema nihaya xwestekî - Present subjunctive: bnr. "indFuture" --> <!-- Dema boriya xwestekî - Preterite subjunctive: bnr. "indFuturePerfect" --> <!-- Raboriya bilaniyê - Imperfect subjunctive --> | subjImperfect.s1 = hebûma | subjImperfect.s2 = hebûya/hebûyayî | subjImperfect.s3 = hebûya | subjImperfect.p1 = hebûna | subjImperfect.p2 = hebûna | subjImperfect.p3 = hebûna | negSubjImperfect.s1 = nebûma — tine/tune bûma | negSubjImperfect.s2 = nebûya/nebûyayî — tine/tune bûya/bûyayî | negSubjImperfect.s3 = nebûya — tine/tune bûya | negSubjImperfect.p1 = nebûna — tine/tune bûna | negSubjImperfect.p2 = nebûna — tine/tune bûna | negSubjImperfect.p3 = nebûna — tine/tune bûna <!-- Raboriya dûr a bilaniyê - Pluperfect subjunctive --> | subjPluperfect.s1 = — | subjPluperfect.s2 = — | subjPluperfect.s3 = — | subjPluperfect.p1 = — | subjPluperfect.p2 = — | subjPluperfect.p3 = — | negSubjPluperfect.s1 = — | negSubjPluperfect.s2 = — | negSubjPluperfect.s3 = — | negSubjPluperfect.p1 = — | negSubjPluperfect.p2 = — | negSubjPluperfect.p3 = — <!-- Raweya mercî - Conditional --> <!-- Çîrokiya dema nihaya mercî - Present conditional: bnr. "subjImperfect" --> <!-- Dema boriya mercî - Preterite conditional: bnr. "subjPluperfect" --> }} ==== Binêre herwiha ==== {| class="wikitable" |- ! Dema niha ! Dema borî ! Dema bê |- | <span style="color:green">min, te, wê, wî, me, we, wan</span> tişt'''ek''' heye | <span style="color:green">min, te, wê, wî, me, we, wan</span> tişt'''ek''' hebû | <span style="color:green">min, te, wê, wî, me, we, wan</span> tişt'''ek''' hebe |- | <span style="color:green">min, te, wê, wî, me, we, wan</span> '''çend''' tişt hene | <span style="color:green">min, te, wê, wî, me, we, wan</span> '''çend''' tişt hebûn | <span style="color:green">min, te, wê, wî, me, we, wan</span> '''çend''' tişt hebin |} a6tyh4qvjgabmcdxxho8r74suwx8kbe 6265611 6265610 2026-07-19T16:19:45Z Ghybu 1393 6265611 wikitext text/x-wiki {{vegere|hebûn}} {{ku-tewandin-tablo | lêker = hebûn | form = negerguhêz | cure = pêkhatî | rehNiha = he-b- {{i|erênî, têne formên dema niha cuda ne}} | rehBorî = he-bû- {{i|erênî}} <!-- Raweya fermanî - Imperative --> | imp.s2 = {{g|ku|hebe}} | imp.p2 = {{g|ku|hebin}} | negImp.s2 = {{g|ku|nebe}}, {{g|ku|mebe}} | negImp.p2 = {{g|ku|nebin}}, {{g|ku|mebin}} <!-- Raweya pêşkerî - Indicative --> <!-- Dema niha - Present --> | indPresent.s1 = {{g|ku|heme}} | indPresent.s2 = {{g|ku|heyî}} | indPresent.s3 = {{g|ku|heye}} | indPresent.p1 = {{g|ku|hene}} | indPresent.p2 = {{g|ku|hene}} | indPresent.p3 = {{g|ku|hene}} | negIndPresent.s1 = {{g|ku|nînim}} — {{g|ku|tine}}/{{g|ku|tune}} me | negIndPresent.s2 = {{g|ku|nînî}} — tine/tune yî | negIndPresent.s3 = {{g|ku|nîne}} — tine/tune ye | negIndPresent.p1 = {{g|ku|nînin}} — tine/tune ne | negIndPresent.p2 = {{g|ku|nînin}} — tine/tune ne | negIndPresent.p3 = {{g|ku|nînin}} — tine/tune ne <!-- Raboriya sade - Simple past --> | indPreterite.s1 = {{g|ku|hebûm}} | indPreterite.s2 = {{g|ku|hebûyî}} | indPreterite.s3 = {{g|ku|hebû}} | indPreterite.p1 = {{g|ku|hebûn}} | indPreterite.p2 = {{g|ku|hebûn}} | indPreterite.p3 = {{g|ku|hebûn}} | negIndPreterite.s1 = {{g|ku|nebûm}} — {{g|ku|tine}}/{{g|ku|tune}} bûm | negIndPreterite.s2 = {{g|ku|nebûyî}} — tine/tune bûyî | negIndPreterite.s3 = {{g|ku|nebû}} — tine/tune bû | negIndPreterite.p1 = {{g|ku|nebûn}} — tine/tune bûn | negIndPreterite.p2 = {{g|ku|nebûn}} — tine/tune bûn | negIndPreterite.p3 = {{g|ku|nebûn}} — tine/tune bûn <!-- Raboriya berdest - Imperfect --> | indImperfect.s1 = — | indImperfect.s2 = — | indImperfect.s3 = — | indImperfect.p1 = — | indImperfect.p2 = — | indImperfect.p3 = — | negIndImperfect.s1 = — | negIndImperfect.s2 = — | negIndImperfect.s3 = — | negIndImperfect.p1 = — | negIndImperfect.p2 = — | negIndImperfect.p3 = — <!-- Raboriya dûr - Pluperfect --> | indPluperfect.s1 = — | indPluperfect.s2 = — | indPluperfect.s3 = — | indPluperfect.p1 = — | indPluperfect.p2 = — | indPluperfect.p3 = — | negIndPluperfect.s1 = — | negIndPluperfect.s2 = — | negIndPluperfect.s3 = — | negIndPluperfect.p1 = — | negIndPluperfect.p2 = — | negIndPluperfect.p3 = — <!-- Dema bê - Future --> | indFuture.s1 = {{g|ku|hebim}} | indFuture.s2 = {{g|ku|hebî}} | indFuture.s3 = {{g|ku|hebe}} | indFuture.p1 = {{g|ku|hebin}} | indFuture.p2 = {{g|ku|hebin}} | indFuture.p3 = {{g|ku|hebin}} | negIndFuture.s1 = {{g|ku|nebim}} — {{g|ku|tine}}/{{g|ku|tune}} bim | negIndFuture.s2 = {{g|ku|nebî}} — tine/tune bî | negIndFuture.s3 = {{g|ku|nebe}} — tine/tune be | negIndFuture.p1 = {{g|ku|nebin}} — tine/tune bin | negIndFuture.p2 = {{g|ku|nebin}} — tine/tune bin | negIndFuture.p3 = {{g|ku|nebin}} — tine/tune bin <!-- Dahatiya pêş - Future perfect --> | indFuturePerfect.s1 = {{g|ku|hebûbim}} | indFuturePerfect.s2 = {{g|ku|hebûbî}} | indFuturePerfect.s3 = {{g|ku|hebûbe}} | indFuturePerfect.p1 = {{g|ku|hebûbin}} | indFuturePerfect.p2 = {{g|ku|hebûbin}} | indFuturePerfect.p3 = {{g|ku|hebûbin}} | negIndFuturePerfect.s1 = {{g|ku|nebûbim}} — {{g|ku|tine}}/{{g|ku|tune}} bûbim | negIndFuturePerfect.s2 = {{g|ku|nebûbî}} — tine/tune bûbî | negIndFuturePerfect.s3 = {{g|ku|nebûbe}} — tine/tune bûbe | negIndFuturePerfect.p1 = {{g|ku|nebûbin}} — tine/tune bûbin | negIndFuturePerfect.p2 = {{g|ku|nebûbin}} — tine/tune bûbin | negIndFuturePerfect.p3 = {{g|ku|nebûbin}} — tine/tune bûbin <!-- Raboriya dûdar - Perfect --> | indPerfect.s1 = {{g|ku|hebûme}} | indPerfect.s2 = {{g|ku|hebûyî}} | indPerfect.s3 = {{g|ku|hebûye}} | indPerfect.p1 = {{g|ku|hebûne}} | indPerfect.p2 = {{g|ku|hebûne}} | indPerfect.p3 = {{g|ku|hebûne}} | negIndPerfect.s1 = {{g|ku|nebûme}} — {{g|ku|tine}}/{{g|ku|tune}} bûme | negIndPerfect.s2 = {{g|ku|nebûyî}} — tine/tune bûyî | negIndPerfect.s3 = {{g|ku|nebûye}} — tine/tune bûye | negIndPerfect.p1 = {{g|ku|nebûne}} — tine/tune bûne | negIndPerfect.p2 = {{g|ku|nebûne}} — tine/tune bûne | negIndPerfect.p3 = {{g|ku|nebûne}} — tine/tune bûne <!-- Çîrokiya boriya dûdar - Non-witnessed pluperfect --> | indNwPluperfect.s1 = — | indNwPluperfect.s2 = — | indNwPluperfect.s3 = — | indNwPluperfect.p1 = — | indNwPluperfect.p2 = — | indNwPluperfect.p3 = — | negIndNwPluperfect.s1 = — | negIndNwPluperfect.s2 = — | negIndNwPluperfect.s3 = — | negIndNwPluperfect.p1 = — | negIndNwPluperfect.p2 = — | negIndNwPluperfect.p3 = — <!-- Raweya xwestekî - Subjunctive --> <!-- Dema nihaya xwestekî - Present subjunctive: bnr. "indFuture" --> <!-- Dema boriya xwestekî - Preterite subjunctive: bnr. "indFuturePerfect" --> <!-- Raboriya bilaniyê - Imperfect subjunctive --> | subjImperfect.s1 = {{g|ku|hebûma}} | subjImperfect.s2 = {{g|ku|hebûya}}/{{g|ku|hebûyayî}} | subjImperfect.s3 = {{g|ku|hebûya}} | subjImperfect.p1 = {{g|ku|hebûna}} | subjImperfect.p2 = {{g|ku|hebûna}} | subjImperfect.p3 = {{g|ku|hebûna}} | negSubjImperfect.s1 = {{g|ku|nebûma}} — {{g|ku|tine}}/{{g|ku|tune}} bûma | negSubjImperfect.s2 = {{g|ku|nebûya}}/{{g|ku|nebûyayî}} — tine/tune bûya/bûyayî | negSubjImperfect.s3 = {{g|ku|nebûya}} — tine/tune bûya | negSubjImperfect.p1 = {{g|ku|nebûna}} — tine/tune bûna | negSubjImperfect.p2 = {{g|ku|nebûna}} — tine/tune bûna | negSubjImperfect.p3 = {{g|ku|nebûna}} — tine/tune bûna <!-- Raboriya dûr a bilaniyê - Pluperfect subjunctive --> | subjPluperfect.s1 = — | subjPluperfect.s2 = — | subjPluperfect.s3 = — | subjPluperfect.p1 = — | subjPluperfect.p2 = — | subjPluperfect.p3 = — | negSubjPluperfect.s1 = — | negSubjPluperfect.s2 = — | negSubjPluperfect.s3 = — | negSubjPluperfect.p1 = — | negSubjPluperfect.p2 = — | negSubjPluperfect.p3 = — <!-- Raweya mercî - Conditional --> <!-- Çîrokiya dema nihaya mercî - Present conditional: bnr. "subjImperfect" --> <!-- Dema boriya mercî - Preterite conditional: bnr. "subjPluperfect" --> }} ==== Binêre herwiha ==== {| class="wikitable" |- ! Dema niha ! Dema borî ! Dema bê |- | <span style="color:green">min, te, wê, wî, me, we, wan</span> tişt'''ek''' heye | <span style="color:green">min, te, wê, wî, me, we, wan</span> tişt'''ek''' hebû | <span style="color:green">min, te, wê, wî, me, we, wan</span> tişt'''ek''' hebe |- | <span style="color:green">min, te, wê, wî, me, we, wan</span> '''çend''' tişt hene | <span style="color:green">min, te, wê, wî, me, we, wan</span> '''çend''' tişt hebûn | <span style="color:green">min, te, wê, wî, me, we, wan</span> '''çend''' tişt hebin |} nagqihjva5k5jm07ft0i72dbytwlm96 MediaWiki:Gadget-aWa.js 8 1240219 6265692 6031774 2026-07-19T22:12:28Z Bikarhêner 3719 6265692 javascript text/javascript "use strict"; /*** [aWa]: [[en:MediaWiki:Gadget-aWa.js|A Wonderfool Archiver]] ***/ // {{documentation}} <nowiki> /*jshint shadow:true, scripturl:true, undef:true, latedef:true, unused:true */ /*global mw, jQuery */ (function () { if (mw.config.get('wgAction') !== 'view') return; var monthNames = [ "kanûna paşîn", "sibat", "adar", "nîsan", "gulan", "hezîran", "tîrmeh", "tebax", "îlon", "çiriya pêşîn", "çiriya paşîn", "kanûna pêşîn" ]; var revMonthNames = {}; for (var j = 0; j < monthNames.length; ++j) revMonthNames[monthNames[j]] = j; function el(tag, child, attr, events) { var node = document.createElement(tag); if (child) { if (typeof child !== 'object') child = [child]; for (var i = 0; i < child.length; ++i) { var ch = child[i]; if ((ch === void(null)) || (ch === null)) continue; else if (typeof ch !== 'object') ch = document.createTextNode(String(ch)); node.appendChild(ch); } } if (attr) for (var key in attr) { node.setAttribute(key, String(attr[key])); } if (events) for (var key in events) { node.addEventListener(key, events[key], false); } return node; } var forumId, remindersList = []; var wgPageName = mw.config.get('wgPageName'); if ((wgPageName === "Wîkîferheng:Daxwazên peyitandinê") ||/^Wîkîferheng:Daxwazên_peyitandinê/.test(wgPageName)) { forumId = 'dp'; remindersList.push(["Ji bîr neke ji bo madeyên peyitandî şablona ", el('code', "{{bêçavkanî}}"), " û/yan ", el('code', "{{p-mane}}"), " ji rûpelê rake."]); } else if ((wgPageName === "Wîkîferheng:Daxwazên_jêbirinê") || /^Wîkîferheng:Daxwazên_jêbirinê/.test(wgPageName)) { forumId = 'dj'; remindersList.push(["Ji bîr neke ji bo madeyên ku neyên jêbirin şablona ", el('code', "{{jêbirin}}"), " ji rûpelê rake."]); } else if ((wgPageName === "Wîkîferheng:Daxwazên_standardkirinê") || /^Wiktionary:Requests_for_moves,_mergers_and_splits\/Unresolved_requests\//.test(wgPageName)) { forumId = 'ds'; remindersList.push(["Ji bîr neke ji bo madeyên ku hatine standardkirin şablona ", el('code', "{{standardkirin}}"), " û/yan ", el('code', "{{ds}}"), " ji rûpelê rake."]); } else if ((wgPageName === "Wîkîferheng:Daxwazên_zelalkirinê") || /^Wiktionary:Requests_for_cleanup\/archive\/\d+\/Unresolved_requests$/.test(wgPageName)) { forumId = 'dz'; remindersList.push(["Ji bîr neke ji bo madeyên ku hatine sererastkirin şablona ", el('code', "{{wdz}}"), " ji rûpelê rake."]); } else if (wgPageName === "Wîkîferheng:Xebat") { forumId = 'xebat'; remindersList.push(["Nîqaşên vê rûpelê tim li [[Wîkîferheng:Xebat/arşîv 1|Wîkîferheng:Xebat/arşîv NO]] têne arşîvkirin."]); } else if (wgPageName === "Wîkîferheng:ceribandin/aWa") { forumId = 'SANDBOX'; remindersList.push(["NO DANGER: Nothing in this room will kill you."]); } else return; if (forumId !== 'feedback') remindersList.push(["Nîqaşên xilasbûyî herî kêm 7 rojan bê arşîv bihêlin."]); function link(child, href, attr, ev) { attr = attr || {}; ev = ev || {}; if (typeof href === 'string') attr.href = href; else { attr.href = 'javascript:void(null);'; ev.click = href; } return el('a', child, attr, ev); } var rxPath = new RegExp('^' + mw.config.get('wgArticlePath').replace('$1', '(.*)') + '$'); // XXX: ugly hack function getPageFromUrl(url) { var m, target; try { target = new mw.Uri(url); } catch (e) { return null; } if (target.host !== location.host) return null; if (target.path === mw.config.get('wgScript')) return new mw.Title(target.query.title); else if ((m = rxPath.exec(target.path))) return new mw.Title(decodeURIComponent(m[1])); return null; } // NOTE: findSectionNumber() previously relied on the .mw-editsection link's // action=edit&section=N query param. MobileFrontend/Minerva strips the // .mw-editsection span from headings entirely, so this always returned null // on mobile and silently dropped the "arşîv bike" link (and, worse, calling // .nextSibling on a missing .mw-editsection later on would throw and abort // the rest of the init loop). Section numbers are now resolved once up // front via action=parse&prop=sections (see sectionMapPromise below) and // matched to headings by document order instead. var api = new mw.Api(); // XXX: seriously, action=parse should return this. var starttimestamp, basetimestamp; api.get({ action: 'query', pageids: mw.config.get('wgArticleId'), prop: 'revisions', curtimestamp: 1, rvstartid: mw.config.get('wgRevisionId'), rvprop: 'timestamp', rvlimit: 1 }).done(function (result) { starttimestamp = result.curtimestamp; basetimestamp = result.query.pages[mw.config.get('wgArticleId')].revisions[0].timestamp; }); // Resolve top-level (level === '2') section indices via the API instead of // scraping .mw-editsection, so this also works on mobile skins that strip // that markup out of the rendered heading. var sectionMapPromise = api.get({ action: 'parse', page: wgPageName, prop: 'sections', formatversion: 2 }).then(function (result) { return result.parse.sections.filter(function (s) { return s.level === '2'; }); }, function (code, result) { console.error('aWa: failed to fetch section map', code, result); return []; }); var toArchive = {}; var uiQueue, uiStatus; function setStatus(child, node) { node = node || uiStatus; if (!node.preceder) node.parentNode.insertBefore(node.preceder = document.createTextNode(''), node); while (node.firstChild) node.removeChild(node.firstChild); if (!child) { if (node.preceder !== true) node.preceder.data = ""; return; } else { if (node.preceder !== true) node.preceder.data = ": "; } if (typeof child === 'string') { node.appendChild(document.createTextNode(child)); return; } for (var i = 0; i < child.length; ++i) { var ch = child[i]; if ((ch === void(null)) || (ch === null)) continue; else if (typeof ch !== 'object') ch = document.createTextNode(String(ch)); node.appendChild(ch); } } var uiProceed, uiWrapper; var uiArchiver = el('div', [ el('form', [ uiWrapper = el('fieldset', [ // ↓↓↓↓↓↓ how fitting. el('legend', [ "A ", link(["Wonderfool"], mw.util.getUrl("wonderfool")), " Archiver ", el('small', ["[", link('veşêre', function () { this.style.fontWeight = uiWrapper.classList.toggle('collapsed') ? 'bold' : ''; }), "]"]) ]), uiQueue = el('ul', null, { 'class': 'queue' }), el('ul', remindersList.map(function (nodes) { return el('li', nodes); }), { 'class': 'reminders' }), uiProceed = el('input', null, { type: 'submit', value: "Dewam bike" }), ' ', el('input', null, { type: 'button', value: "Bigre" }, { click: function () { uiArchiver.style.display = 'none'; } }), uiStatus = el('p', null, { 'class': 'main-statusbar' }) ]) ], { action: 'javascript:void(0);' }, { submit: function () { if (!uiQueue.hasChildNodes()) { // XXX: should probably check the toArchive object instead setStatus("The archiving queue is empty."); return; } if (forumId !== 'SANDBOX') { uiProceed.disabled = true; uiArchiver.classList.add('archiving-in-progress'); } var complete = false; window.addEventListener('beforeunload', function (ev) { if (!complete) { return (ev.returnValue = "Discussions are still being archived."); } }, false); setStatus("Naveroka rûpelê tê girtin…"); api.get({ action: 'parse', oldid: mw.config.get('wgRevisionId'), prop: 'parsetree', }).then(function (result) { setStatus("Slicing up discussions…"); var prettyPageName = (new mw.Title(wgPageName)).getPrefixedText(); function serialiseMarkup(node) { if (node.nodeType === node.TEXT_NODE) return node.data; var children = []; for (var child = node.firstChild; child; child = child.nextSibling) children.push(serialiseMarkup(child)); if (node.tagName === 'part') return '|' + children.join(''); else if (node.tagName === 'tplarg') return '{{{' + children.join('') + '}}}'; else if (node.tagName === 'template') return '{{' + children.join('') + '}}'; else if (node.tagName === 'ext') return '<' + children.join(''); else if (node.tagName === 'attr') return children.join('') + (node.parentNode.lastChild === node ? '/>' : ''); else if (node.tagName === 'inner') return '>' + children.join(''); else return children.join(''); } var parseTree = jQuery.parseXML(result.parse.parsetree['*']); var headerMap = {}; var headers = parseTree.getElementsByTagName('h'); for (var i = 0; i < headers.length; ++i) { headerMap[headers[i].getAttribute('i')] = headers[i]; } var majorQueue = [], minorQueue = [], obliterated = []; var keys = Object.keys(toArchive); for (var j = 0; j < keys.length; ++j) { var item = toArchive[keys[j]]; var sectHead = headerMap[item.sect]; var sectContents = []; for ( var node = sectHead, next = sectHead.nextSibling; node && (!node.getAttribute || !node.getAttribute('level') || (+node.getAttribute('level') > +sectHead.getAttribute('level')) || (node === sectHead)); (next = node.nextSibling, node.parentNode.removeChild(node), node = next) ) { sectContents.push(serialiseMarkup(node)); } var secttext = sectContents.join(''); var discussionTitle; switch (forumId) { case 'dj' : discussionTitle = "Nîqaşa [[" + prettyPageName + "|jêbirinê]]" ; break; case 'rfdo' : discussionTitle = "Nîqaşa [[" + prettyPageName + "|ceribandinê]]" ; break; case 'dp' : discussionTitle = "Nîqaşa [[" + prettyPageName + "|peyitandinê]]" ; break; case 'dz' : discussionTitle = "Nîqaşa [[" + prettyPageName + "|zelalkirinê]]" ; break; case 'ds' : discussionTitle = "Nîqaşa [[" + prettyPageName + "|standardkirinê]]" ; break; case 'xebat' : discussionTitle = item.secttitle ; break; default : discussionTitle = "Archived from [[" + prettyPageName + "]]" ; break; } var rxStamp = /(\d\d?):(\d\d),\s*(\d+)\s*([A-ZÎÛÇŞ][a-zîûçş]+)\s*(\d\d\d\d+)\s*\(UTC\)/g; var m, timestamps = []; while ((m = rxStamp.exec(secttext))) timestamps.push(Date.UTC(parseInt(m[5], 10), revMonthNames[m[4]], parseInt(m[3], 10), parseInt(m[1], 10), parseInt(m[2], 10))); timestamps.sort(); if ((timestamps.length > 0) && (forumId !== 'xebat')) { var first = new Date(timestamps[0]), last = new Date(timestamps[timestamps.length - 1]); if (first.getUTCFullYear() === last.getUTCFullYear()) { if (first.getUTCMonth() === last.getUTCMonth()) discussionTitle += ": " + monthNames[first.getUTCMonth()] + " " + first.getUTCFullYear(); else discussionTitle += ": " + monthNames[first.getUTCMonth()] + "–" + monthNames[last.getUTCMonth()] + " " + first.getUTCFullYear(); } else { discussionTitle += ": " + monthNames[first.getUTCMonth()] + " " + first.getUTCFullYear() + '–' + monthNames[last.getUTCMonth()] + " " + last.getUTCFullYear(); } } if (!item.talk) { obliterated.push(item.secttitle); continue; // requested not to archive. } if (forumId === 'xebat') { // The section title above is now the exact original // heading text (e.g. "Tercimeyên zel"), and // MediaWiki will add "== Tercimeyên zel ==" itself // via sectiontitle when posting with section=new. // So just drop the original heading line instead of // wrapping it in a {{fake==}} placeholder — keeping // it would duplicate the heading. secttext = secttext.replace(/^(=+)(.*?)\1\n?/, ''); } else { secttext = secttext.replace(/^(=+)(.*?)\1(?=\n|$)/, '{{fake$1|1=$2}}'); } majorQueue.push({ targetPage: item.talk, uiStatus: item.uiStatus, sectTitle: discussionTitle, summary: '[[MediaWiki:Gadget-aWa.js/belgekirin|aWa]]: Arşîvkirina nîqaşê ji rûpela [[' + prettyPageName + ']]', content: '{{arşîv-ser|' + forumId + '|' + item.result + '|link=Taybet:PermanentLink/' + mw.config.get('wgRevisionId') + '#' + item.sectid + '}}\n' + secttext.trimRight() + '\n{{arşîv-bin}}' }); var backlinks = item.backlinks; for (var k = 0; k < backlinks.length; ++k) { if (!backlinks[k]) continue; var saneDiscussionTitle = discussionTitle.replace(/\[\[(?:.*?\|)?(.*?)\]\]/g, '$1'); // XXX var linkTarget = item.talk.getPrefixedText() + "#" + saneDiscussionTitle; minorQueue.push({ targetPage: backlinks[k].page, uiStatus: backlinks[k].uiStatus, sectTitle: discussionTitle, summary: "[[MediaWiki:Gadget-aWa.js/belgekirin|aWa]]: Li [[" + linkTarget + "]] lînka nîqaşê ji [[" + prettyPageName + "]] tê zêdekirin", content: ": ''Binêre [[" + linkTarget + "]].''~~~~" }); } } var headers = Array.prototype.slice.call(parseTree.getElementsByTagName('h')); for (var i = 0; i < headers.length; ++i) { if (headers[i].getAttribute('level') !== '1') continue; if (!/^=\s*(Kanûna paşîn|Sibat|Adar|Nîsan|Gulan|Hezîran|Tîrmeh|Tebax|Îlon|Çiriya pêşîn|Çiriya paşîn|Kanûna pêşîn)\s+\d\d\d\d+\s*=$/.test(headers[i].textContent)) continue; out: for (var node = headers[i].nextSibling;; node = node.nextSibling) { switch (node ? node.nodeType : null) { case parseTree.ELEMENT_NODE: if ((node.tagName !== 'h') || (node.getAttribute('level') !== '1')) break out; /* fall through */ case null: while ((headers[i].nextSibling) !== node) headers[i].parentNode.removeChild(headers[i].nextSibling); headers[i].parentNode.removeChild(headers[i]); break out; case parseTree.TEXT_NODE: if (!/^\s*$/.test(node.data)) break out; break; default: break out; } } } var wikitext = serialiseMarkup(parseTree.documentElement); setStatus("Nîqaş ji rûpelê tên jêbirin…"); var summary; var no = "madeyê"; if (majorQueue.length > 1) no = "madeyan"; if (majorQueue.length) summary = '[[MediaWiki:Gadget-aWa.js/belgekirin|aWa]]: Arşîvkirina ' + majorQueue.length + ' ' + no +' li ' + majorQueue.map(function (item) { return '[[' + item.targetPage.getPrefixedText() + ']]'; }).join(", ") + (obliterated.length ? " û jêbirina " + obliterated.length + ": \"" + obliterated.join("\", \"") + "\"": ""); else summary = "[[MediaWiki:Gadget-aWa.js/belgekirin|aWa]]: Jêbirina " + obliterated.length + " made(yan): \"" + obliterated.join("\", \"") + "\""; if (forumId === 'SANDBOX') { setStatus(); alert("Kurte: " + summary + "\nWîkînivîsa dawî:\n\n" + wikitext); majorQueue.forEach(function (item) { alert("[[" + item.targetPage.getPrefixedText() + "]]: " + item.sectTitle + "\n\n" + item.content); }); minorQueue.forEach(function (item) { alert("[[" + item.targetPage.getPrefixedText() + "]]: " + item.sectTitle + "\n\n" + item.content); }); return; } api.post({ action: 'edit', pageid: mw.config.get('wgArticleId'), token: mw.user.tokens.get('csrfToken'), summary: summary, notminor: 1, text: wikitext, basetimestamp: basetimestamp, starttimestamp: starttimestamp }).then(function (result) { function processQueue(queue) { return jQuery.when.apply(jQuery, queue.map(function (item) { setStatus("Tê qeydkirin…", item.uiStatus); return jQuery.Deferred(function (d) { api.post({ action: 'edit', token: mw.user.tokens.get('csrfToken'), notminor: 1, section: 'new', sectiontitle: item.sectTitle, title: item.targetPage.getPrefixedDb(), text: item.content, summary: item.summary, redirect: 1 // XXX }).then(function (result) { if (result.edit.result !== 'Success') { setStatus("Xeletî binêre konsolê", item.uiStatus); d.reject(); console.error(result); return; } // XXX: preferably check if a page is a redirect BEFORE archiving. if (result.redirects) { var target = result.redirects.pop().to; setStatus(["Redirected to ", link(target, mw.util.getUrl(target))], item.uiStatus); d.resolve(); return; } setStatus("OK", item.uiStatus); d.resolve(); }, function (code, result) { setStatus(["Error: [", el('code', [code]), "]"], item.uiStatus); console.error('Request error', result); d.reject(); }); }).promise(); })); } if (result.edit.result !== 'Success') { setStatus("Xeletiyeke nediyar. Ji bo detayan li konsolê binêrin."); console.error(result); complete = true; return; } setStatus("Nîqaşên arşîvkirî li rûpelên gotûbêjan tên barkirin…"); processQueue(majorQueue).then(function () { setStatus("Lînkên vegerînê tên lêzêdekirin…"); processQueue(minorQueue).then(function () { setStatus("Temam. Tê dîsa barkirin…"); complete = true; location.reload(); }, function () { complete = true; setStatus("Archiving was successful, but there was an error while adding backlinks. You can visit the talk pages to add backlinks manually."); }); }, function () { complete = true; setStatus([ "Oops… there was an error while archiving discussions. Go to your ", link("contributions list", mw.util.getUrl('Special:Contributions/' + mw.config.get('wgUserName'))), " to clean things up and try again." ]); }); }, function (code, result) { complete = true; if (code === 'editconflict') { setStatus([ 'Edit conflict detected. Please ', link('refresh the page', function () { location.reload(); }), ' and try again.' ]); return; } if (code === 'http') { setStatus(['Request error: ' + result.textStatus]); console.error('API request error: ', result); return; } if (code === 'ok-but-empty') { setStatus(['Returned empty response from server.']); return; } setStatus([ 'Error while saving the main discussion page: ', result.error.info, ' [code ', el('code', result.error.code), ']' ]); console.error(arguments); }); }, function (code, result) { if (code === 'http') { setStatus('Request error: ' + result.textStatus); console.error('API request error: ', result); return; } if (code === 'ok-but-empty') { setStatus('Received empty response from server.'); return; } setStatus(['Error: ', result.error.info, ' [code ', el('code', [result.error.code]), ']']); return; }); } }) ], { 'class': 'kephir-awa-dialog', 'style': 'display: none;' }); document.body.appendChild(uiArchiver); uiStatus.preceder = true; // Resolves the target page for Xebat archiving: Wîkîferheng:Xebat/arşîv N, // starting at N=1. If that page exists and is over 70,000 bytes, tries // N+1, and so on, until it finds a page that's either missing (not yet // created) or still under the size limit. function findXebatArchiveTarget(n) { var pageTitle = 'Wîkîferheng:Xebat/arşîv ' + n; return api.get({ action: 'query', titles: pageTitle, prop: 'info' }).then(function (result) { var pages = result.query.pages; var pageId = Object.keys(pages)[0]; var page = pages[pageId]; // Page doesn't exist yet: safe to use. if (page.missing !== undefined) return new mw.Title(pageTitle); // Page exists but is too big: move on to the next number. if (page.length > 70000) return findXebatArchiveTarget(n + 1); return new mw.Title(pageTitle); }, function (code, result) { console.error('aWa: failed to check size of', pageTitle, code, result); // On error, fall back to using this page rather than blocking archiving. return new mw.Title(pageTitle); }); } var headers = document.querySelectorAll(".mw-heading > h2"); var dupTracker = {}; function makeLinkFor(headerNode, links, age, section) { var targetChecked = false, targetCheckRequest; if ((section === null) || (section === undefined)) return; // On desktop, insert right after the <h2> title but BEFORE any // DiscussionTools metadata bar (the "Şiroveya dawî" / comment-count / // author-count line, div.ext-discussiontools-init-section-bar) if one // is present, and before the plain .mw-editsection edit link — this is // static markup that nothing else touches, so it's safe. // // IMPORTANT: the class 'ext-discussiontools-init-section' on the // .mw-heading wrapper does NOT reliably indicate the mobile (Minerva) // skin — DiscussionTools adds this same class on desktop (Vector etc.) // whenever DT is enabled, which is the normal case on wikis that have // it turned on. Checking that class was previously used as a mobile // signal and caused the archive link to be inserted as a sibling AFTER // the whole .mw-heading div even on desktop, landing it after // "Şiroveya dawî" instead of before it. // // On real Minerva/mobile pages, .mw-heading's contents — the overflow // menu, subscribe button, and metadata bar — are OOUI widgets // built/rebuilt by DT's own JS shortly after page load, and that // rebuild wipes out anything inserted inside .mw-heading beforehand // (tried re-inserting via MutationObserver on every DT mutation too — // still didn't survive). So on Minerva we insert as a sibling right // after the whole .mw-heading div instead — outside DT's reach — which // lands the link after the metadata bar rather than before it. We // detect Minerva via mw.config's skin name, not via a DT-added class. var mwHeadingDiv = headerNode.parentNode; var isMobileSkin = mw.config.get('skin') === 'minerva'; var metadataBar = mwHeadingDiv.querySelector('.ext-discussiontools-init-section-bar'); var insertParent, insertBefore; if (isMobileSkin) { insertParent = mwHeadingDiv.parentNode; insertBefore = mwHeadingDiv.nextSibling; } else if (metadataBar) { // Desktop with DiscussionTools enabled: insert inside .mw-heading, // right before the metadata bar (which holds "Şiroveya dawî" etc.) insertParent = mwHeadingDiv; insertBefore = metadataBar; } else { // Desktop, no DT metadata bar at all (DT disabled/older markup): // fall back to right after the header node itself. insertParent = mwHeadingDiv; insertBefore = headerNode.nextSibling; } var archiveSpan = el('span', [ '[', link('arşîv bike', function (ev) { // Defensively stop this from bubbling into any ancestor click // handling (DiscussionTools on Minerva/mobile attaches its own // click handling across .mw-heading) and from following the // javascript:void(null) href as a "real" navigation. if (ev) { ev.preventDefault(); ev.stopPropagation(); } var that = this, config = { secttitle: headerNode.textContent, sect: section, sectid: headerNode.id, temp: 'archived', backlinks: [] }; setStatus(); uiArchiver.style.display = ''; if (this.item) return; toArchive[section] = config; var uiArchiveTarget, uiArchiveTargetLink, uiArchiveNowhereLink; var uiResult, results = {}; var uiBacklinks, uiAddBacklink, uiLinksFromSel; function setTarget(page, noCheck) { if (!page) { uiArchiveTarget.style.display = 'none'; uiArchiveNowhereLink.classList.add('active-mode'); uiBacklinks.classList.add('irrelevant'); uiAddBacklink.classList.add('irrelevant'); uiLinksFromSel.classList.add('irrelevant'); if (uiResult) uiResult.classList.add('irrelevant'); if (!config.talk) return; delete dupTracker[config.talk.getPrefixedDb()]; config.talk = null; return; } config.talk = page; dupTracker[page.getPrefixedDb()] = true; uiArchiveTarget.style.display = ''; uiArchiveTargetLink.textContent = page.getPrefixedText(); uiArchiveTargetLink.href = mw.util.getUrl(page.getPrefixedDb()); uiArchiveNowhereLink.classList.remove('active-mode'); uiBacklinks.classList.remove('irrelevant'); uiAddBacklink.classList.remove('irrelevant'); uiLinksFromSel.classList.remove('irrelevant'); if (uiResult) uiResult.classList.remove('irrelevant'); if (!noCheck) { targetCheckRequest = api.get({ action: 'query', titles: page.getPrefixedDb(), redirects: 1 }).then(function (result) { if (result.query.redirects) { setStatus([ "Archive destination [[", link(page.getPrefixedText(), mw.util.getUrl(page.getPrefixedDb(), { 'redirect': 'no' })), "]] is a redirect; corrected." ]); setTarget(new mw.Title(result.query.redirects.pop().to), true); } targetChecked = true; targetCheckRequest = null; }); } else targetChecked = true; } function addBacklink(page, noCheck) { if (!page) return; var uiItem, blConfig = {}; var i = config.backlinks.length; config.backlinks.push(blConfig); var uiLink; function changePage(newPage, noCheck) { blConfig.page = newPage; blConfig.checked = noCheck; uiLink.textContent = newPage.getPrefixedText(); dupTracker[newPage.getPrefixedDb()] = true; if (!noCheck) { blConfig.checkRequest = api.get({ action: 'query', titles: newPage.getPrefixedDb(), redirects: 1 }).then(function (result) { if (result.query.redirects) { setStatus([ "Backlink destination [[", link(newPage.getPrefixedText(), mw.util.getUrl(newPage.getPrefixedDb(), { 'redirect': 'no' })), "]] is a redirect; corrected." ]); changePage(new mw.Title(result.query.redirects.pop().to), true); page = blConfig.page; } blConfig.checked = true; blConfig.checkRequest = null; }); } } uiBacklinks.appendChild(uiItem = el('li', [ uiLink = link(page.getPrefixedText(), mw.util.getUrl(page.getPrefixedDb()), { 'title': "Lînkeke vê nîqaşê dê li vê rûpelê were danîn" }), el('span', [ " (", link('betal bike', function () { uiItem.parentNode.removeChild(uiItem); delete config.backlinks[i]; delete dupTracker[page.getPrefixedDb()]; }, { 'title': "Li wê rûpelê lînkeke nîqaşê daneyîne" }), " \u2022 ", link("bike ya sereke", function () { if (!config.talk) { uiItem.parentNode.removeChild(uiItem); delete config.backlinks[i]; if (blConfig.checkRequest) blConfig.checkRequest.abort(); setTarget(page, blConfig.checked); return; } if (blConfig.checkRequest) blConfig.checkRequest.abort(); if (targetCheckRequest) targetCheckRequest.abort(); changePage(config.talk, targetChecked); setTarget(page, blConfig.checked); page = blConfig.page; }, { 'title': "Vê rûpelê bike hedefa arşîvê ya sereke" }), ")" ], { 'class': 'hide-when-archiving' }), blConfig.uiStatus = el('span') ])); changePage(page, noCheck); return i; } function setResult(result) { for (var key in results) results[key].classList.remove('active-mode'); if (results[result]) results[result].classList.add('active-mode'); config.result = result; } uiQueue.appendChild(this.item = el('li', [ '"', link(headerNode.textContent, '#' + headerNode.id, { 'title': "Ji bo dîtina nîqaşê bitikîne" }), '"', uiArchiveTarget = el('span', [ "→ [[", uiArchiveTargetLink = link('?', 'javascript:void(window.warranty);', { 'title': "Nîqaş dê li vê rûpelê were arşîvkirin" }), "]]" ]), config.uiStatus = el('span'), el('br'), el('small', [ link("hedefê biguhêre", function () { var newTarget = prompt('Cihê nû ya arşîvê?', config.talk ? config.talk.getPrefixedText() : ""); if (!newTarget) return; try { newTarget = new mw.Title(newTarget); } catch (e) { setStatus("Navê rûpelê ne derbasdar e"); return; } if (newTarget.getNamespaceId() < 0) { setStatus("Li valahiyeke taybet nikare were arşîvkirin"); return; } newTarget.namespace |= 1; setTarget(newTarget); setStatus(); }, { 'title': "Cihê arşîvkirina gotûbêjê biguhêre" }), " \u2022 ", uiArchiveNowhereLink = link("jê bibe", function () { setTarget(null); }, { 'title': "Vê gotûbêjê arşîv neke û jê bibe" }), " \u2022 ", uiAddBacklink = link("Li rûpela din lînk zêde bike", function () { var newTarget = prompt("Li kû derê?", ''); if (!newTarget) return; try { newTarget = new mw.Title(newTarget); } catch (e) { setStatus("Navê rûpelê ne derbasdar e"); return; } if (newTarget.getNamespaceId() < 0) { setStatus("Li valahiyeke taybet nikare were arşîvkirin"); return; } newTarget.namespace |= 1; addBacklink(newTarget); setStatus(); }, { 'title': "Rûpelekê lê zêde bike ku tê de lînka vegerîna vê gotûbêjê were danîn" }), " \u2022 ", uiLinksFromSel = link("ji hilbijartinê", function () { var sel = window.getSelection(), taken = {}; var intersectsNode = function (node) { var tmp = document.createRange(); tmp.selectNode(node); return (this.compareBoundaryPoints(this.START_TO_START, tmp) >= 0) && (this.compareBoundaryPoints(this.END_TO_END, tmp) <= 0); }; for (var i = 0; i < sel.rangeCount; ++i) { var range = sel.getRangeAt(i); var links = range.commonAncestorContainer.getElementsByTagName('a'); if (!range.intersectsNode) range.intersectsNode = intersectsNode; for (var j = 0; j < links.length; ++j) { if (!range.intersectsNode(links[j])) continue; var title = getPageFromUrl(links[j].href); if (!title || (title.getNamespaceId() < 0)) continue; if (title) { title.namespace |= 1; if (taken[title.getPrefixedDb()]) continue; addBacklink(title); taken[title.getPrefixedDb()] = true; } } range.detach(); } }, { 'title': "Lînkên vegerînê li rûpelên ku di hilbijartina niha de zêde bike" }), " \u2022 ", link("betal bike", function () { that.item.parentNode.removeChild(that.item); delete toArchive[section]; delete that.item; }, { 'title': "Dev ji arşîvkirinê berde" }), ((forumId === 'dj') || (forumId === 'rfdo') || (forumId === 'dp') || (forumId === 'SANDBOX')) ? uiResult = el('span', [ " \u2022 netîce: ", results.passed = link("bi ser ket", function () { setResult('passed'); }, { 'title': "Ev nîqaş bi ser ket (hatiye peyitandin an nayê jêbirin)" }), " \u2022 ", results.failed = link("têk çû", function () { setResult('failed'); }, { 'title': "Ev nîqaş têk çû (nehatiye peyitandin an tê jêbirin" }), " \u2022 ", results.archived = link("tiştekî din", function () { setResult('archived'); }, { 'title': "Netîce tine ye yan tiştekî din" } ) ]) : null ], { 'class': 'hide-when-archiving' }), uiBacklinks = el('ul', [], { 'class': 'kephir-awa-backlinks' }) ])); var result = 'archived'; // Expected HTML elements: // <div class="mw-heading ..."><h2><span ... class="mw-headline" ...> var mwHeading = headerNode.parentNode; if (!mwHeading.classList.contains("mw-heading")) { console.error("Expected to find element with class mw-heading as parent of %o", headerNode); } if (results.passed) { var resultText; for (var node = mwHeading.nextSibling; node; node = node.nextSibling) { if (!node.getElementsByClassName) continue; if (node.classList.contains("mw-heading") || node.getElementsByClassName("mw-heading").length > 0) break; var bs = node.getElementsByTagName('b'); for (var j = 0; j < bs.length; ++j) { var b = bs[j]; resultText = b.textContent || b.innerText; if (/no\s+consensus/i.test(b.parentNode.textContent)) result = 'archived'; else { if (/\b(failed|Nehat peyitandin|jê bibe|not\s+restored)\b/i.test(resultText)) { result = 'failed'; } else if (/\b(passed|bim\u00EEne|Hat peyitandin|restored|undeleted)\b/i.test(resultText)) { result = 'passed'; } } } } } setResult(result); // Xebat always archives to a numbered page (Wîkîferheng:Xebat/arşîv N), // never to a page linked from the section heading itself — but if // the heading does link to a page, that page's talk page still // gets added as a backlink (see links[0] handling below). // Starting at N=1, check the byte size of each archive page in // turn; if it's over 70 KB, move on to N+1 (creating a new // archive page once we reach one that doesn't exist yet or is // still under the limit). if (forumId === 'xebat') { findXebatArchiveTarget(1).then(function (title) { setTarget(title); }); // The primary archive target is always the numbered Xebat // archive, but if the section title itself is a link (e.g. // to the article under discussion), still add that page's // talk page as a backlink. if (links[0]) { var titleLink = getPageFromUrl(links[0].href); if (titleLink && (titleLink.getNamespaceId() >= 0)) { titleLink.namespace |= 1; addBacklink(titleLink); } } } else if (links[0]) { var title = getPageFromUrl(links[0].href); if (title.getNamespaceId() >= 0) { title.namespace |= 1; setTarget(title); } else setTarget(null); } else { setTarget(null); } if (forumId !== 'xebat') { for (var i = 1; i < links.length; ++i) { var title = getPageFromUrl(links[i].href); title.namespace |= 1; addBacklink(title); } } }), age ? el('small', [' (mesaja dawî: ' + age + ')']) : void(0), ']' ], { "class": "mw-editsection" }); insertParent.insertBefore(archiveSpan, insertBefore); } var levels = {}; for (var i = 0; i < headers.length; ++i) { var level = parseInt(headers[i].parentNode.tagName.substr(1), 10); for (var k = 1; k <= 6; ++k) { if (k < level) { if (levels[k]) levels[k].subHeaders.push(headers[i]); } else delete levels[k]; } levels[level] = headers[i]; headers[i].subHeaders = []; } function collectUntilH2(node) { var nodes = []; while (node && (node.tagName !== 'H2')) { if (node.getElementsByTagName && node.getElementsByTagName('h2').length) { return nodes.concat(collectUntilH2(node.firstChild)); } nodes.push(node); node = node.nextSibling; } return nodes; } sectionMapPromise.then(function (sectionMap) { for (var i = 0; i < headers.length; ++i) { /*jshint loopfunc:true */ var links = Array.prototype.filter.call( headers[i].querySelectorAll('a:not(.ext-discussiontools-init-section-subscribe a)'), function (item) { var title = getPageFromUrl(item.href); return title && (title.getNamespaceId() >= 0); } ); if (!links.length) links.unshift(null); for (var j = 0; j < headers[i].subHeaders.length; ++j) { links = links.concat(Array.prototype.filter.call(headers[i].subHeaders[j].querySelectorAll('a:not(.ext-discussiontools-init-section-subscribe a)'), function (item) { var title = getPageFromUrl(item.href); return title && (title.getNamespaceId() >= 0); })); } // Fixed: previously .parentNode.parentNode climbed one level too // high past the .mw-heading wrapper, so collectUntilH2 walked an // unrelated sibling subtree and found no timestamps, leaving `age` // null forever. .parentNode (the .mw-heading div) is the correct // starting point. var nodes = collectUntilH2(headers[i].parentNode.nextSibling); var timestamps = Array.prototype.concat.call(nodes.map(function (node) { return node.textContent || ''; }).join('').match(/(\d\d?):(\d\d),\s*(\d+)\s*(.*?)\s*(\d\d\d\d+)\s*\(UTC\)/g) || [], nodes.map(function(node) { // Comments in Local Time if (!node.getElementsByClassName) return; var nodes = Array.prototype.slice.call(node.getElementsByClassName('localcomments')); if (/(^|\s)localcomments(\s|$)/.test(node.className)) nodes.push(node); return nodes.map(function (node) { return node.title; }); }).reduce(function (accum, item) { return item ? accum.concat(item) : accum; }, [])).map(function (ts) { var m = /(\d\d?):(\d\d),\s*(\d+)\s*(.*?)\s*(\d\d\d\d+)\s*\(UTC\)/.exec(ts); return Date.UTC(parseInt(m[5], 10), revMonthNames[m[4]], parseInt(m[3], 10), parseInt(m[1], 10), parseInt(m[2], 10)); }).sort(); var age = null; if (timestamps.length) { age = Math.floor((Date.now() - timestamps[timestamps.length - 1]) / 86400000) + ' roj'; } var sectionEntry = sectionMap[i]; makeLinkFor(headers[i], links, age, sectionEntry ? sectionEntry.index : null); } }); })(); // </nowiki> 8jjd23ldbgke0k2ob1fppud6qu29thn MediaWiki:Gadget-aWa.css 8 1240220 6265691 5609758 2026-07-19T22:11:37Z Bikarhêner 3719 6265691 css text/css .kephir-awa-dialog { font-size: 10pt; width: 36em; position: fixed; right: 1em; top: 3em; border: 1px solid var(--wikt-palette-green-7, #3c3); background: var(--wikt-palette-palegreen, #efe); color: var(--wikt-palette-black, #202122); padding: 0.1em 0.5em; z-index: 12; } .kephir-awa-dialog .irrelevant { opacity: 0.5; } .kephir-awa-dialog .reminders { font-size: smaller; border-top: 2px groove var(--wikt-palette-lightgrey, silver); border-bottom: 2px groove var(--wikt-palette-lightgrey, silver); padding: 0.5em 0 0.5em 1.5em; margin: 1.5em 0; } .kephir-awa-dialog .main-statusbar { margin-top: 1.5em; border-top: 2px groove var(--wikt-palette-lightgrey, silver); } .kephir-awa-dialog .main-statusbar:empty { display: none; } .kephir-awa-dialog .queue { max-height: 25em; overflow-y: auto; margin-left: 0; padding-left: 2em; } .kephir-awa-dialog.archiving-in-progress .hide-when-archiving { display: none; } .kephir-awa-dialog .active-mode { font-weight: bold; } .kephir-awa-backlinks { font-size: smaller; } .kephir-awa-dialog fieldset.collapsed > :not(legend) { display: none; } /* Mobile: the fixed 36em width overflows/clips on narrow viewports (e.g. Minerva at ~380px), and with no height limit the dialog can run off the bottom of the screen with no way to reach the submit/close buttons. Make it fluid-width and cap its height with its own scroll instead. */ @media (max-width: 640px) { .kephir-awa-dialog { width: auto; left: 0.5em; right: 0.5em; top: 0.5em; max-height: calc(100vh - 1em); overflow-y: auto; box-sizing: border-box; font-size: 12px; } .kephir-awa-dialog .queue { max-height: 12em; } } az4r1ry6jwp1cdjz8objp5frmjcuhp8 Gotûbêja MediaWiki:Gadget-aWa.js 9 1320172 6265620 6015684 2026-07-19T17:00:06Z Wikihez 7344 [[MediaWiki:Gadget-aWa.js/belgekirin|aWa]]: Li [[Wîkîferheng:Xebat/arşîv 1#MediaWiki:Gadget-aWa.js]] lînka nîqaşê ji [[Wîkîferheng:Xebat]] tê zêdekirin 6265620 wikitext text/x-wiki == Nûkirin == Silav @[[Bikarhêner:Bikarhêner|Bikarhêner]]. Xêra xwe dikarî sayfeya [[Bikarhêner:Balyozxane/Gadget-aWa.js]] kopî bikî li sayfeya [[MediaWiki:Gadget-aWa.js]]? [[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 17:57, 31 tebax 2024 (UTC) == MediaWiki:Gadget-aWa.js == : ''Binêre [[Wîkîferheng:Xebat/arşîv 1#MediaWiki:Gadget-aWa.js]].''[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 17:00, 19 tîrmeh 2026 (UTC) obxpblojygg8ycakv8ik3ivjcbh2q3r 6265622 6265620 2026-07-19T17:01:19Z Wikihez 7344 Restored revision 6015684 by [[Special:Contributions/Wikihez|Wikihez]] ([[User talk:Wikihez|talk]]) ([[:m:User:Xiplus/TwinkleGlobal|TwinkleGlobal]]) 6265622 wikitext text/x-wiki == Nûkirin == Silav @[[Bikarhêner:Bikarhêner|Bikarhêner]]. Xêra xwe dikarî sayfeya [[Bikarhêner:Balyozxane/Gadget-aWa.js]] kopî bikî li sayfeya [[MediaWiki:Gadget-aWa.js]]? [[Bikarhêner:Balyozxane|Balyozxane]] ([[Gotûbêja bikarhêner:Balyozxane|gotûbêj]]) 17:57, 31 tebax 2024 (UTC) gcz6f4riooet5rwy6lrfn8deqlz3ovh Bikarhêner:Wikihez/skrîpt 2 1324934 6265657 6102519 2026-07-19T20:26:14Z Wikihez 7344 /* JSON */ 6265657 wikitext text/x-wiki <center> <inputbox> type=create preload=Bikarhêner:Wikihez/skrîpt/preload default=Bikarhêner:Wikihez/skrîpt/ buttonlabel=Çêke width=50 </inputbox> </center> * [[Bikarhêner:Wikihez/common.js|common.js]] * [[Bikarhêner:Wikihez/common.css|common.css]] * [[Bikarhêner:Wikihez/test.js|test.js]] * [[Bikarhêner:Wikihez/test.py|test.py]] * [[Bikarhêner:Wikihez/test.json|test.json]] ==JSON== {{Special:PrefixIndex/Bikarhêner:Wikihez/skrîpt/json/|stripprefix=yes|hideredirects=yes}} {{Special:Şablon:Jêgirtin/|stripprefix=yes|hideredirects=yes}} ==Python== {{Special:PrefixIndex/Bikarhêner:Wikihez/skrîpt/py/|stripprefix=yes|hideredirects=yes}} ==Javascript== ===JS info=== {{Special:PrefixIndex/Bikarhêner:Wikihez/skrîpt/înfo/|stripprefix=yes|hideredirects=yes}} ===Skrîpt=== {{Special:PrefixIndex/Bikarhêner:Wikihez/skrîpt/js/|stripprefix=yes|hideredirects=yes}} 8ipkviubid52wa6vgufva706pcduhru 6265658 6265657 2026-07-19T20:26:29Z Wikihez 7344 /* JSON */ 6265658 wikitext text/x-wiki <center> <inputbox> type=create preload=Bikarhêner:Wikihez/skrîpt/preload default=Bikarhêner:Wikihez/skrîpt/ buttonlabel=Çêke width=50 </inputbox> </center> * [[Bikarhêner:Wikihez/common.js|common.js]] * [[Bikarhêner:Wikihez/common.css|common.css]] * [[Bikarhêner:Wikihez/test.js|test.js]] * [[Bikarhêner:Wikihez/test.py|test.py]] * [[Bikarhêner:Wikihez/test.json|test.json]] ==JSON== {{Special:PrefixIndex/Bikarhêner:Wikihez/skrîpt/json/|stripprefix=yes|hideredirects=yes}} {{Special:PrefixIndex/Şablon:Jêgirtin/|stripprefix=yes|hideredirects=yes}} ==Python== {{Special:PrefixIndex/Bikarhêner:Wikihez/skrîpt/py/|stripprefix=yes|hideredirects=yes}} ==Javascript== ===JS info=== {{Special:PrefixIndex/Bikarhêner:Wikihez/skrîpt/înfo/|stripprefix=yes|hideredirects=yes}} ===Skrîpt=== {{Special:PrefixIndex/Bikarhêner:Wikihez/skrîpt/js/|stripprefix=yes|hideredirects=yes}} qy3z5aguzo27l6a8hp7u0ucc776x4hz MediaWiki:Gadget-start.js/data.json 8 1357737 6265566 6251318 2026-07-19T13:45:37Z Wikihez 7344 6265566 json application/json { "langChoices": [ [ "ku", "kurmancî" ], [ "zza", "zazakî" ], [ "ckb", "soranî" ], [ "sdh", "kurdiya başûrî" ], [ "hac", "hewramî" ], [ "de", "almanî" ], [ "ar", "erebî" ], [ "fa", "farisî" ], [ "fr", "fransî" ], [ "fi", "fînî" ], [ "en", "îngilîzî" ], [ "ja", "japonî" ], [ "sv", "swêdî" ], [ "tr", "tirkî" ] ], "posChoices": [ [ "navdêr", "Navdêr (îsm)" ], [ "lêker", "Lêker (fiîl)" ], [ "rengdêr", "Rengdêr (sifet)" ], [ "hoker", "Hoker (zerf)" ], [ "serenav", "Serenav (îsmê xisûsî)" ], [ "artîkel", "Artîkel" ], [ "baneşan", "Baneşan (nîda)" ], [ "bazinedaçek", "Bazinedaçek" ], [ "cînav", "Cînav (zemîr)" ], [ "daçek", "Daçek (edat)" ], [ "girêdek", "Girêdek" ], [ "gotineke pêşiyan", "Gotineke pêşiyan" ], [ "hejmar", "Hejmar" ], [ "hevok", "Hevok (cimle)" ], [ "îfade", "Îfade" ], [ "kurtenav", "Kurtenav" ], [ "navgir", "Navgir" ], [ "paşdaçek", "Paşdaçek" ], [ "paşgir", "Paşgir" ], [ "pêşdaçek", "Pêşdaçek" ], [ "pêşgir", "Pêşgir" ], [ "pirtik", "Pirtik" ], [ "reh", "Reh" ], [ "sembol", "Sembol" ], [ "tîp", "Tîp (herf)" ] ], "posExamples": { "navdêr": "Kelîmeyên ji bo tiştan (sêv, heywan, qedeh) yan terman (dilşadî, bextiyarî hwd.) di rêzimanê de.", "lêker": "Kelîmeyên ji bo kirin an bûyînê wekî 'nivîsîn' yan 'xeber dan'.", "rengdêr": "Kelîmeyên ku wesfa navdêran nîşan didin wekî 'sêva sor' yan 'xwarina şîrîn'.", "hoker": "Kelîmeyên ku dem, cih yan awayê kirinê diyar dikin wekî 'bi vî awayî' yan 'demkî'.", "daçek": "Kelîmeyên ku cih, dem yan hereketê diyar dikin wekî 'di.. de' yan 'ji'.", "cînav": "Kelîmeyên ku li şûna navdêran tên bikaranîn daku navdêr neyên dubarekirin wekî 'ew' yan 'em'.", "baneşan": "Kelîmeyên ku hest, deng hwd. îfade dikin wekî 'noşî!' yan 'aferîn'.", "serenav": "Navdêrên ku şexsiyetên ferdî nîşan didin, wek navên kes, cih an organîzasyonan nimûne 'London' yan 'Diyarbekir'.", "gotineke pêşiyan": "Gotinên ku di nav xelkê de bi berbelavî tên bikaranîn bo nimûne 'Serê neêşe ne hewceyî destmalê ye'." }, "genderLabels": { "m": "mê", "n": "nêr", "nt": "nêtar", "mn": "mê û nêr", "mnmane": "mê yan nêr li gorî maneyê", "g": "giştî", "y": "yekjimar", "p": "pirjimar" }, "tplDefs": [ { "name": "awayekî din", "langs": null }, { "name": "guharto", "langs": null }, { "name": "hevmaneya", "langs": null }, { "name": "kevnbûyî", "langs": null }, { "name": "kêmpeyda", "langs": null }, { "name": "şaşnivîs", "langs": null }, { "name": "awayê Jacobsonê", "langs": [ "zza" ] }, { "name": "rastnivîs", "langs": [ "ku" ], "noLang": true }, { "name": "ku-Latn", "langs": [ "ku" ], "noLang": true }, { "name": "sdh-Arab", "langs": [ "sdh" ], "noLang": true }, { "name": "hac-Arab", "langs": [ "hac" ], "noLang": true }, { "name": "ja-romanîzekirin", "langs": [ "ja" ], "noLang": true }, { "name": "ckb-Arab", "langs": [ "ckb" ], "noLang": true } ], "jederDefs": { "jêder-kitêb": { "label": "Kitêb", "fields": [ { "key": "nivîskar", "label": "Nivîskar" }, { "key": "sernav", "label": "Sernav" }, { "key": "sernavê orjînal", "label": "Sernavê orjînal" }, { "key": "terciman", "label": "Terciman" }, { "key": "weşanxane", "label": "Weşanxane" }, { "key": "cih", "label": "Cih" }, { "key": "sal", "label": "Sal" }, { "key": "sala orjînal", "label": "Sala orjînal" }, { "key": "çap", "label": "Çap" }, { "key": "rûpel", "label": "Rûpel" }, { "key": "isbn", "label": "ISBN" }, { "key": "url", "label": "URL" } ] }, "jêder-kovar": { "label": "Kovar", "fields": [ { "key": "nivîskar", "label": "Nivîskar" }, { "key": "nivîskar2", "label": "Nivîskar 2" }, { "key": "sernav", "label": "Sernav" }, { "key": "sernavê orjînal", "label": "Sernavê orjînal" }, { "key": "kovar", "label": "Kovar" }, { "key": "terciman", "label": "Terciman" }, { "key": "weşanxane", "label": "Weşanxane" }, { "key": "cild", "label": "Cild" }, { "key": "hejmar", "label": "Hejmar" }, { "key": "sal", "label": "Sal" }, { "key": "rûpel", "label": "Rûpel" }, { "key": "url", "label": "URL" } ] }, "jêder-websîte": { "label": "Websîte", "fields": [ { "key": "nivîskar", "label": "Nivîskar" }, { "key": "sernav", "label": "Sernav" }, { "key": "terciman", "label": "Terciman" }, { "key": "websîte", "label": "Websîte" }, { "key": "url", "label": "URL" }, { "key": "arşîv", "label": "Arşîva URLê" }, { "key": "sal", "label": "Sal" }, { "key": "tarîx", "label": "Tarîx" } ] } }, "pronTpls": [ { "name": "IPA", "desc": "Alfabeya fonetîk a navmiletî (IPA)", "snippet": "* {{IPA|CODE|/…/}}" }, { "name": "bilêv", "desc": "{{bilêv|herf|nerm, req|hejmar}}", "snippet": "* {{bilêv|herf|cure|hejmar}}" }, { "name": "kîte", "desc": "Şablona hecekirinê", "snippet": "* {{kîte|CODE|he|ce}}" }, { "name": "hevdeng", "desc": "Hevdeng — gotinên bi heman dengî", "snippet": "* {{hevdeng|CODE|…}}" }, { "name": "ku-IPA", "desc": "IPAya otomatîk ji bo kurmancî (kontrol hewce ye)", "snippet": "* {{ku-IPA}}", "langs": [ "ku" ], "noLang": true }, { "name": "ku-kîte", "desc": "Şablona hecekirinê ji bo kurmancî", "snippet": "* {{ku-kîte}}", "langs": [ "ku" ], "noLang": true }, { "name": "zza-IPA", "desc": "IPAya otomatîk ji bo zazakî", "snippet": "* {{zza-IPA}}", "langs": [ "zza" ], "noLang": true }, { "name": "zza-kîte", "desc": "Şablona hecekirinê ji bo zazakî", "snippet": "* {{zza-kîte}}", "langs": [ "zza" ], "noLang": true } ], "etymTpls": [ { "name": "ji", "desc": "Ji zimanekî din hatiye — {{ji|en|ku|anatomy|tr=|t=}}", "snippet": "{{ji|SOURCELANG|CODE|…}}" }, { "name": "deyn", "desc": "Deynkirî — {{deyn|lang|kod|kelîme}}", "snippet": "{{deyn|SOURCELANG|CODE|…}}" }, { "name": "mîr", "desc": "Mîrasmayî — {{mîr|lang|kod|kelîme}}", "snippet": "{{mîr|SOURCELANG|CODE|…}}" }, { "name": "qertaf", "desc": "Ji bi pêşgir, paşgir û hevedudanî — {{qertaf|kod|pêşgir-|reh}}", "snippet": "{{qertaf|CODE|…|…}}" }, { "name": "q", "desc": "Referans bo rûpelekê — {{q|kod|kelîme}} navê zimanî dernakeve", "snippet": "{{q|CODE|…}}" }, { "name": "hv", "desc": "Hevreh — {{hv|lang|kelîme}} navê zimanî derdikeve", "snippet": "{{hv|SOURCELANG|…}}" }, { "name": "nh", "desc": "Nehevreh — {{nh|lang|kelîme}} navê zimanî derdikeve", "snippet": "{{nh|SOURCELANG|…}}" }, { "name": "cotreh", "desc": "Cotreh — teror {{cotreh|ku|tirs}}", "snippet": "{{cotreh|CODE|…}}" }, { "name": "yekser", "desc": "tercimeya yekser — {{yekser|lang|kod|kelîme}}", "snippet": "{{yekser|SOURCELANG|CODE|…}}" }, { "name": "wergirtin", "desc": "Wergirtina maneyê — {{wergirtin|lang|kod|kelîme}}", "snippet": "{{wergirtin|SOURCELANG|CODE|…}}" }, { "name": "paşvesazî", "desc": "Paşvesazî — greed {{paşvesazî|en|greedy}}", "snippet": "{{paşvesazî|CODE|…}}" }, { "name": "qusandin", "desc": "Qusandin — Miho {{qusandin|ku|Mihemmed}}", "snippet": "{{qusandin|CODE|…}}" }, { "name": "têkilkirin", "desc": "Têkilkirin — sormancî {{têkilkirin|ku|soranî|kurmancî}}", "snippet": "{{têkilkirin|CODE|…}}" }, { "name": "nyz", "desc": "Nayê zanîn — {{nyz|ku|hûr=1}}", "snippet": "{{nyz|CODE}}" }, { "name": "onom", "desc": "Onomatopoetîk — {{onom|ku|hûr=1}}", "snippet": "{{onom|CODE}}" }, { "name": "navmiletî", "desc": "Navmiletî — {{navmiletî|ku|hûr=1}}", "snippet": "{{navmiletî|CODE}}" }, { "name": "neo", "desc": "neolojîzm — {{neolojîzm|ku|hûr=1}}", "snippet": "{{neolojîzm|CODE}}" } ], "metadata": { "aa": { "haswikt": 1, "sc": [ "Latn", "Ethi" ] }, "ab": { "haswikt": 1, "sc": [ "Cyrl", "Latn", "Geor" ] }, "aer": { "sc": "Latn" }, "af": { "g": [ "y", "p" ], "haswikt": 1 }, "ak": { "haswikt": 1 }, "akk": { "g": [ "n", "m", "n-p", "m-p" ], "sc": "Xsux" }, "als": { "haswikt": 1 }, "am": { "g": [ "n", "m", "n-p", "m-p" ], "haswikt": 1, "sc": "Ethi" }, "an": { "g": [ "n", "m", "n-p", "m-p" ], "haswikt": 1 }, "ang": { "alt": 1, "g": [ "n", "m", "nt", "n-p", "m-p", "nt-p" ], "haswikt": 1 }, "ar": { "g": [ "n", "m", "n-p", "m-p", "p" ], "alt": 1, "haswikt": 1, "sc": "Arab" }, "arc": { "g": [ "n", "m", "n-p", "m-p" ], "sc": [ "Hebr", "Syrc" ] }, "are": {}, "arz": { "alt": 1, "g": [ "n", "m", "n-p", "m-p" ], "sc": "Arab" }, "as": { "haswikt": 1, "sc": "Beng" }, "ast": { "g": [ "n", "m", "n-p", "m-p" ], "haswikt": 1 }, "av": { "haswikt": 1 }, "ay": { "haswikt": 1 }, "az": { "g": [ "y", "p" ], "haswikt": 1, "sc": [ "Latn", "Cyrl", "Arab" ] }, "ba": { "g": [ "y", "p" ], "sc": "Cyrl" }, "bar": {}, "bat-smg": { "g": [ "n", "m", "n-p", "m-p" ] }, "bbl": { "sc": "Geor" }, "be": { "g": [ "n", "m", "nt", "n-p", "m-p", "nt-p", "p", "împf", "pf" ], "haswikt": 1, "sc": "Cyrl" }, "be-x-old": { "sc": "Cyrl" }, "bg": { "g": [ "n", "m", "nt", "n-p", "m-p", "nt-p", "p", "împf", "pf" ], "haswikt": 1, "sc": "Cyrl" }, "bh": { "haswikt": 1, "sc": "Deva" }, "bhb": { "sc": "Deva" }, "bi": { "haswikt": 1 }, "blt": { "sc": "Tavt" }, "bm": { "haswikt": 1, "sc": [ "Latn", "Nkoo", "Arab" ] }, "bn": { "haswikt": 1, "sc": "Beng" }, "bo": { "haswikt": 1, "sc": "Tibt" }, "br": { "g": [ "n", "m" ], "haswikt": 1 }, "ca": { "g": [ "n", "m", "n-p", "m-p" ], "haswikt": 1 }, "cdo": { "sc": "Hani" }, "ce": { "sc": "Cyrl" }, "ch": { "haswikt": 1 }, "chr": { "haswikt": 1, "sc": "Cher" }, "cjy": { "sc": "Hani" }, "ckb": { "haswikt": 1, "sc": "Arab", "wsc": "ku-Arab" }, "cmn": { "sc": "Hani", "wiktprefix": "zh" }, "co": { "haswikt": 1 }, "cpx": { "sc": "Hani" }, "cr": { "haswikt": 1, "sc": "Cans" }, "crh": {}, "cs": { "g": [ "n", "m", "nt", "n-p", "m-p", "nt-p", "p", "împf", "pf" ], "haswikt": 1 }, "csb": { "g": [ "n", "m", "nt", "n-p", "m-p", "nt-p", "p", "împf", "pf" ], "haswikt": 1 }, "cu": { "g": [ "n", "m", "nt", "n-p", "m-p", "nt-p", "p", "împf", "pf" ], "sc": [ "Cyrs", "Glag" ] }, "cv": { "sc": "Cyrl" }, "cy": { "g": [ "n", "m", "n-p", "m-p" ], "haswikt": 1 }, "czh": { "sc": "Hani" }, "czo": { "sc": "Hani" }, "da": { "g": [ "g", "nt", "g-p", "nt-p", "p" ], "haswikt": 1 }, "dax": {}, "de": { "g": [ "n", "m", "nt", "n-p", "m-p", "nt-p", "p" ], "haswikt": 1, "allowCaps": 1 }, "dhg": {}, "djb": {}, "dji": {}, "djr": {}, "dng": { "sc": "Cyrl" }, "dsb": { "g": [ "n", "m", "nt", "n-p", "m-p", "nt-p", "p", "împf", "pf" ] }, "dsx": {}, "duj": {}, "dv": { "g": [ "y", "p" ], "haswikt": 1, "sc": "Thaa" }, "dz": { "haswikt": 1, "sc": "Tibt" }, "el": { "g": [ "n", "m", "nt", "n-p", "m-p", "nt-p" ], "haswikt": 1 }, "en": { "g": [ "y", "p" ], "haswikt": 1 }, "eo": { "g": [ "y", "p" ], "haswikt": 1 }, "es": { "g": [ "n", "m", "n-p", "m-p", "p" ], "haswikt": 1 }, "et": { "g": [ "y", "p" ], "haswikt": 1 }, "ett": { "g": [ "y", "p" ], "sc": "Ital" }, "eu": { "g": [ "y", "p" ], "haswikt": 1 }, "fa": { "haswikt": 1, "g": [ "y", "p" ], "sc": "Arab", "wsc": "fa-Arab" }, "fa-cls": { "wiktprefix": "fa", "sc": "Arab", "wsc": "fa-Arab" }, "fa-ira": { "wiktprefix": "fa", "sc": "Arab", "wsc": "fa-Arab" }, "fi": { "g": [ "y", "p" ], "haswikt": 1 }, "fil": {}, "fj": { "haswikt": 1 }, "fo": { "g": [ "n", "m", "nt" ], "haswikt": 1 }, "fr": { "g": [ "n", "m", "mnmane", "n-p", "m-p", "p" ], "haswikt": 1 }, "frm": { "g": [ "n", "m", "n-p", "m-p" ] }, "fro": { "g": [ "n", "m", "n-p", "m-p" ] }, "fur": { "g": [ "n", "m", "n-p", "m-p" ] }, "fy": { "g": [ "g", "nt", "p" ], "haswikt": 1 }, "ga": { "g": [ "n", "m", "n-p", "m-p", "p" ], "haswikt": 1 }, "gan": { "sc": "Hani" }, "gd": { "g": [ "n", "m", "n-p", "m-p" ], "haswikt": 1 }, "gez": { "sc": "Ethi" }, "gl": { "g": [ "n", "m", "n-p", "m-p" ], "haswikt": 1 }, "gmw-ecg": { "g": [ "n", "m", "nt", "p" ], "allowCaps": 1 }, "gmy": { "sc": "Linb" }, "gn": { "haswikt": 1 }, "gnn": { "sc": "Latn" }, "got": { "g": [ "n", "m", "nt", "n-p", "m-p", "nt-p" ], "sc": "Goth" }, "grc": { "g": [ "n", "m", "nt", "n-p", "m-p", "nt-p", "p" ] }, "gsw": { "g": [ "n", "m", "nt", "p" ], "allowCaps": 1 }, "gu": { "g": [ "n", "m", "nt", "n-p", "m-p", "nt-p" ], "haswikt": 1, "sc": "Gujr" }, "guf": { "sc": "Latn" }, "gv": { "haswikt": 1 }, "ha": { "haswikt": 1 }, "hak": { "sc": "Hani" }, "har": { "sc": "Ethi" }, "he": { "alt": 1, "g": [ "n", "m", "n-p", "m-p", "p" ], "haswikt": 1, "sc": "Hebr" }, "hi": { "g": [ "n", "m", "n-p", "m-p", "p" ], "haswikt": 1, "sc": "Deva" }, "hif": { "sc": [ "Latn", "Deva" ] }, "hit": { "sc": "Xsux" }, "hrx": { "g": [ "n", "m", "nt", "n-p", "m-p", "nt-p" ], "haswikt": 1 }, "hsb": { "g": [ "n", "m", "nt", "n-p", "m-p", "nt-p", "p", "împf", "pf" ], "haswikt": 1 }, "hsn": { "sc": "Hani" }, "hu": { "g": [ "y", "p" ], "haswikt": 1 }, "hy": { "g": [ "y", "p" ], "haswikt": 1, "sc": "Armn" }, "ia": { "haswikt": 1 }, "id": { "haswikt": 1 }, "ie": { "haswikt": 1 }, "ik": { "haswikt": 1 }, "ike": { "sc": "Cans" }, "ikt": { "sc": "Cans" }, "io": { "haswikt": 1 }, "is": { "g": [ "n", "m", "nt", "n-p", "m-p", "nt-p" ], "haswikt": 1 }, "it": { "g": [ "n", "m", "n-p", "m-p", "p" ], "haswikt": 1 }, "iu": { "haswikt": 1, "sc": "Cans" }, "ja": { "haswikt": 1, "sc": "Jpan" }, "jay": { "sc": "Latn" }, "jbo": { "haswikt": 1 }, "jv": { "haswikt": 1 }, "ka": { "g": [ "y", "p" ], "haswikt": 1 }, "khb": { "sc": [ "Talu", "Lana", "Thai" ] }, "kjh": { "sc": "Cyrl" }, "kk": { "haswikt": 1, "g": [ "y", "p" ], "sc": "Cyrl" }, "kkh": { "sc": [ "Lana", "Thai" ] }, "kl": { "haswikt": 1 }, "km": { "haswikt": 1, "sc": "Khmr" }, "kn": { "haswikt": 1, "sc": "Knda" }, "ku": { "g": [ "n", "m", "mn", "n-p", "m-p", "p" ], "wiktprefix": "ku" }, "ko": { "haswikt": 1, "sc": "Kore" }, "krc": { "g": [ "y", "p" ], "sc": "Cyrl" }, "ks": { "haswikt": 1, "sc": [ "Arab", "Deva" ], "wsc": "ks-Arab" }, "kw": { "haswikt": 1 }, "ky": { "haswikt": 1, "g": [ "y", "p" ], "sc": "Cyrl" }, "la": { "alt": 1, "g": [ "n", "m", "nt", "n-p", "m-p", "nt-p" ], "haswikt": 1 }, "lb": { "g": [ "n", "m", "nt", "p" ], "haswikt": 1, "allowCaps": 1 }, "lez": { "sc": "Cyrl" }, "li": { "haswikt": 1 }, "lki": { "wiktprefix": "ku" }, "lld": { "g": [ "n", "m", "n-p", "m-p" ], "haswikt": 1 }, "lmo": { "g": [ "n", "m", "n-p", "m-p" ], "haswikt": 1 }, "ln": { "haswikt": 1 }, "lo": { "haswikt": 1, "sc": "Laoo" }, "lt": { "alt": 1, "g": [ "n", "m", "n-p", "m-p" ], "haswikt": 1 }, "lv": { "g": [ "n", "m", "n-p", "m-p" ], "haswikt": 1 }, "lzz": { "sc": "Geor" }, "mg": { "haswikt": 1 }, "mh": { "haswikt": 1 }, "mi": { "g": 0, "haswikt": 1 }, "mk": { "g": [ "n", "m", "nt", "n-p", "m-p", "nt-p", "p", "împf", "pf" ], "haswikt": 1, "sc": "Cyrl" }, "ml": { "haswikt": 1, "sc": "Mlym" }, "mn": { "g": [ "y", "p" ], "haswikt": 1, "sc": [ "Cyrl", "Mong" ] }, "mnp": { "sc": "Hani" }, "mo": { "haswikt": 1, "sc": "Cyrl" }, "mol": { "sc": "Cyrl" }, "mr": { "g": [ "n", "m", "nt" ], "haswikt": 1, "sc": "Deva" }, "ms": { "haswikt": 1, "sc": [ "Latn", "Arab" ] }, "mt": { "g": [ "n", "m", "n-p", "m-p", "p" ], "haswikt": 1 }, "mwp": { "sc": "Latn" }, "my": { "haswikt": 1, "sc": "Mymr" }, "na": { "haswikt": 1 }, "nah": { "haswikt": 1 }, "nan": { "wiktprefix": "zh-min-nan", "sc": "Hani" }, "nb": { "g": [ "n", "m", "nt", "n-p", "m-p", "nt-p", "p" ], "wiktprefix": "no" }, "nds-de": { "g": [ "n", "m", "nt", "n-p", "m-p", "nt-p" ], "wiktprefix": "nds" }, "nds-nl": { "g": [ "n", "m", "nt", "n-p", "m-p", "nt-p" ], "wiktprefix": "nds" }, "ne": { "haswikt": 1, "sc": "Deva" }, "nl": { "g": [ "n", "m", "nt", "n-p", "m-p", "nt-p", "p" ], "haswikt": 1 }, "nn": { "g": [ "n", "m", "nt", "n-p", "m-p", "nt-p", "p" ], "haswikt": 1 }, "no": { "g": [ "n", "m", "nt", "n-p", "m-p", "nt-p", "p" ], "haswikt": 1 }, "nod": { "sc": "Lana" }, "non": { "g": [ "n", "m", "nt", "n-p", "m-p", "nt-p" ] }, "oc": { "g": [ "n", "m", "n-p", "m-p" ], "haswikt": 1 }, "om": { "haswikt": 1 }, "or": { "haswikt": 1, "sc": "Orya" }, "orv": { "g": [ "n", "m", "nt", "n-p", "m-p", "nt-p", "p", "împf", "pf" ], "sc": "Cyrs" }, "osc": { "sc": "Ital" }, "ota": { "g": [ "y", "p" ], "sc": "Arab", "wsc": "ota-Arab" }, "pa": { "g": [ "n", "m", "n-p", "m-p", "p" ], "haswikt": 1, "sc": [ "Guru", "Arab" ] }, "pdt": { "g": [ "n", "m", "nt", "n-p", "m-p", "nt-p" ], "wiktprefix": "nds" }, "peo": { "sc": "Xpeo" }, "phn": { "sc": "Phnx" }, "pi": { "g": [ "n", "m", "nt", "n-p", "m-p", "nt-p" ], "haswikt": 1 }, "pjt": { "sc": "Latn" }, "pl": { "g": [ "n", "m", "nt", "n-p", "m-p", "nt-p", "p", "împf", "pf" ], "haswikt": 1 }, "pms": { "g": [ "n", "m", "n-p", "m-p" ], "haswikt": 1 }, "pox": { "g": [ "n", "m", "nt", "n-p", "m-p", "nt-p", "împf", "pf" ] }, "prs": { "wiktprefix": "fa", "sc": "Arab", "wsc": "fa-Arab" }, "ps": { "g": [ "n", "m", "n-p", "m-p", "p" ], "haswikt": 1, "sc": "Arab", "wsc": "ps-Arab" }, "pt": { "g": [ "n", "m", "n-p", "m-p", "p" ], "haswikt": 1 }, "qu": { "haswikt": 1 }, "rgn": { "g": [ "n", "m", "n-p", "m-p" ] }, "rit": { "sc": "Latn" }, "rm": { "g": [ "n", "m" ], "haswikt": 1 }, "rn": { "haswikt": 1 }, "ro": { "g": [ "n", "m", "nt", "n-p", "m-p", "nt-p", "p" ], "haswikt": 1, "sc": [ "Latn", "Cyrl" ] }, "roa-rup": { "haswikt": 1 }, "ru": { "alt": 1, "g": [ "n", "m", "nt", "n-p", "m-p", "nt-p", "p", "împf", "pf" ], "haswikt": 1, "sc": "Cyrl" }, "rue": { "g": [ "n", "m", "nt", "n-p", "m-p", "nt-p", "p", "împf", "pf" ], "sc": "Cyrl" }, "ruo": { "g": [ "n", "m", "nt", "n-p", "m-p", "nt-p" ] }, "rup": { "g": [ "n", "m", "nt", "n-p", "m-p", "nt-p" ], "wiktprefix": "roa-rup" }, "ruq": { "g": [ "n", "m", "nt", "n-p", "m-p", "nt-p" ] }, "rw": { "haswikt": 1 }, "sa": { "g": [ "n", "m", "nt", "n-p", "m-p", "nt-p" ], "haswikt": 1, "sc": "Deva" }, "sah": { "sc": "Cyrl" }, "sc": { "haswikt": 1 }, "scn": { "g": [ "n", "m", "n-p", "m-p" ], "haswikt": 1 }, "sco": { "sc": "Latn" }, "sd": { "haswikt": 1, "sc": "Arab", "wsc": "sd-Arab" }, "sdh": { "sc": "Arab", "wiktprefix": "ku" }, "sg": { "haswikt": 1 }, "sh": { "alt": 1, "g": [ "n", "m", "nt", "n-p", "m-p", "nt-p", "p", "împf", "pf" ], "haswikt": 1, "sc": [ "Latn", "Cyrl" ] }, "si": { "haswikt": 1, "sc": "Sinh" }, "simple": { "haswikt": 1 }, "sk": { "g": [ "n", "m", "nt", "n-p", "m-p", "nt-p", "p", "împf", "pf" ], "haswikt": 1 }, "sl": { "alt": 1, "g": [ "n", "m", "nt", "n-p", "m-p", "nt-p", "p", "împf", "pf" ], "haswikt": 1 }, "sm": { "haswikt": 1 }, "sn": { "haswikt": 1 }, "so": { "haswikt": 1 }, "spx": { "sc": "Ital" }, "sq": { "g": [ "n", "m" ], "haswikt": 1 }, "ss": { "haswikt": 1 }, "st": { "haswikt": 1 }, "su": { "haswikt": 1 }, "sux": { "sc": "Xsux" }, "sv": { "g": [ "g", "nt", "g-p", "nt-p" ], "haswikt": 1 }, "sva": { "sc": "Geor" }, "sw": { "nclass": 1, "haswikt": 1 }, "syc": { "sc": "Syrc" }, "syr": { "sc": "Syrc" }, "szl": { "g": [ "n", "m", "nt", "n-p", "m-p", "nt-p", "p", "împf", "pf" ] }, "ta": { "haswikt": 1, "sc": "Taml" }, "tdd": { "sc": "Tale" }, "te": { "haswikt": 1, "sc": "Telu" }, "tg": { "g": [ "y", "p" ], "haswikt": 1, "sc": "Cyrl" }, "th": { "haswikt": 1, "sc": "Thai" }, "ti": { "haswikt": 1, "sc": "Ethi" }, "tig": { "sc": "Ethi" }, "tiw": { "sc": "Latn" }, "tk": { "g": [ "y", "p" ], "haswikt": 1 }, "tl": { "haswikt": 1, "sc": [ "Latn", "Tglg" ] }, "tmr": { "sc": "Hebr" }, "tn": { "haswikt": 1 }, "to": { "haswikt": 1 }, "tpi": { "haswikt": 1 }, "tr": { "g": [ "y", "p" ], "alt": 1, "haswikt": 1 }, "ts": { "haswikt": 1 }, "tt": { "g": [ "y", "p" ], "haswikt": 1 }, "tts": { "sc": "Thai" }, "tw": { "haswikt": 1 }, "udi": { "sc": [ "Cyrl", "Latn", "Armn", "Geor" ] }, "ug": { "g": [ "y", "p" ], "haswikt": 1, "sc": "Arab", "wsc": "ug-Arab" }, "uga": { "sc": "Ugar" }, "uk": { "g": [ "n", "m", "nt", "n-p", "m-p", "nt-p", "p", "împf", "pf" ], "haswikt": 1, "sc": "Cyrl" }, "ulk": { "sc": "Latn" }, "ur": { "g": [ "n", "m", "n-p", "m-p", "p" ], "haswikt": 1, "sc": "Arab", "wsc": "ur-Arab" }, "uz": { "g": [ "y", "p" ], "haswikt": 1 }, "vec": { "g": [ "n", "m", "n-p", "m-p" ], "haswikt": 1 }, "vi": { "haswikt": 1 }, "vls": { "g": [ "n", "m", "nt", "n-p", "m-p", "nt-p" ] }, "vo": { "haswikt": 1 }, "wa": { "haswikt": 1 }, "wbp": { "sc": "Latn" }, "wo": { "haswikt": 1 }, "wuu": { "sc": "Hani" }, "xae": { "sc": "Ital" }, "xcr": { "sc": "Cari" }, "xfa": { "sc": "Ital" }, "xh": { "alt": 1, "nclass": 1, "haswikt": 1 }, "xlc": { "sc": "Lyci" }, "xld": { "sc": "Lydi" }, "xlu": { "sc": "Xsux" }, "xmf": { "sc": "Geor" }, "xno": { "g": [ "n", "m", "n-p", "m-p" ] }, "xrr": { "sc": "Ital" }, "xst": { "sc": "Ethi" }, "xum": { "sc": "Ital" }, "xve": { "sc": "Ital" }, "xvo": { "sc": "Ital" }, "yi": { "g": [ "n", "m", "nt", "n-p", "m-p", "nt-p", "p" ], "haswikt": 1, "sc": "Hebr" }, "yo": { "haswikt": 1 }, "yua": { "g": [ "y", "p" ], "alt": 1 }, "yue": { "sc": "Hani" }, "za": { "haswikt": 1, "sc": "Latn" }, "zh-classical": { "sc": "Hani" }, "zh-min-nan": { "haswikt": 1 }, "zh-yue": { "sc": "Hani" }, "zu": { "alt": 1, "nclass": 1, "haswikt": 1 }, "zza": { "g": [ "n", "m", "mn", "n-p", "m-p", "p" ], "wiktprefix": "diq" } } } atp50w60myj97udv8t654il58tki05m 6265608 6265566 2026-07-19T16:00:03Z Wikihez 7344 6265608 json application/json { "langChoices": [ [ "ku", "kurmancî" ], [ "zza", "zazakî" ], [ "ckb", "soranî" ], [ "sdh", "kurdiya başûrî" ], [ "hac", "hewramî" ], [ "de", "almanî" ], [ "ar", "erebî" ], [ "fa", "farisî" ], [ "fr", "fransî" ], [ "fi", "fînî" ], [ "en", "îngilîzî" ], [ "ja", "japonî" ], [ "sv", "swêdî" ], [ "tr", "tirkî" ] ], "posChoices": [ [ "navdêr", "Navdêr (îsm)" ], [ "lêker", "Lêker (fiîl)" ], [ "rengdêr", "Rengdêr (sifet)" ], [ "hoker", "Hoker (zerf)" ], [ "serenav", "Serenav (îsmê xisûsî)" ], [ "artîkel", "Artîkel" ], [ "baneşan", "Baneşan (nîda)" ], [ "bazinedaçek", "Bazinedaçek" ], [ "cînav", "Cînav (zemîr)" ], [ "daçek", "Daçek (edat)" ], [ "girêdek", "Girêdek" ], [ "gotineke pêşiyan", "Gotineke pêşiyan" ], [ "hejmar", "Hejmar" ], [ "hevok", "Hevok (cimle)" ], [ "îfade", "Îfade" ], [ "kurtenav", "Kurtenav" ], [ "navgir", "Navgir" ], [ "paşdaçek", "Paşdaçek" ], [ "paşgir", "Paşgir" ], [ "pêşdaçek", "Pêşdaçek" ], [ "pêşgir", "Pêşgir" ], [ "pirtik", "Pirtik" ], [ "reh", "Reh" ], [ "sembol", "Sembol" ], [ "tîp", "Tîp (herf)" ] ], "posExamples": { "navdêr": "Kelîmeyên ji bo tiştan (sêv, heywan, qedeh) yan terman (dilşadî, bextiyarî hwd.) di rêzimanê de.", "lêker": "Kelîmeyên ji bo kirin an bûyînê wekî 'nivîsîn' yan 'xeber dan'.", "rengdêr": "Kelîmeyên ku wesfa navdêran nîşan didin wekî 'sêva sor' yan 'xwarina şîrîn'.", "hoker": "Kelîmeyên ku dem, cih yan awayê kirinê diyar dikin wekî 'bi vî awayî' yan 'demkî'.", "daçek": "Kelîmeyên ku cih, dem yan hereketê diyar dikin wekî 'di.. de' yan 'ji'.", "cînav": "Kelîmeyên ku li şûna navdêran tên bikaranîn daku navdêr neyên dubarekirin wekî 'ew' yan 'em'.", "baneşan": "Kelîmeyên ku hest, deng hwd. îfade dikin wekî 'noşî!' yan 'aferîn'.", "serenav": "Navdêrên ku şexsiyetên ferdî nîşan didin, wek navên kes, cih an organîzasyonan nimûne 'London' yan 'Diyarbekir'.", "gotineke pêşiyan": "Gotinên ku di nav xelkê de bi berbelavî tên bikaranîn bo nimûne 'Serê neêşe ne hewceyî destmalê ye'." }, "genderLabels": { "m": "mê", "n": "nêr", "nt": "nêtar", "mn": "mê û nêr", "mnmane": "mê yan nêr li gorî maneyê", "g": "giştî", "y": "yekjimar", "p": "pirjimar" }, "tplDefs": [ { "name": "awayê Jacobsonê", "langs": [ "zza" ] }, { "name": "rastnivîs", "langs": [ "ku" ], "noLang": true }, { "name": "ku-Latn", "langs": [ "ku" ], "noLang": true }, { "name": "sdh-Arab", "langs": [ "sdh" ], "noLang": true }, { "name": "hac-Arab", "langs": [ "hac" ], "noLang": true }, { "name": "ja-romanîzekirin", "langs": [ "ja" ], "noLang": true }, { "name": "ckb-Arab", "langs": [ "ckb" ], "noLang": true }, { "name": "awayekî din", "langs": null }, { "name": "guharto", "langs": null }, { "name": "hevmaneya", "langs": null }, { "name": "kevnbûyî", "langs": null }, { "name": "kêmpeyda", "langs": null }, { "name": "şaşnivîs", "langs": null } ], "jederDefs": { "jêder-kitêb": { "label": "Kitêb", "fields": [ { "key": "nivîskar", "label": "Nivîskar" }, { "key": "sernav", "label": "Sernav" }, { "key": "sernavê orjînal", "label": "Sernavê orjînal" }, { "key": "terciman", "label": "Terciman" }, { "key": "weşanxane", "label": "Weşanxane" }, { "key": "cih", "label": "Cih" }, { "key": "sal", "label": "Sal" }, { "key": "sala orjînal", "label": "Sala orjînal" }, { "key": "çap", "label": "Çap" }, { "key": "rûpel", "label": "Rûpel" }, { "key": "isbn", "label": "ISBN" }, { "key": "url", "label": "URL" } ] }, "jêder-kovar": { "label": "Kovar", "fields": [ { "key": "nivîskar", "label": "Nivîskar" }, { "key": "nivîskar2", "label": "Nivîskar 2" }, { "key": "sernav", "label": "Sernav" }, { "key": "sernavê orjînal", "label": "Sernavê orjînal" }, { "key": "kovar", "label": "Kovar" }, { "key": "terciman", "label": "Terciman" }, { "key": "weşanxane", "label": "Weşanxane" }, { "key": "cild", "label": "Cild" }, { "key": "hejmar", "label": "Hejmar" }, { "key": "sal", "label": "Sal" }, { "key": "rûpel", "label": "Rûpel" }, { "key": "url", "label": "URL" } ] }, "jêder-websîte": { "label": "Websîte", "fields": [ { "key": "nivîskar", "label": "Nivîskar" }, { "key": "sernav", "label": "Sernav" }, { "key": "terciman", "label": "Terciman" }, { "key": "websîte", "label": "Websîte" }, { "key": "url", "label": "URL" }, { "key": "arşîv", "label": "Arşîva URLê" }, { "key": "sal", "label": "Sal" }, { "key": "tarîx", "label": "Tarîx" } ] } }, "pronTpls": [ { "name": "ku-IPA", "desc": "IPAya otomatîk ji bo kurmancî (kontrol hewce ye)", "snippet": "* {{ku-IPA}}", "langs": [ "ku" ], "noLang": true }, { "name": "ku-kîte", "desc": "Şablona hecekirinê ji bo kurmancî", "snippet": "* {{ku-kîte}}", "langs": [ "ku" ], "noLang": true }, { "name": "zza-IPA", "desc": "IPAya otomatîk ji bo zazakî", "snippet": "* {{zza-IPA}}", "langs": [ "zza" ], "noLang": true }, { "name": "zza-kîte", "desc": "Şablona hecekirinê ji bo zazakî", "snippet": "* {{zza-kîte}}", "langs": [ "zza" ], "noLang": true }, { "name": "IPA", "desc": "Alfabeya fonetîk a navmiletî (IPA)", "snippet": "* {{IPA|CODE|/…/}}" }, { "name": "bilêv", "desc": "{{bilêv|herf|nerm, req|hejmar}}", "snippet": "* {{bilêv|herf|cure|hejmar}}" }, { "name": "kîte", "desc": "Şablona hecekirinê", "snippet": "* {{kîte|CODE|he|ce}}" }, { "name": "hevdeng", "desc": "Hevdeng — gotinên bi heman dengî", "snippet": "* {{hevdeng|CODE|…}}" } ], "etymTpls": [ { "name": "ji", "desc": "Ji zimanekî din hatiye — {{ji|en|ku|anatomy|tr=|t=}}", "snippet": "{{ji|SOURCELANG|CODE|…}}" }, { "name": "deyn", "desc": "Deynkirî — {{deyn|lang|kod|kelîme}}", "snippet": "{{deyn|SOURCELANG|CODE|…}}" }, { "name": "mîr", "desc": "Mîrasmayî — {{mîr|lang|kod|kelîme}}", "snippet": "{{mîr|SOURCELANG|CODE|…}}" }, { "name": "qertaf", "desc": "Ji bi pêşgir, paşgir û hevedudanî — {{qertaf|kod|pêşgir-|reh}}", "snippet": "{{qertaf|CODE|…|…}}" }, { "name": "q", "desc": "Referans bo rûpelekê — {{q|kod|kelîme}} navê zimanî dernakeve", "snippet": "{{q|CODE|…}}" }, { "name": "hv", "desc": "Hevreh — {{hv|lang|kelîme}} navê zimanî derdikeve", "snippet": "{{hv|SOURCELANG|…}}" }, { "name": "nh", "desc": "Nehevreh — {{nh|lang|kelîme}} navê zimanî derdikeve", "snippet": "{{nh|SOURCELANG|…}}" }, { "name": "cotreh", "desc": "Cotreh — teror {{cotreh|ku|tirs}}", "snippet": "{{cotreh|CODE|…}}" }, { "name": "yekser", "desc": "tercimeya yekser — {{yekser|lang|kod|kelîme}}", "snippet": "{{yekser|SOURCELANG|CODE|…}}" }, { "name": "wergirtin", "desc": "Wergirtina maneyê — {{wergirtin|lang|kod|kelîme}}", "snippet": "{{wergirtin|SOURCELANG|CODE|…}}" }, { "name": "paşvesazî", "desc": "Paşvesazî — greed {{paşvesazî|en|greedy}}", "snippet": "{{paşvesazî|CODE|…}}" }, { "name": "qusandin", "desc": "Qusandin — Miho {{qusandin|ku|Mihemmed}}", "snippet": "{{qusandin|CODE|…}}" }, { "name": "têkilkirin", "desc": "Têkilkirin — sormancî {{têkilkirin|ku|soranî|kurmancî}}", "snippet": "{{têkilkirin|CODE|…}}" }, { "name": "nyz", "desc": "Nayê zanîn — {{nyz|ku|hûr=1}}", "snippet": "{{nyz|CODE}}" }, { "name": "onom", "desc": "Onomatopoetîk — {{onom|ku|hûr=1}}", "snippet": "{{onom|CODE}}" }, { "name": "navmiletî", "desc": "Navmiletî — {{navmiletî|ku|hûr=1}}", "snippet": "{{navmiletî|CODE}}" }, { "name": "neo", "desc": "neolojîzm — {{neolojîzm|ku|hûr=1}}", "snippet": "{{neolojîzm|CODE}}" } ], "metadata": { "aa": { "haswikt": 1, "sc": [ "Latn", "Ethi" ] }, "ab": { "haswikt": 1, "sc": [ "Cyrl", "Latn", "Geor" ] }, "aer": { "sc": "Latn" }, "af": { "g": [ "y", "p" ], "haswikt": 1 }, "ak": { "haswikt": 1 }, "akk": { "g": [ "n", "m", "n-p", "m-p" ], "sc": "Xsux" }, "als": { "haswikt": 1 }, "am": { "g": [ "n", "m", "n-p", "m-p" ], "haswikt": 1, "sc": "Ethi" }, "an": { "g": [ "n", "m", "n-p", "m-p" ], "haswikt": 1 }, "ang": { "alt": 1, "g": [ "n", "m", "nt", "n-p", "m-p", "nt-p" ], "haswikt": 1 }, "ar": { "g": [ "n", "m", "n-p", "m-p", "p" ], "alt": 1, "haswikt": 1, "sc": "Arab" }, "arc": { "g": [ "n", "m", "n-p", "m-p" ], "sc": [ "Hebr", "Syrc" ] }, "are": {}, "arz": { "alt": 1, "g": [ "n", "m", "n-p", "m-p" ], "sc": "Arab" }, "as": { "haswikt": 1, "sc": "Beng" }, "ast": { "g": [ "n", "m", "n-p", "m-p" ], "haswikt": 1 }, "av": { "haswikt": 1 }, "ay": { "haswikt": 1 }, "az": { "g": [ "y", "p" ], "haswikt": 1, "sc": [ "Latn", "Cyrl", "Arab" ] }, "ba": { "g": [ "y", "p" ], "sc": "Cyrl" }, "bar": {}, "bat-smg": { "g": [ "n", "m", "n-p", "m-p" ] }, "bbl": { "sc": "Geor" }, "be": { "g": [ "n", "m", "nt", "n-p", "m-p", "nt-p", "p", "împf", "pf" ], "haswikt": 1, "sc": "Cyrl" }, "be-x-old": { "sc": "Cyrl" }, "bg": { "g": [ "n", "m", "nt", "n-p", "m-p", "nt-p", "p", "împf", "pf" ], "haswikt": 1, "sc": "Cyrl" }, "bh": { "haswikt": 1, "sc": "Deva" }, "bhb": { "sc": "Deva" }, "bi": { "haswikt": 1 }, "blt": { "sc": "Tavt" }, "bm": { "haswikt": 1, "sc": [ "Latn", "Nkoo", "Arab" ] }, "bn": { "haswikt": 1, "sc": "Beng" }, "bo": { "haswikt": 1, "sc": "Tibt" }, "br": { "g": [ "n", "m" ], "haswikt": 1 }, "ca": { "g": [ "n", "m", "n-p", "m-p" ], "haswikt": 1 }, "cdo": { "sc": "Hani" }, "ce": { "sc": "Cyrl" }, "ch": { "haswikt": 1 }, "chr": { "haswikt": 1, "sc": "Cher" }, "cjy": { "sc": "Hani" }, "ckb": { "haswikt": 1, "sc": "Arab", "wsc": "ku-Arab" }, "cmn": { "sc": "Hani", "wiktprefix": "zh" }, "co": { "haswikt": 1 }, "cpx": { "sc": "Hani" }, "cr": { "haswikt": 1, "sc": "Cans" }, "crh": {}, "cs": { "g": [ "n", "m", "nt", "n-p", "m-p", "nt-p", "p", "împf", "pf" ], "haswikt": 1 }, "csb": { "g": [ "n", "m", "nt", "n-p", "m-p", "nt-p", "p", "împf", "pf" ], "haswikt": 1 }, "cu": { "g": [ "n", "m", "nt", "n-p", "m-p", "nt-p", "p", "împf", "pf" ], "sc": [ "Cyrs", "Glag" ] }, "cv": { "sc": "Cyrl" }, "cy": { "g": [ "n", "m", "n-p", "m-p" ], "haswikt": 1 }, "czh": { "sc": "Hani" }, "czo": { "sc": "Hani" }, "da": { "g": [ "g", "nt", "g-p", "nt-p", "p" ], "haswikt": 1 }, "dax": {}, "de": { "g": [ "n", "m", "nt", "n-p", "m-p", "nt-p", "p" ], "haswikt": 1, "allowCaps": 1 }, "dhg": {}, "djb": {}, "dji": {}, "djr": {}, "dng": { "sc": "Cyrl" }, "dsb": { "g": [ "n", "m", "nt", "n-p", "m-p", "nt-p", "p", "împf", "pf" ] }, "dsx": {}, "duj": {}, "dv": { "g": [ "y", "p" ], "haswikt": 1, "sc": "Thaa" }, "dz": { "haswikt": 1, "sc": "Tibt" }, "el": { "g": [ "n", "m", "nt", "n-p", "m-p", "nt-p" ], "haswikt": 1 }, "en": { "g": [ "y", "p" ], "haswikt": 1 }, "eo": { "g": [ "y", "p" ], "haswikt": 1 }, "es": { "g": [ "n", "m", "n-p", "m-p", "p" ], "haswikt": 1 }, "et": { "g": [ "y", "p" ], "haswikt": 1 }, "ett": { "g": [ "y", "p" ], "sc": "Ital" }, "eu": { "g": [ "y", "p" ], "haswikt": 1 }, "fa": { "haswikt": 1, "g": [ "y", "p" ], "sc": "Arab", "wsc": "fa-Arab" }, "fa-cls": { "wiktprefix": "fa", "sc": "Arab", "wsc": "fa-Arab" }, "fa-ira": { "wiktprefix": "fa", "sc": "Arab", "wsc": "fa-Arab" }, "fi": { "g": [ "y", "p" ], "haswikt": 1 }, "fil": {}, "fj": { "haswikt": 1 }, "fo": { "g": [ "n", "m", "nt" ], "haswikt": 1 }, "fr": { "g": [ "n", "m", "mnmane", "n-p", "m-p", "p" ], "haswikt": 1 }, "frm": { "g": [ "n", "m", "n-p", "m-p" ] }, "fro": { "g": [ "n", "m", "n-p", "m-p" ] }, "fur": { "g": [ "n", "m", "n-p", "m-p" ] }, "fy": { "g": [ "g", "nt", "p" ], "haswikt": 1 }, "ga": { "g": [ "n", "m", "n-p", "m-p", "p" ], "haswikt": 1 }, "gan": { "sc": "Hani" }, "gd": { "g": [ "n", "m", "n-p", "m-p" ], "haswikt": 1 }, "gez": { "sc": "Ethi" }, "gl": { "g": [ "n", "m", "n-p", "m-p" ], "haswikt": 1 }, "gmw-ecg": { "g": [ "n", "m", "nt", "p" ], "allowCaps": 1 }, "gmy": { "sc": "Linb" }, "gn": { "haswikt": 1 }, "gnn": { "sc": "Latn" }, "got": { "g": [ "n", "m", "nt", "n-p", "m-p", "nt-p" ], "sc": "Goth" }, "grc": { "g": [ "n", "m", "nt", "n-p", "m-p", "nt-p", "p" ] }, "gsw": { "g": [ "n", "m", "nt", "p" ], "allowCaps": 1 }, "gu": { "g": [ "n", "m", "nt", "n-p", "m-p", "nt-p" ], "haswikt": 1, "sc": "Gujr" }, "guf": { "sc": "Latn" }, "gv": { "haswikt": 1 }, "ha": { "haswikt": 1 }, "hak": { "sc": "Hani" }, "har": { "sc": "Ethi" }, "he": { "alt": 1, "g": [ "n", "m", "n-p", "m-p", "p" ], "haswikt": 1, "sc": "Hebr" }, "hi": { "g": [ "n", "m", "n-p", "m-p", "p" ], "haswikt": 1, "sc": "Deva" }, "hif": { "sc": [ "Latn", "Deva" ] }, "hit": { "sc": "Xsux" }, "hrx": { "g": [ "n", "m", "nt", "n-p", "m-p", "nt-p" ], "haswikt": 1 }, "hsb": { "g": [ "n", "m", "nt", "n-p", "m-p", "nt-p", "p", "împf", "pf" ], "haswikt": 1 }, "hsn": { "sc": "Hani" }, "hu": { "g": [ "y", "p" ], "haswikt": 1 }, "hy": { "g": [ "y", "p" ], "haswikt": 1, "sc": "Armn" }, "ia": { "haswikt": 1 }, "id": { "haswikt": 1 }, "ie": { "haswikt": 1 }, "ik": { "haswikt": 1 }, "ike": { "sc": "Cans" }, "ikt": { "sc": "Cans" }, "io": { "haswikt": 1 }, "is": { "g": [ "n", "m", "nt", "n-p", "m-p", "nt-p" ], "haswikt": 1 }, "it": { "g": [ "n", "m", "n-p", "m-p", "p" ], "haswikt": 1 }, "iu": { "haswikt": 1, "sc": "Cans" }, "ja": { "haswikt": 1, "sc": "Jpan" }, "jay": { "sc": "Latn" }, "jbo": { "haswikt": 1 }, "jv": { "haswikt": 1 }, "ka": { "g": [ "y", "p" ], "haswikt": 1 }, "khb": { "sc": [ "Talu", "Lana", "Thai" ] }, "kjh": { "sc": "Cyrl" }, "kk": { "haswikt": 1, "g": [ "y", "p" ], "sc": "Cyrl" }, "kkh": { "sc": [ "Lana", "Thai" ] }, "kl": { "haswikt": 1 }, "km": { "haswikt": 1, "sc": "Khmr" }, "kn": { "haswikt": 1, "sc": "Knda" }, "ku": { "g": [ "n", "m", "mn", "n-p", "m-p", "p" ], "wiktprefix": "ku" }, "ko": { "haswikt": 1, "sc": "Kore" }, "krc": { "g": [ "y", "p" ], "sc": "Cyrl" }, "ks": { "haswikt": 1, "sc": [ "Arab", "Deva" ], "wsc": "ks-Arab" }, "kw": { "haswikt": 1 }, "ky": { "haswikt": 1, "g": [ "y", "p" ], "sc": "Cyrl" }, "la": { "alt": 1, "g": [ "n", "m", "nt", "n-p", "m-p", "nt-p" ], "haswikt": 1 }, "lb": { "g": [ "n", "m", "nt", "p" ], "haswikt": 1, "allowCaps": 1 }, "lez": { "sc": "Cyrl" }, "li": { "haswikt": 1 }, "lki": { "wiktprefix": "ku" }, "lld": { "g": [ "n", "m", "n-p", "m-p" ], "haswikt": 1 }, "lmo": { "g": [ "n", "m", "n-p", "m-p" ], "haswikt": 1 }, "ln": { "haswikt": 1 }, "lo": { "haswikt": 1, "sc": "Laoo" }, "lt": { "alt": 1, "g": [ "n", "m", "n-p", "m-p" ], "haswikt": 1 }, "lv": { "g": [ "n", "m", "n-p", "m-p" ], "haswikt": 1 }, "lzz": { "sc": "Geor" }, "mg": { "haswikt": 1 }, "mh": { "haswikt": 1 }, "mi": { "g": 0, "haswikt": 1 }, "mk": { "g": [ "n", "m", "nt", "n-p", "m-p", "nt-p", "p", "împf", "pf" ], "haswikt": 1, "sc": "Cyrl" }, "ml": { "haswikt": 1, "sc": "Mlym" }, "mn": { "g": [ "y", "p" ], "haswikt": 1, "sc": [ "Cyrl", "Mong" ] }, "mnp": { "sc": "Hani" }, "mo": { "haswikt": 1, "sc": "Cyrl" }, "mol": { "sc": "Cyrl" }, "mr": { "g": [ "n", "m", "nt" ], "haswikt": 1, "sc": "Deva" }, "ms": { "haswikt": 1, "sc": [ "Latn", "Arab" ] }, "mt": { "g": [ "n", "m", "n-p", "m-p", "p" ], "haswikt": 1 }, "mwp": { "sc": "Latn" }, "my": { "haswikt": 1, "sc": "Mymr" }, "na": { "haswikt": 1 }, "nah": { "haswikt": 1 }, "nan": { "wiktprefix": "zh-min-nan", "sc": "Hani" }, "nb": { "g": [ "n", "m", "nt", "n-p", "m-p", "nt-p", "p" ], "wiktprefix": "no" }, "nds-de": { "g": [ "n", "m", "nt", "n-p", "m-p", "nt-p" ], "wiktprefix": "nds" }, "nds-nl": { "g": [ "n", "m", "nt", "n-p", "m-p", "nt-p" ], "wiktprefix": "nds" }, "ne": { "haswikt": 1, "sc": "Deva" }, "nl": { "g": [ "n", "m", "nt", "n-p", "m-p", "nt-p", "p" ], "haswikt": 1 }, "nn": { "g": [ "n", "m", "nt", "n-p", "m-p", "nt-p", "p" ], "haswikt": 1 }, "no": { "g": [ "n", "m", "nt", "n-p", "m-p", "nt-p", "p" ], "haswikt": 1 }, "nod": { "sc": "Lana" }, "non": { "g": [ "n", "m", "nt", "n-p", "m-p", "nt-p" ] }, "oc": { "g": [ "n", "m", "n-p", "m-p" ], "haswikt": 1 }, "om": { "haswikt": 1 }, "or": { "haswikt": 1, "sc": "Orya" }, "orv": { "g": [ "n", "m", "nt", "n-p", "m-p", "nt-p", "p", "împf", "pf" ], "sc": "Cyrs" }, "osc": { "sc": "Ital" }, "ota": { "g": [ "y", "p" ], "sc": "Arab", "wsc": "ota-Arab" }, "pa": { "g": [ "n", "m", "n-p", "m-p", "p" ], "haswikt": 1, "sc": [ "Guru", "Arab" ] }, "pdt": { "g": [ "n", "m", "nt", "n-p", "m-p", "nt-p" ], "wiktprefix": "nds" }, "peo": { "sc": "Xpeo" }, "phn": { "sc": "Phnx" }, "pi": { "g": [ "n", "m", "nt", "n-p", "m-p", "nt-p" ], "haswikt": 1 }, "pjt": { "sc": "Latn" }, "pl": { "g": [ "n", "m", "nt", "n-p", "m-p", "nt-p", "p", "împf", "pf" ], "haswikt": 1 }, "pms": { "g": [ "n", "m", "n-p", "m-p" ], "haswikt": 1 }, "pox": { "g": [ "n", "m", "nt", "n-p", "m-p", "nt-p", "împf", "pf" ] }, "prs": { "wiktprefix": "fa", "sc": "Arab", "wsc": "fa-Arab" }, "ps": { "g": [ "n", "m", "n-p", "m-p", "p" ], "haswikt": 1, "sc": "Arab", "wsc": "ps-Arab" }, "pt": { "g": [ "n", "m", "n-p", "m-p", "p" ], "haswikt": 1 }, "qu": { "haswikt": 1 }, "rgn": { "g": [ "n", "m", "n-p", "m-p" ] }, "rit": { "sc": "Latn" }, "rm": { "g": [ "n", "m" ], "haswikt": 1 }, "rn": { "haswikt": 1 }, "ro": { "g": [ "n", "m", "nt", "n-p", "m-p", "nt-p", "p" ], "haswikt": 1, "sc": [ "Latn", "Cyrl" ] }, "roa-rup": { "haswikt": 1 }, "ru": { "alt": 1, "g": [ "n", "m", "nt", "n-p", "m-p", "nt-p", "p", "împf", "pf" ], "haswikt": 1, "sc": "Cyrl" }, "rue": { "g": [ "n", "m", "nt", "n-p", "m-p", "nt-p", "p", "împf", "pf" ], "sc": "Cyrl" }, "ruo": { "g": [ "n", "m", "nt", "n-p", "m-p", "nt-p" ] }, "rup": { "g": [ "n", "m", "nt", "n-p", "m-p", "nt-p" ], "wiktprefix": "roa-rup" }, "ruq": { "g": [ "n", "m", "nt", "n-p", "m-p", "nt-p" ] }, "rw": { "haswikt": 1 }, "sa": { "g": [ "n", "m", "nt", "n-p", "m-p", "nt-p" ], "haswikt": 1, "sc": "Deva" }, "sah": { "sc": "Cyrl" }, "sc": { "haswikt": 1 }, "scn": { "g": [ "n", "m", "n-p", "m-p" ], "haswikt": 1 }, "sco": { "sc": "Latn" }, "sd": { "haswikt": 1, "sc": "Arab", "wsc": "sd-Arab" }, "sdh": { "sc": "Arab", "wiktprefix": "ku" }, "sg": { "haswikt": 1 }, "sh": { "alt": 1, "g": [ "n", "m", "nt", "n-p", "m-p", "nt-p", "p", "împf", "pf" ], "haswikt": 1, "sc": [ "Latn", "Cyrl" ] }, "si": { "haswikt": 1, "sc": "Sinh" }, "simple": { "haswikt": 1 }, "sk": { "g": [ "n", "m", "nt", "n-p", "m-p", "nt-p", "p", "împf", "pf" ], "haswikt": 1 }, "sl": { "alt": 1, "g": [ "n", "m", "nt", "n-p", "m-p", "nt-p", "p", "împf", "pf" ], "haswikt": 1 }, "sm": { "haswikt": 1 }, "sn": { "haswikt": 1 }, "so": { "haswikt": 1 }, "spx": { "sc": "Ital" }, "sq": { "g": [ "n", "m" ], "haswikt": 1 }, "ss": { "haswikt": 1 }, "st": { "haswikt": 1 }, "su": { "haswikt": 1 }, "sux": { "sc": "Xsux" }, "sv": { "g": [ "g", "nt", "g-p", "nt-p" ], "haswikt": 1 }, "sva": { "sc": "Geor" }, "sw": { "nclass": 1, "haswikt": 1 }, "syc": { "sc": "Syrc" }, "syr": { "sc": "Syrc" }, "szl": { "g": [ "n", "m", "nt", "n-p", "m-p", "nt-p", "p", "împf", "pf" ] }, "ta": { "haswikt": 1, "sc": "Taml" }, "tdd": { "sc": "Tale" }, "te": { "haswikt": 1, "sc": "Telu" }, "tg": { "g": [ "y", "p" ], "haswikt": 1, "sc": "Cyrl" }, "th": { "haswikt": 1, "sc": "Thai" }, "ti": { "haswikt": 1, "sc": "Ethi" }, "tig": { "sc": "Ethi" }, "tiw": { "sc": "Latn" }, "tk": { "g": [ "y", "p" ], "haswikt": 1 }, "tl": { "haswikt": 1, "sc": [ "Latn", "Tglg" ] }, "tmr": { "sc": "Hebr" }, "tn": { "haswikt": 1 }, "to": { "haswikt": 1 }, "tpi": { "haswikt": 1 }, "tr": { "g": [ "y", "p" ], "alt": 1, "haswikt": 1 }, "ts": { "haswikt": 1 }, "tt": { "g": [ "y", "p" ], "haswikt": 1 }, "tts": { "sc": "Thai" }, "tw": { "haswikt": 1 }, "udi": { "sc": [ "Cyrl", "Latn", "Armn", "Geor" ] }, "ug": { "g": [ "y", "p" ], "haswikt": 1, "sc": "Arab", "wsc": "ug-Arab" }, "uga": { "sc": "Ugar" }, "uk": { "g": [ "n", "m", "nt", "n-p", "m-p", "nt-p", "p", "împf", "pf" ], "haswikt": 1, "sc": "Cyrl" }, "ulk": { "sc": "Latn" }, "ur": { "g": [ "n", "m", "n-p", "m-p", "p" ], "haswikt": 1, "sc": "Arab", "wsc": "ur-Arab" }, "uz": { "g": [ "y", "p" ], "haswikt": 1 }, "vec": { "g": [ "n", "m", "n-p", "m-p" ], "haswikt": 1 }, "vi": { "haswikt": 1 }, "vls": { "g": [ "n", "m", "nt", "n-p", "m-p", "nt-p" ] }, "vo": { "haswikt": 1 }, "wa": { "haswikt": 1 }, "wbp": { "sc": "Latn" }, "wo": { "haswikt": 1 }, "wuu": { "sc": "Hani" }, "xae": { "sc": "Ital" }, "xcr": { "sc": "Cari" }, "xfa": { "sc": "Ital" }, "xh": { "alt": 1, "nclass": 1, "haswikt": 1 }, "xlc": { "sc": "Lyci" }, "xld": { "sc": "Lydi" }, "xlu": { "sc": "Xsux" }, "xmf": { "sc": "Geor" }, "xno": { "g": [ "n", "m", "n-p", "m-p" ] }, "xrr": { "sc": "Ital" }, "xst": { "sc": "Ethi" }, "xum": { "sc": "Ital" }, "xve": { "sc": "Ital" }, "xvo": { "sc": "Ital" }, "yi": { "g": [ "n", "m", "nt", "n-p", "m-p", "nt-p", "p" ], "haswikt": 1, "sc": "Hebr" }, "yo": { "haswikt": 1 }, "yua": { "g": [ "y", "p" ], "alt": 1 }, "yue": { "sc": "Hani" }, "za": { "haswikt": 1, "sc": "Latn" }, "zh-classical": { "sc": "Hani" }, "zh-min-nan": { "haswikt": 1 }, "zh-yue": { "sc": "Hani" }, "zu": { "alt": 1, "nclass": 1, "haswikt": 1 }, "zza": { "g": [ "n", "m", "mn", "n-p", "m-p", "p" ], "wiktprefix": "diq" } } } o14ynzc69oj2xuiv87pucmwd146scjm 6265609 6265608 2026-07-19T16:01:43Z Wikihez 7344 6265609 json application/json { "langChoices": [ [ "ku", "kurmancî" ], [ "zza", "zazakî" ], [ "ckb", "soranî" ], [ "sdh", "kurdiya başûrî" ], [ "hac", "hewramî" ], [ "de", "almanî" ], [ "ar", "erebî" ], [ "fa", "farisî" ], [ "fr", "fransî" ], [ "fi", "fînî" ], [ "en", "îngilîzî" ], [ "ja", "japonî" ], [ "sv", "swêdî" ], [ "tr", "tirkî" ] ], "posChoices": [ [ "navdêr", "Navdêr (îsm)" ], [ "lêker", "Lêker (fiîl)" ], [ "rengdêr", "Rengdêr (sifet)" ], [ "hoker", "Hoker (zerf)" ], [ "serenav", "Serenav (îsmê xisûsî)" ], [ "artîkel", "Artîkel" ], [ "baneşan", "Baneşan (nîda)" ], [ "bazinedaçek", "Bazinedaçek" ], [ "cînav", "Cînav (zemîr)" ], [ "daçek", "Daçek (edat)" ], [ "girêdek", "Girêdek" ], [ "gotineke pêşiyan", "Gotineke pêşiyan" ], [ "hejmar", "Hejmar" ], [ "hevok", "Hevok (cimle)" ], [ "îfade", "Îfade" ], [ "kurtenav", "Kurtenav" ], [ "navgir", "Navgir" ], [ "paşdaçek", "Paşdaçek" ], [ "paşgir", "Paşgir" ], [ "pêşdaçek", "Pêşdaçek" ], [ "pêşgir", "Pêşgir" ], [ "pirtik", "Pirtik" ], [ "reh", "Reh" ], [ "sembol", "Sembol" ], [ "tîp", "Tîp (herf)" ] ], "posExamples": { "navdêr": "Kelîmeyên ji bo tiştan (sêv, heywan, qedeh) yan terman (dilşadî, bextiyarî hwd.) di rêzimanê de.", "lêker": "Kelîmeyên ji bo kirin an bûyînê wekî 'nivîsîn' yan 'xeber dan'.", "rengdêr": "Kelîmeyên ku wesfa navdêran nîşan didin wekî 'sêva sor' yan 'xwarina şîrîn'.", "hoker": "Kelîmeyên ku dem, cih yan awayê kirinê diyar dikin wekî 'bi vî awayî' yan 'demkî'.", "daçek": "Kelîmeyên ku cih, dem yan hereketê diyar dikin wekî 'di.. de' yan 'ji'.", "cînav": "Kelîmeyên ku li şûna navdêran tên bikaranîn daku navdêr neyên dubarekirin wekî 'ew' yan 'em'.", "baneşan": "Kelîmeyên ku hest, deng hwd. îfade dikin wekî 'noşî!' yan 'aferîn'.", "serenav": "Navdêrên ku şexsiyetên ferdî nîşan didin, wek navên kes, cih an organîzasyonan nimûne 'London' yan 'Diyarbekir'.", "gotineke pêşiyan": "Gotinên ku di nav xelkê de bi berbelavî tên bikaranîn bo nimûne 'Serê neêşe ne hewceyî destmalê ye'." }, "genderLabels": { "m": "mê", "n": "nêr", "nt": "nêtar", "mn": "mê û nêr", "mnmane": "mê yan nêr li gorî maneyê", "g": "giştî", "y": "yekjimar", "p": "pirjimar" }, "tplDefs": [ { "name": "awayê Jacobsonê", "langs": [ "zza" ] }, { "name": "rastnivîs", "langs": [ "ku" ], "noLang": true }, { "name": "ku-Latn", "langs": [ "ku" ], "noLang": true }, { "name": "sdh-Arab", "langs": [ "sdh" ], "noLang": true }, { "name": "hac-Arab", "langs": [ "hac" ], "noLang": true }, { "name": "ja-romanîzekirin", "langs": [ "ja" ], "noLang": true }, { "name": "ckb-Arab", "langs": [ "ckb" ], "noLang": true }, { "name": "awayekî din", "langs": null }, { "name": "guharto", "langs": null }, { "name": "hevmaneya", "langs": null }, { "name": "kevnbûyî", "langs": null }, { "name": "kêmpeyda", "langs": null }, { "name": "şaşnivîs", "langs": null } ], "jederDefs": { "jêder-kitêb": { "label": "Kitêb", "fields": [ { "key": "nivîskar", "label": "Nivîskar" }, { "key": "sernav", "label": "Sernav" }, { "key": "sernavê orjînal", "label": "Sernavê orjînal" }, { "key": "terciman", "label": "Terciman" }, { "key": "weşanxane", "label": "Weşanxane" }, { "key": "cih", "label": "Cih" }, { "key": "sal", "label": "Sal" }, { "key": "sala orjînal", "label": "Sala orjînal" }, { "key": "çap", "label": "Çap" }, { "key": "rûpel", "label": "Rûpel" }, { "key": "isbn", "label": "ISBN" }, { "key": "url", "label": "URL" } ] }, "jêder-kovar": { "label": "Kovar", "fields": [ { "key": "nivîskar", "label": "Nivîskar" }, { "key": "nivîskar2", "label": "Nivîskar 2" }, { "key": "sernav", "label": "Sernav" }, { "key": "sernavê orjînal", "label": "Sernavê orjînal" }, { "key": "kovar", "label": "Kovar" }, { "key": "terciman", "label": "Terciman" }, { "key": "weşanxane", "label": "Weşanxane" }, { "key": "cild", "label": "Cild" }, { "key": "hejmar", "label": "Hejmar" }, { "key": "sal", "label": "Sal" }, { "key": "rûpel", "label": "Rûpel" }, { "key": "url", "label": "URL" } ] }, "jêder-websîte": { "label": "Websîte", "fields": [ { "key": "nivîskar", "label": "Nivîskar" }, { "key": "sernav", "label": "Sernav" }, { "key": "terciman", "label": "Terciman" }, { "key": "websîte", "label": "Websîte" }, { "key": "url", "label": "URL" }, { "key": "arşîv", "label": "Arşîva URLê" }, { "key": "sal", "label": "Sal" }, { "key": "tarîx", "label": "Tarîx" } ] } }, "pronTpls": [ { "name": "ku-IPA", "desc": "IPAya otomatîk ji bo kurmancî (kontrol hewce ye)", "snippet": "* {{ku-IPA}}", "langs": [ "ku" ], "noLang": true }, { "name": "ku-kîte", "desc": "Hecekirina otomatîk ji bo kurmancî", "snippet": "* {{ku-kîte}}", "langs": [ "ku" ], "noLang": true }, { "name": "zza-IPA", "desc": "IPAya otomatîk ji bo zazakî", "snippet": "* {{zza-IPA}}", "langs": [ "zza" ], "noLang": true }, { "name": "zza-kîte", "desc": "Hecekirina otomatîk ji bo zazakî", "snippet": "* {{zza-kîte}}", "langs": [ "zza" ], "noLang": true }, { "name": "IPA", "desc": "Alfabeya fonetîk a navmiletî (IPA)", "snippet": "* {{IPA|CODE|/…/}}" }, { "name": "bilêv", "desc": "{{bilêv|herf|nerm, req|hejmar}}", "snippet": "* {{bilêv|herf|cure|hejmar}}" }, { "name": "kîte", "desc": "Şablona hecekirinê", "snippet": "* {{kîte|CODE|he|ce}}" }, { "name": "hevdeng", "desc": "Hevdeng — gotinên bi heman dengî", "snippet": "* {{hevdeng|CODE|…}}" } ], "etymTpls": [ { "name": "ji", "desc": "Ji zimanekî din hatiye — {{ji|en|ku|anatomy|tr=|t=}}", "snippet": "{{ji|SOURCELANG|CODE|…}}" }, { "name": "deyn", "desc": "Deynkirî — {{deyn|lang|kod|kelîme}}", "snippet": "{{deyn|SOURCELANG|CODE|…}}" }, { "name": "mîr", "desc": "Mîrasmayî — {{mîr|lang|kod|kelîme}}", "snippet": "{{mîr|SOURCELANG|CODE|…}}" }, { "name": "qertaf", "desc": "Ji bi pêşgir, paşgir û hevedudanî — {{qertaf|kod|pêşgir-|reh}}", "snippet": "{{qertaf|CODE|…|…}}" }, { "name": "q", "desc": "Referans bo rûpelekê — {{q|kod|kelîme}} navê zimanî dernakeve", "snippet": "{{q|CODE|…}}" }, { "name": "hv", "desc": "Hevreh — {{hv|lang|kelîme}} navê zimanî derdikeve", "snippet": "{{hv|SOURCELANG|…}}" }, { "name": "nh", "desc": "Nehevreh — {{nh|lang|kelîme}} navê zimanî derdikeve", "snippet": "{{nh|SOURCELANG|…}}" }, { "name": "cotreh", "desc": "Cotreh — teror {{cotreh|ku|tirs}}", "snippet": "{{cotreh|CODE|…}}" }, { "name": "yekser", "desc": "tercimeya yekser — {{yekser|lang|kod|kelîme}}", "snippet": "{{yekser|SOURCELANG|CODE|…}}" }, { "name": "wergirtin", "desc": "Wergirtina maneyê — {{wergirtin|lang|kod|kelîme}}", "snippet": "{{wergirtin|SOURCELANG|CODE|…}}" }, { "name": "paşvesazî", "desc": "Paşvesazî — greed {{paşvesazî|en|greedy}}", "snippet": "{{paşvesazî|CODE|…}}" }, { "name": "qusandin", "desc": "Qusandin — Miho {{qusandin|ku|Mihemmed}}", "snippet": "{{qusandin|CODE|…}}" }, { "name": "têkilkirin", "desc": "Têkilkirin — sormancî {{têkilkirin|ku|soranî|kurmancî}}", "snippet": "{{têkilkirin|CODE|…}}" }, { "name": "nyz", "desc": "Nayê zanîn — {{nyz|ku|hûr=1}}", "snippet": "{{nyz|CODE}}" }, { "name": "onom", "desc": "Onomatopoetîk — {{onom|ku|hûr=1}}", "snippet": "{{onom|CODE}}" }, { "name": "navmiletî", "desc": "Navmiletî — {{navmiletî|ku|hûr=1}}", "snippet": "{{navmiletî|CODE}}" }, { "name": "neo", "desc": "neolojîzm — {{neolojîzm|ku|hûr=1}}", "snippet": "{{neolojîzm|CODE}}" } ], "metadata": { "aa": { "haswikt": 1, "sc": [ "Latn", "Ethi" ] }, "ab": { "haswikt": 1, "sc": [ "Cyrl", "Latn", "Geor" ] }, "aer": { "sc": "Latn" }, "af": { "g": [ "y", "p" ], "haswikt": 1 }, "ak": { "haswikt": 1 }, "akk": { "g": [ "n", "m", "n-p", "m-p" ], "sc": "Xsux" }, "als": { "haswikt": 1 }, "am": { "g": [ "n", "m", "n-p", "m-p" ], "haswikt": 1, "sc": "Ethi" }, "an": { "g": [ "n", "m", "n-p", "m-p" ], "haswikt": 1 }, "ang": { "alt": 1, "g": [ "n", "m", "nt", "n-p", "m-p", "nt-p" ], "haswikt": 1 }, "ar": { "g": [ "n", "m", "n-p", "m-p", "p" ], "alt": 1, "haswikt": 1, "sc": "Arab" }, "arc": { "g": [ "n", "m", "n-p", "m-p" ], "sc": [ "Hebr", "Syrc" ] }, "are": {}, "arz": { "alt": 1, "g": [ "n", "m", "n-p", "m-p" ], "sc": "Arab" }, "as": { "haswikt": 1, "sc": "Beng" }, "ast": { "g": [ "n", "m", "n-p", "m-p" ], "haswikt": 1 }, "av": { "haswikt": 1 }, "ay": { "haswikt": 1 }, "az": { "g": [ "y", "p" ], "haswikt": 1, "sc": [ "Latn", "Cyrl", "Arab" ] }, "ba": { "g": [ "y", "p" ], "sc": "Cyrl" }, "bar": {}, "bat-smg": { "g": [ "n", "m", "n-p", "m-p" ] }, "bbl": { "sc": "Geor" }, "be": { "g": [ "n", "m", "nt", "n-p", "m-p", "nt-p", "p", "împf", "pf" ], "haswikt": 1, "sc": "Cyrl" }, "be-x-old": { "sc": "Cyrl" }, "bg": { "g": [ "n", "m", "nt", "n-p", "m-p", "nt-p", "p", "împf", "pf" ], "haswikt": 1, "sc": "Cyrl" }, "bh": { "haswikt": 1, "sc": "Deva" }, "bhb": { "sc": "Deva" }, "bi": { "haswikt": 1 }, "blt": { "sc": "Tavt" }, "bm": { "haswikt": 1, "sc": [ "Latn", "Nkoo", "Arab" ] }, "bn": { "haswikt": 1, "sc": "Beng" }, "bo": { "haswikt": 1, "sc": "Tibt" }, "br": { "g": [ "n", "m" ], "haswikt": 1 }, "ca": { "g": [ "n", "m", "n-p", "m-p" ], "haswikt": 1 }, "cdo": { "sc": "Hani" }, "ce": { "sc": "Cyrl" }, "ch": { "haswikt": 1 }, "chr": { "haswikt": 1, "sc": "Cher" }, "cjy": { "sc": "Hani" }, "ckb": { "haswikt": 1, "sc": "Arab", "wsc": "ku-Arab" }, "cmn": { "sc": "Hani", "wiktprefix": "zh" }, "co": { "haswikt": 1 }, "cpx": { "sc": "Hani" }, "cr": { "haswikt": 1, "sc": "Cans" }, "crh": {}, "cs": { "g": [ "n", "m", "nt", "n-p", "m-p", "nt-p", "p", "împf", "pf" ], "haswikt": 1 }, "csb": { "g": [ "n", "m", "nt", "n-p", "m-p", "nt-p", "p", "împf", "pf" ], "haswikt": 1 }, "cu": { "g": [ "n", "m", "nt", "n-p", "m-p", "nt-p", "p", "împf", "pf" ], "sc": [ "Cyrs", "Glag" ] }, "cv": { "sc": "Cyrl" }, "cy": { "g": [ "n", "m", "n-p", "m-p" ], "haswikt": 1 }, "czh": { "sc": "Hani" }, "czo": { "sc": "Hani" }, "da": { "g": [ "g", "nt", "g-p", "nt-p", "p" ], "haswikt": 1 }, "dax": {}, "de": { "g": [ "n", "m", "nt", "n-p", "m-p", "nt-p", "p" ], "haswikt": 1, "allowCaps": 1 }, "dhg": {}, "djb": {}, "dji": {}, "djr": {}, "dng": { "sc": "Cyrl" }, "dsb": { "g": [ "n", "m", "nt", "n-p", "m-p", "nt-p", "p", "împf", "pf" ] }, "dsx": {}, "duj": {}, "dv": { "g": [ "y", "p" ], "haswikt": 1, "sc": "Thaa" }, "dz": { "haswikt": 1, "sc": "Tibt" }, "el": { "g": [ "n", "m", "nt", "n-p", "m-p", "nt-p" ], "haswikt": 1 }, "en": { "g": [ "y", "p" ], "haswikt": 1 }, "eo": { "g": [ "y", "p" ], "haswikt": 1 }, "es": { "g": [ "n", "m", "n-p", "m-p", "p" ], "haswikt": 1 }, "et": { "g": [ "y", "p" ], "haswikt": 1 }, "ett": { "g": [ "y", "p" ], "sc": "Ital" }, "eu": { "g": [ "y", "p" ], "haswikt": 1 }, "fa": { "haswikt": 1, "g": [ "y", "p" ], "sc": "Arab", "wsc": "fa-Arab" }, "fa-cls": { "wiktprefix": "fa", "sc": "Arab", "wsc": "fa-Arab" }, "fa-ira": { "wiktprefix": "fa", "sc": "Arab", "wsc": "fa-Arab" }, "fi": { "g": [ "y", "p" ], "haswikt": 1 }, "fil": {}, "fj": { "haswikt": 1 }, "fo": { "g": [ "n", "m", "nt" ], "haswikt": 1 }, "fr": { "g": [ "n", "m", "mnmane", "n-p", "m-p", "p" ], "haswikt": 1 }, "frm": { "g": [ "n", "m", "n-p", "m-p" ] }, "fro": { "g": [ "n", "m", "n-p", "m-p" ] }, "fur": { "g": [ "n", "m", "n-p", "m-p" ] }, "fy": { "g": [ "g", "nt", "p" ], "haswikt": 1 }, "ga": { "g": [ "n", "m", "n-p", "m-p", "p" ], "haswikt": 1 }, "gan": { "sc": "Hani" }, "gd": { "g": [ "n", "m", "n-p", "m-p" ], "haswikt": 1 }, "gez": { "sc": "Ethi" }, "gl": { "g": [ "n", "m", "n-p", "m-p" ], "haswikt": 1 }, "gmw-ecg": { "g": [ "n", "m", "nt", "p" ], "allowCaps": 1 }, "gmy": { "sc": "Linb" }, "gn": { "haswikt": 1 }, "gnn": { "sc": "Latn" }, "got": { "g": [ "n", "m", "nt", "n-p", "m-p", "nt-p" ], "sc": "Goth" }, "grc": { "g": [ "n", "m", "nt", "n-p", "m-p", "nt-p", "p" ] }, "gsw": { "g": [ "n", "m", "nt", "p" ], "allowCaps": 1 }, "gu": { "g": [ "n", "m", "nt", "n-p", "m-p", "nt-p" ], "haswikt": 1, "sc": "Gujr" }, "guf": { "sc": "Latn" }, "gv": { "haswikt": 1 }, "ha": { "haswikt": 1 }, "hak": { "sc": "Hani" }, "har": { "sc": "Ethi" }, "he": { "alt": 1, "g": [ "n", "m", "n-p", "m-p", "p" ], "haswikt": 1, "sc": "Hebr" }, "hi": { "g": [ "n", "m", "n-p", "m-p", "p" ], "haswikt": 1, "sc": "Deva" }, "hif": { "sc": [ "Latn", "Deva" ] }, "hit": { "sc": "Xsux" }, "hrx": { "g": [ "n", "m", "nt", "n-p", "m-p", "nt-p" ], "haswikt": 1 }, "hsb": { "g": [ "n", "m", "nt", "n-p", "m-p", "nt-p", "p", "împf", "pf" ], "haswikt": 1 }, "hsn": { "sc": "Hani" }, "hu": { "g": [ "y", "p" ], "haswikt": 1 }, "hy": { "g": [ "y", "p" ], "haswikt": 1, "sc": "Armn" }, "ia": { "haswikt": 1 }, "id": { "haswikt": 1 }, "ie": { "haswikt": 1 }, "ik": { "haswikt": 1 }, "ike": { "sc": "Cans" }, "ikt": { "sc": "Cans" }, "io": { "haswikt": 1 }, "is": { "g": [ "n", "m", "nt", "n-p", "m-p", "nt-p" ], "haswikt": 1 }, "it": { "g": [ "n", "m", "n-p", "m-p", "p" ], "haswikt": 1 }, "iu": { "haswikt": 1, "sc": "Cans" }, "ja": { "haswikt": 1, "sc": "Jpan" }, "jay": { "sc": "Latn" }, "jbo": { "haswikt": 1 }, "jv": { "haswikt": 1 }, "ka": { "g": [ "y", "p" ], "haswikt": 1 }, "khb": { "sc": [ "Talu", "Lana", "Thai" ] }, "kjh": { "sc": "Cyrl" }, "kk": { "haswikt": 1, "g": [ "y", "p" ], "sc": "Cyrl" }, "kkh": { "sc": [ "Lana", "Thai" ] }, "kl": { "haswikt": 1 }, "km": { "haswikt": 1, "sc": "Khmr" }, "kn": { "haswikt": 1, "sc": "Knda" }, "ku": { "g": [ "n", "m", "mn", "n-p", "m-p", "p" ], "wiktprefix": "ku" }, "ko": { "haswikt": 1, "sc": "Kore" }, "krc": { "g": [ "y", "p" ], "sc": "Cyrl" }, "ks": { "haswikt": 1, "sc": [ "Arab", "Deva" ], "wsc": "ks-Arab" }, "kw": { "haswikt": 1 }, "ky": { "haswikt": 1, "g": [ "y", "p" ], "sc": "Cyrl" }, "la": { "alt": 1, "g": [ "n", "m", "nt", "n-p", "m-p", "nt-p" ], "haswikt": 1 }, "lb": { "g": [ "n", "m", "nt", "p" ], "haswikt": 1, "allowCaps": 1 }, "lez": { "sc": "Cyrl" }, "li": { "haswikt": 1 }, "lki": { "wiktprefix": "ku" }, "lld": { "g": [ "n", "m", "n-p", "m-p" ], "haswikt": 1 }, "lmo": { "g": [ "n", "m", "n-p", "m-p" ], "haswikt": 1 }, "ln": { "haswikt": 1 }, "lo": { "haswikt": 1, "sc": "Laoo" }, "lt": { "alt": 1, "g": [ "n", "m", "n-p", "m-p" ], "haswikt": 1 }, "lv": { "g": [ "n", "m", "n-p", "m-p" ], "haswikt": 1 }, "lzz": { "sc": "Geor" }, "mg": { "haswikt": 1 }, "mh": { "haswikt": 1 }, "mi": { "g": 0, "haswikt": 1 }, "mk": { "g": [ "n", "m", "nt", "n-p", "m-p", "nt-p", "p", "împf", "pf" ], "haswikt": 1, "sc": "Cyrl" }, "ml": { "haswikt": 1, "sc": "Mlym" }, "mn": { "g": [ "y", "p" ], "haswikt": 1, "sc": [ "Cyrl", "Mong" ] }, "mnp": { "sc": "Hani" }, "mo": { "haswikt": 1, "sc": "Cyrl" }, "mol": { "sc": "Cyrl" }, "mr": { "g": [ "n", "m", "nt" ], "haswikt": 1, "sc": "Deva" }, "ms": { "haswikt": 1, "sc": [ "Latn", "Arab" ] }, "mt": { "g": [ "n", "m", "n-p", "m-p", "p" ], "haswikt": 1 }, "mwp": { "sc": "Latn" }, "my": { "haswikt": 1, "sc": "Mymr" }, "na": { "haswikt": 1 }, "nah": { "haswikt": 1 }, "nan": { "wiktprefix": "zh-min-nan", "sc": "Hani" }, "nb": { "g": [ "n", "m", "nt", "n-p", "m-p", "nt-p", "p" ], "wiktprefix": "no" }, "nds-de": { "g": [ "n", "m", "nt", "n-p", "m-p", "nt-p" ], "wiktprefix": "nds" }, "nds-nl": { "g": [ "n", "m", "nt", "n-p", "m-p", "nt-p" ], "wiktprefix": "nds" }, "ne": { "haswikt": 1, "sc": "Deva" }, "nl": { "g": [ "n", "m", "nt", "n-p", "m-p", "nt-p", "p" ], "haswikt": 1 }, "nn": { "g": [ "n", "m", "nt", "n-p", "m-p", "nt-p", "p" ], "haswikt": 1 }, "no": { "g": [ "n", "m", "nt", "n-p", "m-p", "nt-p", "p" ], "haswikt": 1 }, "nod": { "sc": "Lana" }, "non": { "g": [ "n", "m", "nt", "n-p", "m-p", "nt-p" ] }, "oc": { "g": [ "n", "m", "n-p", "m-p" ], "haswikt": 1 }, "om": { "haswikt": 1 }, "or": { "haswikt": 1, "sc": "Orya" }, "orv": { "g": [ "n", "m", "nt", "n-p", "m-p", "nt-p", "p", "împf", "pf" ], "sc": "Cyrs" }, "osc": { "sc": "Ital" }, "ota": { "g": [ "y", "p" ], "sc": "Arab", "wsc": "ota-Arab" }, "pa": { "g": [ "n", "m", "n-p", "m-p", "p" ], "haswikt": 1, "sc": [ "Guru", "Arab" ] }, "pdt": { "g": [ "n", "m", "nt", "n-p", "m-p", "nt-p" ], "wiktprefix": "nds" }, "peo": { "sc": "Xpeo" }, "phn": { "sc": "Phnx" }, "pi": { "g": [ "n", "m", "nt", "n-p", "m-p", "nt-p" ], "haswikt": 1 }, "pjt": { "sc": "Latn" }, "pl": { "g": [ "n", "m", "nt", "n-p", "m-p", "nt-p", "p", "împf", "pf" ], "haswikt": 1 }, "pms": { "g": [ "n", "m", "n-p", "m-p" ], "haswikt": 1 }, "pox": { "g": [ "n", "m", "nt", "n-p", "m-p", "nt-p", "împf", "pf" ] }, "prs": { "wiktprefix": "fa", "sc": "Arab", "wsc": "fa-Arab" }, "ps": { "g": [ "n", "m", "n-p", "m-p", "p" ], "haswikt": 1, "sc": "Arab", "wsc": "ps-Arab" }, "pt": { "g": [ "n", "m", "n-p", "m-p", "p" ], "haswikt": 1 }, "qu": { "haswikt": 1 }, "rgn": { "g": [ "n", "m", "n-p", "m-p" ] }, "rit": { "sc": "Latn" }, "rm": { "g": [ "n", "m" ], "haswikt": 1 }, "rn": { "haswikt": 1 }, "ro": { "g": [ "n", "m", "nt", "n-p", "m-p", "nt-p", "p" ], "haswikt": 1, "sc": [ "Latn", "Cyrl" ] }, "roa-rup": { "haswikt": 1 }, "ru": { "alt": 1, "g": [ "n", "m", "nt", "n-p", "m-p", "nt-p", "p", "împf", "pf" ], "haswikt": 1, "sc": "Cyrl" }, "rue": { "g": [ "n", "m", "nt", "n-p", "m-p", "nt-p", "p", "împf", "pf" ], "sc": "Cyrl" }, "ruo": { "g": [ "n", "m", "nt", "n-p", "m-p", "nt-p" ] }, "rup": { "g": [ "n", "m", "nt", "n-p", "m-p", "nt-p" ], "wiktprefix": "roa-rup" }, "ruq": { "g": [ "n", "m", "nt", "n-p", "m-p", "nt-p" ] }, "rw": { "haswikt": 1 }, "sa": { "g": [ "n", "m", "nt", "n-p", "m-p", "nt-p" ], "haswikt": 1, "sc": "Deva" }, "sah": { "sc": "Cyrl" }, "sc": { "haswikt": 1 }, "scn": { "g": [ "n", "m", "n-p", "m-p" ], "haswikt": 1 }, "sco": { "sc": "Latn" }, "sd": { "haswikt": 1, "sc": "Arab", "wsc": "sd-Arab" }, "sdh": { "sc": "Arab", "wiktprefix": "ku" }, "sg": { "haswikt": 1 }, "sh": { "alt": 1, "g": [ "n", "m", "nt", "n-p", "m-p", "nt-p", "p", "împf", "pf" ], "haswikt": 1, "sc": [ "Latn", "Cyrl" ] }, "si": { "haswikt": 1, "sc": "Sinh" }, "simple": { "haswikt": 1 }, "sk": { "g": [ "n", "m", "nt", "n-p", "m-p", "nt-p", "p", "împf", "pf" ], "haswikt": 1 }, "sl": { "alt": 1, "g": [ "n", "m", "nt", "n-p", "m-p", "nt-p", "p", "împf", "pf" ], "haswikt": 1 }, "sm": { "haswikt": 1 }, "sn": { "haswikt": 1 }, "so": { "haswikt": 1 }, "spx": { "sc": "Ital" }, "sq": { "g": [ "n", "m" ], "haswikt": 1 }, "ss": { "haswikt": 1 }, "st": { "haswikt": 1 }, "su": { "haswikt": 1 }, "sux": { "sc": "Xsux" }, "sv": { "g": [ "g", "nt", "g-p", "nt-p" ], "haswikt": 1 }, "sva": { "sc": "Geor" }, "sw": { "nclass": 1, "haswikt": 1 }, "syc": { "sc": "Syrc" }, "syr": { "sc": "Syrc" }, "szl": { "g": [ "n", "m", "nt", "n-p", "m-p", "nt-p", "p", "împf", "pf" ] }, "ta": { "haswikt": 1, "sc": "Taml" }, "tdd": { "sc": "Tale" }, "te": { "haswikt": 1, "sc": "Telu" }, "tg": { "g": [ "y", "p" ], "haswikt": 1, "sc": "Cyrl" }, "th": { "haswikt": 1, "sc": "Thai" }, "ti": { "haswikt": 1, "sc": "Ethi" }, "tig": { "sc": "Ethi" }, "tiw": { "sc": "Latn" }, "tk": { "g": [ "y", "p" ], "haswikt": 1 }, "tl": { "haswikt": 1, "sc": [ "Latn", "Tglg" ] }, "tmr": { "sc": "Hebr" }, "tn": { "haswikt": 1 }, "to": { "haswikt": 1 }, "tpi": { "haswikt": 1 }, "tr": { "g": [ "y", "p" ], "alt": 1, "haswikt": 1 }, "ts": { "haswikt": 1 }, "tt": { "g": [ "y", "p" ], "haswikt": 1 }, "tts": { "sc": "Thai" }, "tw": { "haswikt": 1 }, "udi": { "sc": [ "Cyrl", "Latn", "Armn", "Geor" ] }, "ug": { "g": [ "y", "p" ], "haswikt": 1, "sc": "Arab", "wsc": "ug-Arab" }, "uga": { "sc": "Ugar" }, "uk": { "g": [ "n", "m", "nt", "n-p", "m-p", "nt-p", "p", "împf", "pf" ], "haswikt": 1, "sc": "Cyrl" }, "ulk": { "sc": "Latn" }, "ur": { "g": [ "n", "m", "n-p", "m-p", "p" ], "haswikt": 1, "sc": "Arab", "wsc": "ur-Arab" }, "uz": { "g": [ "y", "p" ], "haswikt": 1 }, "vec": { "g": [ "n", "m", "n-p", "m-p" ], "haswikt": 1 }, "vi": { "haswikt": 1 }, "vls": { "g": [ "n", "m", "nt", "n-p", "m-p", "nt-p" ] }, "vo": { "haswikt": 1 }, "wa": { "haswikt": 1 }, "wbp": { "sc": "Latn" }, "wo": { "haswikt": 1 }, "wuu": { "sc": "Hani" }, "xae": { "sc": "Ital" }, "xcr": { "sc": "Cari" }, "xfa": { "sc": "Ital" }, "xh": { "alt": 1, "nclass": 1, "haswikt": 1 }, "xlc": { "sc": "Lyci" }, "xld": { "sc": "Lydi" }, "xlu": { "sc": "Xsux" }, "xmf": { "sc": "Geor" }, "xno": { "g": [ "n", "m", "n-p", "m-p" ] }, "xrr": { "sc": "Ital" }, "xst": { "sc": "Ethi" }, "xum": { "sc": "Ital" }, "xve": { "sc": "Ital" }, "xvo": { "sc": "Ital" }, "yi": { "g": [ "n", "m", "nt", "n-p", "m-p", "nt-p", "p" ], "haswikt": 1, "sc": "Hebr" }, "yo": { "haswikt": 1 }, "yua": { "g": [ "y", "p" ], "alt": 1 }, "yue": { "sc": "Hani" }, "za": { "haswikt": 1, "sc": "Latn" }, "zh-classical": { "sc": "Hani" }, "zh-min-nan": { "haswikt": 1 }, "zh-yue": { "sc": "Hani" }, "zu": { "alt": 1, "nclass": 1, "haswikt": 1 }, "zza": { "g": [ "n", "m", "mn", "n-p", "m-p", "p" ], "wiktprefix": "diq" } } } fxqn4ajv0zmtnbysmnuthf3fitw0t18 Wîkîferheng:Xebat 4 1357857 6265574 6265493 2026-07-19T14:15:29Z Wikihez 7344 /* MediaWiki:Gadget-start.js */ Bersiv 6265574 wikitext text/x-wiki {{/ser}} = Karên ferhengî = == Mane == * [[:Kategorî:Madeyên bê beşa mane]] ** [[:Kategorî:Madeyên bê beşa mane bi kurmancî]] Li ser van rûpelan ev made hene ku maneyan wan nehatine nivîsin û divê werin nivîsin. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Etîmolojî == *[[:Kategorî:Daxwazên etîmolojiyê]] **[[:Kategorî:Daxwazên etîmolojiyê bi kurmancî]] Li ser van rûpelan ev made hene ku etîmolojiya wan hîn nehatine nivîsin. Ji bo alîkariyê binêre [[WF:Etîmolojî]] —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Cureyê rêzimanî == * [[:Kategorî:Gotarên bê kategoriya rêzimanî]] * [[:Kategorî:Gotarên bê kategoriya rêzimanî bi kurmancî]] Li ser van rûpelan ev made hene ku cureyên wan yên rêzimanî hîn nehatine nivîsin. Ji bo alîkariyê binêre [[Alîkarî:Cureyên peyvan]] —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Kontrol == * [[:Kategorî:Kontrol]] ** [[:Kategorî:Kontrola maneyê]] Ev madde bi botê hatine çêkirin, yek bi yek divê werin kontrolkirin. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) = Şablon = == IPA == * {{ş|IPA}} divê [[Modul:IPA]] bi kar bîne. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Deng == Kurdîkirina belgekirina {{ş|deng}} lazim e.--[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 00:06, 19 tîrmeh 2026 (UTC) = Modul = == Modul:form of/templates == * [[Modul:form of/templates]]: Divê ev modul were rojanekirin û xeletiyên berê wekî ([[hevalê]]) werin rastkirin. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Modul:columns == * [[Modul:columns]] were rojanekirin û {{ş|kol3}} bila lînka ''nîşan bide'' deyne beriya sernavê, kolê di qutiya rengî de bila nebe. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Modul:etymon == * [[Modul:etymon kevn]]: Rojanekirin hewce ye. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) = Javascript = == [[Mediawiki:Gadget-citoid-helper.js]] == Ji bo bi citoidê kopîkirina malûmatên çavkaniyan amûreke wisa lazim e. Xisûsen ji ber ku bi çend amûrên din dikare were bikaranîn. * [[Bikarhêner:Wikihez/skrîpt/js/Gadget-citoid-helper.js]] --> [[Mediawiki:Gadget-citoid-helper.js]] Feqat çend problem hene, şablonên me de kêmasiya parametreyan gelek in û xerîteyên citoidê hîn nehatine çêkirin. Wana sererast bikin dûre vê amûrê çêkin, piştre [[MediaWiki:Gadget-start.js|start.js]] û [[MediaWiki:Gadget-wikt.add-examples.js|add examples.js]] were rojanekirin. - --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 00:04, 19 tîrmeh 2026 (UTC) == [[MediaWiki:Gadget-aWa.js]] == Divê were rojanekirin ji bo ku di mobîlê de jî bixebite.[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 19:59, 17 tîrmeh 2026 (UTC) : Ez dibêjim çêbû lê bila hinekî din test bikim dûre em bar bikin: * [[Bikarhêner:Wikihez/Gadget-aWa.css]] --> [[MediaWiki:Gadget-aWa.css]] * [[Bikarhêner:Wikihez/Gadget-aWa.js]] --> [[MediaWiki:Gadget-aWa.js]] --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 22:04, 17 tîrmeh 2026 (UTC) :Min formata [[WF:Xebat]] wisa kir ku li [[WF:Xebat/arşîv 1]] arşîv bike lê niha dibêjim bila li gotûbêja sayfeyên xwe were zêde kirin wê baştir be. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 00:11, 19 tîrmeh 2026 (UTC) ::Lînkek li gotûbêja sayfeya eleqedar were dayîn bes e, wekî din li arşîv 1 were qeydkirin qet nebe dîtina wan hêsantir be. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 00:27, 19 tîrmeh 2026 (UTC) == [[MediaWiki:Gadget-start.js]] == Rojanekirin hewce ye. Min gelek tişt lê zêde kir lê ez niha test dikime. Piştre em bar bikin: * [[Bikarhêner:Wikihez/Gadget-start.js]] --> [[MediaWiki:Gadget-start.js]] * [[Bikarhêner:Wikihez/Gadget-start.css]] --> [[MediaWiki:Gadget-start.css]] --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 22:08, 17 tîrmeh 2026 (UTC) :Min [[MediaWiki:Gadget-start.js/data.json|data.json]] çêkir ji bo ku bi hêsanî malûmatên heyî werin guhartin bêyî guhartina Javascriptê. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 19:49, 18 tîrmeh 2026 (UTC) :Xeletiyên ku ji bîr nekim rast bikim: :* Wextê min çavkanî "kitêb" hilbijart û bi destî tije kir xeletiyeke [https://ku.wiktionary.org/w/index.php?title=xezete&diff=prev&oldid=6265392 wisa] derket her kelîme hate lînkkirin. :* <code>html("⠿")</code> ev ne lazim e. :* textarea ji bo çavkaniyên jêgirtinan xaseten yên sernav hîn jî ne draggable e. :* pêşdîtina zindî checkbox wextê tê rakirin, pêşdîtin winda nabe. :* Butona mobîlê ya vekirina formê di moda tarî de belî nabe, tenê wekî qutiyeke tarî xuya dibe. :* Metna hişyarkirinê di guhartina rûpelên heyî de lazim e baştir bikim. :[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 23:51, 18 tîrmeh 2026 (UTC) ::Ev problem çêbûn, ez ê binêrim ka çi problemên din hene. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 14:15, 19 tîrmeh 2026 (UTC) == [[Mediawiki:Gadget-QQ.js]] == Ev amûr di şikle Minerva de. Her daîm vê xeletiyê dide: <syntaxhighlight lang="js"> TypeError: Cannot read properties of null (reading 'addEventListener') at css () at runScript () at Array.<anonymous> () at flushCssBuffer () </syntaxhighlight> [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 19:29, 18 tîrmeh 2026 (UTC) :* [[Bikarhêner:Wikihez/skrîpt/js/Gadget-QQ.js]] --> [[Mediawiki:Gadget-QQ.js]] :* [[Bikarhêner:Wikihez/Gadget-QQ.css]] --> [[Mediawiki:Gadget-QQ.css]] :Ez dibêjim çêbû lê ka çend roj biceribînim. Tiştên ku hatin sererastkirin: :# Google Books API Key dikarî zêde bikî, dixe cookies û di gerokê de dimîne. Berê bê API Key dixebitiya lê êdî mecbûr e ku API Key-a te hebe, bidestxistina wê ne zêde zor e lê dîsa jî tevlihev e. :# Êdî di mobîlê de dixebite, heta di mobîlê de xweştir xuya dike. :# Moda tarî :# OOUI dewsa jquery.ui :# Li qutiyê çi dixwazî zêde bikî, dikare li gorî îsm, sifet, fiîl bitewîne. Lê ji bo fiîl tenê dikare çend heb inflection bîne. :# Butona paqij bike lê zêde kir. :# Çend paqijiyên jêgirtinên Google Kitêbê niha hene. :[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 23:38, 18 tîrmeh 2026 (UTC) == [[MediaWiki:Gadget-wikt.add-examples.js]] == Min ev amûr hinek rojane kir feqat çend problem hene berî ku bar bikin. Tiştên ku min guhart: # Êdî li sayfeyên bi {{ş|maneid}} jî dixebite, # Cihê di wîkîtekstê de yê ku jêgirtin were îlawekirin baştir bû, # [[Mediawiki:Gadget-citoid-helper.js|citoid helper]] zêde kir ji bo ku bi hêsanî çavkanî bi riya doi, isbn an urlyê werin tijîkirin. * [[Bikarhêner:Wikihez/Gadget-wikt.add-examples.css]] --> [[MediaWiki:Gadget-wikt.add-examples.css]] * [[Bikarhêner:Wikihez/Gadget-wikt.add-examples.js]] --> [[MediaWiki:Gadget-wikt.add-examples.js]] - --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 00:50, 19 tîrmeh 2026 (UTC) == Gadget-translation editor == * [[MediaWiki:Gadget-translation editor.js]]: divê formata en.wîktê were bikaranîn ji ber ku me gelek tercime ji en.wîktê kopî kir û ev js hîn nikare formata wekî li jêr bi kar bîne. <syntaxhighlight lang="wikitext"> * {{Z|sh}}: *: Kirîlî: *: Latînî </syntaxhighlight> —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Gadget-linkify == * [[Mediawiki:Gadget-linkify.js]] ''rûpeleke'' wekî<syntaxhighlight lang="wikitext">[[rûpeleke]]</syntaxhighlight> lînk dike, bi regexê belkî dikare wisa bike <syntaxhighlight lang="wikitext">[[rûpel]]eke</syntaxhighlight> —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Gadget-herf guhartin == * Amûreke din wekî [[Mediawiki:Gadget-linkify.js|linkify]] lazim e ku herfên mezin biçûk bike ji bo kurmancî.—[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) = Moda tarî = == MediaWiki:Newarticletext == * [[MediaWiki:Newarticletext]]: Divê rengên wê were rastkirin.—[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Modul:dara kategoriyan == * [[Modul:dara kategoriyan]] link_box —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == mane? == * {{ş|mane?}} —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == bêçavkanî == * {{ş|bêçavkanî}} —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == de-tew-nerm-ern == * {{ş|de-tew-nerm-ern}} —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) = Bot = Karên ku bi botê werin çêkirin ji kerema xwe li vir binivîsin. == Kategorî:Biwêj == [[:Kategorî:Biwêj]] divê were paqijkirin, lîsteya madeyên {{ş|biwêj}} çêke, yên ku tê de bûn, kirin, man hene filtre bike yên din bi destî tê çêkirin.—[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Jêgirtin == Xistina jêgirtinên beşa [https://ku.wiktionary.org/w/index.php?search=insource%3A%2F%3D+*Ji+%5BWw%5D%C3%AAjey%C3%AA+*%3D%2F&title=Taybet%3AL%C3%AAger%C3%AEn&profile=advanced&fulltext=1&ns0=1&searchToken=8rh0bmw8dccsi7aynl6zli8uf ji wêjeyê] li beşa maneyê. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Bota Toolforgeê == Botekî Toolforgeê lazim e ji bo ku xeletiyên biçûk wekî şablonên bi navên îngilîzî werin kurdîkirin yan jî valahiya beşan rast bike û hwd.—[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Updatew == Bota [[Bikarhêner:Wikihez/skrîpt/py/updateW.py|updateW]] divê were rojanekirin. Yan jî yekî nû were çêkirin. Şablonên {{ş|W}} di beşa tercimeyan de sererast dike û zimanan rêz dike. Ya niha xeletiya navê zimanî dide.—[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == sihir --> sêhr == Tercimeyên ''[[sêhr]]'' hemû dibêje ''sihir'' loma bi botê lazim e kirin ''sêhr''. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 17:43, 18 tîrmeh 2026 (UTC) :Sihirbaz --> sêhrbaz [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:07, 18 tîrmeh 2026 (UTC) == Tercimeyên dîroknas == Li tercimeyên [[dîroknas]], hevmaneyên wê hewce ye were îlawekirin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:44, 18 tîrmeh 2026 (UTC) == Sererastkirina formata xwestina nimûneyan == <syntaxhighlight lang="wikitext">#: {{mînak?|ku}}</syntaxhighlight> bike <syntaxhighlight lang="wikitext">#* {{bênimûne|ku}}</syntaxhighlight> [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 01:06, 19 tîrmeh 2026 (UTC) 3ieybact1j3sx0mbt6u2v5kojmh903w 6265618 6265574 2026-07-19T17:00:05Z Wikihez 7344 [[MediaWiki:Gadget-aWa.js/belgekirin|aWa]]: Arşîvkirina 1 madeyê li [[Wîkîferheng:Xebat/arşîv 1]] 6265618 wikitext text/x-wiki {{/ser}} = Karên ferhengî = == Mane == * [[:Kategorî:Madeyên bê beşa mane]] ** [[:Kategorî:Madeyên bê beşa mane bi kurmancî]] Li ser van rûpelan ev made hene ku maneyan wan nehatine nivîsin û divê werin nivîsin. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Etîmolojî == *[[:Kategorî:Daxwazên etîmolojiyê]] **[[:Kategorî:Daxwazên etîmolojiyê bi kurmancî]] Li ser van rûpelan ev made hene ku etîmolojiya wan hîn nehatine nivîsin. Ji bo alîkariyê binêre [[WF:Etîmolojî]] —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Cureyê rêzimanî == * [[:Kategorî:Gotarên bê kategoriya rêzimanî]] * [[:Kategorî:Gotarên bê kategoriya rêzimanî bi kurmancî]] Li ser van rûpelan ev made hene ku cureyên wan yên rêzimanî hîn nehatine nivîsin. Ji bo alîkariyê binêre [[Alîkarî:Cureyên peyvan]] —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Kontrol == * [[:Kategorî:Kontrol]] ** [[:Kategorî:Kontrola maneyê]] Ev madde bi botê hatine çêkirin, yek bi yek divê werin kontrolkirin. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) = Şablon = == IPA == * {{ş|IPA}} divê [[Modul:IPA]] bi kar bîne. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Deng == Kurdîkirina belgekirina {{ş|deng}} lazim e.--[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 00:06, 19 tîrmeh 2026 (UTC) = Modul = == Modul:form of/templates == * [[Modul:form of/templates]]: Divê ev modul were rojanekirin û xeletiyên berê wekî ([[hevalê]]) werin rastkirin. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Modul:columns == * [[Modul:columns]] were rojanekirin û {{ş|kol3}} bila lînka ''nîşan bide'' deyne beriya sernavê, kolê di qutiya rengî de bila nebe. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Modul:etymon == * [[Modul:etymon kevn]]: Rojanekirin hewce ye. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) = Javascript = == [[Mediawiki:Gadget-citoid-helper.js]] == Ji bo bi citoidê kopîkirina malûmatên çavkaniyan amûreke wisa lazim e. Xisûsen ji ber ku bi çend amûrên din dikare were bikaranîn. * [[Bikarhêner:Wikihez/skrîpt/js/Gadget-citoid-helper.js]] --> [[Mediawiki:Gadget-citoid-helper.js]] Feqat çend problem hene, şablonên me de kêmasiya parametreyan gelek in û xerîteyên citoidê hîn nehatine çêkirin. Wana sererast bikin dûre vê amûrê çêkin, piştre [[MediaWiki:Gadget-start.js|start.js]] û [[MediaWiki:Gadget-wikt.add-examples.js|add examples.js]] were rojanekirin. - --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 00:04, 19 tîrmeh 2026 (UTC) == [[MediaWiki:Gadget-start.js]] == Rojanekirin hewce ye. Min gelek tişt lê zêde kir lê ez niha test dikime. Piştre em bar bikin: * [[Bikarhêner:Wikihez/Gadget-start.js]] --> [[MediaWiki:Gadget-start.js]] * [[Bikarhêner:Wikihez/Gadget-start.css]] --> [[MediaWiki:Gadget-start.css]] --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 22:08, 17 tîrmeh 2026 (UTC) :Min [[MediaWiki:Gadget-start.js/data.json|data.json]] çêkir ji bo ku bi hêsanî malûmatên heyî werin guhartin bêyî guhartina Javascriptê. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 19:49, 18 tîrmeh 2026 (UTC) :Xeletiyên ku ji bîr nekim rast bikim: :* Wextê min çavkanî "kitêb" hilbijart û bi destî tije kir xeletiyeke [https://ku.wiktionary.org/w/index.php?title=xezete&diff=prev&oldid=6265392 wisa] derket her kelîme hate lînkkirin. :* <code>html("⠿")</code> ev ne lazim e. :* textarea ji bo çavkaniyên jêgirtinan xaseten yên sernav hîn jî ne draggable e. :* pêşdîtina zindî checkbox wextê tê rakirin, pêşdîtin winda nabe. :* Butona mobîlê ya vekirina formê di moda tarî de belî nabe, tenê wekî qutiyeke tarî xuya dibe. :* Metna hişyarkirinê di guhartina rûpelên heyî de lazim e baştir bikim. :[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 23:51, 18 tîrmeh 2026 (UTC) ::Ev problem çêbûn, ez ê binêrim ka çi problemên din hene. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 14:15, 19 tîrmeh 2026 (UTC) == [[Mediawiki:Gadget-QQ.js]] == Ev amûr di şikle Minerva de. Her daîm vê xeletiyê dide: <syntaxhighlight lang="js"> TypeError: Cannot read properties of null (reading 'addEventListener') at css () at runScript () at Array.<anonymous> () at flushCssBuffer () </syntaxhighlight> [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 19:29, 18 tîrmeh 2026 (UTC) :* [[Bikarhêner:Wikihez/skrîpt/js/Gadget-QQ.js]] --> [[Mediawiki:Gadget-QQ.js]] :* [[Bikarhêner:Wikihez/Gadget-QQ.css]] --> [[Mediawiki:Gadget-QQ.css]] :Ez dibêjim çêbû lê ka çend roj biceribînim. Tiştên ku hatin sererastkirin: :# Google Books API Key dikarî zêde bikî, dixe cookies û di gerokê de dimîne. Berê bê API Key dixebitiya lê êdî mecbûr e ku API Key-a te hebe, bidestxistina wê ne zêde zor e lê dîsa jî tevlihev e. :# Êdî di mobîlê de dixebite, heta di mobîlê de xweştir xuya dike. :# Moda tarî :# OOUI dewsa jquery.ui :# Li qutiyê çi dixwazî zêde bikî, dikare li gorî îsm, sifet, fiîl bitewîne. Lê ji bo fiîl tenê dikare çend heb inflection bîne. :# Butona paqij bike lê zêde kir. :# Çend paqijiyên jêgirtinên Google Kitêbê niha hene. :[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 23:38, 18 tîrmeh 2026 (UTC) == [[MediaWiki:Gadget-wikt.add-examples.js]] == Min ev amûr hinek rojane kir feqat çend problem hene berî ku bar bikin. Tiştên ku min guhart: # Êdî li sayfeyên bi {{ş|maneid}} jî dixebite, # Cihê di wîkîtekstê de yê ku jêgirtin were îlawekirin baştir bû, # [[Mediawiki:Gadget-citoid-helper.js|citoid helper]] zêde kir ji bo ku bi hêsanî çavkanî bi riya doi, isbn an urlyê werin tijîkirin. * [[Bikarhêner:Wikihez/Gadget-wikt.add-examples.css]] --> [[MediaWiki:Gadget-wikt.add-examples.css]] * [[Bikarhêner:Wikihez/Gadget-wikt.add-examples.js]] --> [[MediaWiki:Gadget-wikt.add-examples.js]] - --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 00:50, 19 tîrmeh 2026 (UTC) == Gadget-translation editor == * [[MediaWiki:Gadget-translation editor.js]]: divê formata en.wîktê were bikaranîn ji ber ku me gelek tercime ji en.wîktê kopî kir û ev js hîn nikare formata wekî li jêr bi kar bîne. <syntaxhighlight lang="wikitext"> * {{Z|sh}}: *: Kirîlî: *: Latînî </syntaxhighlight> —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Gadget-linkify == * [[Mediawiki:Gadget-linkify.js]] ''rûpeleke'' wekî<syntaxhighlight lang="wikitext">[[rûpeleke]]</syntaxhighlight> lînk dike, bi regexê belkî dikare wisa bike <syntaxhighlight lang="wikitext">[[rûpel]]eke</syntaxhighlight> —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Gadget-herf guhartin == * Amûreke din wekî [[Mediawiki:Gadget-linkify.js|linkify]] lazim e ku herfên mezin biçûk bike ji bo kurmancî.—[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) = Moda tarî = == MediaWiki:Newarticletext == * [[MediaWiki:Newarticletext]]: Divê rengên wê were rastkirin.—[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Modul:dara kategoriyan == * [[Modul:dara kategoriyan]] link_box —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == mane? == * {{ş|mane?}} —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == bêçavkanî == * {{ş|bêçavkanî}} —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == de-tew-nerm-ern == * {{ş|de-tew-nerm-ern}} —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) = Bot = Karên ku bi botê werin çêkirin ji kerema xwe li vir binivîsin. == Kategorî:Biwêj == [[:Kategorî:Biwêj]] divê were paqijkirin, lîsteya madeyên {{ş|biwêj}} çêke, yên ku tê de bûn, kirin, man hene filtre bike yên din bi destî tê çêkirin.—[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Jêgirtin == Xistina jêgirtinên beşa [https://ku.wiktionary.org/w/index.php?search=insource%3A%2F%3D+*Ji+%5BWw%5D%C3%AAjey%C3%AA+*%3D%2F&title=Taybet%3AL%C3%AAger%C3%AEn&profile=advanced&fulltext=1&ns0=1&searchToken=8rh0bmw8dccsi7aynl6zli8uf ji wêjeyê] li beşa maneyê. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Bota Toolforgeê == Botekî Toolforgeê lazim e ji bo ku xeletiyên biçûk wekî şablonên bi navên îngilîzî werin kurdîkirin yan jî valahiya beşan rast bike û hwd.—[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Updatew == Bota [[Bikarhêner:Wikihez/skrîpt/py/updateW.py|updateW]] divê were rojanekirin. Yan jî yekî nû were çêkirin. Şablonên {{ş|W}} di beşa tercimeyan de sererast dike û zimanan rêz dike. Ya niha xeletiya navê zimanî dide.—[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == sihir --> sêhr == Tercimeyên ''[[sêhr]]'' hemû dibêje ''sihir'' loma bi botê lazim e kirin ''sêhr''. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 17:43, 18 tîrmeh 2026 (UTC) :Sihirbaz --> sêhrbaz [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:07, 18 tîrmeh 2026 (UTC) == Tercimeyên dîroknas == Li tercimeyên [[dîroknas]], hevmaneyên wê hewce ye were îlawekirin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:44, 18 tîrmeh 2026 (UTC) == Sererastkirina formata xwestina nimûneyan == <syntaxhighlight lang="wikitext">#: {{mînak?|ku}}</syntaxhighlight> bike <syntaxhighlight lang="wikitext">#* {{bênimûne|ku}}</syntaxhighlight> [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 01:06, 19 tîrmeh 2026 (UTC) gkseagbit7n7z1oolgbv3xnxuavluzt 6265623 6265618 2026-07-19T17:01:34Z Wikihez 7344 Restored revision 6265574 by [[Special:Contributions/Wikihez|Wikihez]] ([[User talk:Wikihez|talk]]) ([[:m:User:Xiplus/TwinkleGlobal|TwinkleGlobal]]) 6265623 wikitext text/x-wiki {{/ser}} = Karên ferhengî = == Mane == * [[:Kategorî:Madeyên bê beşa mane]] ** [[:Kategorî:Madeyên bê beşa mane bi kurmancî]] Li ser van rûpelan ev made hene ku maneyan wan nehatine nivîsin û divê werin nivîsin. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Etîmolojî == *[[:Kategorî:Daxwazên etîmolojiyê]] **[[:Kategorî:Daxwazên etîmolojiyê bi kurmancî]] Li ser van rûpelan ev made hene ku etîmolojiya wan hîn nehatine nivîsin. Ji bo alîkariyê binêre [[WF:Etîmolojî]] —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Cureyê rêzimanî == * [[:Kategorî:Gotarên bê kategoriya rêzimanî]] * [[:Kategorî:Gotarên bê kategoriya rêzimanî bi kurmancî]] Li ser van rûpelan ev made hene ku cureyên wan yên rêzimanî hîn nehatine nivîsin. Ji bo alîkariyê binêre [[Alîkarî:Cureyên peyvan]] —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Kontrol == * [[:Kategorî:Kontrol]] ** [[:Kategorî:Kontrola maneyê]] Ev madde bi botê hatine çêkirin, yek bi yek divê werin kontrolkirin. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) = Şablon = == IPA == * {{ş|IPA}} divê [[Modul:IPA]] bi kar bîne. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Deng == Kurdîkirina belgekirina {{ş|deng}} lazim e.--[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 00:06, 19 tîrmeh 2026 (UTC) = Modul = == Modul:form of/templates == * [[Modul:form of/templates]]: Divê ev modul were rojanekirin û xeletiyên berê wekî ([[hevalê]]) werin rastkirin. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Modul:columns == * [[Modul:columns]] were rojanekirin û {{ş|kol3}} bila lînka ''nîşan bide'' deyne beriya sernavê, kolê di qutiya rengî de bila nebe. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Modul:etymon == * [[Modul:etymon kevn]]: Rojanekirin hewce ye. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) = Javascript = == [[Mediawiki:Gadget-citoid-helper.js]] == Ji bo bi citoidê kopîkirina malûmatên çavkaniyan amûreke wisa lazim e. Xisûsen ji ber ku bi çend amûrên din dikare were bikaranîn. * [[Bikarhêner:Wikihez/skrîpt/js/Gadget-citoid-helper.js]] --> [[Mediawiki:Gadget-citoid-helper.js]] Feqat çend problem hene, şablonên me de kêmasiya parametreyan gelek in û xerîteyên citoidê hîn nehatine çêkirin. Wana sererast bikin dûre vê amûrê çêkin, piştre [[MediaWiki:Gadget-start.js|start.js]] û [[MediaWiki:Gadget-wikt.add-examples.js|add examples.js]] were rojanekirin. - --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 00:04, 19 tîrmeh 2026 (UTC) == [[MediaWiki:Gadget-aWa.js]] == Divê were rojanekirin ji bo ku di mobîlê de jî bixebite.[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 19:59, 17 tîrmeh 2026 (UTC) : Ez dibêjim çêbû lê bila hinekî din test bikim dûre em bar bikin: * [[Bikarhêner:Wikihez/Gadget-aWa.css]] --> [[MediaWiki:Gadget-aWa.css]] * [[Bikarhêner:Wikihez/Gadget-aWa.js]] --> [[MediaWiki:Gadget-aWa.js]] --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 22:04, 17 tîrmeh 2026 (UTC) :Min formata [[WF:Xebat]] wisa kir ku li [[WF:Xebat/arşîv 1]] arşîv bike lê niha dibêjim bila li gotûbêja sayfeyên xwe were zêde kirin wê baştir be. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 00:11, 19 tîrmeh 2026 (UTC) ::Lînkek li gotûbêja sayfeya eleqedar were dayîn bes e, wekî din li arşîv 1 were qeydkirin qet nebe dîtina wan hêsantir be. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 00:27, 19 tîrmeh 2026 (UTC) == [[MediaWiki:Gadget-start.js]] == Rojanekirin hewce ye. Min gelek tişt lê zêde kir lê ez niha test dikime. Piştre em bar bikin: * [[Bikarhêner:Wikihez/Gadget-start.js]] --> [[MediaWiki:Gadget-start.js]] * [[Bikarhêner:Wikihez/Gadget-start.css]] --> [[MediaWiki:Gadget-start.css]] --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 22:08, 17 tîrmeh 2026 (UTC) :Min [[MediaWiki:Gadget-start.js/data.json|data.json]] çêkir ji bo ku bi hêsanî malûmatên heyî werin guhartin bêyî guhartina Javascriptê. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 19:49, 18 tîrmeh 2026 (UTC) :Xeletiyên ku ji bîr nekim rast bikim: :* Wextê min çavkanî "kitêb" hilbijart û bi destî tije kir xeletiyeke [https://ku.wiktionary.org/w/index.php?title=xezete&diff=prev&oldid=6265392 wisa] derket her kelîme hate lînkkirin. :* <code>html("⠿")</code> ev ne lazim e. :* textarea ji bo çavkaniyên jêgirtinan xaseten yên sernav hîn jî ne draggable e. :* pêşdîtina zindî checkbox wextê tê rakirin, pêşdîtin winda nabe. :* Butona mobîlê ya vekirina formê di moda tarî de belî nabe, tenê wekî qutiyeke tarî xuya dibe. :* Metna hişyarkirinê di guhartina rûpelên heyî de lazim e baştir bikim. :[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 23:51, 18 tîrmeh 2026 (UTC) ::Ev problem çêbûn, ez ê binêrim ka çi problemên din hene. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 14:15, 19 tîrmeh 2026 (UTC) == [[Mediawiki:Gadget-QQ.js]] == Ev amûr di şikle Minerva de. Her daîm vê xeletiyê dide: <syntaxhighlight lang="js"> TypeError: Cannot read properties of null (reading 'addEventListener') at css () at runScript () at Array.<anonymous> () at flushCssBuffer () </syntaxhighlight> [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 19:29, 18 tîrmeh 2026 (UTC) :* [[Bikarhêner:Wikihez/skrîpt/js/Gadget-QQ.js]] --> [[Mediawiki:Gadget-QQ.js]] :* [[Bikarhêner:Wikihez/Gadget-QQ.css]] --> [[Mediawiki:Gadget-QQ.css]] :Ez dibêjim çêbû lê ka çend roj biceribînim. Tiştên ku hatin sererastkirin: :# Google Books API Key dikarî zêde bikî, dixe cookies û di gerokê de dimîne. Berê bê API Key dixebitiya lê êdî mecbûr e ku API Key-a te hebe, bidestxistina wê ne zêde zor e lê dîsa jî tevlihev e. :# Êdî di mobîlê de dixebite, heta di mobîlê de xweştir xuya dike. :# Moda tarî :# OOUI dewsa jquery.ui :# Li qutiyê çi dixwazî zêde bikî, dikare li gorî îsm, sifet, fiîl bitewîne. Lê ji bo fiîl tenê dikare çend heb inflection bîne. :# Butona paqij bike lê zêde kir. :# Çend paqijiyên jêgirtinên Google Kitêbê niha hene. :[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 23:38, 18 tîrmeh 2026 (UTC) == [[MediaWiki:Gadget-wikt.add-examples.js]] == Min ev amûr hinek rojane kir feqat çend problem hene berî ku bar bikin. Tiştên ku min guhart: # Êdî li sayfeyên bi {{ş|maneid}} jî dixebite, # Cihê di wîkîtekstê de yê ku jêgirtin were îlawekirin baştir bû, # [[Mediawiki:Gadget-citoid-helper.js|citoid helper]] zêde kir ji bo ku bi hêsanî çavkanî bi riya doi, isbn an urlyê werin tijîkirin. * [[Bikarhêner:Wikihez/Gadget-wikt.add-examples.css]] --> [[MediaWiki:Gadget-wikt.add-examples.css]] * [[Bikarhêner:Wikihez/Gadget-wikt.add-examples.js]] --> [[MediaWiki:Gadget-wikt.add-examples.js]] - --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 00:50, 19 tîrmeh 2026 (UTC) == Gadget-translation editor == * [[MediaWiki:Gadget-translation editor.js]]: divê formata en.wîktê were bikaranîn ji ber ku me gelek tercime ji en.wîktê kopî kir û ev js hîn nikare formata wekî li jêr bi kar bîne. <syntaxhighlight lang="wikitext"> * {{Z|sh}}: *: Kirîlî: *: Latînî </syntaxhighlight> —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Gadget-linkify == * [[Mediawiki:Gadget-linkify.js]] ''rûpeleke'' wekî<syntaxhighlight lang="wikitext">[[rûpeleke]]</syntaxhighlight> lînk dike, bi regexê belkî dikare wisa bike <syntaxhighlight lang="wikitext">[[rûpel]]eke</syntaxhighlight> —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Gadget-herf guhartin == * Amûreke din wekî [[Mediawiki:Gadget-linkify.js|linkify]] lazim e ku herfên mezin biçûk bike ji bo kurmancî.—[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) = Moda tarî = == MediaWiki:Newarticletext == * [[MediaWiki:Newarticletext]]: Divê rengên wê were rastkirin.—[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Modul:dara kategoriyan == * [[Modul:dara kategoriyan]] link_box —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == mane? == * {{ş|mane?}} —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == bêçavkanî == * {{ş|bêçavkanî}} —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == de-tew-nerm-ern == * {{ş|de-tew-nerm-ern}} —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) = Bot = Karên ku bi botê werin çêkirin ji kerema xwe li vir binivîsin. == Kategorî:Biwêj == [[:Kategorî:Biwêj]] divê were paqijkirin, lîsteya madeyên {{ş|biwêj}} çêke, yên ku tê de bûn, kirin, man hene filtre bike yên din bi destî tê çêkirin.—[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Jêgirtin == Xistina jêgirtinên beşa [https://ku.wiktionary.org/w/index.php?search=insource%3A%2F%3D+*Ji+%5BWw%5D%C3%AAjey%C3%AA+*%3D%2F&title=Taybet%3AL%C3%AAger%C3%AEn&profile=advanced&fulltext=1&ns0=1&searchToken=8rh0bmw8dccsi7aynl6zli8uf ji wêjeyê] li beşa maneyê. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Bota Toolforgeê == Botekî Toolforgeê lazim e ji bo ku xeletiyên biçûk wekî şablonên bi navên îngilîzî werin kurdîkirin yan jî valahiya beşan rast bike û hwd.—[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Updatew == Bota [[Bikarhêner:Wikihez/skrîpt/py/updateW.py|updateW]] divê were rojanekirin. Yan jî yekî nû were çêkirin. Şablonên {{ş|W}} di beşa tercimeyan de sererast dike û zimanan rêz dike. Ya niha xeletiya navê zimanî dide.—[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == sihir --> sêhr == Tercimeyên ''[[sêhr]]'' hemû dibêje ''sihir'' loma bi botê lazim e kirin ''sêhr''. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 17:43, 18 tîrmeh 2026 (UTC) :Sihirbaz --> sêhrbaz [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:07, 18 tîrmeh 2026 (UTC) == Tercimeyên dîroknas == Li tercimeyên [[dîroknas]], hevmaneyên wê hewce ye were îlawekirin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:44, 18 tîrmeh 2026 (UTC) == Sererastkirina formata xwestina nimûneyan == <syntaxhighlight lang="wikitext">#: {{mînak?|ku}}</syntaxhighlight> bike <syntaxhighlight lang="wikitext">#* {{bênimûne|ku}}</syntaxhighlight> [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 01:06, 19 tîrmeh 2026 (UTC) 3ieybact1j3sx0mbt6u2v5kojmh903w 6265624 6265623 2026-07-19T17:02:38Z Wikihez 7344 /* MediaWiki:Gadget-aWa.js */ 6265624 wikitext text/x-wiki {{/ser}} = Karên ferhengî = == Mane == * [[:Kategorî:Madeyên bê beşa mane]] ** [[:Kategorî:Madeyên bê beşa mane bi kurmancî]] Li ser van rûpelan ev made hene ku maneyan wan nehatine nivîsin û divê werin nivîsin. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Etîmolojî == *[[:Kategorî:Daxwazên etîmolojiyê]] **[[:Kategorî:Daxwazên etîmolojiyê bi kurmancî]] Li ser van rûpelan ev made hene ku etîmolojiya wan hîn nehatine nivîsin. Ji bo alîkariyê binêre [[WF:Etîmolojî]] —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Cureyê rêzimanî == * [[:Kategorî:Gotarên bê kategoriya rêzimanî]] * [[:Kategorî:Gotarên bê kategoriya rêzimanî bi kurmancî]] Li ser van rûpelan ev made hene ku cureyên wan yên rêzimanî hîn nehatine nivîsin. Ji bo alîkariyê binêre [[Alîkarî:Cureyên peyvan]] —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Kontrol == * [[:Kategorî:Kontrol]] ** [[:Kategorî:Kontrola maneyê]] Ev madde bi botê hatine çêkirin, yek bi yek divê werin kontrolkirin. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) = Şablon = == IPA == * {{ş|IPA}} divê [[Modul:IPA]] bi kar bîne. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Deng == Kurdîkirina belgekirina {{ş|deng}} lazim e.--[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 00:06, 19 tîrmeh 2026 (UTC) = Modul = == Modul:form of/templates == * [[Modul:form of/templates]]: Divê ev modul were rojanekirin û xeletiyên berê wekî ([[hevalê]]) werin rastkirin. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Modul:columns == * [[Modul:columns]] were rojanekirin û {{ş|kol3}} bila lînka ''nîşan bide'' deyne beriya sernavê, kolê di qutiya rengî de bila nebe. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Modul:etymon == * [[Modul:etymon kevn]]: Rojanekirin hewce ye. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) = Javascript = == [[Mediawiki:Gadget-citoid-helper.js]] == Ji bo bi citoidê kopîkirina malûmatên çavkaniyan amûreke wisa lazim e. Xisûsen ji ber ku bi çend amûrên din dikare were bikaranîn. * [[Bikarhêner:Wikihez/skrîpt/js/Gadget-citoid-helper.js]] --> [[Mediawiki:Gadget-citoid-helper.js]] Feqat çend problem hene, şablonên me de kêmasiya parametreyan gelek in û xerîteyên citoidê hîn nehatine çêkirin. Wana sererast bikin dûre vê amûrê çêkin, piştre [[MediaWiki:Gadget-start.js|start.js]] û [[MediaWiki:Gadget-wikt.add-examples.js|add examples.js]] were rojanekirin. - --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 00:04, 19 tîrmeh 2026 (UTC) == [[MediaWiki:Gadget-aWa.js]] == Divê were rojanekirin ji bo ku di mobîlê de jî bixebite.[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 19:59, 17 tîrmeh 2026 (UTC) : Ez dibêjim çêbû lê bila hinekî din test bikim dûre em bar bikin: * [[Bikarhêner:Wikihez/Gadget-aWa.css]] --> [[MediaWiki:Gadget-aWa.css]] * [[Bikarhêner:Wikihez/Gadget-aWa.js]] --> [[MediaWiki:Gadget-aWa.js]] --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 22:04, 17 tîrmeh 2026 (UTC) :Min formata [[WF:Xebat]] wisa kir ku li [[WF:Xebat/arşîv 1]] arşîv bike lê niha dibêjim bila li gotûbêja sayfeyên xwe were zêde kirin wê baştir be. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 00:11, 19 tîrmeh 2026 (UTC) ::Lînkek li gotûbêja sayfeya eleqedar were dayîn bes e, wekî din li arşîv 1 were qeydkirin qet nebe dîtina wan hêsantir be. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 00:27, 19 tîrmeh 2026 (UTC) :::Ev jî çêbû. {{r|Bikarhêner}} dikarî rûpelên jêr kopî paste bikî? * [[Bikarhêner:Wikihez/Gadget-aWa.css]] --> [[MediaWiki:Gadget-aWa.css]] * [[Bikarhêner:Wikihez/Gadget-aWa.js]] --> [[MediaWiki:Gadget-aWa.js]] --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 17:02, 19 tîrmeh 2026 (UTC) == [[MediaWiki:Gadget-start.js]] == Rojanekirin hewce ye. Min gelek tişt lê zêde kir lê ez niha test dikime. Piştre em bar bikin: * [[Bikarhêner:Wikihez/Gadget-start.js]] --> [[MediaWiki:Gadget-start.js]] * [[Bikarhêner:Wikihez/Gadget-start.css]] --> [[MediaWiki:Gadget-start.css]] --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 22:08, 17 tîrmeh 2026 (UTC) :Min [[MediaWiki:Gadget-start.js/data.json|data.json]] çêkir ji bo ku bi hêsanî malûmatên heyî werin guhartin bêyî guhartina Javascriptê. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 19:49, 18 tîrmeh 2026 (UTC) :Xeletiyên ku ji bîr nekim rast bikim: :* Wextê min çavkanî "kitêb" hilbijart û bi destî tije kir xeletiyeke [https://ku.wiktionary.org/w/index.php?title=xezete&diff=prev&oldid=6265392 wisa] derket her kelîme hate lînkkirin. :* <code>html("⠿")</code> ev ne lazim e. :* textarea ji bo çavkaniyên jêgirtinan xaseten yên sernav hîn jî ne draggable e. :* pêşdîtina zindî checkbox wextê tê rakirin, pêşdîtin winda nabe. :* Butona mobîlê ya vekirina formê di moda tarî de belî nabe, tenê wekî qutiyeke tarî xuya dibe. :* Metna hişyarkirinê di guhartina rûpelên heyî de lazim e baştir bikim. :[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 23:51, 18 tîrmeh 2026 (UTC) ::Ev problem çêbûn, ez ê binêrim ka çi problemên din hene. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 14:15, 19 tîrmeh 2026 (UTC) == [[Mediawiki:Gadget-QQ.js]] == Ev amûr di şikle Minerva de. Her daîm vê xeletiyê dide: <syntaxhighlight lang="js"> TypeError: Cannot read properties of null (reading 'addEventListener') at css () at runScript () at Array.<anonymous> () at flushCssBuffer () </syntaxhighlight> [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 19:29, 18 tîrmeh 2026 (UTC) :* [[Bikarhêner:Wikihez/skrîpt/js/Gadget-QQ.js]] --> [[Mediawiki:Gadget-QQ.js]] :* [[Bikarhêner:Wikihez/Gadget-QQ.css]] --> [[Mediawiki:Gadget-QQ.css]] :Ez dibêjim çêbû lê ka çend roj biceribînim. Tiştên ku hatin sererastkirin: :# Google Books API Key dikarî zêde bikî, dixe cookies û di gerokê de dimîne. Berê bê API Key dixebitiya lê êdî mecbûr e ku API Key-a te hebe, bidestxistina wê ne zêde zor e lê dîsa jî tevlihev e. :# Êdî di mobîlê de dixebite, heta di mobîlê de xweştir xuya dike. :# Moda tarî :# OOUI dewsa jquery.ui :# Li qutiyê çi dixwazî zêde bikî, dikare li gorî îsm, sifet, fiîl bitewîne. Lê ji bo fiîl tenê dikare çend heb inflection bîne. :# Butona paqij bike lê zêde kir. :# Çend paqijiyên jêgirtinên Google Kitêbê niha hene. :[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 23:38, 18 tîrmeh 2026 (UTC) == [[MediaWiki:Gadget-wikt.add-examples.js]] == Min ev amûr hinek rojane kir feqat çend problem hene berî ku bar bikin. Tiştên ku min guhart: # Êdî li sayfeyên bi {{ş|maneid}} jî dixebite, # Cihê di wîkîtekstê de yê ku jêgirtin were îlawekirin baştir bû, # [[Mediawiki:Gadget-citoid-helper.js|citoid helper]] zêde kir ji bo ku bi hêsanî çavkanî bi riya doi, isbn an urlyê werin tijîkirin. * [[Bikarhêner:Wikihez/Gadget-wikt.add-examples.css]] --> [[MediaWiki:Gadget-wikt.add-examples.css]] * [[Bikarhêner:Wikihez/Gadget-wikt.add-examples.js]] --> [[MediaWiki:Gadget-wikt.add-examples.js]] - --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 00:50, 19 tîrmeh 2026 (UTC) == Gadget-translation editor == * [[MediaWiki:Gadget-translation editor.js]]: divê formata en.wîktê were bikaranîn ji ber ku me gelek tercime ji en.wîktê kopî kir û ev js hîn nikare formata wekî li jêr bi kar bîne. <syntaxhighlight lang="wikitext"> * {{Z|sh}}: *: Kirîlî: *: Latînî </syntaxhighlight> —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Gadget-linkify == * [[Mediawiki:Gadget-linkify.js]] ''rûpeleke'' wekî<syntaxhighlight lang="wikitext">[[rûpeleke]]</syntaxhighlight> lînk dike, bi regexê belkî dikare wisa bike <syntaxhighlight lang="wikitext">[[rûpel]]eke</syntaxhighlight> —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Gadget-herf guhartin == * Amûreke din wekî [[Mediawiki:Gadget-linkify.js|linkify]] lazim e ku herfên mezin biçûk bike ji bo kurmancî.—[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) = Moda tarî = == MediaWiki:Newarticletext == * [[MediaWiki:Newarticletext]]: Divê rengên wê were rastkirin.—[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Modul:dara kategoriyan == * [[Modul:dara kategoriyan]] link_box —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == mane? == * {{ş|mane?}} —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == bêçavkanî == * {{ş|bêçavkanî}} —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == de-tew-nerm-ern == * {{ş|de-tew-nerm-ern}} —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) = Bot = Karên ku bi botê werin çêkirin ji kerema xwe li vir binivîsin. == Kategorî:Biwêj == [[:Kategorî:Biwêj]] divê were paqijkirin, lîsteya madeyên {{ş|biwêj}} çêke, yên ku tê de bûn, kirin, man hene filtre bike yên din bi destî tê çêkirin.—[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Jêgirtin == Xistina jêgirtinên beşa [https://ku.wiktionary.org/w/index.php?search=insource%3A%2F%3D+*Ji+%5BWw%5D%C3%AAjey%C3%AA+*%3D%2F&title=Taybet%3AL%C3%AAger%C3%AEn&profile=advanced&fulltext=1&ns0=1&searchToken=8rh0bmw8dccsi7aynl6zli8uf ji wêjeyê] li beşa maneyê. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Bota Toolforgeê == Botekî Toolforgeê lazim e ji bo ku xeletiyên biçûk wekî şablonên bi navên îngilîzî werin kurdîkirin yan jî valahiya beşan rast bike û hwd.—[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Updatew == Bota [[Bikarhêner:Wikihez/skrîpt/py/updateW.py|updateW]] divê were rojanekirin. Yan jî yekî nû were çêkirin. Şablonên {{ş|W}} di beşa tercimeyan de sererast dike û zimanan rêz dike. Ya niha xeletiya navê zimanî dide.—[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == sihir --> sêhr == Tercimeyên ''[[sêhr]]'' hemû dibêje ''sihir'' loma bi botê lazim e kirin ''sêhr''. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 17:43, 18 tîrmeh 2026 (UTC) :Sihirbaz --> sêhrbaz [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:07, 18 tîrmeh 2026 (UTC) == Tercimeyên dîroknas == Li tercimeyên [[dîroknas]], hevmaneyên wê hewce ye were îlawekirin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:44, 18 tîrmeh 2026 (UTC) == Sererastkirina formata xwestina nimûneyan == <syntaxhighlight lang="wikitext">#: {{mînak?|ku}}</syntaxhighlight> bike <syntaxhighlight lang="wikitext">#* {{bênimûne|ku}}</syntaxhighlight> [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 01:06, 19 tîrmeh 2026 (UTC) 56qvj9uqlies85f87cbcehr6mqxgbwc 6265677 6265624 2026-07-19T21:21:15Z Wikihez 7344 /* MediaWiki:Gadget-start.js */ Bersiv 6265677 wikitext text/x-wiki {{/ser}} = Karên ferhengî = == Mane == * [[:Kategorî:Madeyên bê beşa mane]] ** [[:Kategorî:Madeyên bê beşa mane bi kurmancî]] Li ser van rûpelan ev made hene ku maneyan wan nehatine nivîsin û divê werin nivîsin. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Etîmolojî == *[[:Kategorî:Daxwazên etîmolojiyê]] **[[:Kategorî:Daxwazên etîmolojiyê bi kurmancî]] Li ser van rûpelan ev made hene ku etîmolojiya wan hîn nehatine nivîsin. Ji bo alîkariyê binêre [[WF:Etîmolojî]] —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Cureyê rêzimanî == * [[:Kategorî:Gotarên bê kategoriya rêzimanî]] * [[:Kategorî:Gotarên bê kategoriya rêzimanî bi kurmancî]] Li ser van rûpelan ev made hene ku cureyên wan yên rêzimanî hîn nehatine nivîsin. Ji bo alîkariyê binêre [[Alîkarî:Cureyên peyvan]] —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Kontrol == * [[:Kategorî:Kontrol]] ** [[:Kategorî:Kontrola maneyê]] Ev madde bi botê hatine çêkirin, yek bi yek divê werin kontrolkirin. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) = Şablon = == IPA == * {{ş|IPA}} divê [[Modul:IPA]] bi kar bîne. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Deng == Kurdîkirina belgekirina {{ş|deng}} lazim e.--[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 00:06, 19 tîrmeh 2026 (UTC) = Modul = == Modul:form of/templates == * [[Modul:form of/templates]]: Divê ev modul were rojanekirin û xeletiyên berê wekî ([[hevalê]]) werin rastkirin. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Modul:columns == * [[Modul:columns]] were rojanekirin û {{ş|kol3}} bila lînka ''nîşan bide'' deyne beriya sernavê, kolê di qutiya rengî de bila nebe. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Modul:etymon == * [[Modul:etymon kevn]]: Rojanekirin hewce ye. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) = Javascript = == [[Mediawiki:Gadget-citoid-helper.js]] == Ji bo bi citoidê kopîkirina malûmatên çavkaniyan amûreke wisa lazim e. Xisûsen ji ber ku bi çend amûrên din dikare were bikaranîn. * [[Bikarhêner:Wikihez/skrîpt/js/Gadget-citoid-helper.js]] --> [[Mediawiki:Gadget-citoid-helper.js]] Feqat çend problem hene, şablonên me de kêmasiya parametreyan gelek in û xerîteyên citoidê hîn nehatine çêkirin. Wana sererast bikin dûre vê amûrê çêkin, piştre [[MediaWiki:Gadget-start.js|start.js]] û [[MediaWiki:Gadget-wikt.add-examples.js|add examples.js]] were rojanekirin. - --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 00:04, 19 tîrmeh 2026 (UTC) == [[MediaWiki:Gadget-aWa.js]] == Divê were rojanekirin ji bo ku di mobîlê de jî bixebite.[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 19:59, 17 tîrmeh 2026 (UTC) : Ez dibêjim çêbû lê bila hinekî din test bikim dûre em bar bikin: * [[Bikarhêner:Wikihez/Gadget-aWa.css]] --> [[MediaWiki:Gadget-aWa.css]] * [[Bikarhêner:Wikihez/Gadget-aWa.js]] --> [[MediaWiki:Gadget-aWa.js]] --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 22:04, 17 tîrmeh 2026 (UTC) :Min formata [[WF:Xebat]] wisa kir ku li [[WF:Xebat/arşîv 1]] arşîv bike lê niha dibêjim bila li gotûbêja sayfeyên xwe were zêde kirin wê baştir be. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 00:11, 19 tîrmeh 2026 (UTC) ::Lînkek li gotûbêja sayfeya eleqedar were dayîn bes e, wekî din li arşîv 1 were qeydkirin qet nebe dîtina wan hêsantir be. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 00:27, 19 tîrmeh 2026 (UTC) :::Ev jî çêbû. {{r|Bikarhêner}} dikarî rûpelên jêr kopî paste bikî? * [[Bikarhêner:Wikihez/Gadget-aWa.css]] --> [[MediaWiki:Gadget-aWa.css]] * [[Bikarhêner:Wikihez/Gadget-aWa.js]] --> [[MediaWiki:Gadget-aWa.js]] --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 17:02, 19 tîrmeh 2026 (UTC) == [[MediaWiki:Gadget-start.js]] == Rojanekirin hewce ye. Min gelek tişt lê zêde kir lê ez niha test dikime. Piştre em bar bikin: * [[Bikarhêner:Wikihez/Gadget-start.js]] --> [[MediaWiki:Gadget-start.js]] * [[Bikarhêner:Wikihez/Gadget-start.css]] --> [[MediaWiki:Gadget-start.css]] --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 22:08, 17 tîrmeh 2026 (UTC) :Min [[MediaWiki:Gadget-start.js/data.json|data.json]] çêkir ji bo ku bi hêsanî malûmatên heyî werin guhartin bêyî guhartina Javascriptê. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 19:49, 18 tîrmeh 2026 (UTC) :Xeletiyên ku ji bîr nekim rast bikim: :* Wextê min çavkanî "kitêb" hilbijart û bi destî tije kir xeletiyeke [https://ku.wiktionary.org/w/index.php?title=xezete&diff=prev&oldid=6265392 wisa] derket her kelîme hate lînkkirin. :* <code>html("⠿")</code> ev ne lazim e. :* textarea ji bo çavkaniyên jêgirtinan xaseten yên sernav hîn jî ne draggable e. :* pêşdîtina zindî checkbox wextê tê rakirin, pêşdîtin winda nabe. :* Butona mobîlê ya vekirina formê di moda tarî de belî nabe, tenê wekî qutiyeke tarî xuya dibe. :* Metna hişyarkirinê di guhartina rûpelên heyî de lazim e baştir bikim. :[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 23:51, 18 tîrmeh 2026 (UTC) ::Ev problem çêbûn, ez ê binêrim ka çi problemên din hene. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 14:15, 19 tîrmeh 2026 (UTC) :::Ji bo qismê çavkaniyê yek dikare API call û Kategorî:Çavkanî bi kar bîne ji bo ku şablon zêde bikî ji yên heyî. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 21:21, 19 tîrmeh 2026 (UTC) == [[Mediawiki:Gadget-QQ.js]] == Ev amûr di şikle Minerva de. Her daîm vê xeletiyê dide: <syntaxhighlight lang="js"> TypeError: Cannot read properties of null (reading 'addEventListener') at css () at runScript () at Array.<anonymous> () at flushCssBuffer () </syntaxhighlight> [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 19:29, 18 tîrmeh 2026 (UTC) :* [[Bikarhêner:Wikihez/skrîpt/js/Gadget-QQ.js]] --> [[Mediawiki:Gadget-QQ.js]] :* [[Bikarhêner:Wikihez/Gadget-QQ.css]] --> [[Mediawiki:Gadget-QQ.css]] :Ez dibêjim çêbû lê ka çend roj biceribînim. Tiştên ku hatin sererastkirin: :# Google Books API Key dikarî zêde bikî, dixe cookies û di gerokê de dimîne. Berê bê API Key dixebitiya lê êdî mecbûr e ku API Key-a te hebe, bidestxistina wê ne zêde zor e lê dîsa jî tevlihev e. :# Êdî di mobîlê de dixebite, heta di mobîlê de xweştir xuya dike. :# Moda tarî :# OOUI dewsa jquery.ui :# Li qutiyê çi dixwazî zêde bikî, dikare li gorî îsm, sifet, fiîl bitewîne. Lê ji bo fiîl tenê dikare çend heb inflection bîne. :# Butona paqij bike lê zêde kir. :# Çend paqijiyên jêgirtinên Google Kitêbê niha hene. :[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 23:38, 18 tîrmeh 2026 (UTC) == [[MediaWiki:Gadget-wikt.add-examples.js]] == Min ev amûr hinek rojane kir feqat çend problem hene berî ku bar bikin. Tiştên ku min guhart: # Êdî li sayfeyên bi {{ş|maneid}} jî dixebite, # Cihê di wîkîtekstê de yê ku jêgirtin were îlawekirin baştir bû, # [[Mediawiki:Gadget-citoid-helper.js|citoid helper]] zêde kir ji bo ku bi hêsanî çavkanî bi riya doi, isbn an urlyê werin tijîkirin. * [[Bikarhêner:Wikihez/Gadget-wikt.add-examples.css]] --> [[MediaWiki:Gadget-wikt.add-examples.css]] * [[Bikarhêner:Wikihez/Gadget-wikt.add-examples.js]] --> [[MediaWiki:Gadget-wikt.add-examples.js]] - --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 00:50, 19 tîrmeh 2026 (UTC) == Gadget-translation editor == * [[MediaWiki:Gadget-translation editor.js]]: divê formata en.wîktê were bikaranîn ji ber ku me gelek tercime ji en.wîktê kopî kir û ev js hîn nikare formata wekî li jêr bi kar bîne. <syntaxhighlight lang="wikitext"> * {{Z|sh}}: *: Kirîlî: *: Latînî </syntaxhighlight> —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Gadget-linkify == * [[Mediawiki:Gadget-linkify.js]] ''rûpeleke'' wekî<syntaxhighlight lang="wikitext">[[rûpeleke]]</syntaxhighlight> lînk dike, bi regexê belkî dikare wisa bike <syntaxhighlight lang="wikitext">[[rûpel]]eke</syntaxhighlight> —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Gadget-herf guhartin == * Amûreke din wekî [[Mediawiki:Gadget-linkify.js|linkify]] lazim e ku herfên mezin biçûk bike ji bo kurmancî.—[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) = Moda tarî = == MediaWiki:Newarticletext == * [[MediaWiki:Newarticletext]]: Divê rengên wê were rastkirin.—[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Modul:dara kategoriyan == * [[Modul:dara kategoriyan]] link_box —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == mane? == * {{ş|mane?}} —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == bêçavkanî == * {{ş|bêçavkanî}} —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == de-tew-nerm-ern == * {{ş|de-tew-nerm-ern}} —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) = Bot = Karên ku bi botê werin çêkirin ji kerema xwe li vir binivîsin. == Kategorî:Biwêj == [[:Kategorî:Biwêj]] divê were paqijkirin, lîsteya madeyên {{ş|biwêj}} çêke, yên ku tê de bûn, kirin, man hene filtre bike yên din bi destî tê çêkirin.—[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Jêgirtin == Xistina jêgirtinên beşa [https://ku.wiktionary.org/w/index.php?search=insource%3A%2F%3D+*Ji+%5BWw%5D%C3%AAjey%C3%AA+*%3D%2F&title=Taybet%3AL%C3%AAger%C3%AEn&profile=advanced&fulltext=1&ns0=1&searchToken=8rh0bmw8dccsi7aynl6zli8uf ji wêjeyê] li beşa maneyê. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Bota Toolforgeê == Botekî Toolforgeê lazim e ji bo ku xeletiyên biçûk wekî şablonên bi navên îngilîzî werin kurdîkirin yan jî valahiya beşan rast bike û hwd.—[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Updatew == Bota [[Bikarhêner:Wikihez/skrîpt/py/updateW.py|updateW]] divê were rojanekirin. Yan jî yekî nû were çêkirin. Şablonên {{ş|W}} di beşa tercimeyan de sererast dike û zimanan rêz dike. Ya niha xeletiya navê zimanî dide.—[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == sihir --> sêhr == Tercimeyên ''[[sêhr]]'' hemû dibêje ''sihir'' loma bi botê lazim e kirin ''sêhr''. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 17:43, 18 tîrmeh 2026 (UTC) :Sihirbaz --> sêhrbaz [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:07, 18 tîrmeh 2026 (UTC) == Tercimeyên dîroknas == Li tercimeyên [[dîroknas]], hevmaneyên wê hewce ye were îlawekirin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:44, 18 tîrmeh 2026 (UTC) == Sererastkirina formata xwestina nimûneyan == <syntaxhighlight lang="wikitext">#: {{mînak?|ku}}</syntaxhighlight> bike <syntaxhighlight lang="wikitext">#* {{bênimûne|ku}}</syntaxhighlight> [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 01:06, 19 tîrmeh 2026 (UTC) ar27dtft8kh045jypru3immj1epuujl 6265678 6265677 2026-07-19T21:21:30Z Wikihez 7344 /* MediaWiki:Gadget-start.js */ 6265678 wikitext text/x-wiki {{/ser}} = Karên ferhengî = == Mane == * [[:Kategorî:Madeyên bê beşa mane]] ** [[:Kategorî:Madeyên bê beşa mane bi kurmancî]] Li ser van rûpelan ev made hene ku maneyan wan nehatine nivîsin û divê werin nivîsin. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Etîmolojî == *[[:Kategorî:Daxwazên etîmolojiyê]] **[[:Kategorî:Daxwazên etîmolojiyê bi kurmancî]] Li ser van rûpelan ev made hene ku etîmolojiya wan hîn nehatine nivîsin. Ji bo alîkariyê binêre [[WF:Etîmolojî]] —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Cureyê rêzimanî == * [[:Kategorî:Gotarên bê kategoriya rêzimanî]] * [[:Kategorî:Gotarên bê kategoriya rêzimanî bi kurmancî]] Li ser van rûpelan ev made hene ku cureyên wan yên rêzimanî hîn nehatine nivîsin. Ji bo alîkariyê binêre [[Alîkarî:Cureyên peyvan]] —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Kontrol == * [[:Kategorî:Kontrol]] ** [[:Kategorî:Kontrola maneyê]] Ev madde bi botê hatine çêkirin, yek bi yek divê werin kontrolkirin. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) = Şablon = == IPA == * {{ş|IPA}} divê [[Modul:IPA]] bi kar bîne. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Deng == Kurdîkirina belgekirina {{ş|deng}} lazim e.--[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 00:06, 19 tîrmeh 2026 (UTC) = Modul = == Modul:form of/templates == * [[Modul:form of/templates]]: Divê ev modul were rojanekirin û xeletiyên berê wekî ([[hevalê]]) werin rastkirin. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Modul:columns == * [[Modul:columns]] were rojanekirin û {{ş|kol3}} bila lînka ''nîşan bide'' deyne beriya sernavê, kolê di qutiya rengî de bila nebe. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Modul:etymon == * [[Modul:etymon kevn]]: Rojanekirin hewce ye. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) = Javascript = == [[Mediawiki:Gadget-citoid-helper.js]] == Ji bo bi citoidê kopîkirina malûmatên çavkaniyan amûreke wisa lazim e. Xisûsen ji ber ku bi çend amûrên din dikare were bikaranîn. * [[Bikarhêner:Wikihez/skrîpt/js/Gadget-citoid-helper.js]] --> [[Mediawiki:Gadget-citoid-helper.js]] Feqat çend problem hene, şablonên me de kêmasiya parametreyan gelek in û xerîteyên citoidê hîn nehatine çêkirin. Wana sererast bikin dûre vê amûrê çêkin, piştre [[MediaWiki:Gadget-start.js|start.js]] û [[MediaWiki:Gadget-wikt.add-examples.js|add examples.js]] were rojanekirin. - --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 00:04, 19 tîrmeh 2026 (UTC) == [[MediaWiki:Gadget-aWa.js]] == Divê were rojanekirin ji bo ku di mobîlê de jî bixebite.[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 19:59, 17 tîrmeh 2026 (UTC) : Ez dibêjim çêbû lê bila hinekî din test bikim dûre em bar bikin: * [[Bikarhêner:Wikihez/Gadget-aWa.css]] --> [[MediaWiki:Gadget-aWa.css]] * [[Bikarhêner:Wikihez/Gadget-aWa.js]] --> [[MediaWiki:Gadget-aWa.js]] --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 22:04, 17 tîrmeh 2026 (UTC) :Min formata [[WF:Xebat]] wisa kir ku li [[WF:Xebat/arşîv 1]] arşîv bike lê niha dibêjim bila li gotûbêja sayfeyên xwe were zêde kirin wê baştir be. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 00:11, 19 tîrmeh 2026 (UTC) ::Lînkek li gotûbêja sayfeya eleqedar were dayîn bes e, wekî din li arşîv 1 were qeydkirin qet nebe dîtina wan hêsantir be. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 00:27, 19 tîrmeh 2026 (UTC) :::Ev jî çêbû. {{r|Bikarhêner}} dikarî rûpelên jêr kopî paste bikî? * [[Bikarhêner:Wikihez/Gadget-aWa.css]] --> [[MediaWiki:Gadget-aWa.css]] * [[Bikarhêner:Wikihez/Gadget-aWa.js]] --> [[MediaWiki:Gadget-aWa.js]] --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 17:02, 19 tîrmeh 2026 (UTC) == [[MediaWiki:Gadget-start.js]] == Rojanekirin hewce ye. Min gelek tişt lê zêde kir lê ez niha test dikime. Piştre em bar bikin: * [[Bikarhêner:Wikihez/Gadget-start.js]] --> [[MediaWiki:Gadget-start.js]] * [[Bikarhêner:Wikihez/Gadget-start.css]] --> [[MediaWiki:Gadget-start.css]] --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 22:08, 17 tîrmeh 2026 (UTC) :Min [[MediaWiki:Gadget-start.js/data.json|data.json]] çêkir ji bo ku bi hêsanî malûmatên heyî werin guhartin bêyî guhartina Javascriptê. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 19:49, 18 tîrmeh 2026 (UTC) :Xeletiyên ku ji bîr nekim rast bikim: :* Wextê min çavkanî "kitêb" hilbijart û bi destî tije kir xeletiyeke [https://ku.wiktionary.org/w/index.php?title=xezete&diff=prev&oldid=6265392 wisa] derket her kelîme hate lînkkirin. :* <code>html("⠿")</code> ev ne lazim e. :* textarea ji bo çavkaniyên jêgirtinan xaseten yên sernav hîn jî ne draggable e. :* pêşdîtina zindî checkbox wextê tê rakirin, pêşdîtin winda nabe. :* Butona mobîlê ya vekirina formê di moda tarî de belî nabe, tenê wekî qutiyeke tarî xuya dibe. :* Metna hişyarkirinê di guhartina rûpelên heyî de lazim e baştir bikim. :[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 23:51, 18 tîrmeh 2026 (UTC) ::Ev problem çêbûn, ez ê binêrim ka çi problemên din hene. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 14:15, 19 tîrmeh 2026 (UTC) :::Çêke: Ji bo qismê çavkaniyê yek dikare API call û Kategorî:Çavkanî bi kar bîne ji bo ku şablon zêde bikî ji yên heyî. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 21:21, 19 tîrmeh 2026 (UTC) == [[Mediawiki:Gadget-QQ.js]] == Ev amûr di şikle Minerva de. Her daîm vê xeletiyê dide: <syntaxhighlight lang="js"> TypeError: Cannot read properties of null (reading 'addEventListener') at css () at runScript () at Array.<anonymous> () at flushCssBuffer () </syntaxhighlight> [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 19:29, 18 tîrmeh 2026 (UTC) :* [[Bikarhêner:Wikihez/skrîpt/js/Gadget-QQ.js]] --> [[Mediawiki:Gadget-QQ.js]] :* [[Bikarhêner:Wikihez/Gadget-QQ.css]] --> [[Mediawiki:Gadget-QQ.css]] :Ez dibêjim çêbû lê ka çend roj biceribînim. Tiştên ku hatin sererastkirin: :# Google Books API Key dikarî zêde bikî, dixe cookies û di gerokê de dimîne. Berê bê API Key dixebitiya lê êdî mecbûr e ku API Key-a te hebe, bidestxistina wê ne zêde zor e lê dîsa jî tevlihev e. :# Êdî di mobîlê de dixebite, heta di mobîlê de xweştir xuya dike. :# Moda tarî :# OOUI dewsa jquery.ui :# Li qutiyê çi dixwazî zêde bikî, dikare li gorî îsm, sifet, fiîl bitewîne. Lê ji bo fiîl tenê dikare çend heb inflection bîne. :# Butona paqij bike lê zêde kir. :# Çend paqijiyên jêgirtinên Google Kitêbê niha hene. :[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 23:38, 18 tîrmeh 2026 (UTC) == [[MediaWiki:Gadget-wikt.add-examples.js]] == Min ev amûr hinek rojane kir feqat çend problem hene berî ku bar bikin. Tiştên ku min guhart: # Êdî li sayfeyên bi {{ş|maneid}} jî dixebite, # Cihê di wîkîtekstê de yê ku jêgirtin were îlawekirin baştir bû, # [[Mediawiki:Gadget-citoid-helper.js|citoid helper]] zêde kir ji bo ku bi hêsanî çavkanî bi riya doi, isbn an urlyê werin tijîkirin. * [[Bikarhêner:Wikihez/Gadget-wikt.add-examples.css]] --> [[MediaWiki:Gadget-wikt.add-examples.css]] * [[Bikarhêner:Wikihez/Gadget-wikt.add-examples.js]] --> [[MediaWiki:Gadget-wikt.add-examples.js]] - --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 00:50, 19 tîrmeh 2026 (UTC) == Gadget-translation editor == * [[MediaWiki:Gadget-translation editor.js]]: divê formata en.wîktê were bikaranîn ji ber ku me gelek tercime ji en.wîktê kopî kir û ev js hîn nikare formata wekî li jêr bi kar bîne. <syntaxhighlight lang="wikitext"> * {{Z|sh}}: *: Kirîlî: *: Latînî </syntaxhighlight> —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Gadget-linkify == * [[Mediawiki:Gadget-linkify.js]] ''rûpeleke'' wekî<syntaxhighlight lang="wikitext">[[rûpeleke]]</syntaxhighlight> lînk dike, bi regexê belkî dikare wisa bike <syntaxhighlight lang="wikitext">[[rûpel]]eke</syntaxhighlight> —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Gadget-herf guhartin == * Amûreke din wekî [[Mediawiki:Gadget-linkify.js|linkify]] lazim e ku herfên mezin biçûk bike ji bo kurmancî.—[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) = Moda tarî = == MediaWiki:Newarticletext == * [[MediaWiki:Newarticletext]]: Divê rengên wê were rastkirin.—[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Modul:dara kategoriyan == * [[Modul:dara kategoriyan]] link_box —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == mane? == * {{ş|mane?}} —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == bêçavkanî == * {{ş|bêçavkanî}} —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == de-tew-nerm-ern == * {{ş|de-tew-nerm-ern}} —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) = Bot = Karên ku bi botê werin çêkirin ji kerema xwe li vir binivîsin. == Kategorî:Biwêj == [[:Kategorî:Biwêj]] divê were paqijkirin, lîsteya madeyên {{ş|biwêj}} çêke, yên ku tê de bûn, kirin, man hene filtre bike yên din bi destî tê çêkirin.—[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Jêgirtin == Xistina jêgirtinên beşa [https://ku.wiktionary.org/w/index.php?search=insource%3A%2F%3D+*Ji+%5BWw%5D%C3%AAjey%C3%AA+*%3D%2F&title=Taybet%3AL%C3%AAger%C3%AEn&profile=advanced&fulltext=1&ns0=1&searchToken=8rh0bmw8dccsi7aynl6zli8uf ji wêjeyê] li beşa maneyê. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Bota Toolforgeê == Botekî Toolforgeê lazim e ji bo ku xeletiyên biçûk wekî şablonên bi navên îngilîzî werin kurdîkirin yan jî valahiya beşan rast bike û hwd.—[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Updatew == Bota [[Bikarhêner:Wikihez/skrîpt/py/updateW.py|updateW]] divê were rojanekirin. Yan jî yekî nû were çêkirin. Şablonên {{ş|W}} di beşa tercimeyan de sererast dike û zimanan rêz dike. Ya niha xeletiya navê zimanî dide.—[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == sihir --> sêhr == Tercimeyên ''[[sêhr]]'' hemû dibêje ''sihir'' loma bi botê lazim e kirin ''sêhr''. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 17:43, 18 tîrmeh 2026 (UTC) :Sihirbaz --> sêhrbaz [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:07, 18 tîrmeh 2026 (UTC) == Tercimeyên dîroknas == Li tercimeyên [[dîroknas]], hevmaneyên wê hewce ye were îlawekirin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:44, 18 tîrmeh 2026 (UTC) == Sererastkirina formata xwestina nimûneyan == <syntaxhighlight lang="wikitext">#: {{mînak?|ku}}</syntaxhighlight> bike <syntaxhighlight lang="wikitext">#* {{bênimûne|ku}}</syntaxhighlight> [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 01:06, 19 tîrmeh 2026 (UTC) en1royxv1qxv7s9syydc7rywueibjbg 6265853 6265678 2026-07-20T09:43:57Z Wikihez 7344 /* Mewlûd */ beşeke nû 6265853 wikitext text/x-wiki {{/ser}} = Karên ferhengî = == Mane == * [[:Kategorî:Madeyên bê beşa mane]] ** [[:Kategorî:Madeyên bê beşa mane bi kurmancî]] Li ser van rûpelan ev made hene ku maneyan wan nehatine nivîsin û divê werin nivîsin. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Etîmolojî == *[[:Kategorî:Daxwazên etîmolojiyê]] **[[:Kategorî:Daxwazên etîmolojiyê bi kurmancî]] Li ser van rûpelan ev made hene ku etîmolojiya wan hîn nehatine nivîsin. Ji bo alîkariyê binêre [[WF:Etîmolojî]] —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Cureyê rêzimanî == * [[:Kategorî:Gotarên bê kategoriya rêzimanî]] * [[:Kategorî:Gotarên bê kategoriya rêzimanî bi kurmancî]] Li ser van rûpelan ev made hene ku cureyên wan yên rêzimanî hîn nehatine nivîsin. Ji bo alîkariyê binêre [[Alîkarî:Cureyên peyvan]] —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Kontrol == * [[:Kategorî:Kontrol]] ** [[:Kategorî:Kontrola maneyê]] Ev madde bi botê hatine çêkirin, yek bi yek divê werin kontrolkirin. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) = Şablon = == IPA == * {{ş|IPA}} divê [[Modul:IPA]] bi kar bîne. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Deng == Kurdîkirina belgekirina {{ş|deng}} lazim e.--[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 00:06, 19 tîrmeh 2026 (UTC) = Modul = == Modul:form of/templates == * [[Modul:form of/templates]]: Divê ev modul were rojanekirin û xeletiyên berê wekî ([[hevalê]]) werin rastkirin. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Modul:columns == * [[Modul:columns]] were rojanekirin û {{ş|kol3}} bila lînka ''nîşan bide'' deyne beriya sernavê, kolê di qutiya rengî de bila nebe. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Modul:etymon == * [[Modul:etymon kevn]]: Rojanekirin hewce ye. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) = Javascript = == [[Mediawiki:Gadget-citoid-helper.js]] == Ji bo bi citoidê kopîkirina malûmatên çavkaniyan amûreke wisa lazim e. Xisûsen ji ber ku bi çend amûrên din dikare were bikaranîn. * [[Bikarhêner:Wikihez/skrîpt/js/Gadget-citoid-helper.js]] --> [[Mediawiki:Gadget-citoid-helper.js]] Feqat çend problem hene, şablonên me de kêmasiya parametreyan gelek in û xerîteyên citoidê hîn nehatine çêkirin. Wana sererast bikin dûre vê amûrê çêkin, piştre [[MediaWiki:Gadget-start.js|start.js]] û [[MediaWiki:Gadget-wikt.add-examples.js|add examples.js]] were rojanekirin. - --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 00:04, 19 tîrmeh 2026 (UTC) == [[MediaWiki:Gadget-aWa.js]] == Divê were rojanekirin ji bo ku di mobîlê de jî bixebite.[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 19:59, 17 tîrmeh 2026 (UTC) : Ez dibêjim çêbû lê bila hinekî din test bikim dûre em bar bikin: * [[Bikarhêner:Wikihez/Gadget-aWa.css]] --> [[MediaWiki:Gadget-aWa.css]] * [[Bikarhêner:Wikihez/Gadget-aWa.js]] --> [[MediaWiki:Gadget-aWa.js]] --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 22:04, 17 tîrmeh 2026 (UTC) :Min formata [[WF:Xebat]] wisa kir ku li [[WF:Xebat/arşîv 1]] arşîv bike lê niha dibêjim bila li gotûbêja sayfeyên xwe were zêde kirin wê baştir be. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 00:11, 19 tîrmeh 2026 (UTC) ::Lînkek li gotûbêja sayfeya eleqedar were dayîn bes e, wekî din li arşîv 1 were qeydkirin qet nebe dîtina wan hêsantir be. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 00:27, 19 tîrmeh 2026 (UTC) :::Ev jî çêbû. {{r|Bikarhêner}} dikarî rûpelên jêr kopî paste bikî? * [[Bikarhêner:Wikihez/Gadget-aWa.css]] --> [[MediaWiki:Gadget-aWa.css]] * [[Bikarhêner:Wikihez/Gadget-aWa.js]] --> [[MediaWiki:Gadget-aWa.js]] --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 17:02, 19 tîrmeh 2026 (UTC) == [[MediaWiki:Gadget-start.js]] == Rojanekirin hewce ye. Min gelek tişt lê zêde kir lê ez niha test dikime. Piştre em bar bikin: * [[Bikarhêner:Wikihez/Gadget-start.js]] --> [[MediaWiki:Gadget-start.js]] * [[Bikarhêner:Wikihez/Gadget-start.css]] --> [[MediaWiki:Gadget-start.css]] --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 22:08, 17 tîrmeh 2026 (UTC) :Min [[MediaWiki:Gadget-start.js/data.json|data.json]] çêkir ji bo ku bi hêsanî malûmatên heyî werin guhartin bêyî guhartina Javascriptê. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 19:49, 18 tîrmeh 2026 (UTC) :Xeletiyên ku ji bîr nekim rast bikim: :* Wextê min çavkanî "kitêb" hilbijart û bi destî tije kir xeletiyeke [https://ku.wiktionary.org/w/index.php?title=xezete&diff=prev&oldid=6265392 wisa] derket her kelîme hate lînkkirin. :* <code>html("⠿")</code> ev ne lazim e. :* textarea ji bo çavkaniyên jêgirtinan xaseten yên sernav hîn jî ne draggable e. :* pêşdîtina zindî checkbox wextê tê rakirin, pêşdîtin winda nabe. :* Butona mobîlê ya vekirina formê di moda tarî de belî nabe, tenê wekî qutiyeke tarî xuya dibe. :* Metna hişyarkirinê di guhartina rûpelên heyî de lazim e baştir bikim. :[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 23:51, 18 tîrmeh 2026 (UTC) ::Ev problem çêbûn, ez ê binêrim ka çi problemên din hene. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 14:15, 19 tîrmeh 2026 (UTC) :::Çêke: Ji bo qismê çavkaniyê yek dikare API call û Kategorî:Çavkanî bi kar bîne ji bo ku şablon zêde bikî ji yên heyî. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 21:21, 19 tîrmeh 2026 (UTC) == [[Mediawiki:Gadget-QQ.js]] == Ev amûr di şikle Minerva de. Her daîm vê xeletiyê dide: <syntaxhighlight lang="js"> TypeError: Cannot read properties of null (reading 'addEventListener') at css () at runScript () at Array.<anonymous> () at flushCssBuffer () </syntaxhighlight> [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 19:29, 18 tîrmeh 2026 (UTC) :* [[Bikarhêner:Wikihez/skrîpt/js/Gadget-QQ.js]] --> [[Mediawiki:Gadget-QQ.js]] :* [[Bikarhêner:Wikihez/Gadget-QQ.css]] --> [[Mediawiki:Gadget-QQ.css]] :Ez dibêjim çêbû lê ka çend roj biceribînim. Tiştên ku hatin sererastkirin: :# Google Books API Key dikarî zêde bikî, dixe cookies û di gerokê de dimîne. Berê bê API Key dixebitiya lê êdî mecbûr e ku API Key-a te hebe, bidestxistina wê ne zêde zor e lê dîsa jî tevlihev e. :# Êdî di mobîlê de dixebite, heta di mobîlê de xweştir xuya dike. :# Moda tarî :# OOUI dewsa jquery.ui :# Li qutiyê çi dixwazî zêde bikî, dikare li gorî îsm, sifet, fiîl bitewîne. Lê ji bo fiîl tenê dikare çend heb inflection bîne. :# Butona paqij bike lê zêde kir. :# Çend paqijiyên jêgirtinên Google Kitêbê niha hene. :[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 23:38, 18 tîrmeh 2026 (UTC) == [[MediaWiki:Gadget-wikt.add-examples.js]] == Min ev amûr hinek rojane kir feqat çend problem hene berî ku bar bikin. Tiştên ku min guhart: # Êdî li sayfeyên bi {{ş|maneid}} jî dixebite, # Cihê di wîkîtekstê de yê ku jêgirtin were îlawekirin baştir bû, # [[Mediawiki:Gadget-citoid-helper.js|citoid helper]] zêde kir ji bo ku bi hêsanî çavkanî bi riya doi, isbn an urlyê werin tijîkirin. * [[Bikarhêner:Wikihez/Gadget-wikt.add-examples.css]] --> [[MediaWiki:Gadget-wikt.add-examples.css]] * [[Bikarhêner:Wikihez/Gadget-wikt.add-examples.js]] --> [[MediaWiki:Gadget-wikt.add-examples.js]] - --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 00:50, 19 tîrmeh 2026 (UTC) == Gadget-translation editor == * [[MediaWiki:Gadget-translation editor.js]]: divê formata en.wîktê were bikaranîn ji ber ku me gelek tercime ji en.wîktê kopî kir û ev js hîn nikare formata wekî li jêr bi kar bîne. <syntaxhighlight lang="wikitext"> * {{Z|sh}}: *: Kirîlî: *: Latînî </syntaxhighlight> —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Gadget-linkify == * [[Mediawiki:Gadget-linkify.js]] ''rûpeleke'' wekî<syntaxhighlight lang="wikitext">[[rûpeleke]]</syntaxhighlight> lînk dike, bi regexê belkî dikare wisa bike <syntaxhighlight lang="wikitext">[[rûpel]]eke</syntaxhighlight> —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Gadget-herf guhartin == * Amûreke din wekî [[Mediawiki:Gadget-linkify.js|linkify]] lazim e ku herfên mezin biçûk bike ji bo kurmancî.—[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) = Moda tarî = == MediaWiki:Newarticletext == * [[MediaWiki:Newarticletext]]: Divê rengên wê were rastkirin.—[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Modul:dara kategoriyan == * [[Modul:dara kategoriyan]] link_box —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == mane? == * {{ş|mane?}} —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == bêçavkanî == * {{ş|bêçavkanî}} —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == de-tew-nerm-ern == * {{ş|de-tew-nerm-ern}} —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) = Bot = Karên ku bi botê werin çêkirin ji kerema xwe li vir binivîsin. == Kategorî:Biwêj == [[:Kategorî:Biwêj]] divê were paqijkirin, lîsteya madeyên {{ş|biwêj}} çêke, yên ku tê de bûn, kirin, man hene filtre bike yên din bi destî tê çêkirin.—[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Jêgirtin == Xistina jêgirtinên beşa [https://ku.wiktionary.org/w/index.php?search=insource%3A%2F%3D+*Ji+%5BWw%5D%C3%AAjey%C3%AA+*%3D%2F&title=Taybet%3AL%C3%AAger%C3%AEn&profile=advanced&fulltext=1&ns0=1&searchToken=8rh0bmw8dccsi7aynl6zli8uf ji wêjeyê] li beşa maneyê. —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Bota Toolforgeê == Botekî Toolforgeê lazim e ji bo ku xeletiyên biçûk wekî şablonên bi navên îngilîzî werin kurdîkirin yan jî valahiya beşan rast bike û hwd.—[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == Updatew == Bota [[Bikarhêner:Wikihez/skrîpt/py/updateW.py|updateW]] divê were rojanekirin. Yan jî yekî nû were çêkirin. Şablonên {{ş|W}} di beşa tercimeyan de sererast dike û zimanan rêz dike. Ya niha xeletiya navê zimanî dide.—[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) == sihir --> sêhr == Tercimeyên ''[[sêhr]]'' hemû dibêje ''sihir'' loma bi botê lazim e kirin ''sêhr''. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 17:43, 18 tîrmeh 2026 (UTC) :Sihirbaz --> sêhrbaz [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:07, 18 tîrmeh 2026 (UTC) == Tercimeyên dîroknas == Li tercimeyên [[dîroknas]], hevmaneyên wê hewce ye were îlawekirin. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:44, 18 tîrmeh 2026 (UTC) == Sererastkirina formata xwestina nimûneyan == <syntaxhighlight lang="wikitext">#: {{mînak?|ku}}</syntaxhighlight> bike <syntaxhighlight lang="wikitext">#* {{bênimûne|ku}}</syntaxhighlight> [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 01:06, 19 tîrmeh 2026 (UTC) == Mewlûd == Sererastkirina jêgirtinên mewlûdê [https://ku.wiktionary.org/w/index.php?search=insource%3A%2Fw%5C%3AMela+His%C3%AAn%C3%AA+Batey%C3%AE%2F&title=Taybet%3AL%C3%AAger%C3%AEn&ns0=1&searchToken=8m0tguy3sqt7edr4sg0u8hedo] wekî [https://ku.wiktionary.org/w/index.php?title=dax%C3%AEdar&curid=284303&diff=6265851&oldid=6142285] [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 09:43, 20 tîrmeh 2026 (UTC) 7uxddjbvpwk87v2p9bfjwrv0luccapu Wîkîferheng:ceribandin/nimûne 4 1357865 6265632 6251171 2026-07-19T19:18:29Z Wikihez 7344 /* */ bi [[MediaWiki:Gadget-AjaxEdit.js|AjaxEdit]]ê re 6265632 wikitext text/x-wiki {{/vê rêzê neguhêre}} == {{ziman|ku}} == === Bilêvkirin === * {{ku-IPA}} * {{ku-kîte}} === Lêker === [[Wêne:Example.jpg|thumb|Mînak]] {{lêker|ku|c=h-gh}} # Maneya 1ê. #: {{mk|ku|'''Nimûneyeke''' bikaranînê ya vê peyvê.}} #* {{bênimûne|ku}} # {{mane?|ku}} #* {{jêder-pirtûk|ku|jêgirtin=Jêgirtinek ji kitêbekê.|nivîskar=Rojen Barnas|sernav=Sîlvan/ Silîvan / FARQÎN|dîrok=2013|weşandxane=Nûbihar|rûpel=189|isbn= 9786055402884, 6055402882}} #* {{jêder-websîte|ku|nivîskar=Gazete Duvar|sernav=Şairê dubeytan: Baba Tahirê Uryan|websîte=https://www.gazeteduvar.com.tr/saire-dubeytan-baba-tahire-uryan-haber-1753893|url=https://www.gazeteduvar.com.tr/saire-dubeytan-baba-tahire-uryan-haber-1753893|sal=2025|tarîx=2025-02-02|jêgirtin=adfasdf}} # Maneya 3an. ==== Bikaranîn ==== ''Çend not li ser bikaranîna peyvê.'' ==== Jê ==== {{kol3|ku|cure=Jê |ceribandinvan }} ==== Têkildar ==== * ''Peyvên ku têkiliya [[etîmolojîk]] bi peyvê re hene''. === Etîmolojî === ''Çîroka tarîxî ya eslê kelîmeyê. Nimûneya bandor'': Ji {{deyn|ota|ku|باندره}}, {{q|ota|باكدیره}}, ({{hv|tr|bandıra}}) ji {{ji|vec|ku|bandéra}} ({{hv|it|bandiera}}) ji {{ji|gem|ku}} *''bandwa-'' ({{cotreh|ku|band|bend}}). Bide ber {{hv|fr|bandière}} (wek {{hv|en|banner}}), {{hv|el|παντιέρα}}. ==== Binêre herwiha ==== * ''Peyvên eleqadar lê belê têkiliya etîmolojîk nîne''. * {{wpedî}} ==== Werger ==== {{werger-ser|1|Maneya 1ê}} * {{Z|en}}: {{W+|en|word}} {{werger-bin}} {{werger-ser|2|Maneya an}} {{werger-bin}} {{werger-bnr|Maneya 3an|kelîme}} === Navdêr === {{ku-tewîn-nav|mînak|mê}} {{navdêr|ku|z=m}} # mane 1 #: mînak 1-1 #: mînak 1-2 #* jêgirtin 1-1 #* jêgirtin 1-2 # mane 2 #: mînak 2-1 #: mînak 2-2 #* jêgirtin 2-1 #* jêgirtin 2-2 # mane 3 ==== Werger ==== {{werger-ser|1|Maneya 1ê}} {{werger-bin}} {{werger-ser|2|Maneya 2an}} {{werger-bin}} {{werger-ser|3|Maneya 3an}} {{werger-bin}} === Çavkanî === {{Çavkanî}} * Çavkaniyên din li vir binivîse. ojhkyoptjbd6q4lcv3awwrdgot0np9m 6265633 6265632 2026-07-19T19:18:38Z Wikihez 7344 /* */ bi [[MediaWiki:Gadget-AjaxEdit.js|AjaxEdit]]ê re 6265633 wikitext text/x-wiki {{/vê rêzê neguhêre}} == {{ziman|ku}} == === Bilêvkirin === * {{ku-IPA}} * {{ku-kîte}} === Lêker === [[Wêne:Example.jpg|thumb|Mînak]] {{lêker|ku|c=h-gh}} # Maneya 1ê. #: {{mk|ku|'''Nimûneyeke''' bikaranînê ya vê peyvê.}} #* {{bênimûne|ku}} # {{ceribandin|ku}} #* {{jêder-pirtûk|ku|jêgirtin=Jêgirtinek ji kitêbekê.|nivîskar=Rojen Barnas|sernav=Sîlvan/ Silîvan / FARQÎN|dîrok=2013|weşandxane=Nûbihar|rûpel=189|isbn= 9786055402884, 6055402882}} #* {{jêder-websîte|ku|nivîskar=Gazete Duvar|sernav=Şairê dubeytan: Baba Tahirê Uryan|websîte=https://www.gazeteduvar.com.tr/saire-dubeytan-baba-tahire-uryan-haber-1753893|url=https://www.gazeteduvar.com.tr/saire-dubeytan-baba-tahire-uryan-haber-1753893|sal=2025|tarîx=2025-02-02|jêgirtin=adfasdf}} # Maneya 3an. ==== Bikaranîn ==== ''Çend not li ser bikaranîna peyvê.'' ==== Jê ==== {{kol3|ku|cure=Jê |ceribandinvan }} ==== Têkildar ==== * ''Peyvên ku têkiliya [[etîmolojîk]] bi peyvê re hene''. === Etîmolojî === ''Çîroka tarîxî ya eslê kelîmeyê. Nimûneya bandor'': Ji {{deyn|ota|ku|باندره}}, {{q|ota|باكدیره}}, ({{hv|tr|bandıra}}) ji {{ji|vec|ku|bandéra}} ({{hv|it|bandiera}}) ji {{ji|gem|ku}} *''bandwa-'' ({{cotreh|ku|band|bend}}). Bide ber {{hv|fr|bandière}} (wek {{hv|en|banner}}), {{hv|el|παντιέρα}}. ==== Binêre herwiha ==== * ''Peyvên eleqadar lê belê têkiliya etîmolojîk nîne''. * {{wpedî}} ==== Werger ==== {{werger-ser|1|Maneya 1ê}} * {{Z|en}}: {{W+|en|word}} {{werger-bin}} {{werger-ser|2|Maneya an}} {{werger-bin}} {{werger-bnr|Maneya 3an|kelîme}} === Navdêr === {{ku-tewîn-nav|mînak|mê}} {{navdêr|ku|z=m}} # mane 1 #: mînak 1-1 #: mînak 1-2 #* jêgirtin 1-1 #* jêgirtin 1-2 # mane 2 #: mînak 2-1 #: mînak 2-2 #* jêgirtin 2-1 #* jêgirtin 2-2 # mane 3 ==== Werger ==== {{werger-ser|1|Maneya 1ê}} {{werger-bin}} {{werger-ser|2|Maneya 2an}} {{werger-bin}} {{werger-ser|3|Maneya 3an}} {{werger-bin}} === Çavkanî === {{Çavkanî}} * Çavkaniyên din li vir binivîse. 3dss0vb2pixq78rem59o1kpmyy7rutl 6265634 6265633 2026-07-19T19:18:47Z Wikihez 7344 /* */ bi [[MediaWiki:Gadget-AjaxEdit.js|AjaxEdit]]ê re 6265634 wikitext text/x-wiki {{/vê rêzê neguhêre}} == {{ziman|ku}} == === Bilêvkirin === * {{ku-IPA}} * {{ku-kîte}} === Lêker === [[Wêne:Example.jpg|thumb|Mînak]] {{lêker|ku|c=h-gh}} # Maneya 1ê. #: {{mk|ku|'''Nimûneyeke''' bikaranînê ya vê peyvê.}} #* {{bênimûne|ku}} # {{ceribandin2|ku}} #* {{jêder-pirtûk|ku|jêgirtin=Jêgirtinek ji kitêbekê.|nivîskar=Rojen Barnas|sernav=Sîlvan/ Silîvan / FARQÎN|dîrok=2013|weşandxane=Nûbihar|rûpel=189|isbn= 9786055402884, 6055402882}} #* {{jêder-websîte|ku|nivîskar=Gazete Duvar|sernav=Şairê dubeytan: Baba Tahirê Uryan|websîte=https://www.gazeteduvar.com.tr/saire-dubeytan-baba-tahire-uryan-haber-1753893|url=https://www.gazeteduvar.com.tr/saire-dubeytan-baba-tahire-uryan-haber-1753893|sal=2025|tarîx=2025-02-02|jêgirtin=adfasdf}} # Maneya 3an. ==== Bikaranîn ==== ''Çend not li ser bikaranîna peyvê.'' ==== Jê ==== {{kol3|ku|cure=Jê |ceribandinvan }} ==== Têkildar ==== * ''Peyvên ku têkiliya [[etîmolojîk]] bi peyvê re hene''. === Etîmolojî === ''Çîroka tarîxî ya eslê kelîmeyê. Nimûneya bandor'': Ji {{deyn|ota|ku|باندره}}, {{q|ota|باكدیره}}, ({{hv|tr|bandıra}}) ji {{ji|vec|ku|bandéra}} ({{hv|it|bandiera}}) ji {{ji|gem|ku}} *''bandwa-'' ({{cotreh|ku|band|bend}}). Bide ber {{hv|fr|bandière}} (wek {{hv|en|banner}}), {{hv|el|παντιέρα}}. ==== Binêre herwiha ==== * ''Peyvên eleqadar lê belê têkiliya etîmolojîk nîne''. * {{wpedî}} ==== Werger ==== {{werger-ser|1|Maneya 1ê}} * {{Z|en}}: {{W+|en|word}} {{werger-bin}} {{werger-ser|2|Maneya an}} {{werger-bin}} {{werger-bnr|Maneya 3an|kelîme}} === Navdêr === {{ku-tewîn-nav|mînak|mê}} {{navdêr|ku|z=m}} # mane 1 #: mînak 1-1 #: mînak 1-2 #* jêgirtin 1-1 #* jêgirtin 1-2 # mane 2 #: mînak 2-1 #: mînak 2-2 #* jêgirtin 2-1 #* jêgirtin 2-2 # mane 3 ==== Werger ==== {{werger-ser|1|Maneya 1ê}} {{werger-bin}} {{werger-ser|2|Maneya 2an}} {{werger-bin}} {{werger-ser|3|Maneya 3an}} {{werger-bin}} === Çavkanî === {{Çavkanî}} * Çavkaniyên din li vir binivîse. on4ylt1q9ugmt6rlfayuhmoo8imtqp6 6265638 6265634 2026-07-19T19:35:31Z Wikihez 7344 pênase hat temamkirin bi amûra « [[Mediawiki:Gadget-wikt.fill-definition|Pênaseyê temam bike]] » (v1.0). 6265638 wikitext text/x-wiki {{/vê rêzê neguhêre}} == {{ziman|ku}} == === Bilêvkirin === * {{ku-IPA}} * {{ku-kîte}} === Lêker === [[Wêne:Example.jpg|thumb|Mînak]] {{lêker|ku|c=h-gh}} # Maneya 1ê. #: {{mk|ku|'''Nimûneyeke''' bikaranînê ya vê peyvê.}} #* {{bênimûne|ku}} # [[test dikim]] [[ka]] [[ev]] [[çi]] [[îş dike]] #* {{jêder-pirtûk|ku|jêgirtin=Jêgirtinek ji kitêbekê.|nivîskar=Rojen Barnas|sernav=Sîlvan/ Silîvan / FARQÎN|dîrok=2013|weşandxane=Nûbihar|rûpel=189|isbn= 9786055402884, 6055402882}} #* {{jêder-websîte|ku|nivîskar=Gazete Duvar|sernav=Şairê dubeytan: Baba Tahirê Uryan|websîte=https://www.gazeteduvar.com.tr/saire-dubeytan-baba-tahire-uryan-haber-1753893|url=https://www.gazeteduvar.com.tr/saire-dubeytan-baba-tahire-uryan-haber-1753893|sal=2025|tarîx=2025-02-02|jêgirtin=adfasdf}} # Maneya 3an. ==== Bikaranîn ==== ''Çend not li ser bikaranîna peyvê.'' ==== Jê ==== {{kol3|ku|cure=Jê |ceribandinvan }} ==== Têkildar ==== * ''Peyvên ku têkiliya [[etîmolojîk]] bi peyvê re hene''. === Etîmolojî === ''Çîroka tarîxî ya eslê kelîmeyê. Nimûneya bandor'': Ji {{deyn|ota|ku|باندره}}, {{q|ota|باكدیره}}, ({{hv|tr|bandıra}}) ji {{ji|vec|ku|bandéra}} ({{hv|it|bandiera}}) ji {{ji|gem|ku}} *''bandwa-'' ({{cotreh|ku|band|bend}}). Bide ber {{hv|fr|bandière}} (wek {{hv|en|banner}}), {{hv|el|παντιέρα}}. ==== Binêre herwiha ==== * ''Peyvên eleqadar lê belê têkiliya etîmolojîk nîne''. * {{wpedî}} ==== Werger ==== {{werger-ser|1|Maneya 1ê}} * {{Z|en}}: {{W+|en|word}} {{werger-bin}} {{werger-ser|2|Maneya an}} {{werger-bin}} {{werger-bnr|Maneya 3an|kelîme}} === Navdêr === {{ku-tewîn-nav|mînak|mê}} {{navdêr|ku|z=m}} # mane 1 #: mînak 1-1 #: mînak 1-2 #* jêgirtin 1-1 #* jêgirtin 1-2 # mane 2 #: mînak 2-1 #: mînak 2-2 #* jêgirtin 2-1 #* jêgirtin 2-2 # mane 3 ==== Werger ==== {{werger-ser|1|Maneya 1ê}} {{werger-bin}} {{werger-ser|2|Maneya 2an}} {{werger-bin}} {{werger-ser|3|Maneya 3an}} {{werger-bin}} === Çavkanî === {{Çavkanî}} * Çavkaniyên din li vir binivîse. ghuiwtv7bme3i0io7j3wyo8aw76dlle 6265639 6265638 2026-07-19T19:36:34Z Wikihez 7344 /* */ bi [[MediaWiki:Gadget-AjaxEdit.js|AjaxEdit]]ê re 6265639 wikitext text/x-wiki {{/vê rêzê neguhêre}} == {{ziman|ku}} == === Bilêvkirin === * {{ku-IPA}} * {{ku-kîte}} === Lêker === [[Wêne:Example.jpg|thumb|Mînak]] {{lêker|ku|c=h-gh}} # Maneya 1ê. #: {{mk|ku|'''Nimûneyeke''' bikaranînê ya vê peyvê.}} #* {{bênimûne|ku}} # {{ceribandin2|ku}} #* {{jêder-pirtûk|ku|jêgirtin=Jêgirtinek ji kitêbekê.|nivîskar=Rojen Barnas|sernav=Sîlvan/ Silîvan / FARQÎN|dîrok=2013|weşandxane=Nûbihar|rûpel=189|isbn= 9786055402884, 6055402882}} #* {{jêder-websîte|ku|nivîskar=Gazete Duvar|sernav=Şairê dubeytan: Baba Tahirê Uryan|websîte=https://www.gazeteduvar.com.tr/saire-dubeytan-baba-tahire-uryan-haber-1753893|url=https://www.gazeteduvar.com.tr/saire-dubeytan-baba-tahire-uryan-haber-1753893|sal=2025|tarîx=2025-02-02|jêgirtin=adfasdf}} # Maneya 3an. ==== Bikaranîn ==== ''Çend not li ser bikaranîna peyvê.'' ==== Jê ==== {{kol3|ku|cure=Jê |ceribandinvan }} ==== Têkildar ==== * ''Peyvên ku têkiliya [[etîmolojîk]] bi peyvê re hene''. === Etîmolojî === ''Çîroka tarîxî ya eslê kelîmeyê. Nimûneya bandor'': Ji {{deyn|ota|ku|باندره}}, {{q|ota|باكدیره}}, ({{hv|tr|bandıra}}) ji {{ji|vec|ku|bandéra}} ({{hv|it|bandiera}}) ji {{ji|gem|ku}} *''bandwa-'' ({{cotreh|ku|band|bend}}). Bide ber {{hv|fr|bandière}} (wek {{hv|en|banner}}), {{hv|el|παντιέρα}}. ==== Binêre herwiha ==== * ''Peyvên eleqadar lê belê têkiliya etîmolojîk nîne''. * {{wpedî}} ==== Werger ==== {{werger-ser|1|Maneya 1ê}} * {{Z|en}}: {{W+|en|word}} {{werger-bin}} {{werger-ser|2|Maneya an}} {{werger-bin}} {{werger-bnr|Maneya 3an|kelîme}} === Navdêr === {{ku-tewîn-nav|mînak|mê}} {{navdêr|ku|z=m}} # mane 1 #: mînak 1-1 #: mînak 1-2 #* jêgirtin 1-1 #* jêgirtin 1-2 # mane 2 #: mînak 2-1 #: mînak 2-2 #* jêgirtin 2-1 #* jêgirtin 2-2 # mane 3 ==== Werger ==== {{werger-ser|1|Maneya 1ê}} {{werger-bin}} {{werger-ser|2|Maneya 2an}} {{werger-bin}} {{werger-ser|3|Maneya 3an}} {{werger-bin}} === Çavkanî === {{Çavkanî}} * Çavkaniyên din li vir binivîse. on4ylt1q9ugmt6rlfayuhmoo8imtqp6 6265640 6265639 2026-07-19T19:37:08Z Wikihez 7344 +nimûneya bikaranînê bi amûra « [[Mediawiki:Gadget-wikt.add-examples|Nimûne zêde bike]] » (v1.7). 6265640 wikitext text/x-wiki {{/vê rêzê neguhêre}} == {{ziman|ku}} == === Bilêvkirin === * {{ku-IPA}} * {{ku-kîte}} === Lêker === [[Wêne:Example.jpg|thumb|Mînak]] {{lêker|ku|c=h-gh}} # Maneya 1ê. #: {{mk|ku|'''Nimûneyeke''' bikaranînê ya vê peyvê.}} #* {{bênimûne|ku}} # {{ceribandin2|ku}} #* {{jêder-pirtûk|ku|jêgirtin=Jêgirtinek ji kitêbekê.|nivîskar=Rojen Barnas|sernav=Sîlvan/ Silîvan / FARQÎN|dîrok=2013|weşandxane=Nûbihar|rûpel=189|isbn= 9786055402884, 6055402882}} #* {{jêder-websîte|ku|nivîskar=Gazete Duvar|sernav=Şairê dubeytan: Baba Tahirê Uryan|websîte=https://www.gazeteduvar.com.tr/saire-dubeytan-baba-tahire-uryan-haber-1753893|url=https://www.gazeteduvar.com.tr/saire-dubeytan-baba-tahire-uryan-haber-1753893|sal=2025|tarîx=2025-02-02|jêgirtin=adfasdf}} #* {{jêder-kitêb|ku|sernav=Shamdinani Stories I|weşanxane=Brill|sal=2026|isbn=978-90-04-75443-0|url=https://brill.com/edcollbook-oa/title/74006|jêgirtin=test}} # Maneya 3an. ==== Bikaranîn ==== ''Çend not li ser bikaranîna peyvê.'' ==== Jê ==== {{kol3|ku|cure=Jê |ceribandinvan }} ==== Têkildar ==== * ''Peyvên ku têkiliya [[etîmolojîk]] bi peyvê re hene''. === Etîmolojî === ''Çîroka tarîxî ya eslê kelîmeyê. Nimûneya bandor'': Ji {{deyn|ota|ku|باندره}}, {{q|ota|باكدیره}}, ({{hv|tr|bandıra}}) ji {{ji|vec|ku|bandéra}} ({{hv|it|bandiera}}) ji {{ji|gem|ku}} *''bandwa-'' ({{cotreh|ku|band|bend}}). Bide ber {{hv|fr|bandière}} (wek {{hv|en|banner}}), {{hv|el|παντιέρα}}. ==== Binêre herwiha ==== * ''Peyvên eleqadar lê belê têkiliya etîmolojîk nîne''. * {{wpedî}} ==== Werger ==== {{werger-ser|1|Maneya 1ê}} * {{Z|en}}: {{W+|en|word}} {{werger-bin}} {{werger-ser|2|Maneya an}} {{werger-bin}} {{werger-bnr|Maneya 3an|kelîme}} === Navdêr === {{ku-tewîn-nav|mînak|mê}} {{navdêr|ku|z=m}} # mane 1 #: mînak 1-1 #: mînak 1-2 #* jêgirtin 1-1 #* jêgirtin 1-2 # mane 2 #: mînak 2-1 #: mînak 2-2 #* jêgirtin 2-1 #* jêgirtin 2-2 # mane 3 ==== Werger ==== {{werger-ser|1|Maneya 1ê}} {{werger-bin}} {{werger-ser|2|Maneya 2an}} {{werger-bin}} {{werger-ser|3|Maneya 3an}} {{werger-bin}} === Çavkanî === {{Çavkanî}} * Çavkaniyên din li vir binivîse. m4ewqxx7sbk4mgbjlwaqucolkirewsr 6265641 6265640 2026-07-19T19:37:24Z Wikihez 7344 pênase hat temamkirin bi amûra « [[Mediawiki:Gadget-wikt.fill-definition|Pênaseyê temam bike]] » (v1.0). 6265641 wikitext text/x-wiki {{/vê rêzê neguhêre}} == {{ziman|ku}} == === Bilêvkirin === * {{ku-IPA}} * {{ku-kîte}} === Lêker === [[Wêne:Example.jpg|thumb|Mînak]] {{lêker|ku|c=h-gh}} # Maneya 1ê. #: {{mk|ku|'''Nimûneyeke''' bikaranînê ya vê peyvê.}} #* {{bênimûne|ku}} # [[test]] #* {{jêder-pirtûk|ku|jêgirtin=Jêgirtinek ji kitêbekê.|nivîskar=Rojen Barnas|sernav=Sîlvan/ Silîvan / FARQÎN|dîrok=2013|weşandxane=Nûbihar|rûpel=189|isbn= 9786055402884, 6055402882}} #* {{jêder-websîte|ku|nivîskar=Gazete Duvar|sernav=Şairê dubeytan: Baba Tahirê Uryan|websîte=https://www.gazeteduvar.com.tr/saire-dubeytan-baba-tahire-uryan-haber-1753893|url=https://www.gazeteduvar.com.tr/saire-dubeytan-baba-tahire-uryan-haber-1753893|sal=2025|tarîx=2025-02-02|jêgirtin=adfasdf}} #* {{jêder-kitêb|ku|sernav=Shamdinani Stories I|weşanxane=Brill|sal=2026|isbn=978-90-04-75443-0|url=https://brill.com/edcollbook-oa/title/74006|jêgirtin=test}} # Maneya 3an. ==== Bikaranîn ==== ''Çend not li ser bikaranîna peyvê.'' ==== Jê ==== {{kol3|ku|cure=Jê |ceribandinvan }} ==== Têkildar ==== * ''Peyvên ku têkiliya [[etîmolojîk]] bi peyvê re hene''. === Etîmolojî === ''Çîroka tarîxî ya eslê kelîmeyê. Nimûneya bandor'': Ji {{deyn|ota|ku|باندره}}, {{q|ota|باكدیره}}, ({{hv|tr|bandıra}}) ji {{ji|vec|ku|bandéra}} ({{hv|it|bandiera}}) ji {{ji|gem|ku}} *''bandwa-'' ({{cotreh|ku|band|bend}}). Bide ber {{hv|fr|bandière}} (wek {{hv|en|banner}}), {{hv|el|παντιέρα}}. ==== Binêre herwiha ==== * ''Peyvên eleqadar lê belê têkiliya etîmolojîk nîne''. * {{wpedî}} ==== Werger ==== {{werger-ser|1|Maneya 1ê}} * {{Z|en}}: {{W+|en|word}} {{werger-bin}} {{werger-ser|2|Maneya an}} {{werger-bin}} {{werger-bnr|Maneya 3an|kelîme}} === Navdêr === {{ku-tewîn-nav|mînak|mê}} {{navdêr|ku|z=m}} # mane 1 #: mînak 1-1 #: mînak 1-2 #* jêgirtin 1-1 #* jêgirtin 1-2 # mane 2 #: mînak 2-1 #: mînak 2-2 #* jêgirtin 2-1 #* jêgirtin 2-2 # mane 3 ==== Werger ==== {{werger-ser|1|Maneya 1ê}} {{werger-bin}} {{werger-ser|2|Maneya 2an}} {{werger-bin}} {{werger-ser|3|Maneya 3an}} {{werger-bin}} === Çavkanî === {{Çavkanî}} * Çavkaniyên din li vir binivîse. 6882jpo2avjvcid2ee0u2ropkxnlb9f 6265644 6265641 2026-07-19T19:42:54Z Wikihez 7344 /* */ bi [[MediaWiki:Gadget-AjaxEdit.js|AjaxEdit]]ê re 6265644 wikitext text/x-wiki {{/vê rêzê neguhêre}} == {{ziman|ku}} == === Bilêvkirin === * {{ku-IPA}} * {{ku-kîte}} === Lêker === [[Wêne:Example.jpg|thumb|Mînak]] {{lêker|ku|c=h-gh}} # Maneya 1ê. #: {{mk|ku|'''Nimûneyeke''' bikaranînê ya vê peyvê.}} #* {{bênimûne|ku}} # {{ceribandin2|ku}} #* {{jêder-pirtûk|ku|jêgirtin=Jêgirtinek ji kitêbekê.|nivîskar=Rojen Barnas|sernav=Sîlvan/ Silîvan / FARQÎN|dîrok=2013|weşandxane=Nûbihar|rûpel=189|isbn= 9786055402884, 6055402882}} #* {{jêder-websîte|ku|nivîskar=Gazete Duvar|sernav=Şairê dubeytan: Baba Tahirê Uryan|websîte=https://www.gazeteduvar.com.tr/saire-dubeytan-baba-tahire-uryan-haber-1753893|url=https://www.gazeteduvar.com.tr/saire-dubeytan-baba-tahire-uryan-haber-1753893|sal=2025|tarîx=2025-02-02|jêgirtin=adfasdf}} #* {{jêder-kitêb|ku|sernav=Shamdinani Stories I|weşanxane=Brill|sal=2026|isbn=978-90-04-75443-0|url=https://brill.com/edcollbook-oa/title/74006|jêgirtin=test}} # Maneya 3an. ==== Bikaranîn ==== ''Çend not li ser bikaranîna peyvê.'' ==== Jê ==== {{kol3|ku|cure=Jê |ceribandinvan }} ==== Têkildar ==== * ''Peyvên ku têkiliya [[etîmolojîk]] bi peyvê re hene''. === Etîmolojî === ''Çîroka tarîxî ya eslê kelîmeyê. Nimûneya bandor'': Ji {{deyn|ota|ku|باندره}}, {{q|ota|باكدیره}}, ({{hv|tr|bandıra}}) ji {{ji|vec|ku|bandéra}} ({{hv|it|bandiera}}) ji {{ji|gem|ku}} *''bandwa-'' ({{cotreh|ku|band|bend}}). Bide ber {{hv|fr|bandière}} (wek {{hv|en|banner}}), {{hv|el|παντιέρα}}. ==== Binêre herwiha ==== * ''Peyvên eleqadar lê belê têkiliya etîmolojîk nîne''. * {{wpedî}} ==== Werger ==== {{werger-ser|1|Maneya 1ê}} * {{Z|en}}: {{W+|en|word}} {{werger-bin}} {{werger-ser|2|Maneya an}} {{werger-bin}} {{werger-bnr|Maneya 3an|kelîme}} === Navdêr === {{ku-tewîn-nav|mînak|mê}} {{navdêr|ku|z=m}} # mane 1 #: mînak 1-1 #: mînak 1-2 #* jêgirtin 1-1 #* jêgirtin 1-2 # mane 2 #: mînak 2-1 #: mînak 2-2 #* jêgirtin 2-1 #* jêgirtin 2-2 # mane 3 ==== Werger ==== {{werger-ser|1|Maneya 1ê}} {{werger-bin}} {{werger-ser|2|Maneya 2an}} {{werger-bin}} {{werger-ser|3|Maneya 3an}} {{werger-bin}} === Çavkanî === {{Çavkanî}} * Çavkaniyên din li vir binivîse. m4ewqxx7sbk4mgbjlwaqucolkirewsr 6265645 6265644 2026-07-19T19:43:51Z Wikihez 7344 pênase hat temamkirin bi amûra « [[Mediawiki:Gadget-wikt.fill-definition|Pênaseyê temam bike]] » (v1.0). 6265645 wikitext text/x-wiki {{/vê rêzê neguhêre}} == {{ziman|ku}} == === Bilêvkirin === * {{ku-IPA}} * {{ku-kîte}} === Lêker === [[Wêne:Example.jpg|thumb|Mînak]] {{lêker|ku|c=h-gh}} # Maneya 1ê. #: {{mk|ku|'''Nimûneyeke''' bikaranînê ya vê peyvê.}} #* {{bênimûne|ku}} # [[testsdfsdafdasfas]] #* {{jêder-pirtûk|ku|jêgirtin=Jêgirtinek ji kitêbekê.|nivîskar=Rojen Barnas|sernav=Sîlvan/ Silîvan / FARQÎN|dîrok=2013|weşandxane=Nûbihar|rûpel=189|isbn= 9786055402884, 6055402882}} #* {{jêder-websîte|ku|nivîskar=Gazete Duvar|sernav=Şairê dubeytan: Baba Tahirê Uryan|websîte=https://www.gazeteduvar.com.tr/saire-dubeytan-baba-tahire-uryan-haber-1753893|url=https://www.gazeteduvar.com.tr/saire-dubeytan-baba-tahire-uryan-haber-1753893|sal=2025|tarîx=2025-02-02|jêgirtin=adfasdf}} #* {{jêder-kitêb|ku|sernav=Shamdinani Stories I|weşanxane=Brill|sal=2026|isbn=978-90-04-75443-0|url=https://brill.com/edcollbook-oa/title/74006|jêgirtin=test}} # Maneya 3an. ==== Bikaranîn ==== ''Çend not li ser bikaranîna peyvê.'' ==== Jê ==== {{kol3|ku|cure=Jê |ceribandinvan }} ==== Têkildar ==== * ''Peyvên ku têkiliya [[etîmolojîk]] bi peyvê re hene''. === Etîmolojî === ''Çîroka tarîxî ya eslê kelîmeyê. Nimûneya bandor'': Ji {{deyn|ota|ku|باندره}}, {{q|ota|باكدیره}}, ({{hv|tr|bandıra}}) ji {{ji|vec|ku|bandéra}} ({{hv|it|bandiera}}) ji {{ji|gem|ku}} *''bandwa-'' ({{cotreh|ku|band|bend}}). Bide ber {{hv|fr|bandière}} (wek {{hv|en|banner}}), {{hv|el|παντιέρα}}. ==== Binêre herwiha ==== * ''Peyvên eleqadar lê belê têkiliya etîmolojîk nîne''. * {{wpedî}} ==== Werger ==== {{werger-ser|1|Maneya 1ê}} * {{Z|en}}: {{W+|en|word}} {{werger-bin}} {{werger-ser|2|Maneya an}} {{werger-bin}} {{werger-bnr|Maneya 3an|kelîme}} === Navdêr === {{ku-tewîn-nav|mînak|mê}} {{navdêr|ku|z=m}} # mane 1 #: mînak 1-1 #: mînak 1-2 #* jêgirtin 1-1 #* jêgirtin 1-2 # mane 2 #: mînak 2-1 #: mînak 2-2 #* jêgirtin 2-1 #* jêgirtin 2-2 # mane 3 ==== Werger ==== {{werger-ser|1|Maneya 1ê}} {{werger-bin}} {{werger-ser|2|Maneya 2an}} {{werger-bin}} {{werger-ser|3|Maneya 3an}} {{werger-bin}} === Çavkanî === {{Çavkanî}} * Çavkaniyên din li vir binivîse. e75nhdouy6hhfstcv60re2zyt0y9zay Wîkîferheng:Xebat/arşîv 1 4 1357876 6265619 6265309 2026-07-19T17:00:05Z Wikihez 7344 [[MediaWiki:Gadget-aWa.js/belgekirin|aWa]]: Arşîvkirina nîqaşê ji rûpela [[Wîkîferheng:Xebat]] 6265619 wikitext text/x-wiki == Tercimeyên zel == {{arşîv-ser|xebat|archived|link=Taybet:PermanentLink/6265301#Tercimeyên_zel}} Tercimeyên [[zel]] hatine çêkirin lê "şelmaq" wekî şablon hatiye nivîsîn. Nimûne: "{{g|bg|плесница}}"—[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) :{{çêbû}} [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 21:13, 17 tîrmeh 2026 (UTC) {{arşîv-bin}} == MediaWiki:Gadget-aWa.js == {{arşîv-ser|xebat|archived|link=Taybet:PermanentLink/6265574#MediaWiki:Gadget-aWa.js}} Divê were rojanekirin ji bo ku di mobîlê de jî bixebite.[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 19:59, 17 tîrmeh 2026 (UTC) : Ez dibêjim çêbû lê bila hinekî din test bikim dûre em bar bikin: * [[Bikarhêner:Wikihez/Gadget-aWa.css]] --> [[MediaWiki:Gadget-aWa.css]] * [[Bikarhêner:Wikihez/Gadget-aWa.js]] --> [[MediaWiki:Gadget-aWa.js]] --[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 22:04, 17 tîrmeh 2026 (UTC) :Min formata [[WF:Xebat]] wisa kir ku li [[WF:Xebat/arşîv 1]] arşîv bike lê niha dibêjim bila li gotûbêja sayfeyên xwe were zêde kirin wê baştir be. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 00:11, 19 tîrmeh 2026 (UTC) ::Lînkek li gotûbêja sayfeya eleqedar were dayîn bes e, wekî din li arşîv 1 were qeydkirin qet nebe dîtina wan hêsantir be. [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 00:27, 19 tîrmeh 2026 (UTC) {{arşîv-bin}} tlgd0r4vajfkwx18axp2dlocz6q9ory 6265621 6265619 2026-07-19T17:00:51Z Wikihez 7344 Restored revision 6265309 by [[Special:Contributions/Wikihez|Wikihez]] ([[User talk:Wikihez|talk]]) ([[:m:User:Xiplus/TwinkleGlobal|TwinkleGlobal]]) 6265621 wikitext text/x-wiki == Tercimeyên zel == {{arşîv-ser|xebat|archived|link=Taybet:PermanentLink/6265301#Tercimeyên_zel}} Tercimeyên [[zel]] hatine çêkirin lê "şelmaq" wekî şablon hatiye nivîsîn. Nimûne: "{{g|bg|плесница}}"—[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 16:17, 16 tîrmeh 2026 (UTC) :{{çêbû}} [[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 21:13, 17 tîrmeh 2026 (UTC) {{arşîv-bin}} bf7t4d2pwwvriq1fsw7pg8go4xjp305 xezete 0 1357889 6265650 6265431 2026-07-19T19:58:17Z Wikihez 7344 /* Navdêr */ 6265650 wikitext text/x-wiki == {{ziman|ku}} == === Bilêvkirin === * {{ku-IPA|ẍezete}} * {{ku-kîte}} === Navdêr === {{ku-tewîn-nav|xezete|mê|guherto=hemû}} {{navdêr|ku|c=m}} # [[ew|Ew]] [[kaxizên]] [[mezin]] ên ku [[her roj]] yan [[her]] [[hefte]] [[hatin|tên]] [[çapkirin|çap kirin]] û [[tê de]] [[xeber]]ên [[dinya]]yê, [[mesele]]yên [[siyaset]]ê, [[îlan]] û [[reklam]] [[hebûn|hene]]. #: {{alt-r|ku|ẍezete|qezete|gazete}} #: {{hevmane|ku|cerîde|rojname}} #: {{nm|ku|Bavo, ji min re '''xezeteyekê''' bistîne, ez lê binêrim ka di dinyayê de çi heye çi tine ye.}} #* {{jêder-kitêb|ku|jêgirtin=Baş e, '''xezete''' dê bi çi ezmanî derkevit?|nivîskar=E. Rehmî Ji Mala Hekarîyan|amadekar=M. E. Bozarslan|sernav=Jîn: kovara Kurdî-Tirkî. Cild 1|weşanxane=Weşanxana Deng|cih=Uppsala|sala weşandinê=1985|sal=1918|rûpel=310|isbn=978-91-970702-0-1}} #* {{jêder-kitêb|ku|jêgirtin=ligor{{sic}} danezanên '''xezete''' ên Turk hezar insan li kurdistan hatin kuştin ku ji %70 jin û zaruk kal » pîrbûn|nivîskar=Hesen Hişyar Serdî|sernav=Dîtin û Bîrhatinên Min|weşanxane=Çapxana Emîral|cih=Beyrût|sal=1993|sala weşandinê=1993|rûpel=380|url=https://bnk.institutkurde.org/images/pdf/CTNPMX4FR6.pdf}} #* {{jêder-websîte|ku|jêgirtin='''Xezeteyên''' Kurdî yên li Stenbolê derdiketin bên îstisnakirin, xezeteyekî millî û wetenî yê ku yekemîn car li Kurdistanê hatîye neşirkirin, ew jî xezeteya Zarê Kirmancî ye, ku min xwendîye.|nivîskar=Seîd Veroj|sernav=Mesûd Fanî (Dr. Mesûd Fanî Bîlgîlî)|websîte=Rûpela nû|url=https://www.rupelanu.com/seid-veroj-mesud-fani-dr-mesud-fani-bilgili-17258h.htm|sal=2021|tarîx=2021-05-04}} #* {{jêder-kitêb|ku|jêgirtin=Hekayêta Betal Kirina '''Xezeta''' Hetawî Kurd|sal=2026|nivîskar=David N. MacKenzie, Ergin Öpengin|url=http://books.google.com.tr/books?id=eqvrEQAAQBAJ&pg=PA383&dq=%22wan+xezetan%22+OR+%22xezet%C3%AA%22+OR+%22xezetin%22+OR+%22xezetek%C3%AA%22+OR+%22xezeta%22+OR+%22w%C3%AA+xezet%C3%AA%22+OR+%22xezetino%22+OR+%22xezetine%22&hl=&cd=2&source=gbs_api|sernav=Shamdinani Stories I: Kurdish Writings on the History and Culture of Central Kurdistan by Mullah Saʼid Shamdinani |weşanxane=BRILL|ISBN=9789004754430|rûpel=383}} #* {{jêder-kitêb|ku|jêgirtin=me '''xezete''' da destê wî jî.|sal=2022|nivîskar=Abdurrahman Benek|url=http://books.google.com.tr/books?id=SdSUEAAAQBAJ&pg=PA33&dq=%22wan+xezetan%22+OR+%22xezet%C3%AA%22+OR+%22xezetin%22+OR+%22xezetek%C3%AA%22+OR+%22xezeta%22+OR+%22w%C3%AA+xezet%C3%AA%22+OR+%22xezetino%22+OR+%22xezetine%22&hl=&cd=3&source=gbs_api|sernav=Payiza Mezinan|weşanxane=Nûbihar|ISBN=9786059413749|rûpel=33}} ==== Jê ==== * {{g|ku|xezeteçî}} ==== Etîmolojî ==== Ji {{deyn|ota|ku|غزته|tr=ẍezete}} ji {{ji|it|ku|gazzetta}}. ==== Werger ==== {{werger-ser|kaxizên mezin ên ku her tên çapkirin|1}} * {{Z|en}}: {{W|en|newspaper}} * {{Z|tr}}: {{W|tr|gazete}} {{werger-bin}} orjcljvat4wybazon5a9ry5xrz7ejjn 6265653 6265650 2026-07-19T20:19:26Z Wikihez 7344 ? 6265653 wikitext text/x-wiki == {{ziman|ku}} == === Bilêvkirin === * {{ku-IPA|ẍezete}} * {{ku-kîte}} === Navdêr === {{ku-tewîn-nav|xezete|mê|guherto=hemû}} {{navdêr|ku|c=m}} # [[ew|Ew]] [[kaxizên]] [[mezin]] ên ku [[her roj]] yan [[her]] [[hefte]] [[hatin|tên]] [[çapkirin|çap kirin]] û [[tê de]] [[xeber]]ên [[dinya]]yê, [[mesele]]yên [[siyaset]]ê, [[îlan]] û [[reklam]] [[hebûn|hene]]. #: {{alt-r|ku|ẍezete|qezete|gazete}} #: {{hevmane|ku|cerîde|rojname}} #: {{nm|ku|Bavo, ji min re '''xezeteyekê''' bistîne, ez lê binêrim ka di dinyayê de çi heye çi tine ye.}} #* {{jêder-kitêb|ku|jêgirtin=Baş e, '''xezete''' dê bi çi ezmanî derkevit?|nivîskar=E. Rehmî Ji Mala Hekarîyan|amadekar=M. E. Bozarslan|sernav=Jîn: kovara Kurdî-Tirkî. Cild 1|weşanxane=Weşanxana Deng|cih=Uppsala|sala weşandinê=1985|sal=1918|rûpel=310|isbn=978-91-970702-0-1}} #* {{jêder-kitêb|ku|jêgirtin=ligor{{sic}} danezanên '''xezete''' ên Turk hezar insan li kurdistan hatin kuştin ku ji %&nbsp;70 jin û zaruk kal » pîrbûn|nivîskar=Hesen Hişyar Serdî|sernav=Dîtin û Bîrhatinên Min|weşanxane=Çapxana Emîral|cih=Beyrût|sal=1993|sala weşandinê=1993|rûpel=380|url=https://bnk.institutkurde.org/images/pdf/CTNPMX4FR6.pdf}} #* {{jêder-websîte|ku|jêgirtin='''Xezeteyên''' Kurdî yên li Stenbolê derdiketin bên îstisnakirin, xezeteyekî millî û wetenî yê ku yekemîn car li Kurdistanê hatîye neşirkirin, ew jî xezeteya Zarê Kirmancî ye, ku min xwendîye.|nivîskar=Seîd Veroj|sernav=Mesûd Fanî (Dr. Mesûd Fanî Bîlgîlî)|websîte=Rûpela nû|url=https://www.rupelanu.com/seid-veroj-mesud-fani-dr-mesud-fani-bilgili-17258h.htm|sal=2021|tarîx=2021-05-04}} #* {{jêder-kitêb|ku|jêgirtin=Hekayêta Betal Kirina '''Xezeta''' Hetawî Kurd|sal=2026|nivîskar=David N. MacKenzie, Ergin Öpengin|url=http://books.google.com.tr/books?id=eqvrEQAAQBAJ&pg=PA383&dq=%22wan+xezetan%22+OR+%22xezet%C3%AA%22+OR+%22xezetin%22+OR+%22xezetek%C3%AA%22+OR+%22xezeta%22+OR+%22w%C3%AA+xezet%C3%AA%22+OR+%22xezetino%22+OR+%22xezetine%22&hl=&cd=2&source=gbs_api|sernav=Shamdinani Stories I: Kurdish Writings on the History and Culture of Central Kurdistan by Mullah Saʼid Shamdinani |weşanxane=BRILL|ISBN=9789004754430|rûpel=383}} #* {{jêder-kitêb|ku|jêgirtin=me '''xezete''' da destê wî jî.|sal=2022|nivîskar=Abdurrahman Benek|url=http://books.google.com.tr/books?id=SdSUEAAAQBAJ&pg=PA33&dq=%22wan+xezetan%22+OR+%22xezet%C3%AA%22+OR+%22xezetin%22+OR+%22xezetek%C3%AA%22+OR+%22xezeta%22+OR+%22w%C3%AA+xezet%C3%AA%22+OR+%22xezetino%22+OR+%22xezetine%22&hl=&cd=3&source=gbs_api|sernav=Payiza Mezinan|weşanxane=Nûbihar|ISBN=9786059413749|rûpel=33}} ==== Jê ==== * {{g|ku|xezeteçî}} ==== Etîmolojî ==== Ji {{deyn|ota|ku|غزته|tr=ẍezete}} ji {{ji|it|ku|gazzetta}}. ==== Werger ==== {{werger-ser|kaxizên mezin ên ku her tên çapkirin|1}} * {{Z|en}}: {{W|en|newspaper}} * {{Z|tr}}: {{W|tr|gazete}} {{werger-bin}} 740i0yecd3me2c3bgzy4okmmtx3lf51 6265654 6265653 2026-07-19T20:23:48Z Wikihez 7344 6265654 wikitext text/x-wiki == {{ziman|ku}} == === Bilêvkirin === * {{ku-IPA|ẍezete}} * {{ku-kîte}} === Navdêr === {{ku-tewîn-nav|xezete|mê|guherto=hemû}} {{navdêr|ku|c=m}} # [[ew|Ew]] [[kaxizên]] [[mezin]] ên ku [[her roj]] yan [[her]] [[hefte]] [[hatin|tên]] [[çapkirin|çap kirin]] û [[tê de]] [[xeber]]ên [[dinya]]yê, [[mesele]]yên [[siyaset]]ê, [[îlan]] û [[reklam]] [[hebûn|hene]]. #: {{alt-r|ku|ẍezete|qezete|gazete}} #: {{hevmane|ku|cerîde|rojname}} #: {{nm|ku|Bavo, ji min re '''xezeteyekê''' bistîne, ez lê binêrim ka di dinyayê de çi heye çi tine ye.}} #* {{jêder-kitêb|ku|jêgirtin=Baş e, '''xezete''' dê bi çi ezmanî derkevit?|nivîskar=E. Rehmî Ji Mala Hekarîyan|amadekar=M. E. Bozarslan|sernav=Jîn: kovara Kurdî-Tirkî. Cild 1|weşanxane=Weşanxana Deng|cih=Uppsala|sala weşandinê=1985|sal=1918|rûpel=310|isbn=978-91-970702-0-1}} #* {{jêder-kitêb|ku|jêgirtin=ligor{{sic}} danezanên '''xezete''' ên Turk hezar insan li kurdistan hatin kuştin ku ji %70 jin û zaruk kal » pîrbûn|nivîskar=Hesen Hişyar Serdî|sernav=Dîtin û Bîrhatinên Min|weşanxane=Çapxana Emîral|cih=Beyrût|sal=1993|sala weşandinê=1993|rûpel=380|url=https://bnk.institutkurde.org/images/pdf/CTNPMX4FR6.pdf}} #* {{jêder-websîte|ku|jêgirtin='''Xezeteyên''' Kurdî yên li Stenbolê derdiketin bên îstisnakirin, xezeteyekî millî û wetenî yê ku yekemîn car li Kurdistanê hatîye neşirkirin, ew jî xezeteya Zarê Kirmancî ye, ku min xwendîye.|nivîskar=Seîd Veroj|sernav=Mesûd Fanî (Dr. Mesûd Fanî Bîlgîlî)|websîte=Rûpela nû|url=https://www.rupelanu.com/seid-veroj-mesud-fani-dr-mesud-fani-bilgili-17258h.htm|sal=2021|tarîx=2021-05-04}} #* {{jêder-kitêb|ku|jêgirtin=Hekayêta Betal Kirina '''Xezeta''' Hetawî Kurd|sal=2026|nivîskar=David N. MacKenzie, Ergin Öpengin|url=http://books.google.com.tr/books?id=eqvrEQAAQBAJ&pg=PA383&dq=%22wan+xezetan%22+OR+%22xezet%C3%AA%22+OR+%22xezetin%22+OR+%22xezetek%C3%AA%22+OR+%22xezeta%22+OR+%22w%C3%AA+xezet%C3%AA%22+OR+%22xezetino%22+OR+%22xezetine%22&hl=&cd=2&source=gbs_api|sernav=Shamdinani Stories I: Kurdish Writings on the History and Culture of Central Kurdistan by Mullah Saʼid Shamdinani |weşanxane=BRILL|ISBN=9789004754430|rûpel=383}} #* {{jêder-kitêb|ku|jêgirtin=me '''xezete''' da destê wî jî.|sal=2022|nivîskar=Abdurrahman Benek|url=http://books.google.com.tr/books?id=SdSUEAAAQBAJ&pg=PA33&dq=%22wan+xezetan%22+OR+%22xezet%C3%AA%22+OR+%22xezetin%22+OR+%22xezetek%C3%AA%22+OR+%22xezeta%22+OR+%22w%C3%AA+xezet%C3%AA%22+OR+%22xezetino%22+OR+%22xezetine%22&hl=&cd=3&source=gbs_api|sernav=Payiza Mezinan|weşanxane=Nûbihar|ISBN=9786059413749|rûpel=33}} ==== Jê ==== * {{g|ku|xezeteçî}} ==== Etîmolojî ==== Ji {{deyn|ota|ku|غزته|tr=ẍezete}} ji {{ji|it|ku|gazzetta}}. ==== Werger ==== {{werger-ser|kaxizên mezin ên ku her tên çapkirin|1}} * {{Z|en}}: {{W|en|newspaper}} * {{Z|tr}}: {{W|tr|gazete}} {{werger-bin}} orjcljvat4wybazon5a9ry5xrz7ejjn 6265655 6265654 2026-07-19T20:24:47Z Wikihez 7344 Restored revision 6265653 by [[Special:Contributions/Wikihez|Wikihez]] ([[User talk:Wikihez|talk]]) ([[:m:User:Xiplus/TwinkleGlobal|TwinkleGlobal]]) 6265655 wikitext text/x-wiki == {{ziman|ku}} == === Bilêvkirin === * {{ku-IPA|ẍezete}} * {{ku-kîte}} === Navdêr === {{ku-tewîn-nav|xezete|mê|guherto=hemû}} {{navdêr|ku|c=m}} # [[ew|Ew]] [[kaxizên]] [[mezin]] ên ku [[her roj]] yan [[her]] [[hefte]] [[hatin|tên]] [[çapkirin|çap kirin]] û [[tê de]] [[xeber]]ên [[dinya]]yê, [[mesele]]yên [[siyaset]]ê, [[îlan]] û [[reklam]] [[hebûn|hene]]. #: {{alt-r|ku|ẍezete|qezete|gazete}} #: {{hevmane|ku|cerîde|rojname}} #: {{nm|ku|Bavo, ji min re '''xezeteyekê''' bistîne, ez lê binêrim ka di dinyayê de çi heye çi tine ye.}} #* {{jêder-kitêb|ku|jêgirtin=Baş e, '''xezete''' dê bi çi ezmanî derkevit?|nivîskar=E. Rehmî Ji Mala Hekarîyan|amadekar=M. E. Bozarslan|sernav=Jîn: kovara Kurdî-Tirkî. Cild 1|weşanxane=Weşanxana Deng|cih=Uppsala|sala weşandinê=1985|sal=1918|rûpel=310|isbn=978-91-970702-0-1}} #* {{jêder-kitêb|ku|jêgirtin=ligor{{sic}} danezanên '''xezete''' ên Turk hezar insan li kurdistan hatin kuştin ku ji %&nbsp;70 jin û zaruk kal » pîrbûn|nivîskar=Hesen Hişyar Serdî|sernav=Dîtin û Bîrhatinên Min|weşanxane=Çapxana Emîral|cih=Beyrût|sal=1993|sala weşandinê=1993|rûpel=380|url=https://bnk.institutkurde.org/images/pdf/CTNPMX4FR6.pdf}} #* {{jêder-websîte|ku|jêgirtin='''Xezeteyên''' Kurdî yên li Stenbolê derdiketin bên îstisnakirin, xezeteyekî millî û wetenî yê ku yekemîn car li Kurdistanê hatîye neşirkirin, ew jî xezeteya Zarê Kirmancî ye, ku min xwendîye.|nivîskar=Seîd Veroj|sernav=Mesûd Fanî (Dr. Mesûd Fanî Bîlgîlî)|websîte=Rûpela nû|url=https://www.rupelanu.com/seid-veroj-mesud-fani-dr-mesud-fani-bilgili-17258h.htm|sal=2021|tarîx=2021-05-04}} #* {{jêder-kitêb|ku|jêgirtin=Hekayêta Betal Kirina '''Xezeta''' Hetawî Kurd|sal=2026|nivîskar=David N. MacKenzie, Ergin Öpengin|url=http://books.google.com.tr/books?id=eqvrEQAAQBAJ&pg=PA383&dq=%22wan+xezetan%22+OR+%22xezet%C3%AA%22+OR+%22xezetin%22+OR+%22xezetek%C3%AA%22+OR+%22xezeta%22+OR+%22w%C3%AA+xezet%C3%AA%22+OR+%22xezetino%22+OR+%22xezetine%22&hl=&cd=2&source=gbs_api|sernav=Shamdinani Stories I: Kurdish Writings on the History and Culture of Central Kurdistan by Mullah Saʼid Shamdinani |weşanxane=BRILL|ISBN=9789004754430|rûpel=383}} #* {{jêder-kitêb|ku|jêgirtin=me '''xezete''' da destê wî jî.|sal=2022|nivîskar=Abdurrahman Benek|url=http://books.google.com.tr/books?id=SdSUEAAAQBAJ&pg=PA33&dq=%22wan+xezetan%22+OR+%22xezet%C3%AA%22+OR+%22xezetin%22+OR+%22xezetek%C3%AA%22+OR+%22xezeta%22+OR+%22w%C3%AA+xezet%C3%AA%22+OR+%22xezetino%22+OR+%22xezetine%22&hl=&cd=3&source=gbs_api|sernav=Payiza Mezinan|weşanxane=Nûbihar|ISBN=9786059413749|rûpel=33}} ==== Jê ==== * {{g|ku|xezeteçî}} ==== Etîmolojî ==== Ji {{deyn|ota|ku|غزته|tr=ẍezete}} ji {{ji|it|ku|gazzetta}}. ==== Werger ==== {{werger-ser|kaxizên mezin ên ku her tên çapkirin|1}} * {{Z|en}}: {{W|en|newspaper}} * {{Z|tr}}: {{W|tr|gazete}} {{werger-bin}} 740i0yecd3me2c3bgzy4okmmtx3lf51 Bikarhêner:Wikihez/Gadget-start.css 2 1357891 6265561 6265458 2026-07-19T13:09:32Z Wikihez 7344 6265561 css text/css /* =================================================================== MediaWiki:Gadget-start.js — companion styles Copy this file into MediaWiki:Common.css (or a dedicated gadget CSS page) so that the JS gadget no longer needs to inject styles at runtime. Requires MediaWiki:Gadget-Palette.css to be loaded for the --wikt-palette-* custom properties. =================================================================== */ /* ── Continue/submit button── */ .wiktku-btn { padding: 0.4em 1.2em; font-size: 1em; border: 1px solid var(--wikt-palette-lightgrey); border-radius: 2px; background: var(--wikt-palette-white); cursor: pointer; } .wiktku-btn:hover { border-color: var(--wikt-palette-blue-9, #72777d); } .wiktku-btn:disabled { cursor: default; opacity: 0.5; } .wiktku-btn-progressive { background: var(--wikt-palette-blue-9); border-color: var(--wikt-palette-blue-9); color: var(--wikt-palette-white); } .wiktku-btn-progressive:hover:not(:disabled) { filter: brightness(1.1); } .wiktku-addlang-notice { margin: 0 0 0.8em; padding: 0.6em 0.8em; background: var(--wikt-palette-paleblue); border: 1px solid var(--wikt-palette-lightgrey); } .wiktku-start-step { padding: 1em 0; border-bottom: 1px solid #e0e0e0; } .wiktku-start-step-question { font-size: 125%; } .wiktku-start-step label { padding-right: 2em; } input[type="text"].wiktku-start-step-field { width: 100%; } input[type="text"].wiktku-start-step-field.wiktku-start-narrow { width: 20em; } select.wiktku-start-narrow { width: 20em; max-width: 100%; box-sizing: border-box; } #wiktku-start-spinner { float: right; margin-left: 1em; } #wiktku-start-form textarea.wiktku-start-step-field, #wiktku-start-form textarea.wiktku-start-narrow, #wiktku-start-form textarea.wiktku-dfn-subfield { resize: both !important; overflow: auto !important; box-sizing: border-box !important; vertical-align: top; } #wiktku-start-form textarea.wiktku-start-narrow, #wiktku-start-form textarea.wiktku-dfn-subfield.wiktku-start-narrow { width: 20em; min-width: 8em; height: calc(1em + 8px); min-height: calc(1em + 8px); padding-top: 2px !important; padding-bottom: 2px !important; line-height: 1.4 !important; } /* ── Mobile autocomplete widget ── */ .wiktku-native-select-wrap { display: inline-block; position: relative; } .wiktku-native-select-wrap input[type="search"] { display: block; width: 20em; max-width: 100%; box-sizing: border-box; } ul.wiktku-ac-results { position: absolute; z-index: 9999; top: 100%; bottom: auto; left: 0; background: var(--wikt-palette-white); border: 1px solid var(--wikt-palette-lightgrey); margin: 0; padding: 0; list-style: none; width: 20em; max-width: 90vw; max-height: 14em; overflow-y: scroll; overscroll-behavior: contain; -webkit-overflow-scrolling: touch; } ul.wiktku-ac-results li { padding: 6px 10px; cursor: pointer; font-size: 0.95em; min-height: 2.4em; display: flex; align-items: center; } ul.wiktku-ac-results li:active { background: var(--wikt-palette-blue-9); color: var(--wikt-palette-white); } /* ── Wikitext preview panel ── */ #wiktku-preview-panel { margin-top: 1em; padding: 0.8em; background: var(--wikt-palette-paleblue); border: 1px solid var(--wikt-palette-lightgrey); white-space: pre-wrap; word-break: break-word; font-family: monospace; font-size: 0.9em; } /* ── Live rendered preview panel (desktop only) ── */ #wiktku-live-preview-panel { margin-top: 1em; padding: 0.8em; background: var(--wikt-palette-paleblue); border: 1px solid var(--wikt-palette-lightgrey); word-break: break-word; min-height: 2em; } /* ── Preview container (holds wikitext + live panels) ── */ #wiktku-preview-container { display: flex; flex-wrap: wrap; gap: 1em; margin-top: 0.5em; } #wiktku-start-form textarea.wiktku-dfn-mane, #wiktku-start-form textarea.wiktku-dfn-nimune-text, #wiktku-start-form .wiktku-dfn-jeder-group textarea.wiktku-dfn-nimune-quote, #wiktku-start-form .wiktku-dfn-nimune-sub textarea.wiktku-dfn-nimune-tr, #wiktku-start-form .wiktku-dfn-nimune-sub textarea.wiktku-dfn-nimune-t, #wiktku-start-form .wiktku-dfn-quote-sub textarea.wiktku-dfn-nimune-quote-tr, #wiktku-start-form .wiktku-dfn-quote-sub textarea.wiktku-dfn-nimune-quote-t, #wiktku-start-form .wiktku-pron-wrap textarea.wiktku-pron-text, #wiktku-start-form .wiktku-etym-wrap textarea.wiktku-etym-text { --wiktku-ta-rows: 2; width: 100%; box-sizing: border-box; height: calc(var(--wiktku-ta-rows) * 1.4em + 8px); min-height: calc(var(--wiktku-ta-rows) * 1.4em + 8px); } #wiktku-start-form .wiktku-pron-wrap textarea.wiktku-pron-text, #wiktku-start-form .wiktku-etym-wrap textarea.wiktku-etym-text { --wiktku-ta-rows: 3; } .wiktku-dfn-nimune-sub, .wiktku-dfn-quote-sub { margin-top: 3px; margin-left: 1em; padding-left: 0.6em; border-left: 2px solid var(--wikt-palette-lightgrey); display: flex; flex-direction: column; gap: 3px; } .wiktku-dfn-nimune-sub textarea.wiktku-dfn-nimune-tr, .wiktku-dfn-nimune-sub textarea.wiktku-dfn-nimune-t { min-width: 8em; padding-top: 2px !important; padding-bottom: 2px !important; line-height: 1.4 !important; font-size: 0.9em; } .wiktku-dfn-nimune-sub textarea.wiktku-dfn-nimune-tr, .wiktku-dfn-quote-sub textarea.wiktku-dfn-nimune-quote-tr { background: var(--wikt-palette-cyan); } .wiktku-dfn-nimune-sub textarea.wiktku-dfn-nimune-t, .wiktku-dfn-quote-sub textarea.wiktku-dfn-nimune-quote-t { background: var(--wikt-palette-palegreen); } /* ── Template selector row inside a sense block ── */ .wiktku-dfn-tpl-row { margin-bottom: 4px; } .wiktku-dfn-tpl-select { font-size: 0.9em; } input.wiktku-dfn-tpl-title { width: 20em; max-width: 100%; box-sizing: border-box; } .wiktku-pron-wrap, .wiktku-etym-wrap { display: flex; flex-direction: column; gap: 4px; } .wiktku-pron-wrap select.wiktku-tpl-insert-select, .wiktku-etym-wrap select.wiktku-tpl-insert-select { border: 1px solid var(--wikt-palette-lightgrey); font-size: 0.9em; width: 100%; box-sizing: border-box; padding: 3px 4px; } .wiktku-pron-wrap select.wiktku-tpl-insert-select { background: var(--wikt-palette-amber-1); } .wiktku-etym-wrap select.wiktku-tpl-insert-select { background: var(--wikt-palette-indigo-1); } .wiktku-pron-wrap textarea.wiktku-pron-text { background: var(--wikt-palette-amber-0); } .wiktku-etym-wrap textarea.wiktku-etym-text { background: var(--wikt-palette-indigo-0); } /* ── POS section tabs ── */ #wiktku-section-tabs { display: flex; flex-wrap: wrap; gap: 4px; margin-bottom: 0.6em; align-items: center; } #wiktku-section-tabs .wiktku-section-tab { padding: 3px 10px; border: 1px solid var(--wikt-palette-lightgrey); border-radius: 3px 3px 0 0; background: var(--wikt-palette-dullcyan); cursor: pointer; font-size: 0.9em; user-select: none; } #wiktku-section-tabs .wiktku-section-tab.wiktku-tab-active { background: var(--wikt-palette-white); border-bottom-color: var(--wikt-palette-white); font-weight: bold; } .wiktku-lang-row-list { margin: 0; padding: 0; list-style: none; } .wiktku-lang-row { display: flex; align-items: flex-start; gap: 6px; margin-bottom: 4px; flex-wrap: wrap; } .wiktku-lang-row-words { margin: 0; padding: 0; list-style: none; display: flex; flex-direction: column; gap: 3px; } /* ── Werger (translation) groups — one per gloss ── */ #wiktku-start-trans .wiktku-trans-group { margin-bottom: 0.8em; } #wiktku-start-trans .wiktku-trans-group:last-child { margin-bottom: 0; } #wiktku-start-trans .wiktku-trans-group-label { font-weight: bold; font-size: 0.9em; margin-bottom: 3px; } /* ── Bi zaravayên din (dialect) groups — one per gloss, mirrors Werger ── */ #wiktku-start-zarava .wiktku-zarava-group { margin-bottom: 0.8em; } #wiktku-start-zarava .wiktku-zarava-group:last-child { margin-bottom: 0; } #wiktku-start-zarava .wiktku-zarava-group-label { font-weight: bold; font-size: 0.9em; margin-bottom: 3px; } .wiktku-dfn-jeder-group { margin-top: 4px; } /* Drag handle for reordering citation rows */ .wiktku-jeder-drag-handle { display: inline-block; cursor: grab; color: var(--wikt-palette-lightgrey, #ccc); font-size: 1.2em; line-height: 1; margin-right: 4px; vertical-align: middle; user-select: none; } .wiktku-jeder-drag-handle:active { cursor: grabbing; } .wiktku-dfn-jeder-list .ui-sortable-placeholder { border: 2px dashed var(--wikt-palette-lightgrey, #ccc); background: transparent; visibility: visible !important; height: 2em; } .wiktku-dfn-quote-src-sel { font-size: 0.9em; margin-top: 4px; display: block; } .wiktku-dfn-quote-src-fields { display: flex; flex-direction: column; gap: 3px; margin-top: 4px; } .wiktku-dfn-quote-src-row { display: flex; align-items: baseline; gap: 4px; flex-wrap: wrap; } .wiktku-dfn-quote-src-row label { font-size: 0.85em; white-space: nowrap; min-width: 8em; } input.wiktku-dfn-quote-src-input { flex: 1 1 12em; max-width: 100%; box-sizing: border-box; } @media (max-width: 720px) { .wiktku-lang-row { flex-direction: column; } #wiktku-start-form textarea.wiktku-dfn-mane, #wiktku-start-form textarea.wiktku-dfn-nimune-text, #wiktku-start-form .wiktku-dfn-nimune-sub textarea.wiktku-dfn-nimune-tr, #wiktku-start-form .wiktku-dfn-nimune-sub textarea.wiktku-dfn-nimune-t, #wiktku-start-form .wiktku-pron-wrap textarea.wiktku-pron-text, #wiktku-start-form .wiktku-etym-wrap textarea.wiktku-etym-text { --wiktku-ta-rows: 4; font-size: 1em; } #wiktku-start-form .wiktku-dfn-jeder-group textarea.wiktku-dfn-nimune-quote, #wiktku-start-form .wiktku-dfn-quote-sub textarea.wiktku-dfn-nimune-quote-tr, #wiktku-start-form .wiktku-dfn-quote-sub textarea.wiktku-dfn-nimune-quote-t { --wiktku-ta-rows: 3; font-size: 1em; } .wiktku-dfn-nimune-sub { margin-left: 0.5em; padding-left: 0.4em; } .wiktku-dfn-nimune-sub textarea.wiktku-dfn-nimune-tr, .wiktku-dfn-nimune-sub textarea.wiktku-dfn-nimune-t { max-width: calc(100vw - 6em); } .wiktku-pron-wrap select.wiktku-tpl-insert-select, .wiktku-etym-wrap select.wiktku-tpl-insert-select { font-size: 1em; min-height: 2.4em; } .wiktku-dfn-quote-src-row label { min-width: 6em; } input.wiktku-dfn-quote-src-input { width: 100%; flex: 1 1 100%; } } @media (prefers-color-scheme: dark) { ul.wiktku-ac-results { background: var(--wikt-palette-white, #1e1e1e); border-color: var(--wikt-palette-lightgrey, #444); color: inherit; } ul.wiktku-ac-results li:active { background: var(--wikt-palette-blue-9, #3a6ea8); color: #fff; } .wiktku-start-step { border-bottom-color: var(--wikt-palette-lightgrey, #444); } .wiktku-addlang-notice { background: var(--wikt-palette-paleblue, #1a2233); border-color: var(--wikt-palette-lightgrey, #444); } #wiktku-preview-panel, #wiktku-live-preview-panel { background: var(--wikt-palette-paleblue, #1a2233); border-color: var(--wikt-palette-lightgrey, #444); } #wiktku-section-tabs .wiktku-section-tab { background: var(--wikt-palette-dullcyan, #1e2d3a); border-color: var(--wikt-palette-lightgrey, #444); color: inherit; } #wiktku-section-tabs .wiktku-section-tab.wiktku-tab-active { background: var(--wikt-palette-white, #121212); border-bottom-color: var(--wikt-palette-white, #121212); } } /* ── "Zimanek lê zêde bike" portlet link icon (Minerva/mobile) ── */ /* Minerva auto-generates the icon span class from the portlet link id. */ /* Uses Feather-core-edit.svg from Wikimedia Commons via CSS mask, matching */ /* the exact pattern Minerva uses for all its own icons. */ .minerva-icon-portletlink-ca-wiktku-addlang { -webkit-mask-image: url("https://upload.wikimedia.org/wikipedia/commons/d/d7/Feather-core-edit.svg"); mask-image: url("https://upload.wikimedia.org/wikipedia/commons/d/d7/Feather-core-edit.svg"); -webkit-mask-repeat: no-repeat; mask-repeat: no-repeat; -webkit-mask-position: center; mask-position: center; -webkit-mask-size: 20px; mask-size: 20px; background-color: currentColor; background-image: none; } 9ldoe9v7n25leb13dpiyxev4o2kkp23 Bikarhêner:Wikihez/Gadget-aWa.css 2 1357892 6265615 6265466 2026-07-19T16:45:35Z Wikihez 7344 6265615 css text/css .kephir-awa-dialog { font-size: 10pt; width: 36em; position: fixed; right: 1em; top: 3em; border: 1px solid var(--wikt-palette-green-7, #3c3); background: var(--wikt-palette-palegreen, #efe); color: var(--wikt-palette-black, #202122); padding: 0.1em 0.5em; z-index: 12; } .kephir-awa-dialog .irrelevant { opacity: 0.5; } .kephir-awa-dialog .reminders { font-size: smaller; border-top: 2px groove var(--wikt-palette-grey, silver); border-bottom: 2px groove var(--wikt-palette-grey, silver); padding: 0.5em 0 0.5em 1.5em; margin: 1.5em 0; } .kephir-awa-dialog .main-statusbar { margin-top: 1.5em; border-top: 2px groove var(--wikt-palette-grey, silver); } .kephir-awa-dialog .main-statusbar:empty { display: none; } .kephir-awa-dialog .queue { max-height: 25em; overflow-y: auto; margin-left: 0; padding-left: 2em; } .kephir-awa-dialog.archiving-in-progress .hide-when-archiving { display: none; } .kephir-awa-dialog .active-mode { font-weight: bold; } .kephir-awa-backlinks { font-size: smaller; } .kephir-awa-dialog fieldset.collapsed > :not(legend) { display: none; } /* Mobile: the fixed 36em width overflows/clips on narrow viewports (e.g. Minerva at ~380px), and with no height limit the dialog can run off the bottom of the screen with no way to reach the submit/close buttons. Make it fluid-width and cap its height with its own scroll instead. */ @media (max-width: 640px) { .kephir-awa-dialog { width: auto; left: 0.5em; right: 0.5em; top: 0.5em; max-height: calc(100vh - 1em); overflow-y: auto; box-sizing: border-box; font-size: 12px; } .kephir-awa-dialog .queue { max-height: 12em; } } jjbcpqvmug3lljn9icdpe54hohvdrs4 6265616 6265615 2026-07-19T16:48:25Z Wikihez 7344 6265616 css text/css .kephir-awa-dialog { font-size: 10pt; width: 36em; position: fixed; right: 1em; top: 3em; border: 1px solid var(--wikt-palette-green-7, #3c3); background: var(--wikt-palette-palegreen, #efe); color: var(--wikt-palette-black, #202122); padding: 0.1em 0.5em; z-index: 12; } .kephir-awa-dialog .irrelevant { opacity: 0.5; } .kephir-awa-dialog .reminders { font-size: smaller; border-top: 2px groove var(--wikt-palette-lightgrey, silver); border-bottom: 2px groove var(--wikt-palette-lightgrey, silver); padding: 0.5em 0 0.5em 1.5em; margin: 1.5em 0; } .kephir-awa-dialog .main-statusbar { margin-top: 1.5em; border-top: 2px groove var(--wikt-palette-lightgrey, silver); } .kephir-awa-dialog .main-statusbar:empty { display: none; } .kephir-awa-dialog .queue { max-height: 25em; overflow-y: auto; margin-left: 0; padding-left: 2em; } .kephir-awa-dialog.archiving-in-progress .hide-when-archiving { display: none; } .kephir-awa-dialog .active-mode { font-weight: bold; } .kephir-awa-backlinks { font-size: smaller; } .kephir-awa-dialog fieldset.collapsed > :not(legend) { display: none; } /* Mobile: the fixed 36em width overflows/clips on narrow viewports (e.g. Minerva at ~380px), and with no height limit the dialog can run off the bottom of the screen with no way to reach the submit/close buttons. Make it fluid-width and cap its height with its own scroll instead. */ @media (max-width: 640px) { .kephir-awa-dialog { width: auto; left: 0.5em; right: 0.5em; top: 0.5em; max-height: calc(100vh - 1em); overflow-y: auto; box-sizing: border-box; font-size: 12px; } .kephir-awa-dialog .queue { max-height: 12em; } } az4r1ry6jwp1cdjz8objp5frmjcuhp8 Wîkîferheng:IPA kurdî 4 1357896 6265548 2026-07-19T12:15:34Z Ghybu 1393 Ghybuî/ê navê [[Wîkîferheng:IPA kurdî]] weke [[Wîkîferheng:IPA kurmancî]] guhart: şaş tê fêm kirin 6265548 wikitext text/x-wiki #BERALÎKIRIN [[Wîkîferheng:IPA kurmancî]] 7fhq3ol7ciak61eazz9mkb1upgx84g1 Gotûbêja Wîkîferhengê:IPA kurdî 5 1357897 6265550 2026-07-19T12:15:34Z Ghybu 1393 Ghybuî/ê navê [[Gotûbêja Wîkîferhengê:IPA kurdî]] weke [[Gotûbêja Wîkîferhengê:IPA kurmancî]] guhart: şaş tê fêm kirin 6265550 wikitext text/x-wiki #BERALÎKIRIN [[Gotûbêja Wîkîferhengê:IPA kurmancî]] 2q7dtr4qyn8c2zin8v0dhujfjdlafaw 6265554 6265550 2026-07-19T12:18:28Z Ghybu 1393 Beralîkirin ji bo [[Gotûbêja Wîkîferhengê:IPA kurmancî]] hate jêbirin. 6265554 wikitext text/x-wiki {{jêbirin}} #BERALÎKIRIN [[Gotûbêja Wîkîferhengê:IPA kurmancî]] 2sfggtvg9hs4emum1ibo18mrcezwasu Şablon:nimûne? 10 1357898 6265628 2026-07-19T18:54:48Z Wikihez 7344 Ji bo [[Şablon:bênimûne]] hat beralîkirin 6265628 wikitext text/x-wiki #BERALÎKIRIN [[Şablon:bênimûne]] rejb0b3zj341oujp4hfucakzdmfrcac postnişîn 0 1357899 6265646 2026-07-19T19:46:51Z Wikihez 7344 ([[Mediawiki:Gadget-start.js|WF:NÛ]] v.2.0) +ku:navdêr:Kesê ku di terîqetê de li meqama şêxîtiyê rûdine. 6265646 wikitext text/x-wiki == {{ziman|ku}} == === Bilêvkirin === * {{ku-kîte}} === Navdêr === {{ku-tewîn-nav|postnişîn|nêr}} {{navdêr|ku|c=n}} # [[kes|Kesê]] ku di [[terîqet|terîqetê]] de li [[meqam]]a [[şêxîtî|şêxîtiyê]] [[rûniştin|rûdine]]. #* {{bênimûne|ku}} ==== Jê ==== * {{g|ku|postnişînî}} ==== Etîmolojî ==== {{ji?|ku}} ==== Werger ==== {{werger-ser|kesê ku di terîqetê de li meqama şêxîtiyê rûdine|1}} * {{Z|tr}}: {{W|tr|postnişin}} {{werger-bin}} 6s5efipov999ezr725mu3wgs99c02zo 6265647 6265646 2026-07-19T19:47:15Z Wikihez 7344 /* */ bi [[MediaWiki:Gadget-AjaxEdit.js|AjaxEdit]]ê re 6265647 wikitext text/x-wiki {{bnr-h|postnişin}} == {{ziman|ku}} == === Bilêvkirin === * {{ku-kîte}} === Navdêr === {{ku-tewîn-nav|postnişîn|nêr}} {{navdêr|ku|c=n}} # [[kes|Kesê]] ku di [[terîqet|terîqetê]] de li [[meqam]]a [[şêxîtî|şêxîtiyê]] [[rûniştin|rûdine]]. #* {{bênimûne|ku}} ==== Jê ==== * {{g|ku|postnişînî}} ==== Etîmolojî ==== {{ji?|ku}} ==== Werger ==== {{werger-ser|kesê ku di terîqetê de li meqama şêxîtiyê rûdine|1}} * {{Z|tr}}: {{W|tr|postnişin}} {{werger-bin}} pbmhltlu2edfmtp0v60ie8rei394ada 6265648 6265647 2026-07-19T19:49:01Z Wikihez 7344 +nimûneya bikaranînê bi amûra « [[Mediawiki:Gadget-wikt.add-examples|Nimûne zêde bike]] » (v1.7). 6265648 wikitext text/x-wiki {{bnr-h|postnişin}} == {{ziman|ku}} == === Bilêvkirin === * {{ku-kîte}} === Navdêr === {{ku-tewîn-nav|postnişîn|nêr}} {{navdêr|ku|c=n}} # [[kes|Kesê]] ku di [[terîqet|terîqetê]] de li [[meqam]]a [[şêxîtî|şêxîtiyê]] [[rûniştin|rûdine]]. #* {{jêder-kitêb|ku|nivîskar=David N. MacKenzie; Ergin Öpengin|sernav=Shamdinani Stories I|weşanxane=Brill|sal=2026|rûpel=384|isbn=978-90-04-75443-0|url=https://brill.com/edcollbook-oa/title/74006|jêgirtin=Ema bab û bapîrêt Şêx ʿEbdulqadir '''postnişîn''' bûne, reîsêt rûḥanî bûne.}} ==== Jê ==== * {{g|ku|postnişînî}} ==== Etîmolojî ==== {{ji?|ku}} ==== Werger ==== {{werger-ser|kesê ku di terîqetê de li meqama şêxîtiyê rûdine|1}} * {{Z|tr}}: {{W|tr|postnişin}} {{werger-bin}} r4aywm0ozcpi2wy04fl1nnnsnmupv9s 6265649 6265648 2026-07-19T19:49:47Z Wikihez 7344 /* */ bi [[MediaWiki:Gadget-AjaxEdit.js|AjaxEdit]]ê re 6265649 wikitext text/x-wiki {{bnr-h|postnişin}} == {{ziman|ku}} == === Bilêvkirin === * {{ku-kîte}} === Navdêr === {{ku-tewîn-nav|postnişîn|nêr}} {{navdêr|ku|c=n}} # [[kes|Kesê]] ku di [[terîqet|terîqetê]] de li [[meqam]]a [[şêxîtî|şêxîtiyê]] [[rûniştin|rûdine]]. #* {{jêder-kitêb|ku|nivîskar=Mela Seîd Şemdînanî|amadekar=David N. MacKenzie; Ergin Öpengin|sernav=Shamdinani Stories I|weşanxane=Brill|sal=2026|rûpel=384|isbn=978-90-04-75443-0|url=https://brill.com/edcollbook-oa/title/74006|jêgirtin=Ema bab û bapîrêt Şêx ʿEbdulqadir '''postnişîn''' bûne, reîsêt rûḥanî bûne.}} ==== Jê ==== * {{g|ku|postnişînî}} ==== Etîmolojî ==== {{ji?|ku}} ==== Werger ==== {{werger-ser|kesê ku di terîqetê de li meqama şêxîtiyê rûdine|1}} * {{Z|tr}}: {{W|tr|postnişin}} {{werger-bin}} eu4l18anp6vm0d8szp3zveojx3cr8pk stepping-stone 0 1357900 6265661 2026-07-19T20:44:20Z Wikihez 7344 Wikihezî/ê navê [[stepping-stone]] weke [[stepping stone]] guhart 6265661 wikitext text/x-wiki #BERALÎKIRIN [[stepping stone]] 8ut0nc2j70jim5rgb6jckyg59df99ts 6265662 6265661 2026-07-19T20:44:41Z Wikihez 7344 [[Bikarhêner:Wikihez/templateScript2.js|TS]]: Ji [[en:stepping-stone|en.wikt]] 6265662 wikitext text/x-wiki == {{ziman|en}} == === Navdêr === {{en-navdêr}} # {{awayekî din|en|stepping stone}} e3av8ywcgtezgvzcn6j9ly23q5qb8vj stepping-stones 0 1357901 6265663 2026-07-19T20:44:52Z Wikihez 7344 Çêkirina formên [[stepping-stone]] ([[WF:BILEZ|Bi lez]]) 6265663 wikitext text/x-wiki == {{ziman|en}} == === Formeke navdêrê === {{navdêr|en|form=erê}} # {{pirjimar|en|stepping-stone}} bngqth8efg3c7oshrqq7aamx33i407b stepping stones 0 1357902 6265665 2026-07-19T20:46:52Z Wikihez 7344 Çêkirina formên [[stepping stone]] ([[WF:BILEZ|Bi lez]]) 6265665 wikitext text/x-wiki == {{ziman|en}} == === Formeke navdêrê === {{navdêr|en|form=erê}} # {{pirjimar|en|stepping stone}} 58bxcmht2fewr4diegsy08676jqnwfs steppingstone 0 1357903 6265666 2026-07-19T20:47:14Z Wikihez 7344 [[Bikarhêner:Wikihez/templateScript2.js|TS]]: Ji [[en:steppingstone|en.wikt]] 6265666 wikitext text/x-wiki == {{ziman|en}} == === Navdêr === {{en-navdêr}} # {{awayekî din|en|stepping stone}} e3av8ywcgtezgvzcn6j9ly23q5qb8vj stones 0 1357904 6265669 2026-07-19T20:50:41Z Wikihez 7344 Çêkirina formên [[stone]] ([[WF:BILEZ|Bi lez]]) 6265669 wikitext text/x-wiki == {{ziman|en}} == === Formeke navdêrê === {{navdêr|en|form=erê}} # {{pirjimar|en|stone}} rje646kk37j0vi32b56k4lulcmkylos Şablon:J:ku:Shamdinani Stories I:2026 10 1357905 6265670 2026-07-19T21:01:56Z Wikihez 7344 Rûpel bi "{{kitêb|nivîskar=Mela Seîd Şemdînanî|amadekar={{w|David N. MacKenzie}}; {{w|Ergin Öpengin}}|sernav=Shamdinani Stories I|weşanxane=Brill|cih=Leiden|sal=~1910|serî=Brill Kurdish Studies|cild=3|sala weşandinê=2026|çap=|rûpel={{{rûpel|{{{r|}}}}}}|isbn=978-90-04-75443-0|url=https://brill.com/edcollbook-oa/title/74006?language=en}}<noinclude><templatedata> { "params": { "rûpel": { "aliases": [ "r" ] } }, "description": "Mela Seîd Şemdîn..." hat çêkirin 6265670 wikitext text/x-wiki {{kitêb|nivîskar=Mela Seîd Şemdînanî|amadekar={{w|David N. MacKenzie}}; {{w|Ergin Öpengin}}|sernav=Shamdinani Stories I|weşanxane=Brill|cih=Leiden|sal=~1910|serî=Brill Kurdish Studies|cild=3|sala weşandinê=2026|çap=|rûpel={{{rûpel|{{{r|}}}}}}|isbn=978-90-04-75443-0|url=https://brill.com/edcollbook-oa/title/74006?language=en}}<noinclude><templatedata> { "params": { "rûpel": { "aliases": [ "r" ] } }, "description": "Mela Seîd Şemdînanî, Amadekar: David N. MacKenzie; Ergin Öpengin Shamdinani Stories I" } </templatedata></noinclude> 1oee43q4qw18jiu7cnk9llh1iub50pj 6265671 6265670 2026-07-19T21:02:07Z Wikihez 7344 6265671 wikitext text/x-wiki {{kitêb|nivîskar=Mela Seîd Şemdînanî|amadekar={{w|David N. MacKenzie}}; {{w|Ergin Öpengin}}|sernav=Shamdinani Stories I|weşanxane=Brill|cih=Leiden|sal=~1910|serî=Brill Kurdish Studies|cild=3|sala weşandinê=2026|çap=|rûpel={{{rûpel|{{{r|}}}}}}|isbn=978-90-04-75443-0|url=https://brill.com/edcollbook-oa/title/74006?language=en}}<noinclude>[[Kategorî:Çavkanî]]<templatedata> { "params": { "rûpel": { "aliases": [ "r" ] } }, "description": "Mela Seîd Şemdînanî, Amadekar: David N. MacKenzie; Ergin Öpengin Shamdinani Stories I" } </templatedata></noinclude> 1u495mereibwak4vawvu5jdcj47um80 Şablon:Shamdinani Stories 10 1357906 6265672 2026-07-19T21:02:36Z Wikihez 7344 Ji bo [[Şablon:J:ku:Shamdinani Stories I:2026]] hat beralîkirin 6265672 wikitext text/x-wiki #BERALÎKIRIN [[Şablon:J:ku:Shamdinani Stories I:2026]] l3u0mcjvo3ui8d6xce8avjpddyvd1oq bazeber 0 1357907 6265673 2026-07-19T21:13:05Z Wikihez 7344 ([[Mediawiki:Gadget-start.js|WF:NÛ]] v.2.0) +ku:navdêr:Kevirê ku li nava avê, çem an heriyê (leganê) tê danîn da ku meriv lingê xwe bide ser û bi gavan di ser re derbasî aliyê din bibe.; karê giran 6265673 wikitext text/x-wiki == {{ziman|ku}} == === Bilêvkirin === * {{ku-kîte}} === Navdêr === {{ku-tewîn-nav|bazeber|mê}} {{navdêr|ku|c=m}} # {{e|ku|Şemdînan}}[[kevirê|Kevirê]] ku li [[nav]]a [[av]]ê an [[çem]]ê [[tê danîn]] [[da ku]] [[meriv]] [[ling]]ê [[xwe]] [[dan|bide]] [[ser]] û bi [[gav]]an [[di ser re]] [[derbas bûn|derbasî]] [[aliyê din]] [[bûn|bibe]]. #: {{alt-r|ku|bazber}} #* {{jêder|ku|jêgirtin=Dibêjin di nihalekê da rîwîyek hebû. Awek nîw boş bi nîweka nihalê da dihate xar. Bazeberek hebû, rîwî lê derbaz dibû her wextê ḥez kiriba.|{{J:ku:Shamdinani Stories I:2026}}}} # {{e|ku|mecazî}}[[kar|Karê]] [[giran]]. #* {{jêder-kitêb|ku|jêgirtin=Bivê-nevê ye li ser her kesê dixwazit xwe li bazeberên giran bavêjit, hûr û dûr binêrit heyne wê ser û ser li tehtekê bikevit.|nivîskar=Mele Mehmûd Dêrşewî|sernav=Miştaxa Çiya Ji Gotinên Pêşîya|weşanxane=Rasheed M. AB|cih=Stockholm|sal=1989|isbn=978-91-7970-535-0}} ==== Etîmolojî ==== {{ji?|ku}} ==== Werger ==== {{werger-ser|kevirê ku li nava av an çemê tê danîn da ku meriv lingê xwe bide ser û bi gavan di ser re derbasî aliyê din bibe|1}} * {{Z|en}}: {{W|en|stepping stone}} * {{Z|tr}}: {{W|tr|atlama taşı}} {{werger-bin}} {{werger-ser|karê giran|2}} {{werger-bin}} === Çavkanî === * {{kovara kurmancî|hejmar=63|sernav=Peyvên devera Şemdînan|nivîskar=Ergîn Opengîn|r=3}} * {{Chyet|r=27}} * {{Zana Farqînî|r=101}} oo96yblh94ibegad0so3o1lwqnlkwf9 6265674 6265673 2026-07-19T21:16:57Z Wikihez 7344 /* */ bi [[MediaWiki:Gadget-AjaxEdit.js|AjaxEdit]]ê re 6265674 wikitext text/x-wiki == {{ziman|ku}} == === Bilêvkirin === * {{ku-kîte}} === Navdêr === {{ku-tewîn-nav|bazeber|mê}} {{navdêr|ku|c=m}} # {{e|ku|Şemdînan}} [[kevirê|Kevirê]] ku li [[nav]]a [[av]]ê an [[çem]]ê [[tê danîn]] [[da ku]] [[meriv]] [[ling]]ê [[xwe]] [[dan|bide]] [[ser]] û bi [[gav]]an [[di ser re]] [[derbas bûn|derbasî]] [[aliyê din]] [[bûn|bibe]]. #: {{alt-r|ku|bazber}} #* {{jêder|ku|jêgirtin=Dibêjin di nihalekê da rîwîyek hebû. Awek nîw boş bi nîweka nihalê da dihate xar. Bazeberek hebû, rîwî lê derbaz dibû her wextê ḥez kiriba.|{{J:ku:Shamdinani Stories I:2026}}}} # {{e|ku|mecazî}}[[kar|Karê]] [[giran]]. #* {{jêder-kitêb|ku|jêgirtin=Bivê-nevê ye li ser her kesê dixwazit xwe li bazeberên giran bavêjit, hûr û dûr binêrit heyne wê ser û ser li tehtekê bikevit.|nivîskar=Mele Mehmûd Dêrşewî|sernav=Miştaxa Çiya Ji Gotinên Pêşîya|weşanxane=Rasheed M. AB|cih=Stockholm|sal=1989|isbn=978-91-7970-535-0}} ==== Etîmolojî ==== {{ji?|ku}} ==== Werger ==== {{werger-ser|kevirê ku li nava av an çemê tê danîn da ku meriv lingê xwe bide ser û bi gavan di ser re derbasî aliyê din bibe|1}} * {{Z|en}}: {{W|en|stepping stone}} * {{Z|tr}}: {{W|tr|atlama taşı}} {{werger-bin}} {{werger-ser|karê giran|2}} {{werger-bin}} === Çavkanî === * {{kovara kurmancî|hejmar=63|sernav=Peyvên devera Şemdînan|nivîskar=Ergîn Opengîn|r=3}} * {{Chyet|r=27}} * {{Zana Farqînî|r=101}} pkx9dwwoiyo716m9lrr31gk52v72tbb 6265675 6265674 2026-07-19T21:17:18Z Wikihez 7344 6265675 wikitext text/x-wiki == {{ziman|ku}} == === Bilêvkirin === * {{ku-kîte}} === Navdêr === {{ku-tewîn-nav|bazeber|mê}} {{navdêr|ku|c=m}} # {{e|ku|Şemdînan}} [[kevirê|Kevirê]] ku li [[nav]]a [[av]]ê an [[çem]]ê [[tê danîn]] [[da ku]] [[meriv]] [[ling]]ê [[xwe]] [[dan|bide]] [[ser]] û bi [[gav]]an [[di ser re]] [[derbas bûn|derbasî]] [[aliyê din]] [[bûn|bibe]]. #: {{alt-r|ku|bazber}} #* {{jêder|ku|jêgirtin=Dibêjin di nihalekê da rîwîyek hebû. Awek nîw boş bi nîweka nihalê da dihate xar. '''Bazeberek''' hebû, rîwî lê derbaz dibû her wextê ḥez kiriba.|{{J:ku:Shamdinani Stories I:2026}}}} # {{e|ku|mecazî}}[[kar|Karê]] [[giran]]. #* {{jêder-kitêb|ku|jêgirtin=Bivê-nevê ye li ser her kesê dixwazit xwe li '''bazeberên''' giran bavêjit, hûr û dûr binêrit heyne wê ser û ser li tehtekê bikevit.|nivîskar=Mele Mehmûd Dêrşewî|sernav=Miştaxa Çiya Ji Gotinên Pêşîya|weşanxane=Rasheed M. AB|cih=Stockholm|sal=1989|isbn=978-91-7970-535-0}} ==== Etîmolojî ==== {{ji?|ku}} ==== Werger ==== {{werger-ser|kevirê ku li nava av an çemê tê danîn da ku meriv lingê xwe bide ser û bi gavan di ser re derbasî aliyê din bibe|1}} * {{Z|en}}: {{W|en|stepping stone}} * {{Z|tr}}: {{W|tr|atlama taşı}} {{werger-bin}} {{werger-ser|karê giran|2}} {{werger-bin}} === Çavkanî === * {{kovara kurmancî|hejmar=63|sernav=Peyvên devera Şemdînan|nivîskar=Ergîn Opengîn|r=3}} * {{Chyet|r=27}} * {{Zana Farqînî|r=101}} r3eeumom5mcccc7fr4zmy3tkcnd8vkj 6265676 6265675 2026-07-19T21:19:06Z Wikihez 7344 /* */ bi [[MediaWiki:Gadget-AjaxEdit.js|AjaxEdit]]ê re 6265676 wikitext text/x-wiki == {{ziman|ku}} == === Bilêvkirin === * {{ku-kîte}} === Navdêr === {{ku-tewîn-nav|bazeber|mê}} {{navdêr|ku|c=m}} # {{e|ku|Şemdînan}} [[kevirê|Kevirê]] ku li [[nav]]a [[av]]ê an [[çem]]ê [[tê danîn]] [[da ku]] [[meriv]] [[ling]]ê [[xwe]] [[dan|bide]] [[ser]] û bi [[gav]]an [[di ser re]] [[derbas bûn|derbasî]] [[aliyê din]] [[bûn|bibe]]. #: {{alt-r|ku|bazber}} #* {{jêder|ku|jêgirtin=Dibêjin di nihalekê da rîwîyek hebû. Awek nîw boş bi nîweka nihalê da dihate xar. '''Bazeberek''' hebû, rîwî lê derbaz dibû her wextê ḥez kiriba.|{{J:ku:Shamdinani Stories I:2026}}}} # {{e|ku|mecazî}} [[kar|Karê]] [[giran]]. #* {{jêder-kitêb|ku|jêgirtin=Bivê-nevê ye li ser her kesê dixwazit xwe li '''bazeberên''' giran bavêjit, hûr û dûr binêrit heyne wê ser û ser li tehtekê bikevit.|nivîskar=Mele Mehmûd Dêrşewî|sernav=Miştaxa Çiya Ji Gotinên Pêşîya|weşanxane=Rasheed M. AB|cih=Stockholm|sal=1989|isbn=978-91-7970-535-0}} ==== Etîmolojî ==== {{ji?|ku}} ==== Werger ==== {{werger-ser|kevirê ku li nava av an çemê tê danîn da ku meriv lingê xwe bide ser û bi gavan di ser re derbasî aliyê din bibe|1}} * {{Z|en}}: {{W|en|stepping stone}} * {{Z|tr}}: {{W|tr|atlama taşı}} {{werger-bin}} {{werger-ser|karê giran|2}} {{werger-bin}} === Çavkanî === * {{kovara kurmancî|hejmar=63|sernav=Peyvên devera Şemdînan|nivîskar=Ergîn Opengîn|r=3}} * {{Chyet|r=27}} * {{Zana Farqînî|r=101}} n45vyw4m8w9alaisx5qncwecvf53e6v 6265680 6265676 2026-07-19T21:26:51Z Wikihez 7344 /* */ bi [[MediaWiki:Gadget-AjaxEdit.js|AjaxEdit]]ê re 6265680 wikitext text/x-wiki == {{ziman|ku}} == === Bilêvkirin === * {{ku-kîte}} === Navdêr === {{ku-tewîn-nav|bazeber|mê}} [[Wêne:Stepping Stones, Egton - geograph.org.uk - 570400.jpg|thumb|bazeber]] {{navdêr|ku|c=m}} # {{e|ku|Şemdînan}} [[kevirê|Kevirê]] ku li [[nav]]a [[av]]ê an [[çem]]ê [[tê danîn]] [[da ku]] [[meriv]] [[ling]]ê [[xwe]] [[dan|bide]] [[ser]] û bi [[gav]]an [[di ser re]] [[derbas bûn|derbasî]] [[aliyê din]] [[bûn|bibe]]. #: {{alt-r|ku|bazber}} #* {{jêder|ku|jêgirtin=Dibêjin di nihalekê da rîwîyek hebû. Awek nîw boş bi nîweka nihalê da dihate xar. '''Bazeberek''' hebû, rîwî lê derbaz dibû her wextê ḥez kiriba.|{{J:ku:Shamdinani Stories I:2026}}}} # {{e|ku|mecazî}} [[kar|Karê]] [[giran]]. #* {{jêder-kitêb|ku|jêgirtin=Bivê-nevê ye li ser her kesê dixwazit xwe li '''bazeberên''' giran bavêjit, hûr û dûr binêrit heyne wê ser û ser li tehtekê bikevit.|nivîskar=Mele Mehmûd Dêrşewî|sernav=Miştaxa Çiya Ji Gotinên Pêşîya|weşanxane=Rasheed M. AB|cih=Stockholm|sal=1989|isbn=978-91-7970-535-0}} ==== Etîmolojî ==== {{ji?|ku}} ==== Werger ==== {{werger-ser|kevirê ku li nava av an çemê tê danîn da ku meriv lingê xwe bide ser û bi gavan di ser re derbasî aliyê din bibe|1}} * {{Z|en}}: {{W|en|stepping stone}} * {{Z|tr}}: {{W|tr|atlama taşı}} {{werger-bin}} {{werger-ser|karê giran|2}} {{werger-bin}} === Çavkanî === * {{kovara kurmancî|hejmar=63|sernav=Peyvên devera Şemdînan|nivîskar=Ergîn Opengîn|r=3}} * {{Chyet|r=27}} * {{Zana Farqînî|r=101}} hr75o57lemki9vnoob9t3c3ig3v7ix1 6265682 6265680 2026-07-19T21:49:37Z Wikihez 7344 /* Navdêr */ 6265682 wikitext text/x-wiki == {{ziman|ku}} == === Bilêvkirin === * {{ku-kîte}} === Navdêr === {{ku-tewîn-nav|bazeber|mê}} [[Wêne:Stepping Stones, Egton - geograph.org.uk - 570400.jpg|thumb|bazeber]] {{navdêr|ku|c=m}} # {{e|ku|Şemdînan}} [[kevirê|Kevirê]] ku li [[nav]]a [[av]]ê an [[çem]]ê [[tê danîn]] [[da ku]] [[meriv]] [[ling]]ê [[xwe]] [[dan|bide]] [[ser]] û bi [[gav]]an [[di ser re]] [[derbas bûn|derbasî]] [[aliyê din]] [[bûn|bibe]]. #: {{alt-r|ku|bazber}} #* {{jêder|ku|jêgirtin=Dibêjin di nihalekê da rîwîyek hebû. Awek nîw boş bi nîweka nihalê da dihate xar. '''Bazeberek''' hebû, rîwî lê derbaz dibû her wextê ḥez kiriba.|{{J:ku:Shamdinani Stories I:2026}}}} #* {{jêder-kitêb|ku|jêgirtin=Kevir di nav avê de datanîn û mirovan di ser re gav dida û diçûn qama dî. Gûzereşiyan ji vê rêgeha '''bazeberê''' re digot gav.|sal=2022|nivîskar=Omer Dilsoz|url=http://books.google.com.tr/books?id=JBuKEAAAQBAJ&pg=PA26&dq=%22wan+bazeberan%22+OR+%22bazeber%C3%AA%22+OR+%22bazeberin%22+OR+%22bazeberek%C3%AA%22+OR+%22bazebera%22+OR+%22w%C3%AA+bazeber%C3%AA%22+OR+%22bazeberino%22+OR+%22bazeberine%22&hl=&cd=3&source=gbs_api|sernav=Gûzereş|weşanxane=Omer Dilsoz|ISBN=9786257568722|rûpel=26}} # {{e|ku|mecazî}} [[kar|Karê]] [[giran]]. #* {{jêder-kitêb|ku|jêgirtin=Bivê-nevê ye li ser her kesê dixwazit xwe li '''bazeberên''' giran bavêjit, hûr û dûr binêrit heyne wê ser û ser li tehtekê bikevit.|nivîskar=Mele Mehmûd Dêrşewî|sernav=Miştaxa Çiya Ji Gotinên Pêşîya|weşanxane=Rasheed M. AB|cih=Stockholm|sal=1989|isbn=978-91-7970-535-0}} ==== Bi alfabeyên din ==== * {{ku-ar|بازەبەر}} ==== Etîmolojî ==== {{ji?|ku}} ==== Werger ==== {{werger-ser|kevirê ku li nava av an çemê tê danîn da ku meriv lingê xwe bide ser û bi gavan di ser re derbasî aliyê din bibe|1}} * {{Z|en}}: {{W|en|stepping stone}} * {{Z|tr}}: {{W|tr|atlama taşı}} {{werger-bin}} {{werger-ser|karê giran|2}} {{werger-bin}} === Çavkanî === * {{kovara kurmancî|hejmar=63|sernav=Peyvên devera Şemdînan|nivîskar=Ergîn Opengîn|r=3}} * {{Chyet|r=27}} * {{Zana Farqînî|r=101}} a31ygq00eezwwkpujla25eg1f9hi36d 6265686 6265682 2026-07-19T22:02:19Z Wikihez 7344 /* Çavkanî */ 6265686 wikitext text/x-wiki == {{ziman|ku}} == === Bilêvkirin === * {{ku-kîte}} === Navdêr === {{ku-tewîn-nav|bazeber|mê}} [[Wêne:Stepping Stones, Egton - geograph.org.uk - 570400.jpg|thumb|bazeber]] {{navdêr|ku|c=m}} # {{e|ku|Şemdînan}} [[kevirê|Kevirê]] ku li [[nav]]a [[av]]ê an [[çem]]ê [[tê danîn]] [[da ku]] [[meriv]] [[ling]]ê [[xwe]] [[dan|bide]] [[ser]] û bi [[gav]]an [[di ser re]] [[derbas bûn|derbasî]] [[aliyê din]] [[bûn|bibe]]. #: {{alt-r|ku|bazber}} #* {{jêder|ku|jêgirtin=Dibêjin di nihalekê da rîwîyek hebû. Awek nîw boş bi nîweka nihalê da dihate xar. '''Bazeberek''' hebû, rîwî lê derbaz dibû her wextê ḥez kiriba.|{{J:ku:Shamdinani Stories I:2026}}}} #* {{jêder-kitêb|ku|jêgirtin=Kevir di nav avê de datanîn û mirovan di ser re gav dida û diçûn qama dî. Gûzereşiyan ji vê rêgeha '''bazeberê''' re digot gav.|sal=2022|nivîskar=Omer Dilsoz|url=http://books.google.com.tr/books?id=JBuKEAAAQBAJ&pg=PA26&dq=%22wan+bazeberan%22+OR+%22bazeber%C3%AA%22+OR+%22bazeberin%22+OR+%22bazeberek%C3%AA%22+OR+%22bazebera%22+OR+%22w%C3%AA+bazeber%C3%AA%22+OR+%22bazeberino%22+OR+%22bazeberine%22&hl=&cd=3&source=gbs_api|sernav=Gûzereş|weşanxane=Omer Dilsoz|ISBN=9786257568722|rûpel=26}} # {{e|ku|mecazî}} [[kar|Karê]] [[giran]]. #* {{jêder-kitêb|ku|jêgirtin=Bivê-nevê ye li ser her kesê dixwazit xwe li '''bazeberên''' giran bavêjit, hûr û dûr binêrit heyne wê ser û ser li tehtekê bikevit.|nivîskar=Mele Mehmûd Dêrşewî|sernav=Miştaxa Çiya Ji Gotinên Pêşîya|weşanxane=Rasheed M. AB|cih=Stockholm|sal=1989|isbn=978-91-7970-535-0}} ==== Bi alfabeyên din ==== * {{ku-ar|بازەبەر}} ==== Etîmolojî ==== {{ji?|ku}} ==== Werger ==== {{werger-ser|kevirê ku li nava av an çemê tê danîn da ku meriv lingê xwe bide ser û bi gavan di ser re derbasî aliyê din bibe|1}} * {{Z|en}}: {{W|en|stepping stone}} * {{Z|tr}}: {{W|tr|atlama taşı}} {{werger-bin}} {{werger-ser|karê giran|2}} {{werger-bin}} === Çavkanî === * {{kovara kurmancî|hejmar=63|sernav=Peyvên devera Şemdînan|nivîskar=Ergîn Opengîn|r=3}} * {{Chyet|r=27}} * {{Zana Farqînî|r=101}} * {{Ç:ku:Henbane borîne|بازەبەر}} a9sjliskb61vv1ad95v08ihg6vu9d6l atlama taşı 0 1357908 6265679 2026-07-19T21:25:36Z Wikihez 7344 ([[Bikarhêner:Wikihez/newentrywiz.js|NEC]]) +tr:navdêr: Bi [[Bikarhêner:Wikihez/CreateTranslation.js|amûrê]] ji wergerên [[bazeber]]: 6265679 wikitext text/x-wiki == {{ziman|tr}} == === Navdêr === {{navdêr|tr}} # [[bazeber]] 0k6f887g2tnzjklyvhu8yxw8fv2z062 Şablon:Ç:ku:Henbane borîne 10 1357909 6265683 2026-07-19T21:58:58Z Wikihez 7344 Rûpel bi "{{kitêb|url=https://lex.vejin.net/nk/dict/henbaneborine|sernav=Henbane Borîne|nivîskar=Hejar|sal=1990}}{{#if:{{{url|}}}|&nbsp;"[{{{url|}}} {{{1}}}]" li ser vejînlex.net}}" hat çêkirin 6265683 wikitext text/x-wiki {{kitêb|url=https://lex.vejin.net/nk/dict/henbaneborine|sernav=Henbane Borîne|nivîskar=Hejar|sal=1990}}{{#if:{{{url|}}}|&nbsp;"[{{{url|}}} {{{1}}}]" li ser vejînlex.net}} raizddv8tnca3pwas2bzgqarb44ugze 6265684 6265683 2026-07-19T22:00:15Z Wikihez 7344 6265684 wikitext text/x-wiki {{kitêb|url=https://lex.vejin.net/nk/dict/henbaneborine|sernav=Henbane Borîne|nivîskar=Hejar|sal=1990}}{{#if:{{{1|}}}|&nbsp;"[{{{1|}}} {{{1|}}}]" li ser vejînlex.net}} fyjnz3gific75zs7ilbc48jtkjj6bdp 6265685 6265684 2026-07-19T22:01:08Z Wikihez 7344 6265685 wikitext text/x-wiki {{kitêb|url=https://lex.vejin.net/nk/dict/henbaneborine|sernav=Henbane Borîne|nivîskar=Hejar|sal=1990}}{{#if:{{{1|}}}|&nbsp;"[https://lex.vejin.net/nk/def/henbaneborine/{{urlencode:{{{1|}}}}} {{{1|}}}]" li ser vejînlex.net}} 5lhjmy22uv4xhbupzzgaj9ms7qa49jf 6265688 6265685 2026-07-19T22:03:38Z Wikihez 7344 6265688 wikitext text/x-wiki {{kitêb|url=https://lex.vejin.net/nk/dict/henbaneborine|sernav=Henbane Borîne|nivîskar=Hejar|sal=1990}}{{#if:{{{1|}}}|&nbsp;"<span class="plainlinks">[https://lex.vejin.net/nk/def/henbaneborine/{{urlencode:{{{1|}}}}} {{{1|}}}]</span>" li ser vejînlex.net}}<noinclude>[[Kategorî:Çavkanî]]</noinclude> iollmds84es6p40sykoe97z48k8k4ly Gotûbêj:zazakînas 1 1357910 6265695 2026-07-19T22:29:29Z Wikihez 7344 [[MediaWiki:Gadget-aWa.js/belgekirin|aWa]]: Arşîvkirina nîqaşê ji rûpela [[Wîkîferheng:Daxwazên peyitandinê]] 6265695 wikitext text/x-wiki == Nîqaşa [[Wîkîferheng:Daxwazên peyitandinê|peyitandinê]] == {{arşîv-ser|dp|failed|link=Taybet:PermanentLink/6265689#zazakînas}} {{fake==|1= <s>[[zazakînas]]</s> }} Bnr. [[Wîkîferheng:Pîvekên tevlîkirinê|Krîterên tevlîkirinê]] —[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 18:16, 15 tîrmeh 2026 (UTC) :{{nepeyitandî}}--[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 22:05, 19 tîrmeh 2026 (UTC) {{arşîv-bin}} mpmn28afrpeigwhq5dehdg2frytm7cj بازەبەر 0 1357912 6265697 2026-07-19T22:57:47Z Wikihez 7344 ([[Mediawiki:Gadget-start.js|WF:NÛ]] v.2.0) +ku:navdêr: 6265697 wikitext text/x-wiki == {{ziman|ku}} == === Navdêr === {{navdêr|ku|c=m}} # {{ku-Latn|bazeber}} #* {{bênimûne|ku}} bbc88ad3ktkqwh9x0flzsdnzds0ccom 6265698 6265697 2026-07-19T23:04:24Z Wikihez 7344 ([[Mediawiki:Gadget-start.js|WF:NÛ]] v.2.0) +ckb:navdêr:bazeber 6265698 wikitext text/x-wiki == {{ziman|ku}} == === Navdêr === {{navdêr|ku|c=m}} # {{ku-Latn|bazeber}} #* {{bênimûne|ku}} == {{ziman|ckb}} == === Navdêr === {{navdêr|ckb}} # [[bazeber|Bazeber]]. #* {{bênimûne|ckb}} ==== Etîmolojî ==== {{ji?|ckb}} eftvkdc4iu52oe8gg7w702wqirmyvno vesselâm 0 1357913 6265751 2026-07-20T06:04:10Z Wikihez 7344 Wikihezî/ê navê [[vesselâm]] weke [[vesselam]] guhart 6265751 wikitext text/x-wiki #BERALÎKIRIN [[vesselam]] kf7lcjxakld0w16uxshfne1d1spdwla 6265760 6265751 2026-07-20T06:23:54Z Wikihez 7344 ([[Mediawiki:Gadget-start.js|WF:NÛ]] v.2.0) +tr:baneşan: 6265760 wikitext text/x-wiki == {{ziman|tr}} == === Baneşan === {{baneşan|tr}} # {{guharto|tr|vesselam}} #* {{bênimûne|tr}} 2tq4txwmir6rglng4ykalvnil0ojm4e Gotûbêj:-înerî 1 1357915 6265808 2026-07-20T08:32:13Z Wikihez 7344 [[MediaWiki:Gadget-aWa.js/belgekirin|aWa]]: Arşîvkirina nîqaşê ji rûpela [[Wîkîferheng:Daxwazên jêbirinê]] 6265808 wikitext text/x-wiki == Nîqaşa [[Wîkîferheng:Daxwazên jêbirinê|jêbirinê]] == {{arşîv-ser|dj|failed|link=Taybet:PermanentLink/6265804#-înerî,_-înertî,_-înerîtî}} {{fake==|1= [[-înerî]], [[-înertî]], [[-înerîtî]] }} {{dengdan|jêbirin|destpêk=06.08.2024|dawî=20.08.2024}} * '''Sedem:''' Xelet in. 1: Ne navdêr in. 2: ne paşgirên rastî ne jî ji ber ku ew "î" ne bi paşgirê lê bi gotinê ve bûye. —[[Bikarhêner:Guherto|Guherto]] ([[Gotûbêja bikarhêner:Guherto|gotûbêj]]) 20:55, 6 tebax 2024 (UTC)<!-- Sedema jêbirinê li şûnda vê nivîsê binivîsin --> <!-- Li jêr dengên xwe li gorî şablona jêr bidin --> * {{jê bibe}} Xelet in. -- [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 16:44, 7 tebax 2024 (UTC) {{arşîv-bin}} rcmhgsfe1l6nwkv6t9r12h09hin1l3x Gotûbêj:-înerîtî 1 1357916 6265809 2026-07-20T08:32:14Z Wikihez 7344 [[MediaWiki:Gadget-aWa.js/belgekirin|aWa]]: Li [[Gotûbêj:-înerî#Nîqaşa jêbirinê]] lînka nîqaşê ji [[Wîkîferheng:Daxwazên jêbirinê]] tê zêdekirin 6265809 wikitext text/x-wiki == Nîqaşa [[Wîkîferheng:Daxwazên jêbirinê|jêbirinê]] == : ''Binêre [[Gotûbêj:-înerî#Nîqaşa jêbirinê]].''[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 08:32, 20 tîrmeh 2026 (UTC) 0i54tmal9ooinsdzllky25i38tld7p1 Gotûbêj:-înertî 1 1357917 6265810 2026-07-20T08:32:14Z Wikihez 7344 [[MediaWiki:Gadget-aWa.js/belgekirin|aWa]]: Li [[Gotûbêj:-înerî#Nîqaşa jêbirinê]] lînka nîqaşê ji [[Wîkîferheng:Daxwazên jêbirinê]] tê zêdekirin 6265810 wikitext text/x-wiki == Nîqaşa [[Wîkîferheng:Daxwazên jêbirinê|jêbirinê]] == : ''Binêre [[Gotûbêj:-înerî#Nîqaşa jêbirinê]].''[[Bikarhêner:Wikihez|Wikihez]] ([[Gotûbêja bikarhêner:Wikihez|gotûbêj]]) 08:32, 20 tîrmeh 2026 (UTC) 0i54tmal9ooinsdzllky25i38tld7p1 Gotûbêj:herî mezin 1 1357918 6265813 2026-07-20T08:35:09Z Wikihez 7344 [[MediaWiki:Gadget-aWa.js/belgekirin|aWa]]: Arşîvkirina nîqaşê ji rûpela [[Wîkîferheng:Daxwazên jêbirinê]] 6265813 wikitext text/x-wiki == Nîqaşa [[Wîkîferheng:Daxwazên jêbirinê|jêbirinê]] == {{arşîv-ser|dj|passed|link=Taybet:PermanentLink/6265811#herî_mezin}} {{fake==|1= [[herî mezin]] }} {{dengdan|jêbirin|destpêk=15.08.2024|dawî=22.08.2024}} * '''Sedem:''' Neferhengî ye, ji bo "komkirina tercimeyan li cihekî" jî "mezintirîn" heye. — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 17:48, 15 tebax 2024 (UTC) <!-- Sedema jêbirinê li şûnda vê nivîsê binivîsin --> <!-- Li jêr dengên xwe li gorî şablona jêr bidin --> * {{arşîv-bin}} pk0zpggixn7uecm5xlmzww59211kww4 6265816 6265813 2026-07-20T08:35:45Z Wikihez 7344 6265816 wikitext text/x-wiki == Nîqaşa [[Wîkîferheng:Daxwazên jêbirinê|jêbirinê]] == {{arşîv-ser|dj|failed|link=Taybet:PermanentLink/6265811#herî_mezin}} {{fake==|1= [[herî mezin]] }} {{dengdan|jêbirin|destpêk=15.08.2024|dawî=22.08.2024}} * '''Sedem:''' Neferhengî ye, ji bo "komkirina tercimeyan li cihekî" jî "mezintirîn" heye. — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 17:48, 15 tebax 2024 (UTC) <!-- Sedema jêbirinê li şûnda vê nivîsê binivîsin --> <!-- Li jêr dengên xwe li gorî şablona jêr bidin --> * {{arşîv-bin}} rr2sge84w1prkdbr0fnt4iahsfh819c Gotûbêj:tewrî mezin 1 1357919 6265815 2026-07-20T08:35:22Z Wikihez 7344 [[MediaWiki:Gadget-aWa.js/belgekirin|aWa]]: Arşîvkirina nîqaşê ji rûpela [[Wîkîferheng:Daxwazên jêbirinê]] 6265815 wikitext text/x-wiki == Nîqaşa [[Wîkîferheng:Daxwazên jêbirinê|jêbirinê]] == {{arşîv-ser|dj|failed|link=Taybet:PermanentLink/6265812#tewrî_mezin}} {{fake==|1= [[tewrî mezin]] }} {{dengdan|jêbirin|destpêk=15.08.2024|dawî=22.08.2024}} * '''Sedem:''' Neferhengî ye, ji bo "komkirina tercimeyan li cihekî" jî "mezintirîn" heye. — [[Bikarhêner:Bikarhêner|Bikarhêner]] ([[Gotûbêja bikarhêner:Bikarhêner|gotûbêj]]) 17:49, 15 tebax 2024 (UTC) <!-- Sedema jêbirinê li şûnda vê nivîsê binivîsin --> <!-- Li jêr dengên xwe li gorî şablona jêr bidin --> * {{arşîv-bin}} fd0zlblctroglvkonzrcummzhyhpje4