Wikipedia
tumwiki
https://tum.wikipedia.org/wiki/Jani_likulu
MediaWiki 1.48.0-wmf.1
first-letter
Media
Special
Talk
User
User talk
Wikipedia
Wikipedia talk
File
File talk
MediaWiki
MediaWiki talk
Template
Template talk
Help
Help talk
Category
Category talk
TimedText
TimedText talk
Module
Module talk
Event
Event talk
Kilifi, Kenya
0
11235
123431
45569
2026-11-02T20:38:55Z
Anthonymunthali44
5642
Duplicate of [[Kilifi County, Kenya]]: redirecting
123431
wikitext
text/x-wiki
#REDIRECT [[Kilifi County, Kenya]]
d2gr0w9bc3wggv89lcr9258azg2svuv
Lamu, Kenya
0
11237
123432
45571
2026-11-02T20:38:58Z
Anthonymunthali44
5642
Duplicate of [[Lamu County, Kenya]]: redirecting
123432
wikitext
text/x-wiki
#REDIRECT [[Lamu County, Kenya]]
5cvguhe5zt6kxcl5ni1su0p4k9w3tvl
Embu, Kenya
0
11242
123435
45503
2026-11-02T20:39:08Z
Anthonymunthali44
5642
Duplicate of [[Embu County, Kenya]]: redirecting
123435
wikitext
text/x-wiki
#REDIRECT [[Embu County, Kenya]]
s4ht58ui2njdqry2vt6ybydyycpl55e
Marsabit, Kenya
0
11246
123433
45575
2026-11-02T20:39:01Z
Anthonymunthali44
5642
Duplicate of [[Marsabit County, Kenya]]: redirecting
123433
wikitext
text/x-wiki
#REDIRECT [[Marsabit County, Kenya]]
7cbjvgxi3wv0mc4t6w4nhfdkwzl67re
Meru, Kenya
0
11247
123434
45576
2026-11-02T20:39:05Z
Anthonymunthali44
5642
Duplicate of [[Meru County, Kenya]]: redirecting
123434
wikitext
text/x-wiki
#REDIRECT [[Meru County, Kenya]]
ljpi25s2vshhlkxryqmxbr18lt30fcy
Chartwell, Johannesburg
0
16165
123440
39237
2026-11-02T21:18:05Z
Anthonymunthali44
5642
Duplicate of [[Chartwell]]: redirecting
123440
wikitext
text/x-wiki
#REDIRECT [[Chartwell]]
7xd191ndxdx1f2i356gk7z6hpx7d60i
Buccleuch, Johannesburg
0
16167
123408
39239
2026-11-02T20:26:40Z
Anthonymunthali44
5642
Duplicate of [[Buccleuch]]: redirecting
123408
wikitext
text/x-wiki
#REDIRECT [[Buccleuch]]
87k734jxl266h8nkzlpc46lwml6r3wv
Constantia Kloof, Gauteng
0
16272
123409
39347
2026-11-02T20:26:43Z
Anthonymunthali44
5642
Duplicate of [[Constantia Kloof]]: redirecting
123409
wikitext
text/x-wiki
#REDIRECT [[Constantia Kloof]]
ivhwul1r23mz4iovwsjnpt58h5kqiwu
Alan Manor, Johannesburg
0
16312
123407
39389
2026-11-02T20:26:37Z
Anthonymunthali44
5642
Duplicate of [[Alan Manor]]: redirecting
123407
wikitext
text/x-wiki
#REDIRECT [[Alan Manor]]
nq6uj9xx9lljlrw96g8kjq3s7xd4pqc
Aeroton, Johannesburg
0
16315
123406
39392
2026-11-02T20:26:34Z
Anthonymunthali44
5642
Duplicate of [[Aeroton]]: redirecting
123406
wikitext
text/x-wiki
#REDIRECT [[Aeroton]]
pxj2bqryze07frsm8n2d7fr4emjslp2
Kitui County, Kenya
0
17711
123436
45583
2026-11-02T20:39:11Z
Anthonymunthali44
5642
Duplicate of [[Kitui, Kenya]]: redirecting
123436
wikitext
text/x-wiki
#REDIRECT [[Kitui, Kenya]]
i6r5d1mt63sg4jxnzy9iqm4tfbi0c7p
Machakos County, Kenya
0
17712
123429
45584
2026-11-02T20:27:48Z
Anthonymunthali44
5642
Duplicate of [[Machakos, Kenya]]: redirecting
123429
wikitext
text/x-wiki
#REDIRECT [[Machakos, Kenya]]
pbwmvlqfl7wlo76bdvb6fwmd371rqjx
Makueni County, Kenya
0
17720
123430
45592
2026-11-02T20:27:52Z
Anthonymunthali44
5642
Duplicate of [[Makueni (Makueni), Kenya]]: redirecting
123430
wikitext
text/x-wiki
#REDIRECT [[Makueni (Makueni), Kenya]]
sxy4zdpe99dtctswv9cmbmlncfccac4
Rumphi (msumba)
0
18002
123442
122674
2026-11-03T06:13:26Z
Anthonymunthali44
5642
Kulemba so: kalembero ka mazgu ghakuzomerezgeka (Wikidata lexemes), Citumbuka cakutowa, na kulondezga nkhani ya Cingelezi (enwiki 1376608943)
123442
wikitext
text/x-wiki
{{Infobox settlement
<!--See the Table at Infobox Settlement for all fields and descriptions of usage-->
<!-- Basic info ---------------->| official_name = Rumphi
| other_name =
| native_name = <!-- for cities whose native name is not in English -->
| nickname =
| settlement_type = <!--For Town or Village (Leave blank for the default City)-->
| motto = <!-- images and maps ----------->
| image_skyline = MalawiRumphiMarket.png
| imagesize =
| image_caption = Msika wa kamsumba ka Rumphi
| image_flag =
| flag_size =
| image_seal =
| seal_size =
| image_shield =
| shield_size =
| image_blank_emblem =
| blank_emblem_type =
| blank_emblem_size =
| image_map =
| mapsize =
| map_caption =
| image_map1 =
| mapsize1 =
| map_caption1 =
| image_dot_map =
| dot_mapsize =
| dot_map_caption =
| dot_x =
| dot_y =
| pushpin_map = Malawi#Northern Region#Rumphi
| pushpin_mapsize = 240
| pushpin_label_position = bottom
| pushpin_map_caption = Location in Malawi
<!-- Location ------------------>| subdivision_type = Country
| subdivision_name = {{flag|Malawi}}
| subdivision_type1 = [[Regions of Malawi|Region]]
| subdivision_name1 = [[Northern Region, Malawi|Northern Region]]
| subdivision_type2 = [[Districts of Malawi|District]]
| subdivision_name2 = [[Rumphi District]]
| subdivision_type3 = Cigaŵa
| subdivision_name3 = [[Chigawa cha Chozoli-Mayembe|Chozoli-Mayembe]]
| subdivision_type4 = TA
| subdivision_name4 = [[TA Rumphi Boma|Rumphi Boma]]
| government_footnotes =
| government_type =
| leader_title =
| leader_name =
| leader_title1 = <!-- for places with, say, both a mayor and a city manager -->
| leader_name1 =
| leader_title2 =
| leader_name2 =
| leader_title3 =
| leader_name3 =
| leader_title4 =
| leader_name4 =
| established_title = <!-- Settled -->
| established_date =
| established_title2 = <!-- Incorporated (town) -->
| established_date2 =
| established_title3 = <!-- Incorporated (city) -->
| established_date3 = <!-- Area --------------------->
| area_magnitude =
| unit_pref = Imperial
<!--Enter: Imperial, if Imperial (metric) is desired-->| area_footnotes =
| area_total_km2 = <!-- ALL fields dealing with a measurements are subject to automatic unit conversion-->
| area_land_km2 = <!--See table @ Template:Infobox Settlement for details on automatic unit conversion-->
| area_water_km2 =
| area_total_sq_mi =
| area_land_sq_mi =
| area_water_sq_mi =
| area_water_percent =
| area_urban_km2 =
| area_urban_sq_mi =
| area_metro_km2 =
| area_metro_sq_mi =
| area_blank1_title =
| area_blank1_km2 =
| area_blank1_sq_mi = <!-- Population ----------------------->
| population_as_of = 2018 Census<ref name="Census2018">{{cite web|url=http://www.nsomalawi.mw/images/stories/data_on_line/demography/census_2018/2018%20Malawi%20Population%20and%20Housing%20Census%20Main%20Report.pdf|title=2018 Population and Housing Census Main Report|publisher=Malawi National Statistical Office|accessdate=25 December 2019|archive-url=https://web.archive.org/web/20200608191931/http://www.nsomalawi.mw/images/stories/data_on_line/demography/census_2018/2018%20Malawi%20Population%20and%20Housing%20Census%20Main%20Report.pdf|archive-date=8 June 2020}}</ref>
| population_footnotes =
| population_note =
| population_total = 22,358
| population_density_km2 =
| population_density_sq_mi =
| population_metro =
| population_density_metro_km2 =
| population_density_metro_sq_mi =
| population_urban =
| population_density_urban_km2 =
| population_density_urban_sq_mi =
| population_blank1_title = Ethnicities
| population_blank1 =
| population_blank2_title = Religions
| population_blank2 =
| population_density_blank1_km2 =
| population_density_blank1_sq_mi = <!-- General information --------------->
| timezone = +2
| utc_offset =
| timezone_DST =
| utc_offset_DST =
| coordinates = {{coord|11|01|S|33|52|E|region:MW|display=inline}}
| elevation_footnotes = <!--for references: use <ref> </ref> tags-->
| elevation_m =
| elevation_ft =
| blank1_name_sec2 = [[Köppen climate classification|Climate]]
| blank1_info_sec2 = [[Humid subtropical climate|Cwa]]
<!-- Area/postal codes & others -------->| postal_code_type = <!-- enter ZIP code, Postcode, Post code, Postal code... -->
| postal_code =
| area_code =
| blank_name =
| blank_info =
| blank1_name =
| blank1_info =
| website =
| footnotes =
}}
'''Rumphi''' ni likulu la [[Boma la Rumphi]] (Rumphi Boma) mu [[Chigaŵa cha Kumpoto|Cigaŵa ca Kumpoto]] ca [[Malaŵi]]. Ni kamsumba ka malonda ako kakuteŵetera ŵalimi ŵanandi ŵakukhala mu vigaŵa vyose vyakuzingilizga.
== Kalongosoro ==
Rumphi kali pa nthowa yakuluta ku Malo gha Caro ghakuvikilira Vinyama gha Nyika, ku Phiri la Thawali la Nyika, na ku Malo ghakuvikilira Vinyama gha Dambo la Vwaza. Kupambana na mzengezgana wake mukulu, [[Mzuzu]], uko kukuŵa dazi lambura koca comene pafupifupi caka cose, Rumphi kali na nyengo yakupambana. Pakuti kamsumba aka nkakuzingilizgika na tuphiri, nyengo zose kali na mphepo yiwemi. Kamsumba aka kakupakana na Mronga wa Rumphi kumafumiro gha dazi, na Mronga wa Rukuru wa Kummwera kummwera.
Ku Rumphi kuli msika wa ng'ombe Cisulo cilicose mulenji pa 6 koloko, uko ŵalimi na ŵamalonda ŵakwiza kuzakaguliska na kugula ng'ombe. Ni msika ukulu comene wa ng'ombe pakati pa [[Lilongwe]], [[Karonga]] na [[Mzimba (msumba)|Mzimba]]. Mumphepete mwa msewu wakuluta ku [[Bolero, Rumphi|Bolero]], kwakulaŵiskana na malo ghakusungirako ndalama gha FDH, kuli Roscher Youth Development Centre.<ref>{{Cite web |title=Home - Roscher Youth Development Centre |url=http://roscheryouthdevelopment.org |archive-url=https://web.archive.org/web/20241010223212/https://roscheryouthdevelopment.org/ |archive-date=2024-10-10 |access-date=2025-05-09 |website=Roscher Youth Development Centre |language=en-GB}}</ref> Pa malo gha wupu uwu, kummwera kwa Mronga wa Rukuru, wupu wa Vwilani Malaŵi e.V. (Support Malawi e.V.) ukambiska nyumba yakwamba ya ŵalendo yakuzengeka na mathumba gha mcenga (Earthbag House Lodge) mu Rumphi. Ŵawukirano ndiwo ŵakayizenga, na viliŵa vya mathumba gha mcenga ghakuwunjikika. Nyumba ya vyakulya yakuzengeka na mathumba gha mcenga (Earthbag Restaurant) nayo yikasonthola ŵalendo kweniso ŵanthu ŵakugona mu nyumba za ŵalendo izi.{{citation needed|date=May 2025}}
Kwamasambiro gha ŵasofi gha St Patrick's Minor Seminary ghali ku Rumphi. Mu 2018, kwamasambiro agha ghakazunulika mu mphala ya [[Ufumu Ubanyi]]. Kwamasambiro agha ghakaŵa pa ubwezi na St Benedict's High School ku Scotland, ndipo mazuŵa ghatatu pambere ulendo wawo undacitike, ŵakaphalirika kuti mapempho ghawo gha vikalata vyakunjilira mu caro ico ghakanika. Vikalata ivi vikawezgeka pamanyuma pakuti wupu wa Scotland Malawi Partnership wayowoyeskana na ŵanthumwi ŵa mphala. Kuwezgeka kwa vikalata ivi kukaŵa kwakuzizwiska, kweni cigaŵa ca boma ico cikaŵa na udindo cikakhumba yayi kudumbiskana umo suzgo ili likatenge likhweŵeke.<ref name=rumphi>{{Cite web |title=School visit rescued after last-minute visa issue |url=https://www.scotland-malawipartnership.org/news/school-visit-rescued-after-last-minute-visa-issue |access-date=2025-05-09 |website=www.scotland-malawipartnership.org |language=en-GB}}</ref>
Kuzingilizga Rumphi kuli minda ya fodya na minda ya [[Chingoma|ngoma]], skaŵa, cikhawu na kacewere.
== Ulongozgi ==
[[Chigaŵa chavisankho cha Pakati, Rumphi|Cigaŵa ca visankho ca Pakati, Rumphi]] ndico cigaŵa ca visankho cikulu ca kamsumba aka. Mu 2025, [[Enoch Chihana|Enock Chakufwa Chihana]] wakasankhika, kweni wakakwezgeka kuŵa Wakuovwira Mulongozgi wa Caro waciŵiri. Mu cisankho cakuzuzga malo ico cikalondezgapo, Dr. [[Matthews Mtumbuka|Mathews Mtumbuka]] wa wupu wa [[United Transformation Movement]] wakasankhika.<ref>{{Cite web |last=NyasaAuthor1 |date=2026-03-18 |title=Analysis: How Dr. Mathews Mtumbuka Captured Rumphi Central While the Blue Alliance Exposed Its Fault Lines - Malawi Nyasa Times - News from Malawi about Malawi |url=https://www.nyasatimes.com/analysis-how-dr-mathews-mtumbuka-captured-rumphi-central-while-the-blue-alliance-exposed-its-fault-lines/ |access-date=2026-05-18 |website=www.nyasatimes.com |language=en-GB}}</ref>
== Kupenda Ŵanthu ==
{| class="wikitable"
! Caka
! Ŵanthu<ref>[https://web.archive.org/web/20070927223224/http://www.world-gazetteer.com/wg.php?x=&men=gcis&lng=en&dat=32&srt=pnan&col=dq&geo=-150 World Gazetteer: Malawi: largest cities and towns and statistics of their population]</ref><ref name="Census2018" />
|-
| 1977
| 3,998
|-
| 1987
| 7,156
|-
| 1998
| 14,069
|-
| 2008
| 17,845
|-
| 2018
| 22,358
|}
== Vithuzi ==
<gallery mode="packed">
File:Pupils and teachers from St Patrick's Minor Seminary in Rumphi.jpg|Ŵasambiri na ŵasambizgi ŵa St Patrick's Minor Seminary
File:P1120150b.jpg|alt=Msika wa ng'ombe wa sabata yiliyose ku Rumphi|Msika wa ng'ombe wa sabata yiliyose ku Rumphi
File:EarthbagHouseRumphi.jpg|Nyumba yakwamba yakuzengeka na mathumba gha mcenga mu Boma la Rumphi, ku Roscher Youth Development Centre
</gallery>
== Vinyake vya Rumphi ==
=== Malo ===
Rumphi kali kummwera kwa Malo gha Caro ghakuvikilira Vinyama gha [[Nyika, Rumphi|Nyika]]. Kufuma ku Mzuzu, uko kuli kummwera kwake, ni ora limoza pa galimoto. Mronga wa Lunyina ukwenda mu mapiri na kufika pakati pa kamsumba aka, ndipo ukupeleka ku Rumphi maonekero ghakutowa.
Likulu la mpingo wa Church of Scotland lili ku [[Livingstonia, Malawi|Livingstonia]], makilomita 80 (mayilo 50) kumpoto kwa kumafumiro gha dazi, pa malo agho ŵanthu ŵakuwona patali [[Nyanja ya Malaŵi]].
=== Ŵanthu ===
Ŵanthu ŵa Rumphi ŵakumanyikwa na lusungu lwawo.{{Citation needed|date=August 2008}}
==== Mitundu ya ŵanthu ====
{| class="wikitable"
|Mtundu
|[[ŵaTumbuka]]
|[[ŵaChewa]]
|[[ŵaNgoni]]
|[[ŵaLomwe]]
|Ŵanyake<ref>Rumphi District in Malawi|Malawi Travel and Business Guide (malawiplus.com)</ref>
|-
|Unandi
|88.06%
|2.97%
|2.43%
|1.74%
|4.80%
|}
==== Cisopa ====
{| class="wikitable"
|Cisopa
|Ŵakhristu
|Ŵasilamu
|Ŵanyake
|Ŵambura kusopa
|-
|Unandi
|93.67%
|1.29%
|4.86%
|0.18%
|}
=== Ulimi ===
Kupatulapo fodya, ngoma, skaŵa, cikhawu na kacewere, mu Rumphi muli so minda ya nchunga na mbohori.
== Ukaboni ==
{{reflist}}
{{malawi-geo-stub}}
1whcrpy1qmh12f8zmyghwk0q20z29th
123443
123442
2026-11-03T09:23:11Z
Anthonymunthali44
5642
Kusola/visola: cigaŵa ca visola (vote = kusola)
123443
wikitext
text/x-wiki
{{Infobox settlement
<!--See the Table at Infobox Settlement for all fields and descriptions of usage-->
<!-- Basic info ---------------->| official_name = Rumphi
| other_name =
| native_name = <!-- for cities whose native name is not in English -->
| nickname =
| settlement_type = <!--For Town or Village (Leave blank for the default City)-->
| motto = <!-- images and maps ----------->
| image_skyline = MalawiRumphiMarket.png
| imagesize =
| image_caption = Msika wa kamsumba ka Rumphi
| image_flag =
| flag_size =
| image_seal =
| seal_size =
| image_shield =
| shield_size =
| image_blank_emblem =
| blank_emblem_type =
| blank_emblem_size =
| image_map =
| mapsize =
| map_caption =
| image_map1 =
| mapsize1 =
| map_caption1 =
| image_dot_map =
| dot_mapsize =
| dot_map_caption =
| dot_x =
| dot_y =
| pushpin_map = Malawi#Northern Region#Rumphi
| pushpin_mapsize = 240
| pushpin_label_position = bottom
| pushpin_map_caption = Location in Malawi
<!-- Location ------------------>| subdivision_type = Country
| subdivision_name = {{flag|Malawi}}
| subdivision_type1 = [[Regions of Malawi|Region]]
| subdivision_name1 = [[Northern Region, Malawi|Northern Region]]
| subdivision_type2 = [[Districts of Malawi|District]]
| subdivision_name2 = [[Rumphi District]]
| subdivision_type3 = Cigaŵa
| subdivision_name3 = [[Chigawa cha Chozoli-Mayembe|Chozoli-Mayembe]]
| subdivision_type4 = TA
| subdivision_name4 = [[TA Rumphi Boma|Rumphi Boma]]
| government_footnotes =
| government_type =
| leader_title =
| leader_name =
| leader_title1 = <!-- for places with, say, both a mayor and a city manager -->
| leader_name1 =
| leader_title2 =
| leader_name2 =
| leader_title3 =
| leader_name3 =
| leader_title4 =
| leader_name4 =
| established_title = <!-- Settled -->
| established_date =
| established_title2 = <!-- Incorporated (town) -->
| established_date2 =
| established_title3 = <!-- Incorporated (city) -->
| established_date3 = <!-- Area --------------------->
| area_magnitude =
| unit_pref = Imperial
<!--Enter: Imperial, if Imperial (metric) is desired-->| area_footnotes =
| area_total_km2 = <!-- ALL fields dealing with a measurements are subject to automatic unit conversion-->
| area_land_km2 = <!--See table @ Template:Infobox Settlement for details on automatic unit conversion-->
| area_water_km2 =
| area_total_sq_mi =
| area_land_sq_mi =
| area_water_sq_mi =
| area_water_percent =
| area_urban_km2 =
| area_urban_sq_mi =
| area_metro_km2 =
| area_metro_sq_mi =
| area_blank1_title =
| area_blank1_km2 =
| area_blank1_sq_mi = <!-- Population ----------------------->
| population_as_of = 2018 Census<ref name="Census2018">{{cite web|url=http://www.nsomalawi.mw/images/stories/data_on_line/demography/census_2018/2018%20Malawi%20Population%20and%20Housing%20Census%20Main%20Report.pdf|title=2018 Population and Housing Census Main Report|publisher=Malawi National Statistical Office|accessdate=25 December 2019|archive-url=https://web.archive.org/web/20200608191931/http://www.nsomalawi.mw/images/stories/data_on_line/demography/census_2018/2018%20Malawi%20Population%20and%20Housing%20Census%20Main%20Report.pdf|archive-date=8 June 2020}}</ref>
| population_footnotes =
| population_note =
| population_total = 22,358
| population_density_km2 =
| population_density_sq_mi =
| population_metro =
| population_density_metro_km2 =
| population_density_metro_sq_mi =
| population_urban =
| population_density_urban_km2 =
| population_density_urban_sq_mi =
| population_blank1_title = Ethnicities
| population_blank1 =
| population_blank2_title = Religions
| population_blank2 =
| population_density_blank1_km2 =
| population_density_blank1_sq_mi = <!-- General information --------------->
| timezone = +2
| utc_offset =
| timezone_DST =
| utc_offset_DST =
| coordinates = {{coord|11|01|S|33|52|E|region:MW|display=inline}}
| elevation_footnotes = <!--for references: use <ref> </ref> tags-->
| elevation_m =
| elevation_ft =
| blank1_name_sec2 = [[Köppen climate classification|Climate]]
| blank1_info_sec2 = [[Humid subtropical climate|Cwa]]
<!-- Area/postal codes & others -------->| postal_code_type = <!-- enter ZIP code, Postcode, Post code, Postal code... -->
| postal_code =
| area_code =
| blank_name =
| blank_info =
| blank1_name =
| blank1_info =
| website =
| footnotes =
}}
'''Rumphi''' ni likulu la [[Boma la Rumphi]] (Rumphi Boma) mu [[Chigaŵa cha Kumpoto|Cigaŵa ca Kumpoto]] ca [[Malaŵi]]. Ni kamsumba ka malonda ako kakuteŵetera ŵalimi ŵanandi ŵakukhala mu vigaŵa vyose vyakuzingilizga.
== Kalongosoro ==
Rumphi kali pa nthowa yakuluta ku Malo gha Caro ghakuvikilira Vinyama gha Nyika, ku Phiri la Thawali la Nyika, na ku Malo ghakuvikilira Vinyama gha Dambo la Vwaza. Kupambana na mzengezgana wake mukulu, [[Mzuzu]], uko kukuŵa dazi lambura koca comene pafupifupi caka cose, Rumphi kali na nyengo yakupambana. Pakuti kamsumba aka nkakuzingilizgika na tuphiri, nyengo zose kali na mphepo yiwemi. Kamsumba aka kakupakana na Mronga wa Rumphi kumafumiro gha dazi, na Mronga wa Rukuru wa Kummwera kummwera.
Ku Rumphi kuli msika wa ng'ombe Cisulo cilicose mulenji pa 6 koloko, uko ŵalimi na ŵamalonda ŵakwiza kuzakaguliska na kugula ng'ombe. Ni msika ukulu comene wa ng'ombe pakati pa [[Lilongwe]], [[Karonga]] na [[Mzimba (msumba)|Mzimba]]. Mumphepete mwa msewu wakuluta ku [[Bolero, Rumphi|Bolero]], kwakulaŵiskana na malo ghakusungirako ndalama gha FDH, kuli Roscher Youth Development Centre.<ref>{{Cite web |title=Home - Roscher Youth Development Centre |url=http://roscheryouthdevelopment.org |archive-url=https://web.archive.org/web/20241010223212/https://roscheryouthdevelopment.org/ |archive-date=2024-10-10 |access-date=2025-05-09 |website=Roscher Youth Development Centre |language=en-GB}}</ref> Pa malo gha wupu uwu, kummwera kwa Mronga wa Rukuru, wupu wa Vwilani Malaŵi e.V. (Support Malawi e.V.) ukambiska nyumba yakwamba ya ŵalendo yakuzengeka na mathumba gha mcenga (Earthbag House Lodge) mu Rumphi. Ŵawukirano ndiwo ŵakayizenga, na viliŵa vya mathumba gha mcenga ghakuwunjikika. Nyumba ya vyakulya yakuzengeka na mathumba gha mcenga (Earthbag Restaurant) nayo yikasonthola ŵalendo kweniso ŵanthu ŵakugona mu nyumba za ŵalendo izi.{{citation needed|date=May 2025}}
Kwamasambiro gha ŵasofi gha St Patrick's Minor Seminary ghali ku Rumphi. Mu 2018, kwamasambiro agha ghakazunulika mu mphala ya [[Ufumu Ubanyi]]. Kwamasambiro agha ghakaŵa pa ubwezi na St Benedict's High School ku Scotland, ndipo mazuŵa ghatatu pambere ulendo wawo undacitike, ŵakaphalirika kuti mapempho ghawo gha vikalata vyakunjilira mu caro ico ghakanika. Vikalata ivi vikawezgeka pamanyuma pakuti wupu wa Scotland Malawi Partnership wayowoyeskana na ŵanthumwi ŵa mphala. Kuwezgeka kwa vikalata ivi kukaŵa kwakuzizwiska, kweni cigaŵa ca boma ico cikaŵa na udindo cikakhumba yayi kudumbiskana umo suzgo ili likatenge likhweŵeke.<ref name=rumphi>{{Cite web |title=School visit rescued after last-minute visa issue |url=https://www.scotland-malawipartnership.org/news/school-visit-rescued-after-last-minute-visa-issue |access-date=2025-05-09 |website=www.scotland-malawipartnership.org |language=en-GB}}</ref>
Kuzingilizga Rumphi kuli minda ya fodya na minda ya [[Chingoma|ngoma]], skaŵa, cikhawu na kacewere.
== Ulongozgi ==
[[Chigaŵa chavisankho cha Pakati, Rumphi|Cigaŵa ca visola ca Pakati, Rumphi]] ndico cigaŵa ca visola cikulu ca kamsumba aka. Mu 2025, [[Enoch Chihana|Enock Chakufwa Chihana]] wakasoleka, kweni wakakwezgeka kuŵa Wakuovwira Mulongozgi wa Caro waciŵiri. Mu cisankho cakuzuzga malo ico cikalondezgapo, Dr. [[Matthews Mtumbuka|Mathews Mtumbuka]] wa wupu wa [[United Transformation Movement]] wakasankhika.<ref>{{Cite web |last=NyasaAuthor1 |date=2026-03-18 |title=Analysis: How Dr. Mathews Mtumbuka Captured Rumphi Central While the Blue Alliance Exposed Its Fault Lines - Malawi Nyasa Times - News from Malawi about Malawi |url=https://www.nyasatimes.com/analysis-how-dr-mathews-mtumbuka-captured-rumphi-central-while-the-blue-alliance-exposed-its-fault-lines/ |access-date=2026-05-18 |website=www.nyasatimes.com |language=en-GB}}</ref>
== Kupenda Ŵanthu ==
{| class="wikitable"
! Caka
! Ŵanthu<ref>[https://web.archive.org/web/20070927223224/http://www.world-gazetteer.com/wg.php?x=&men=gcis&lng=en&dat=32&srt=pnan&col=dq&geo=-150 World Gazetteer: Malawi: largest cities and towns and statistics of their population]</ref><ref name="Census2018" />
|-
| 1977
| 3,998
|-
| 1987
| 7,156
|-
| 1998
| 14,069
|-
| 2008
| 17,845
|-
| 2018
| 22,358
|}
== Vithuzi ==
<gallery mode="packed">
File:Pupils and teachers from St Patrick's Minor Seminary in Rumphi.jpg|Ŵasambiri na ŵasambizgi ŵa St Patrick's Minor Seminary
File:P1120150b.jpg|alt=Msika wa ng'ombe wa sabata yiliyose ku Rumphi|Msika wa ng'ombe wa sabata yiliyose ku Rumphi
File:EarthbagHouseRumphi.jpg|Nyumba yakwamba yakuzengeka na mathumba gha mcenga mu Boma la Rumphi, ku Roscher Youth Development Centre
</gallery>
== Vinyake vya Rumphi ==
=== Malo ===
Rumphi kali kummwera kwa Malo gha Caro ghakuvikilira Vinyama gha [[Nyika, Rumphi|Nyika]]. Kufuma ku Mzuzu, uko kuli kummwera kwake, ni ora limoza pa galimoto. Mronga wa Lunyina ukwenda mu mapiri na kufika pakati pa kamsumba aka, ndipo ukupeleka ku Rumphi maonekero ghakutowa.
Likulu la mpingo wa Church of Scotland lili ku [[Livingstonia, Malawi|Livingstonia]], makilomita 80 (mayilo 50) kumpoto kwa kumafumiro gha dazi, pa malo agho ŵanthu ŵakuwona patali [[Nyanja ya Malaŵi]].
=== Ŵanthu ===
Ŵanthu ŵa Rumphi ŵakumanyikwa na lusungu lwawo.{{Citation needed|date=August 2008}}
==== Mitundu ya ŵanthu ====
{| class="wikitable"
|Mtundu
|[[ŵaTumbuka]]
|[[ŵaChewa]]
|[[ŵaNgoni]]
|[[ŵaLomwe]]
|Ŵanyake<ref>Rumphi District in Malawi|Malawi Travel and Business Guide (malawiplus.com)</ref>
|-
|Unandi
|88.06%
|2.97%
|2.43%
|1.74%
|4.80%
|}
==== Cisopa ====
{| class="wikitable"
|Cisopa
|Ŵakhristu
|Ŵasilamu
|Ŵanyake
|Ŵambura kusopa
|-
|Unandi
|93.67%
|1.29%
|4.86%
|0.18%
|}
=== Ulimi ===
Kupatulapo fodya, ngoma, skaŵa, cikhawu na kacewere, mu Rumphi muli so minda ya nchunga na mbohori.
== Ukaboni ==
{{reflist}}
{{malawi-geo-stub}}
du4uv5766tkgupnlp1gf7izibilgzkq
Ga-Lepadima, Limpopo
0
18688
123410
48810
2026-11-02T20:26:47Z
Anthonymunthali44
5642
Duplicate of [[Ga-Lepadima]]: redirecting
123410
wikitext
text/x-wiki
#REDIRECT [[Ga-Lepadima]]
0r0qder44u86r1p8cb4jhniigksqu6s
Ga-Madiba, Limpopo
0
18700
123411
48828
2026-11-02T20:26:50Z
Anthonymunthali44
5642
Duplicate of [[Ga-Madiba]]: redirecting
123411
wikitext
text/x-wiki
#REDIRECT [[Ga-Madiba]]
1xr4it6t5vhr2tsgop4wksbph0zws6w
Ga-Mahoai, Limpopo
0
18704
123412
48832
2026-11-02T20:26:53Z
Anthonymunthali44
5642
Duplicate of [[Ga-Mahoai]]: redirecting
123412
wikitext
text/x-wiki
#REDIRECT [[Ga-Mahoai]]
kcmwqdpa6oxdq9zpwkrmopbmk8mz3xc
Ga-Ngwetsana, Limpopo
0
18723
123413
48851
2026-11-02T20:26:56Z
Anthonymunthali44
5642
Duplicate of [[Ga-Ngwetsana]]: redirecting
123413
wikitext
text/x-wiki
#REDIRECT [[Ga-Ngwetsana]]
g02pymul8a669epuihs6esbqwqfmykn
Ga-Ramokadikadi, Limpopo
0
18724
123414
48852
2026-11-02T20:27:00Z
Anthonymunthali44
5642
Duplicate of [[Ga-Ramokadikadi]]: redirecting
123414
wikitext
text/x-wiki
#REDIRECT [[Ga-Ramokadikadi]]
1hlq84yyyobvakuiequseghxenpv6he
Jozini, KwaZulu Natal
0
19555
123424
50298
2026-11-02T20:27:32Z
Anthonymunthali44
5642
Duplicate of [[Jozini]]: redirecting
123424
wikitext
text/x-wiki
#REDIRECT [[Jozini]]
duqtpmd04grc8lrkk3qmhdac8k4ccl1
Mtubatuba, KwaZulu Natal
0
19610
123425
50354
2026-11-02T20:27:35Z
Anthonymunthali44
5642
Duplicate of [[Mtubatuba]]: redirecting
123425
wikitext
text/x-wiki
#REDIRECT [[Mtubatuba]]
gp9thqbyqevsaolk13t1dv71pds3g5o
Mzuzu
0
20477
123441
122784
2026-11-02T23:38:10Z
Anthonymunthali44
5642
Kulondezga nkhani ya ChiNgelezi mzere na mzere; malembo gha mazgu ghakuzomerezgeka (Wikidata lexemes); vinthu vinyake vyasungika pasi
123441
wikitext
text/x-wiki
{{Infobox settlement
<!--See the Table at Infobox Settlement for all fields and descriptions of usage-->
<!-- Basic info ---------------->| official_name = Mzuzu
| other_name =
| native_name = <!-- for cities whose native name is not in English -->
| nickname =
| settlement_type = Msumba
| motto = <!-- images and maps ----------->
| image_skyline = MzuzuMalawi.JPG
| imagesize = 300px
| image_caption = Mzuzu
| image_flag =
| flag_size =
| image_seal =
| seal_size =
| image_shield =
| shield_size =
| image_blank_emblem =
| blank_emblem_type =
| blank_emblem_size =
| image_map =
| mapsize =
| map_caption =
| image_map1 =
| mapsize1 =
| map_caption1 =
| image_dot_map =
| dot_mapsize =
| dot_map_caption =
| dot_x =
| dot_y =
| pushpin_map = Malawi#Northern Region#Mzimba
| pushpin_mapsize = 240
| pushpin_label_position = bottom
| pushpin_map_caption = Location in Malawi
<!-- Location ------------------>| subdivision_type = Country
| subdivision_name = {{flag|Malawi}}
| subdivision_type1 = [[Regions of Malawi|Region]]
| subdivision_name1 = [[Northern Region, Malawi|Northern Region]]
| subdivision_type2 = [[Districts of Malawi|District]]
| subdivision_name2 = [[Mzimba]]
| subdivision_type3 = [[Chigaŵa chavisankho]]
| subdivision_name3 = [[Chigaŵa chavisankho cha Mzuzu Msumba|Mzuzu Msumba]]
| subdivision_type4 =
| subdivision_name4 = <!-- Politics ----------------->
| government_footnotes =
| government_type =
| leader_title =
| leader_name =
| leader_title1 = <!-- for places with, say, both a mayor and a city manager -->
| leader_name1 =
| leader_title2 =
| leader_name2 =
| leader_title3 =
| leader_name3 =
| leader_title4 =
| leader_name4 =
| established_title = <!-- Settled -->
| established_date =
| established_title2 = <!-- Incorporated (town) -->
| established_date2 =
| established_title3 = <!-- Incorporated (city) -->
| established_date3 = <!-- Area --------------------->
| area_magnitude =
| unit_pref = Imperial
<!--Enter: Imperial, if Imperial (metric) is desired-->| area_footnotes =
| area_total_km2 = <!-- ALL fields dealing with a measurements are subject to automatic unit conversion-->
| area_land_km2 = <!--See table @ Template:Infobox Settlement for details on automatic unit conversion-->
| area_water_km2 =
| area_total_sq_mi =
| area_land_sq_mi =
| area_water_sq_mi =
| area_water_percent =
| area_urban_km2 =
| area_urban_sq_mi =
| area_metro_km2 =
| area_metro_sq_mi =
| area_blank1_title =
| area_blank1_km2 =
| area_blank1_sq_mi = <!-- Population ----------------------->
| population_as_of = 2018 Census<ref>[https://malawi.unfpa.org/sites/...pdf/2018%20Census%20Preliminary%20Report.pdf] {{Dead link|date=April 2020 |bot=InternetArchiveBot |fix-attempted=yes }}</ref>
| population_footnotes =
| population_note =
| population_total = 221,272
| population_density_km2 =
| population_density_sq_mi =
| population_metro =
| population_density_metro_km2 =
| population_density_metro_sq_mi =
| population_urban =
| population_density_urban_km2 =
| population_density_urban_sq_mi =
| population_blank1_title = Ethnicities
| population_blank1 =
| population_blank2_title = Religions
| population_blank2 =
| population_density_blank1_km2 =
| population_density_blank1_sq_mi = <!-- General information --------------->
| timezone = +2
| utc_offset =
| timezone_DST =
| utc_offset_DST =
| coordinates = {{coord|11.45807|S|34.015131|E|region:MW|display=inline,title}}
| elevation_footnotes = <!--for references: use <ref> </ref> tags-->
| elevation_m =
| elevation_ft =
| blank1_name_sec2 = [[Köppen climate classification|Climate]]
| blank1_info_sec2 = [[Oceanic climate#Subtropical highland variety (Cwb)|Cwb]]
<!-- Area/postal codes & others -------->| postal_code_type = <!-- enter ZIP code, Postcode, Post code, Postal code... -->
| postal_code =
| area_code =
| blank_name =
| blank_info =
| blank1_name =
| blank1_info =
| website =
| footnotes =
}}
'''Mzuzu''' ni likulu la [[Chigaŵa cha Kumpoto|Cigaŵa ca Kumpoto]] mu [[Malaŵi]], ndipo ni msumba wacitatu mu Malaŵi pa unandi wa ŵanthu. Msumba uwu uli na ŵanthu 221,272 ŵakukhalamo na ŵanthu 20,000 ŵakwizakwiza (ŵasambiri ŵa Kwamasambiro ghakulu kwa Mzuzu), ndipo mu malo ghose ghakuzingilizga msumba uwu muli ŵanthu pafupifupi miliyoni yimoza.<ref name="commonwealth-of-nations.org">{{Cite web |title=Municipal in Malawi, Malawi Municipal, Mzuzu City Assembly welcome, Commonwealth |url=http://www.commonwealth-of-nations.org/Malawi/Municipal/Mzuzu_City_Assembly/welcome |url-status=dead |archive-url=https://web.archive.org/web/20110724031431/http://www.commonwealth-of-nations.org/Malawi/Municipal/Mzuzu_City_Assembly/welcome |archive-date=24 July 2011 |access-date=9 June 2011 |df=dmy-all}}</ref> Msumba uwu uli mu [[Boma la Mzimba]]. Mzuzu uli mu mpata wa mu mapili gha Viphya, ndipo malo gha ulimi ghakuzingilizga msumba uwu ghakumanyikwa comene na kulima tiyi, mphira na khofi. Nkholongo ya Viphya, iyo yili kumwera kwa msumba uwu, ndiyo nkholongo yikulu comene mu Afilika iyo ŵanthu ŵakapanda, ndipo nkholongo zakuvikilirika za Lunyangwa na Kaning'ina zili kumafumiro gha dazi gha msumba uwu.<ref name="TA">{{cite journal|date=August 2001|title=Malawi: Fragile Forests|journal=Travel Africa Magazine|issue=17|url=http://www.travelafricamag.com/content/view/149/56/|url-status=dead|archive-url=https://web.archive.org/web/20060822032058/http://www.travelafricamag.com/content/view/149/56/|archive-date=22 August 2006|df=dmy-all}}</ref>
Malo gha mu msumba uwu ni Chiŵavi, Luŵinga, Area 1B, Chiŵanja, Katoto, Zolozolo, Masasa, Mchenga-utuŵa, Chimaliro, Kaning'ina na Kataŵa.
== Kupenda Ŵanthu ==
{{historical populations|11=1977|12=16,108|13=1987|14=51,904|15=1998|16=86,980|17=2008|18=133,968|19=2018|20=221,272|percentages=pagr|footnote=source:<ref>{{Cite web|url=http://www.citypopulation.de/en/malawi/cities/|title=Malawi: Regions, Major Cities, Towns & Urban Localities - Population Statistics, Maps, Charts, Weather and Web Information|website=Citypopulation.de|access-date=22 November 2021}}</ref>|align=right}}
=== Mitundu ya ŵanthu ===
{{bar box|title=Mitundu mu Msumba wa Mzuzu (2018 Census)<ref name="Census2018" />|titlebar=#ddd|left1=Ethnic Groups|right1=percent|float=right|bars={{bar percent|Tumbuka|darkgreen|51.71}}
{{bar percent|Chewa|purple|13.51}}
{{bar percent|Ngoni|red|8.09}}
{{bar percent|Tonga|black|7.36}}
{{bar percent|Nkhonde|orange|4.08}}
{{bar percent|Lambya|darkblue|3.75}}{{bar percent|Yao|green|3.59}}
{{bar percent|Lomwe|maroon|3.54}}
{{bar percent|Sukwa|darkgray|1.07}}
{{bar percent|Sena|gray|0.66}}
{{bar percent|Mang'anja|tan|0.38}}
{{bar percent|Nyanja|lime|0.28}}
{{bar percent|Other|Violet|2}}}}Kuyana na kalembera wa 2018, Ŵatumbuka ndiwo ni mtundu ukulu comene mu msumba uwu, ndipo ŵakuŵa 80.50% ya ŵanthu wose. Mitundu yinyake yikuŵa 19.50% ya ŵanthu.<ref name="Census2018">{{cite web |title=2018 Population and Housing Census Main Report |url=http://www.nsomalawi.mw/images/stories/data_on_line/demography/census_2018/2018%20Malawi%20Population%20and%20Housing%20Census%20Main%20Report.pdf |access-date=25 December 2019 |publisher=Malawi National Statistical Office |archive-url=https://web.archive.org/web/20200608191931/http://www.nsomalawi.mw/images/stories/data_on_line/demography/census_2018/2018%20Malawi%20Population%20and%20Housing%20Census%20Main%20Report.pdf |archive-date=8 June 2020}}</ref>
=== Cisopa ===
{{Pie chart|thumb=right|caption='''Religions in Mzuzu City (2018 Census)<ref name="Census2018" />'''|label1=Church of Central Africa Presbyterian|value1=28.01|color2=#36A|label2=Catholic|value2=17.28|color1=#6A5|label3=Seventh-day Adventist/Baptist/Apostolic|value3=16.27|color3=#FF33AC|label4=Pentecostal|value4=6.62|color4=#1A9|label5=Anglican|value5=1.58|color5=#E17720|label6=Other Christian|value6=22.21|color6=#F0FF00|label7=Muslim|value7=4.06|color7=#64ECDF|label8=Traditional|value8=0.1|color8=#36A|label9=Other|value9=3.59|color9=#6A5|label10=No Religion|value10=0.28|color10=#FF33AC}}Mpingo ukulu comene mu Mzuzu ni Church of Central Africa Presbyterian (28.01%). Wakulondezgapo ni mpingo wa Katolika (17.28%). Visopa vinyake vicoko ni Seventh-day Adventist, Baptist na Apostolic (16.27% pamoza), Pentecostal (6.62%), Anglican (1.58%), mipingo yinyake ya Cikhristu (22.21%), Cisilamu (4.06%), cisopa ca makolo (0.1%), visopa vinyake (3.59%), na ŵanthu ŵambura cisopa (0.28%) mu msumba uwu.<ref name="Census2018" />
== Ukhaliro ==
Mzuzu uli na nyumba yakusungiramo vinthu vyakale, iyo yikajulika mu 1986, ndipo yikulongola vinthu vyakale vya mitundu yakupambanapambana ya Cigaŵa ca Kumpoto.<ref name="Lusaka">{{cite journal|last1=Lusaka|first1=Mwayi|date=4 Jan 2023|title=Curating the nation: Collections, ethnographic representations and heritage production at Museum of Malawi|url=https://www.tandfonline.com/doi/10.1080/23311983.2022.2160577|journal=Cogent Arts & Humanities|volume=10|doi=10.1080/23311983.2022.2160577|s2cid=255631526|access-date=26 January 2023}}</ref>
== Umoyo ==
Msumba wa Mzuzu ndimo muli Cipatala Cikulu ca Mzuzu (Mzuzu Central Hospital), cimoza mwa vipatala vinayi vikulu mu caru.
== Nyengo ==
Mzuzu uli na nyengo ya malo ghapacanya gha mu cigaŵa ca kufupi na tropiki (Cwb), ndipo vula yikuwa makora mwaka wose, kweniso koca yikuŵa yakuzizimirako na yiwemi.
{{Weather box|location=Mzuzu (1961–1990)|metric first=Yes|single line=Yes|Jan high C=25.5|Feb high C=25.6|Mar high C=24.8|Apr high C=23.5|May high C=22.1|Jun high C=20.4|Jul high C=20.3|Aug high C=21.9|Sep high C=25.1|Oct high C=27.2|Nov high C=27.2|Dec high C=26.1|year high C=24.1|Jan mean C=19.9|Feb mean C=20.0|Mar mean C=19.5|Apr mean C=18.7|May mean C=16.4|Jun mean C=13.9|Jul mean C=13.1|Aug mean C=14.0|Sep mean C=16.7|Oct mean C=19.4|Nov mean C=20.5|Dec mean C=20.1|year mean C=17.7|Jan low C=16.1|Feb low C=16.5|Mar low C=16.0|Apr low C=14.9|May low C=11.6|Jun low C=7.9|Jul low C=6.5|Aug low C=6.6|Sep low C=8.7|Oct low C=11.7|Nov low C=14.2|Dec low C=15.9|year low C=12.2|precipitation colour=green|Jan precipitation mm=203.3|Feb precipitation mm=179.5|Mar precipitation mm=224.1|Apr precipitation mm=213.0|May precipitation mm=58.8|Jun precipitation mm=29.5|Jul precipitation mm=30.1|Aug precipitation mm=11.8|Sep precipitation mm=10.4|Oct precipitation mm=35.4|Nov precipitation mm=95.7|Dec precipitation mm=197.0|year precipitation mm=1288.6|Jan humidity=82|Feb humidity=82|Mar humidity=85|Apr humidity=86|May humidity=85|Jun humidity=84|Jul humidity=83|Aug humidity=77|Sep humidity=67|Oct humidity=62|Nov humidity=70|Dec humidity=80|year humidity=79|unit precipitation days=0.3 mm|Jan precipitation days=20|Feb precipitation days=18|Mar precipitation days=20|Apr precipitation days=19|May precipitation days=9|Jun precipitation days=6|Jul precipitation days=6|Aug precipitation days=3|Sep precipitation days=2|Oct precipitation days=3|Nov precipitation days=9|Dec precipitation days=18|year precipitation days=133|Jan sun=145.7|Feb sun=137.2|Mar sun=164.3|Apr sun=171.0|May sun=217.0|Jun sun=219.0|Jul sun=238.7|Aug sun=275.9|Sep sun=288.0|Oct sun=300.7|Nov sun=252.0|Dec sun=176.7|year sun=2586.2|Jand sun=4.7|Febd sun=4.9|Mard sun=5.3|Aprd sun=5.7|Mayd sun=7.0|Jund sun=7.3|Juld sun=7.7|Augd sun=8.9|Sepd sun=9.6|Octd sun=9.7|Novd sun=8.4|Decd sun=5.7|yeard sun=|source 1=NOAA<ref name= NOAA>{{cite web
| url = ftp://ftp.atdd.noaa.gov/pub/GCOS/WMO-Normals/TABLES/REG__I/MW/67489.TXT
| title = Mzuzu Climate Normals 1961–1990
| publisher = [[National Oceanic and Atmospheric Administration]]
| access-date = 10 August 2016}}</ref>}}
== Cuma na Vyakuzenga ==
Vyakulima ni khofi, makuni, vipaso, mkaka na uci. Mu msumba uwu ndimo muli Kwamasambiro ghakulu kwa Mzuzu. Kusanda kwa mu 2022 pa Mzuzu, uko European Union yikapeleka ndalama, kukalongola nkhongono za msumba uwu na nthowa izo cuma cake cingakulila.
== Masambiro ==
Mu msumba uwu muli Kwamasambiro ghakulu kwa Mzuzu na Mzuzu Academy.<ref>{{cite web |title=Homepage |url=http://www.mzuzuacademy.org |publisher=mzuzuacademy.org}}</ref>
== Ŵalendo ==
Nyanja ya Malaŵi, malo ghakuvikilira vinyama gha cisapa ca Vwaza, na malo ghakuvikilira vinyama gha Nyika, agho ndigho ghakulu comene mu Malaŵi, vyose vili pafupi na Mzuzu.
== Vyakwendera ==
Msumba wa Mzuzu uli na malo gha ndege gha Mzuzu (Mzuzu Airport). Mu Zizima 2015, Unduna wa Milimo ya Boma na Vyakwendera wa Malaŵi ukayowoya kuti ukukhumba kuzenga malo ghaphya gha ndege, kweni mu 2022 vikalongola kuti kuzenga kucali kwambika yayi.
== Masewero ==
Matimu ghaŵiri gha mphira wa malundi, Moyale Barracks FC na Mzuni, ghakwimilira msumba uwu mu mpikisano ukulu comene wa Malaŵi. Bwalo la Masewero la Mzuzu (Mzuzu Stadium), ilo likukwana ŵanthu 15,000, ndilo pera bwalo la masewero mu msumba uwu, ndipo likazengeka pafupifupi mu 1970 na ŵakayidi.
== Ŵanthu Ŵakumanyikwa ==
* [[:en:Shepherd_Bushiri|Shepherd Bushiri]], uyo wakambiska mpingo wa Enlightened Christian Gathering, ni wa ku Mzuzu.
* Tusayiwe Mkhondya ni musambizgi wa ku Mzuzu.
== Vinyake vya Mzuzu ==
=== Mbiri ===
Msumba uwu ukazengeka mu 1947 kuzingilizga munda wa mafuta gha Tung wa Commonwealth Development Corporation, ndipo ukasangika mu 1985. Zina lakuti Mzuzu lili kufuma ku lizgu lakuti 'Vizuzu', ilo likayowoyeka mwakubudika na ŵazungu. Vizuzu ni vyakumera ivyo vikukula mumphepete mwa mlonga wa Lunyangwa. Vyakumera ivi ŵakaviwona kufupi na sukulu ya Mzuzu Government Secondary School, iyo yikucemeka so kuti Area 1A.
=== Mitundu yinyake ya ŵanthu ===
Pa kalembera wa 2018, mitundu yinyake ya ŵanthu mu msumba uwu yikaŵa Chewa na 13.51%, Ngoni na 8.09%, Tonga na 7.36%, Nkhonde na 4.08%, Lambya na 3.75%, Yao na 3.59%, Lomwe na 3.54%, Sukwa na 1.07%, Sena na 0.66%, Mang'anja na 0.38%, Nyanja na 0.28%, na mitundu yinyake na 2%.<ref name="Census2018" />
=== Viyowoyero na vyakulya ===
Citumbuka cikuyowoyeka comene mu Mzuzu, kweni viyowoyero vinyake nga ni Cicewa, Citonga, Ciswahili na Cingonde navyo vikuyowoyeka. Vyakulya ivyo ŵanthu ŵanandi ŵakutemwa ni sima (ya cimanga, panji ya maniyu, panji ya mayagho), mpunga, na somba ya batala (Mormyrus longirostris), iyo yikufuma ku Nyanja ya Malaŵi kufupi na Nkhata Bay. Vyakulya vinyake ivyo ŵanthu ŵakutemwa kulya ni cimanga, nthochi, vibama, nkhuku, maniyu na mbatata.
=== Vipatala vinyake ===
Mu msumba uwu muli so Mapale Health Centre, iyo yili pafupi na Shoprite. Paliso vipatala vinandi vya CHAM nga ni St. John, St. John of God Mental Hospital na Nkhorongo SDA Clinic. Msumba uwu uli so na vipatala vinyake vicoko nga ni Katoto MASM Medi Clinic, Mumbwe na Kandindindi Evergreen. Kampani ya Kentam Products Limited, iyo yikupanga munkhwala, yili ku Mzuzu.
=== Cuma ===
Cifukwa ca Kwamasambiro ghakulu kwa Mzuzu, msumba uwu uli na ŵanthu ŵaluso comene. Msumba uwu uli na malo ghawemi gha vyakulya, kweni ucali kupanga magesi. Ndalama zikwenda makora cifukwa ca mabanki ghaphya.<ref name="commonwealth-of-nations.org" /> Kweniso mu msumba uwu muli malonda ghacoko na ghapakati agho ghakupeleka mauthenga gha pa foni, mawebusayiti na mashopu. Malonda nga ni Chipiku, Peoples Trading na A.C. Opticals ghalipo. Msumba uwu ndimo muli makampani gha Mzuzu Coffee, Kentam Products Limited, Mzupaso Paints Limited na magazini ya Northern Life. Mzuzu uli na misika yikulu yiŵiri, kusazgapo Msika wa Taifa, uwo ukuguliska vipaso, vyakuvwala, mafoni, skapato na vinthu vinyake. Mzuzu uli so na msika wa Wasenga Brothers, uwo ukucemeka so Msika wa Mzuzu.
[[File:Mzuzu Market 10.jpg|thumb|Wasenga Brothers|left]]
=== Masambiro ===
Kwamasambiro ghakulu kwa Mzuzu ghakambika mu 1999, ndipo ghali na vigaŵa vinkhondi: Tourism and Hospitality Management, Education, Health Sciences, Environmental Sciences, na Information and Library Science. Mzuzu Technical College, iyo Ŵadada Ŵatuŵa ŵakayambiska mu 1958, yili ku Mzuzu. Mu msumba uwu muli sukulu zikulu za kumpoto nga ni Marymount Secondary School, Wukani Private Secondary School, Katoto Government Secondary School, Zolozolo Community Day Secondary School, Viphya Schools na Mzuzu Academy. Msumba uwu uli so na sukulu zinandi za pasi nga ni Wukani, Trust Academy, Wongani (iyo ŵa MIC Catholic Sisters ŵakuyendeska), Beehive na Hilltop.
=== Malo na ulimi ===
Msumba wa Mzuzu uli na makuni ghanandi kweniso mapili. Mu msumba uwu muli makuni ghanandi gha miombo. Kumpoto na kumwera kwa msumba uwu kuli mapili gha Viphya, agho ghali na utheka na makuni. Mu nyengo ya kuzizima, mu Mzuzu mukuzizima comene. Ŵanthu ŵanandi ŵakulima tiyi, mphira na khofi.
=== Ŵalendo ===
Nyanja ya Malaŵi yili na mcenga, ndipo ŵanthu ŵakutemwa kusambira mu maji. Ku malo ghakuvikilira vinyama gha Nyika, ŵanthu ŵakwenda mu mapili, ŵakukwera njinga, ŵakukwera mahaci na kwenda pa galimoto. Malo gha vyakusanguluska gha mu hotelo ya Mzuzu na O Seasons, agho kale ghakacemekanga Key Lounge, ghakukopa ŵanthu ŵa mu caru cose na vyaru vinyake. Malo ghanyake ghakusanguluskilako ni Mzuzu Golf Club, Villa Kagwentha (iyo yikumanyikwa na disko mise yiliyose ya Cisulo) na Squirrels Park. Paliso malo ghakupambanapambana ghakupumulilako nga ni Lake View Lodge na Mzuzu Sanctuary. Mzuzu Botanic Gardens yili ku Zolozolo. Ŵanthu ŵangenda mu mapili gha Kaning'ina. Damu la Gulliver, ilo likupeleka maji ku msumba wa Mzuzu na vigaŵa vyakuzingilizga, likupeleka so malo ghakwenda.
Gulu lakwamba la Scout (UK) lazenga msasa wa Scout uwo uli na vinthu vinandi kuwaro kwa Mzuzu.<ref>{{Cite web |title=Kavuzicampsite |url=http://www.campingmalawi.com/ |url-status=dead |archive-url=https://web.archive.org/web/20170706065004/http://www.campingmalawi.com/ |archive-date=6 July 2017 |access-date=19 June 2017}}</ref><ref>{{Cite web |title=1st Poulner Scout Group - Kavuzi Campsite |url=http://www.1stpoulnerscouts.org.uk/malawi/kavuzi-campsite/ |url-status=dead |archive-url=https://web.archive.org/web/20160703092919/http://1stpoulnerscouts.org.uk/malawi/kavuzi-campsite/ |archive-date=3 July 2016 |access-date=19 June 2017 |df=dmy-all}}</ref>
=== Vyakwendera vinyake ===
Mu 2017, boma likamba kuzenga malo ghaphya na ghakulu gha ndege mu cigaŵa ca Dunduzu.<ref name="commonwealth-of-nations.org" /> Msumba wa Mzuzu uli mumphepete mwa msewu ukulu wa M1, uwo ukufuma kumpoto kuluta kumwera. Mzuzu ni malo gha kumpoto kwa msewu wa M5, uwo ukujumpha kumafumiro gha dazi mu mapili gha Viphya kuluta ku Nkhata Bay, ndipo kufuma apo ukuluta kumwera kufupi na Nyanja ya Malaŵi.
=== Masewero ghanyake ===
Ŵanthu ŵanandi ku Mzuzu ŵakutemwa masewero gha mphira wa malundi. Mu msumba uwu muli so matimu ghaŵiri gha basketball, [[Nkhulande]] na [[Pistons]].
=== Shepherd Bushiri ===
Bushiri ndiyo wakambiska so PSB Network<ref>{{Cite web |title=PSB Network | The Mobile Network That Cares |url=http://www.mypsb.co.za/ |website=Mypsb.co.za |accessdate=22 November 2021 |archive-url=https://web.archive.org/web/20211122191845/http://www.mypsb.co.za/ |archive-date=22 November 2021}}</ref> na Prophetic Channel.<ref>{{Cite web |title=Prophet Shepherd Bushiri - YouTube |url=https://www.youtube.com/user/propheticchannelTv |access-date=22 November 2021 |publisher=[[YouTube]]}}</ref>
== Ukaboni ==
<references group="" responsive="1"></references>
== Milumikizgi yakuwaro ==
{{commons category-inline}}{{Authority control}}
[[Category:Msumba mu Boma la Mzimba]]
gfhrbm2f5oc1yct5kujbftusqru1er5
Chatsworth, KwaZulu Natala
0
20924
123437
62514
2026-11-02T21:17:56Z
Anthonymunthali44
5642
Duplicate of [[Chatsworth, KwaZulu Natal]]: redirecting
123437
wikitext
text/x-wiki
#REDIRECT [[Chatsworth, KwaZulu Natal]]
bqhrdrmsdum5ry6n4ou7cp7r7deh5he
Lephalale (Ellisras), Limpopo
0
23961
123417
67192
2026-11-02T20:27:09Z
Anthonymunthali44
5642
Duplicate of [[Lephalale, Limpopo]]: redirecting
123417
wikitext
text/x-wiki
#REDIRECT [[Lephalale, Limpopo]]
8ygor3489gdigpqfq8qvpzp5w5jgcho
Mookgophong (Naboomspruit), Limpopo
0
23966
123439
67197
2026-11-02T21:18:02Z
Anthonymunthali44
5642
Duplicate of [[Mookgophong, Limpopo]]: redirecting
123439
wikitext
text/x-wiki
#REDIRECT [[Mookgophong, Limpopo]]
6k8lqjbhkebhyuqennqemnx2ytzx69u
Ulundi, KwaZulu Natal
0
23994
123428
67226
2026-11-02T20:27:45Z
Anthonymunthali44
5642
Duplicate of [[Ulundi]]: redirecting
123428
wikitext
text/x-wiki
#REDIRECT [[Ulundi]]
iarnw0fsa7e47hkl0e58e6683ey11gg
Nongoma, KwaZulu Natal
0
23995
123426
67227
2026-11-02T20:27:39Z
Anthonymunthali44
5642
Duplicate of [[Nongoma]]: redirecting
123426
wikitext
text/x-wiki
#REDIRECT [[Nongoma]]
0w6mnlhqvs79svkdfj28fo9bmnbfvfn
Cornfields, KwaZulu Natala
0
24042
123438
67278
2026-11-02T21:17:59Z
Anthonymunthali44
5642
Duplicate of [[Cornfields, KwaZulu Natal]]: redirecting
123438
wikitext
text/x-wiki
#REDIRECT [[Cornfields, KwaZulu Natal]]
tlxng5on2tduuhor26wq77hu7nbr4xi
Nquthu, KwaZulu Natal
0
24355
123427
68006
2026-11-02T20:27:42Z
Anthonymunthali44
5642
Duplicate of [[Nquthu]]: redirecting
123427
wikitext
text/x-wiki
#REDIRECT [[Nquthu]]
656ugoucs4gtg2yzmrr25004rizfmgv
Impendle, KwaZulu Natal
0
24427
123423
68079
2026-11-02T20:27:29Z
Anthonymunthali44
5642
Duplicate of [[Impendle]]: redirecting
123423
wikitext
text/x-wiki
#REDIRECT [[Impendle]]
nszcgpe3uk2oz9vty4k7qamfipt6yar
Kisii (Kenia)
0
25432
123420
70672
2026-11-02T20:27:19Z
Anthonymunthali44
5642
Duplicate of [[Kisii, Kenya]]: redirecting
123420
wikitext
text/x-wiki
#REDIRECT [[Kisii, Kenya]]
hkrq35rnoypfrf1bzwwxbe0tt1036px
Kakamega
0
25435
123419
70675
2026-11-02T20:27:16Z
Anthonymunthali44
5642
Duplicate of [[Kakamega, Kenya]]: redirecting
123419
wikitext
text/x-wiki
#REDIRECT [[Kakamega, Kenya]]
6hbvfhw7n4p9wkhnb06m2tesx441urn
Ngoussoua, Ndele
0
26138
123422
72920
2026-11-02T20:27:26Z
Anthonymunthali44
5642
Duplicate of [[Ngoussoua, Bamingui]]: redirecting
123422
wikitext
text/x-wiki
#REDIRECT [[Ngoussoua, Bamingui]]
fxcgco9j3yudgpsdx4qt42b6mjqrrdg
Essen, Germany
0
27264
123415
74702
2026-11-02T20:27:03Z
Anthonymunthali44
5642
Duplicate of [[Essen]]: redirecting
123415
wikitext
text/x-wiki
#REDIRECT [[Essen]]
q5xwwlqumxfkccfvz1f4f2zc3cfpcuh
Offenbach am Main
0
27351
123416
74798
2026-11-02T20:27:06Z
Anthonymunthali44
5642
Duplicate of [[Offenbach]]: redirecting
123416
wikitext
text/x-wiki
#REDIRECT [[Offenbach]]
q7e3lt3q9f8ube1f0088y703kwet5zc
MediaWiki:Group-sysop.js
8
36383
123404
115767
2026-11-02T19:50:27Z
Maintenance script
3102
Use thumb.wikimedia.org for thumbnails ([[phab:T427465]], Operator: Ladsgroup)
123404
javascript
text/javascript
// <nowiki>
$(function () {
// Opt-out
if ( window.disableSysopJS ) {
return;
}
/**
* Automatic deletion dropdown
*
* Looks for CSD/XFD/PROD templates on a page; if one is present, picks up
* the deletion reason that's hidden on the template and tweaks the 'delete'
* tab link to preload that deletion summary.
*
* Maintainers: Happy-melon
*/
(function () {
var link, reason;
if (document.getElementById('ca-delete') && document.getElementById('delete-criterion')) {
link = document.getElementById('ca-delete').getElementsByTagName('A')[0];
reason = document.getElementById('delete-reason').innerHTML;
link.setAttribute('href' , link.getAttribute('href') + '&wpReason=' + reason);
}
})();
/**
* Sensitive IP checker
*
* Notify admins when they might block a sensitive IP address. IP addresses
* may be classed as sensitive for political reasons, or because they
* affect bots or other technical services which Wikipedia uses. See
* [[WP:SIP]] for more details.
*
* Maintainers: Mr. Stradivarius
*/
if (mw.config.get('wgCanonicalSpecialPageName') === 'Block' || mw.config.get('wgCanonicalSpecialPageName') === 'Contributions') {
// Load dependencies.
mw.loader.using([
'ext.gadget.libSensitiveIPs',
'mediawiki.api',
'mediawiki.util',
'mediawiki.jqueryMsg',
]).then( function() {
// Check whether we have a valid IP address or CIDR range, and exit
// if not. (If the second argument to isIPAddress is true, then
// CIDR ranges are allowed as well.)
// Can't use wgRelevantUserName, it isn't defined for IP ranges: [[phab:T206954]]
if (mw.config.get('wgCanonicalSpecialPageName') === 'Block') {
$ip = $('input[name=wpTarget]');
} else if (mw.config.get('wgCanonicalSpecialPageName') === 'Contributions') {
$ip = $('input[name=target]');
}
if (!$ip.length || !mw.util.isIPAddress($ip.val(), true)) {
return;
}
// Test whether the IP or range is sensitive.
mw.libs.sensitiveIPs.query({
test: [$ip.val()]
}).then(function (data) {
var match = data.sensitiveips.matches[0],
description,
$msg;
if (!match) {
// The IP address or range is not sensitive, so exit.
return;
}
// The IP or range is sensitive, so notify the user. First,
// get the description of the entity the IP or range belongs
// to.
description = data.sensitiveips.entities[match['entity-id']].description;
if (!description) {
throw new Error('No description found for entity with code "' + match['entity-id'] + '"');
}
// Vary message according to page
var action = mw.config.get('wgCanonicalSpecialPageName') === 'Block' ? 'blocking' : 'viewing';
// Set the message text. The description is in wikitext, so
// we set the whole message as wikitext and then parse it into
// HTML with message.parse().
mw.messages.set({
'sysop-sensitive-ip-block-warning': 'You are ' + action +
' a sensitive IP address belonging to ' +
description +
'. Please be sure to ' +
'[[meta:Communications committee/Notable blocks|notify]] the ' +
'[[meta:Communications committee|Wikimedia Foundation Communications Committee]] ' +
'immediately if blocked.'
});
// Assemble the message to notify the user with.
$msg = $('<table>').append(
$('<tr>').append(
$('<td>').css({'vertical-align':'center'}).append(
$('<img>').attr({'src': '//thumb.wikimedia.org/wikipedia/commons/thumb/f/f7/Nuvola_apps_important.svg/60px-Nuvola_apps_important.svg.png'}).css({width: '48px'})
)
).append(
'<td>' + mw.message('sysop-sensitive-ip-block-warning').parse() + '</td>'
)
);
// Send the notification.
mw.notify($msg);
});
});
}
});
// </nowiki>
ohb0axlwig6mrg2lnv4eohwfebpnl38
Hamar Municipality
0
37216
123418
93150
2026-11-02T20:27:13Z
Anthonymunthali44
5642
Duplicate of [[Hamar]]: redirecting
123418
wikitext
text/x-wiki
#REDIRECT [[Hamar]]
q258itn0c11s1eubwd1uv499x31y7hg
Template:IPA vowels/styles.css
10
37533
123405
93802
2026-11-02T19:50:28Z
Maintenance script
3102
Use thumb.wikimedia.org for thumbnails ([[phab:T427465]], Operator: Ladsgroup)
123405
sanitized-css
text/css
/* {{pp-template}} */
.IPA-vowels-noaudio {
background: #f8f9fa url(//thumb.wikimedia.org/wikipedia/commons/thumb/4/4f/Blank_vowel_trapezoid.svg/320px-Blank_vowel_trapezoid.svg.png) bottom 10% right 10% no-repeat;
}
.IPA-vowels-audio {
background: #f8f9fa url(//thumb.wikimedia.org/wikipedia/commons/thumb/4/4f/Blank_vowel_trapezoid.svg/600px-Blank_vowel_trapezoid.svg.png) bottom 10% right 10% no-repeat;
}
.IPA-vowels-main {
table-layout: fixed;
border-collapse: collapse;
text-align: center;
}
.IPA-vowels-nocaption {
border: 1px solid #a2a9b1;
}
.IPA-vowels-main th {
vertical-align: middle;
background: #f8f9fa;
}
.IPA-vowels-main th[scope="col"] {
text-align: center;
padding-top: 0.2em;
}
.IPA-vowels-main th[scope="row"] {
text-align: right;
padding-left: 0.4em;
}
.IPA-vowels-main td {
vertical-align: middle;
}
.IPA-vowels-noaudio td {
width: 106.67px;
min-width: 106.67px;
height: 32px;
}
.IPA-vowels-audio td {
width: 200px;
min-width: 200px;
height: 60px;
}
.IPA-vowels-minorcaption {
font-weight: normal;
}
.IPA-vowels-container {
display: flex;
justify-content: center;
font-size: 125%;
line-height: 1.2;
}
.IPA-vowels-container-dot {
text-align: center;
width: 1em;
background: #f8f9fa;
}
.IPA-vowels-container-left {
max-width: 1em;
min-width: 1em;
direction: rtl;
text-align: right;
}
.IPA-vowels-container-left > span {
padding-left: 0.2em;
background: #f8f9fa;
}
.IPA-vowels-container-right {
max-width: 1em;
min-width: 1em;
direction: ltr;
text-align: left;
}
.IPA-vowels-container-right > span {
padding-right: 0.2em;
background: #f8f9fa;
}
.IPA-vowels-container-single {
padding-left: 0.2em;
padding-right: 0.2em;
background: #f8f9fa;
}
dj6mjw7wirewcxg2r3a8kuvu3alj6zs
Zulueta (Remedios)
0
45610
123421
108386
2026-11-02T20:27:22Z
Anthonymunthali44
5642
Duplicate of [[Zulueta, Cuba]]: redirecting
123421
wikitext
text/x-wiki
#REDIRECT [[Zulueta, Cuba]]
352qclmdkwigghgabfx05zhfvr9cb0k
MediaWiki:Gadget-Adiutor.css
8
45914
123400
109173
2026-11-02T19:50:21Z
Maintenance script
3102
Use thumb.wikimedia.org for thumbnails ([[phab:T427465]], Operator: Ladsgroup)
123400
css
text/css
/*
* Adiutor: A gadget to assist various user actions
* Author: Vikipolimer
* Licencing and attribution: Creative Commons Attribution-ShareAlike 4.0 International (CC BY-SA 4.0)
*/
.adiutor-user-dashboard-container {
padding: 65px;
background-image: url(https://upload.wikimedia.org/wikipedia/commons/a/ac/Illustration_of_Reading_Wikipedia_in_the_Classroom_%28blue%29_03.png);
background-repeat: no-repeat;
background-position: calc(100% - 10%) 30%;
background-size: 35%;
}
.adiutor-user-dashboard-stats-container {
width: 55%;
display: flex !important;
margin-top: 35px;
}
.adiutor-user-dashboard-adiutor-total-stats {
float: left;
width: inherit;
background-color: #3367cc !important;
border: none !important;
color: white;
}
.adiutor-user-dashboard-adiutor-total-stats .oo-ui-iconElement-icon {
filter: invert(2);
}
.adiutor-user-dashboard-adiutor-csd-stats {
float: left;
width: inherit;
margin: 0px !important;
border: none !important;
;
}
.adiutor-user-dashboard-adiutor-afd-stats {
float: right;
margin: 0px !important;
width: inherit;
border: none !important;
;
}
.adiutor-user-dashboard-main-x {
height: -webkit-fill-available;
}
span.adiutor-user-dashboard-top-logo {
width: 201px;
display: inline-grid;
text-align-last: left;
}
span.adiutor-user-dashboard-bottom-about-button {
width: 201px;
display: inline-grid;
text-align-last: left;
}
label.adiutor-user-dashboard-contribution-count {
display: block;
font-size: 16px;
line-height: 36px;
font-weight: 100;
margin-bottom: 10px;
}
label.adiutor-user-dashboard-welcome-text {
font-size: 34px;
margin-right: 14px;
font-weight: 300;
}
label.adiutor-user-dashboard-welcome-username {
font-size: 34px;
font-weight: 700;
color: #3366cc;
}
.adiutor-user-dashboard-adiutor-description {
width: 55%;
margin-top: 50px;
font-size: 17px;
text-align: justify;
}
.adiutor-user-dashboard-adiutor-description .oo-ui-labelElement-label {
font-weight: 300;
}
label.adiutor-user-dashboard-logo {
background-image: url('https://upload.wikimedia.org/wikipedia/commons/1/1a/Adiutor_logo.svg');
width: 200px;
height: 100px;
background-size: 133px;
background-repeat: no-repeat;
position: absolute;
bottom: 0;
right: 0;
}
.adiutor-administrator-helper-csd-requests-butons {
float: right;
}
.adiutor-administrator-helper-article-content {
margin-top: 70px !important;
}
.adiutor-administrator-helper-csd-article-content {
padding: 0 !important;
}
.adiutor-administrator-helper-csd--toolbar {
height: 33px;
padding: 10px;
background: #ffffff;
border-bottom: 1px solid #c8ccd0;
position: fixed;
width: 100%;
width: -webkit-fill-available;
text-align: right;
}
.adiutor-administrator-helper-csd--content-area {
margin-top: 60px;
padding: 50px;
}
.adiutor-administrator-helper-csd-toolbar-page-name {
float: left;
padding: 10px;
font-weight: 900;
font-size: 14px;
}
.afd-helper-button-group {
float: right;
font-size: 12px;
}
.afd-helper-comment-textarea textarea {
height: 80px;
}
.afd-helper-notification {
position: fixed;
top: 90px;
right: 70px;
width: 215px;
font-size: 12px;
padding: 20px !important;
}
.afd-opinion-select-btn-group {
display: flex !important;
flex-wrap: wrap !important;
width: 100%;
padding: 0;
margin: 0;
}
.afd-opinion-select-btn {
flex-grow: 1;
display: grid !important;
font-size: 12px;
}
.afd-result-select-btn-group {
display: flex !important;
flex-wrap: wrap !important;
width: 100%;
padding: 0;
margin: 0;
}
.afd-result-select-btn {
flex-grow: 1;
display: grid !important;
font-size: 12px;
}
.xfd-closed .afd-helper-button-group {
display: none;
}
#Bakım_bağlantıları .afd-helper-button-group {
display: none;
}
.adiutor-top-selector {
margin-top: 2px;
}
.adiutor-csd-modal-container {
display: flex;
position: inherit;
}
.adiutor-csd-modal-container .one {
width: 50%;
float: left;
}
.adiutor-csd-modal-container .two {
width: 50%;
float: right;
padding-left: 25px;
}
.cov-url-list-item {
padding: 10px;
background: #ffffff;
list-style: none;
margin-bottom: 5px;
border: 1px solid #dadada;
}
.cov-url-list-item a {
color: black;
}
ul.cov-url-list {
padding: 0;
margin: 0;
}
.cov-url-list-item-vio-high {
border: 1px solid #de3333;
background: white;
color: red;
}
.cov-url-list-item-vio-high a {
font-weight: 900;
color: #de3333;
}
.adiutor-top-settings-menu {
border-top: 1px solid #cecece;
}
.adiutor-top-user-menu {
border-bottom: 1px solid #cecece;
}
.adiutor-user-status {
position: relative;
font-size: 14px;
float: right;
color: #04af89;
font-family: system-ui;
text-align: right;
font-weight: 700;
}
.adiutor-user-status-active {
position: relative;
width: 75px;
font-size: 14px;
float: right;
color: #04af89;
font-family: system-ui;
text-align: right;
font-weight: 700;
}
.adiutor-user-status-active:before {
content: '';
width: 26px;
height: 24px;
position: absolute;
top: 9px;
left: 6px;
background-image: url(https://upload.wikimedia.org/wikipedia/commons/a/aa/OOjs_UI_icon_userTalk-ltr-constructive.svg);
background-repeat: no-repeat;
background-size: 18px;
}
.adiutor-user-status-passive {
position: relative;
width: 110px;
font-size: 14px;
float: right;
color: #04af89;
font-family: system-ui;
text-align: right;
font-weight: 700;
}
.adiutor-user-status-passive:before {
content: '';
width: 26px;
height: 24px;
position: absolute;
top: 9px;
left: 6px;
background-image: url(https://upload.wikimedia.org/wikipedia/commons/b/b6/OOjs_UI_icon_userTalk-ltr.svg);
background-repeat: no-repeat;
background-size: 18px;
}
.adiutor-user-status-away {
position: relative;
width: 85px;
font-size: 14px;
float: right;
color: #d9ab21;
font-family: system-ui;
text-align: right;
font-weight: 700;
}
.adiutor-user-status-away:before {
content: '';
width: 26px;
height: 24px;
position: absolute;
top: 9px;
left: 6px;
background-image: url(https://upload.wikimedia.org/wikipedia/commons/b/b6/OOjs_UI_icon_userTalk-ltr.svg);
background-repeat: no-repeat;
background-size: 18px;
}
.adiutor-user-status-selector {
display: inline;
float: right;
width: 98px;
font-size: 12px;
font-family: sans-serif;
}
.adiutor-top-rrd-menu {
border-bottom: 1px solid #cecece;
}
.adiutor-mentor-response-preview-area {
margin-top: 15px;
border: 1px solid #a2a9b1;
padding: 10px;
}
.adiutor-rpp-botton-select {
margin-top: 10px;
}
.adiutor-top-user-menu-end {
border-bottom: 1px solid #a2a9b1;
}
.adiutor-tag-list-container {
max-height: 350px;
overflow: scroll;
}
.adiutor-csd-modal-dialog-notification {
position: absolute;
top: 60px;
right: 100px;
z-index: 999;
}
.articles-worked-on-popup .oo-ui-popupWidget-head {
box-sizing: border-box;
border-bottom: 1px solid #c8ccd1;
margin: 0;
font-size: 1.2em;
font-weight: bold;
line-height: 2.5595238em;
}
.articles-worked-on-popup>.oo-ui-popupWidget-popup>.oo-ui-popupWidget-footer {
width: 100%;
margin: 0;
border-top: 1px solid #c8ccd1;
}
.articles-worked-on-popup-footer-buttons {
display: flex;
margin: 0;
justify-content: space-between;
}
.articles-worked-on-popup-footer-button {
flex: 1;
margin: 0;
display: grid;
height: 50px;
border: none;
}
.articles-worked-on-popup-footer-button .oo-ui-buttonElement-button {
padding: 14px !important;
font-size: inherit;
font-weight: bold;
border-top: none;
border-bottom: none;
border-right: none;
}
.adiutor-work-list-item:hover {
background: #ececec !important;
}
.adiutor-work-list-item {
margin: 0px !important;
cursor: pointer;
padding-left: 10px !important;
border: none !important;
background: #f8f9fa !important;
border-top: 1px solid #a2a9b1 !important;
}
.articles-worked-on-popup-search-box input {
height: 50px;
border: none !important;
padding-left: 10px !important;
}
.adiutor-aricle-detail-box {
margin-top: -0.7px;
padding: 10px !important;
display: list-item;
height: 50px;
padding-top: 15px !important;
font-size: 12px;
background-color: #f7f8f9 !important;
border-color: #a2a9b1 !important;
}
span.adiutor-aricle-detail-box-button-group {
right: 45px;
display: revert;
position: absolute;
top: 8px;
}
.articles-worked-on-popup-search-box-enmpy {
display: flex;
padding: 5px;
padding-bottom: 15px;
font-weight: initial;
padding-top: 20px;
padding-right: 15px;
}
.articles-worked-on-popup-search-box-enmpy-image .oo-ui-iconElement-icon {
display: none !important;
}
.articles-worked-on-popup-search-box-enmpy-image .oo-ui-labelElement-label {
padding: 10px;
margin: 0;
padding-top: 0;
}
.adiutor-page-more-info-tip-author {
border: none !important;
margin: 0 !important;
}
.adiutor-page-more-info-tip-date {
border: none !important;
margin: 0 !important;
}
.adiutor-page-more-info-tip-keyword {
border: none !important;
margin: 0 !important;
border-top: 1px solid #a2a9b1 !important;
}
.adiutor-user-page-container {
margin-top: 20px;
display: initial;
position: inherit;
}
.adiutor-user-page-box-container {
width: 99.80%;
display: flex !important;
margin: 0;
background: #f8f9fa;
border: 1px solid #d1d1d1;
height: 90px;
}
.adiutor-user-page-username-details {
float: left;
width: inherit;
background-color: #f8f9fa !important;
border: none !important;
color: #000;
display: grid;
padding-left: 54px !important;
}
.adiutor-user-page-username-details .oo-ui-iconElement-icon {
filter: invert(2);
}
.adiutor-user-page-change-count {
float: left;
width: inherit;
margin: 0px !important;
border: none !important;
background-color: #ffffff00 !important;
border-left: 1px solid #d1d1d1 !important;
}
.adiutor-user-page-miscellaneous {
float: right;
margin: 0px !important;
width: inherit;
border: none !important;
;
}
span.adiutor-user-page-button-group {
display: inherit;
position: relative;
margin-top: 28px !important;
margin-right: 18px !important;
}
.adiutor-user-page-username-details .oo-ui-iconElement-icon {
background-image: url(https://thumb.wikimedia.org/wikipedia/commons/thumb/4/47/OOjs_UI_icon_userAvatarOutline-progressive.svg/1920px-OOjs_UI_icon_userAvatarOutline-progressive.svg.png);
background-position: center !important;
width: 50px;
height: 50px;
filter: unset;
display: block;
float: left;
background-size: 50px;
margin-top: 18px;
margin-left: 16px;
}
h2.adiutor-help-content-heading-sub {
font-size: 16px;
font-weight: 900;
color: #3367cc;
}
span.adiutor-aricle-show-video-button {
position: absolute;
z-index: 99;
right: 23px;
top: 30px;
}
.adiutor-dashboard-administrator-tools-welcome {
display: flex;
justify-content: space-around;
align-items: center;
flex-direction: column;
padding: 50px;
}
.adiutor-dashboard-administrator-tools-fd-welcome-messsage {
margin: 0;
width: 55%;
display: revert;
text-align: center;
}
.adiutor-dashboard-administrator-tools-fd-welcome-messsage .oo-ui-labelElement-label {
margin: 0;
}
.adiutor-dashboard-administrator-tools-fd-welcome-messsage span {
margin: 0 !important;
}
.adiutor-dashboard-administrator-tools-welcome-img span {
display: none;
margin: 0 !important;
width: 100%;
}
.adiutor-dashboard-administrator-tools-welcome-top{
display: contents !important;
}
cuau3lkp1he8bpcpzxnmqddnw8rra1s
MediaWiki:Gadget-ProveIt-classic.js
8
46305
123401
110461
2026-11-02T19:50:22Z
Maintenance script
3102
Use thumb.wikimedia.org for thumbnails ([[phab:T427465]], Operator: Ladsgroup)
123401
javascript
text/javascript
/* _____________________________________________________________________________
* | |
* | === WARNING: GLOBAL GADGET FILE === |
* | Changes to this page affect many users. |
* | Please discuss changes on the talk page or on [[WT:Gadget]] before editing. |
* |_____________________________________________________________________________|
*/
// <nowiki>
/*
* Imported from Git commit 72b9abf17fe33ab8af55a7cfb074a9beb35365ab as of 2015-03-09 from https://github.com/proveit-js/proveit
* Changes should be made through that GitHub project.
*/
/*
* ProveIt ([[User:ProveIt GT]]) is a powerful GUI tool for viewing, adding, editing, and inserting references on Wikipedia.
*
* Copyright 2008 - 2011
*
* Georgia Tech Research Corporation
*
* Atlanta, GA 30332-0415
*
* Copyright 2011 -
*
* Matthew Flaschen
*
* ALL RIGHTS RESERVED
*
* ProveIt is available under the GNU Free Documentation License (GFDL-1.3.txt), Creative Commons
* Attribution/Share-Alike License 3.0 (http://creativecommons.org/licenses/by-sa/3.0/), and the GNU
* General Public License 2 (GPL-2.txt)
*
* Includes icons from the Silk set (http://www.famfamfam.com/lab/icons/silk/), by Mark James, used under
* the Creative Commons Attribution 3.0 License.
*/
/**
* Electronic Learning Communities
* @module elc
*/
( function ( mw, $ ) {
/*
Second parameter (pre-existing proveit object, if any) passed to extend overrides first.
Gives users option to easily override initial constants, such as shouldAddSummary.
If proveit is unintentionally imported more than once, the first import will take precedence.
*/
/**
* Main class and namespace for ProveIt software. This is the only global variable.
* @class proveit
*/
var proveit = window.proveit = $.extend({
/**
* Approximately half the height of the edit box. Used in scrolling when highlighting text.
* @type Number
*/
HALF_EDIT_BOX_HEIGHT: 200,
// This could be preference-controlled, instead of hard-coded.
/**
* Language used for descriptions
* @type String
*/
LANG: "en",
/**
* Text before param name (e.g. url, title, etc.) in creation box, to avoid collisions with unrelated ids.
* @type String
*/
NEW_PARAM_PREFIX: "newparam",
/**
* Text before param name (e.g. url, title, etc.) in edit box, to avoid collisions with unrelated ids.
* @type String
*/
EDIT_PARAM_PREFIX: "editparam",
GUI_ID: "proveit",
/* Used to map between keys, including citation parameter names, and human-readable text. It can be
* internationalized easily. Add descriptions.xx , where xx is
* the ISO 639-1 code for a language, then set proveit.LANG to "xx"
* to use the new descriptions.
*/
descriptions :
{
en :
{
agency: "Agency",
name: "Name",
author: "Author (L, F)",
author2: "Author two (L, F)",
author3: "Author three (L, F)",
author4: "Author four (L, F)",
author5: "Author five (L, F)",
author6: "Author six (L, F)",
author7: "Author seven (L, F)",
author8: "Author eight (L, F)",
author9: "Author nine (L, F)",
last: "Last name",
last2: "Last name (auth. two)",
last3: "Last name (auth. three)",
last4: "Last name (auth. four)",
last5: "Last name (auth. five)",
last6: "Last name (auth. six)",
last7: "Last name (auth. seven)",
last8: "Last name (auth. eight)",
last9: "Last name (auth. nine)",
first: "First name",
first2: "First name (auth. two)",
first3: "First name (auth. three)",
first4: "First name (auth. four)",
first5: "First name (auth. five)",
first6: "First name (auth. six)",
first7: "First name (auth. seven)",
first8: "First name (auth. eight)",
first9: "First name (auth. nine)",
authorlink: "Author article name",
title: "Title",
trans_title: "Title in English",
publisher: "Publisher",
year: "Year",
location: "Location",
place: "Location of work",
isbn: "ISBN",
id: "ID",
doi: "DOI",
page: "Page",
pages: "Pages",
quote: "Quote",
month: "Month",
journal: "Journal",
edition: "Edition",
volume: "Volume",
issue: "Issue",
url: "URL",
date: "Publication date",
accessdate: "Access date",
coauthors: "Co-authors",
booktitle: "Title of Proceedings",
contribution: "Contribution/Chapter",
encyclopedia: "Encyclopedia",
newsgroup: "Newsgroup",
version: "Version",
site: "Site",
newspaper: "Newspaper",
"publication-place": "Publication location",
editor: "Editor (L, F)",
article: "Article",
pubplace: "Publisher location",
pubyear: "Publication year",
inventor: "Inventor (L, F)",
"issue-date": "Issue date",
"patent-number": "Patent number",
"country-code": "Country code (XX)",
work: "Work",
format: "Format",
issn: "ISSN",
pmid: "PMID",
chapter: "Chapter",
web: "Web",
book: "Book",
conference: "Conference",
news: "News",
paper: "Paper",
"press release": "Press release",
interview: "Interview",
"AV media": "Audiovisual work",
subject: "Subject",
subjectlink: "Subject article name",
subject2: "Subject two",
subjectlink2: "Subject two article name",
subject3: "Subject three",
subjectlink3: "Subject three article name",
subject4: "Subject four",
interviewer: "Interviewer",
cointerviewers: "Co-interviewers",
type: "Type",
program: "Program",
callsign: "Call sign",
city: "City",
archiveurl: "Archive URL",
archivedate: "Date archived",
episode: "Episode",
episodelink: "Episode article name",
series: "Series",
serieslink: "Series article name",
credits: "Credits",
network: "Network",
station: "Station",
airdate: "Airdate",
began: "Start date",
ended: "End date",
season: "Season number",
seriesno: "Season number",
number: "Number",
minutes: "Minutes",
transcript: "Transcript",
transcripturl: "Transcript URL",
people: "People",
medium: "Production medium",
language: "Language",
time: "Time",
oclc: "OCLC",
ref: "Anchor ID",
deadurl: 'Dead URL?',
raw: 'Unknown format'
},
// Finnish translation by Olli (ollinpostit at gmail.com)
fi: {
agency: "Edustaja",
name: "Nimi",
author: "Tekijä",
author2: "Tekijä kaksi",
author3: "Tekijä kolme",
author4: "Tekijä neljä",
author5: "Tekijä viisi",
author6: "Tekijä kuusi",
author7: "Tekijä seitsemän",
author8: "Tekijä kahdeksan",
author9: "Tekijä yhdeksän",
last: "Sukunimi",
last2: "Sukunimi (tekijä 2)",
last3: "Sukunimi (tekijä 3)",
last4: "Sukunimi (tekijä 4)",
last5: "Sukunimi (tekijä 5)",
last6: "Sukunimi (tekijä 6)",
last7: "Sukunimi (tekijä 7)",
last8: "Sukunimi (tekijä 8)",
last9: "Sukunimi (tekijä 9)",
first: "Etunimi",
first2: "Etunimi (tekijä 2)",
first3: "Etunimi (tekijä 3)",
first4: "Etunimi (tekijä 4)",
first5: "Etunimi (tekijä 5)",
first6: "Etunimi (tekijä 6)",
first7: "Etunimi (tekijä 7)",
first8: "Etunimi (tekijä 8)",
first9: "Etunimi (tekijä 9)",
authorlink: "Tekijästä kertova sivu",
title: "Otsikko",
publisher: "Julkaisija",
year: "Vuosi",
location: "Paikka",
place: "Työn paikka",
isbn: "ISBN",
id: "ID",
doi: "DOI",
page: "Sivu",
pages: "Sivuja",
quote: "Lainaus",
month: "Kuukausi",
journal: "Aikakauslehti",
edition: "Painos",
volume: "Vuosikerta",
issue: "Numero",
url: "Osoite",
date: "Julkaisupäivä",
accessdate: "Luettu",
coauthors: "Muut tekijät",
booktitle: "Jatko-osien otsikko",
contribution: "Osallistuminen/yhteistyö",
encyclopedia: "Tietosanakirja",
newsgroup: "Uutisryhmä",
version: "Versio",
site: "Sivusto",
newspaper: "Sanomalehti",
"publication-place": "Julkaisupaikka",
editor: "Toimittaja",
article: "Artikkeli",
pubplace: "Julkaisijan paikka",
pubyear: "Julkaisuvuosi",
inventor: "Keksijä",
"issue-date": "Saatavilla päivänä",
"patent-number": "Patenttinumero",
"country-code": "Maakoodi (XX)",
work: "Työ",
format: "Muoto",
issn: "ISSN",
pmid: "PMID",
chapter: "Luku",
web: "Verkko",
book: "Kirja",
conference: "Kokous",
news: "Uutiset",
paper: "Lehti",
"press release": "Lehdistötiedote",
interview: "Haastattelu",
subject: "Otsikko",
subjectlink: "Artikkelin otsikko",
subject2: "Otsikko kaksi",
subjectlink2: "Artikkelin kaksi otsikko",
subject3: "Otsikko kolme",
subjectlink3: "Artikkelin kolme otsikko",
subject4: "Otsikko neljä",
interviewer: "Haastattelija",
cointerviewers: "Muut haastattelijat",
type: "Tyyppi",
program: "Ohjelma",
callsign: "Call sign",
city: "Kaupunki",
archiveurl: "Arkiston osoite",
archivedate: "Arkistointipäivämäärä",
episode: "Jakso",
episodelink: "Jakson sivun nimi",
series: "Sarja",
serieslink: "Sarjan sivun nimi",
credits: "Tekijät",
network: "Verkko",
station: "Asema",
airdate: "Lähetyspäivä",
began: "Aloituspäivä",
ended: "Lopetuspäivä",
season: "Kauden numero",
seriesno: "Kauden numero",
number: "Numero",
minutes: "Minuutit",
transcript: "Puhtaaksi kirjoitettu teksti",
transcripturl: "Puhtaaksikirjoitetun osoite",
video: "Video",
people: "Ihmiset",
medium: "Tuotantomedia",
language: "Kieli",
time: "Aika",
oclc: "OCLC",
ref: "Ankkurin ID-tunnus"
}
},
/**
* Optional preference to specify default date format for new references.
* If set, it overrides the general date preference from Special:Preferences.
*
* @type {String} supported date format string
*/
dateFormatString: null,
/**
* Singleton used to format dates according to user preference
*
* @type DateFormatter
*/
dateFormatter: null,
/**
* Gets the effective preference for date format. If there is no ProveIt-specific
* preference already at proveit.dateFormatString, it will determine the correct preference
* from MW user preferences. Then, it will store that value to proveit.dateFormatString
*
* @return {String} format string to use for dates
*/
getDatePreference: function () {
if (this.dateFormatString === null) {
this.dateFormatString = mw.user.options.get('date');
}
return this.dateFormatString;
},
/**
* Returns descriptions for the current language.
* @return {Object} descriptions
*/
getDescriptions: function()
{
//this could be made Cite-specific if needed.
return this.descriptions[proveit.LANG];
},
/**
* String added to logs for easy search
* @type String
*/
LOG_MARKER: "[ProveIt] ",
/**
* Convenience log function
* @param {...Object} var_args objects (including strings) to log
*/
log: function()
{
var args = Array.prototype.slice.call(arguments);
args.unshift(this.LOG_MARKER);
mw.log.apply(mw, args);
},
/**
* Log error object if possible, using error (preferable), or log, if available.
* @param {Error} ex error object
*/
logException: function(ex)
{
var args = [ex, ex.stack];
if(typeof(console) === "object" && $.isFunction(console.error))
{
args.unshift(this.LOG_MARKER);
console.error.apply(null, args);
}
else
{
this.log.apply(this, args);
}
},
/**
* Returns true if the page has a wikitext edit box
*
* @return {Boolean} true if the page has a wikitext edit box, false otherwise
*/
isEditPage: function()
{
var contentModel = mw.config.get( 'wgPageContentModel' ),
action = mw.config.get( 'wgAction' );
return contentModel === 'wikitext' && ( action === 'edit' || action === 'submit' );
},
/**
* Returns true if the page is likely to contain references
* @return {Boolean} true if page is supported, false otherwise
*/
isSupportedPage: function()
{
var namespace = mw.config.get( 'wgCanonicalNamespace' ),
pageName = mw.config.get( 'wgPageName' );
// "Regular" article, userspace, or Wikipedia:Sandbox (exception for testing).
return ( namespace === '' || namespace === 'User' || pageName === 'Wikipedia:Sandbox');
},
/**
* Convenience function. Returns the refbox element.
* @return {$Node} reference box
*/
getReferenceBox: function()
{
return $("#refs");
},
/**
* Provides the x (left) and y (top) offsets to a given element. From QuirksMode (http://www.quirksmode.org/js/findpos.html), a freely available site by Peter-Paul Koch
* @param {Node} node any HTML node
* @return {Object} offsets to node, as object with left and top properties.
*/
getPosition: function(node)
{
var left = 0, top = 0;
do
{
left += node.offsetLeft;
top += node.offsetTop;
} while (node = node.offsetParent);
return {"left": left, "top": top};
},
/**
* Highlights a given length of text, at a particular index.
* @param {Number} startInd start index in Wikipedia edit box
* @param {Number} length length of string to highlight
* @return {Boolean} always true
*/
highlightLengthAtIndex: function(startInd, length)
{
if(startInd < 0 || length < 0)
{
this.log("highlightStringAtIndex: invalid negative arguments");
}
var box = this.getTextbox();
var origText = box.value;
var editTop = this.getPosition(box).top;
box.value = origText.substring(0, startInd);
box.focus();
box.scrollTop = 1000000; //Larger than any real textarea (hopefully)
var curScrollTop = box.scrollTop;
box.value += origText.substring(startInd);
if(curScrollTop > 0)
{
box.scrollTop = curScrollTop + this.HALF_EDIT_BOX_HEIGHT;
}
$(box).focus().textSelection('setSelection',
{
start: startInd,
end: startInd + length
});
editTop = this.getPosition(box).top;
window.scroll(0, editTop);
return true;
},
/**
* Highlights the first instance of a given string in the MediaWiki edit box.
* @param {String} targetStr the string in the edit box to highlight
* @return {Boolean} true if successful, false otherwise
*/
highlightTargetString: function(targetStr)
{
var origText = this.getTextboxText();
var startInd = origText.indexOf(targetStr);
if(startInd == -1)
{
this.log("Target string \"" + targetStr + "\" not found.");
return false;
}
return this.highlightLengthAtIndex(startInd, targetStr.length);
},
/**
* Convenience function. Returns the raw MediaWiki textarea element.
* @return {Node} the edit box element
*/
getTextbox: function()
{
return $("#wpTextbox1")[0];
},
/**
* Provides value of edit box with CR normalization
*
* @return {String} value of edit box with CRs stripped if document.selection exists
*/
getTextboxText: function()
{
var box = this.getTextbox();
var value = box.value;
if(!box.selectionStart && document.selection) // IE 8-like behavior
{
value = value.replace(/\r\n/g, "\n");
}
return value;
},
/**
* Returns raw edit form element, which contains MWEditBox, among other things.
* @return {Node} the edit form element
*/
getMWEditForm: function()
{
return $("#editform")[0];
},
/**
* Runs a given function on submission of edit form
* @param {Function} subFunc function to run on submission
*/
addOnsubmit: function(subFunc)
{
var form = this.getMWEditForm();
if(!form)
{
throw new Error("No edit form, possibly due to protected page.");
}
form.addEventListener("submit", subFunc, false);
},
/**
* Returns the raw MW edit summary element
* @return {Node} the edit summary element
*/
getSummary: function()
{
return $("#wpSummary")[0];
},
/**
* Keep track of whether we have already added an onsubmit function to include ProveIt in the summary.
* This guarantees the function will not be run twice.
* @type Boolean
*/
summaryFunctionAdded: false,
/**
* Does the user want us to ever add "Edited by ProveIt" summary?
* @type Boolean
*/
shouldAddSummary: true,
/**
* ProveIt should be visible on load (rather than requiring toolbar button click) on supported edit pages
* @type Boolean
*/
loadVisible: true,
/**
* Maximize ProveIt when it first becomes visible. If false, it will start minimized. This has no effect on when it becomes visible.
* @type Boolean
*/
loadMaximized: false,
/**
* Specifies to include ProveIt edit summary on next save.
* Can be disabled by modifying shouldAddSummary
*/
includeProveItEditSummary: function()
{
if(this.shouldAddSummary && !this.summaryFunctionAdded)
{
try
{
var thisproveit = this;
this.addOnsubmit(function()
{
var summary = thisproveit.getSummary();
if(summary.value.indexOf("ProveIt") == -1)
{
summary.value += " (edited with [[User:ProveIt_GT|ProveIt]])";
}
});
this.summaryFunctionAdded = true;
}
catch(e)
{
this.log("Failed to add onsubmit handler. e.message: " + e.message);
}
}
},
/**
* Setup button so users can load ProveIt on demand
*/
setupButton: function()
{
var $box = $(this.getTextbox());
// Ensures wikiEditor is loaded
$box.on('wikiEditor-toolbar-buildSection-main', function(event, section)
{
delete section.groups.insert.tools.reference;
section.groups.insert.tools.proveit = {
label: 'ProveIt',
type: 'button',
icon: '//thumb.wikimedia.org/wikipedia/commons/thumb/1/19/ProveIt_logo_for_user_boxes.svg/22px-ProveIt_logo_for_user_boxes.svg.png',
action: {
type: 'callback',
execute: function()
{
proveit.toggleVisibility();
}
}
};
});
},
/**
* Sets up ProveIt if we're on an edit page. This includes setting up the toolbar button. Depending on configuration and the current page, it may also call load to show ProveIt.
*/
setup: function()
{
if(this.isEditPage())
{
if(this.loadVisible && this.isSupportedPage())
{
this.load();
}
this.setupButton();
}
},
/**
* Loads dependencies and creates GUI
*/
load: function()
{
$(function() {
var dependencies = ['jquery.ui', 'jquery.textSelection', 'mediawiki.util'];
var preference = proveit.getDatePreference();
proveit.dateFormatter = new proveit.DateFormatter(preference);
mw.loader.using(dependencies, function() {
try {
proveit.createGUI();
if(proveit.loadMaximized)
{
proveit.toggleViewAddVisibility();
}
}
catch(ex) {
proveit.logException(ex);
}
}, function(ex, errorDependencies) {
proveit.log('Failed to load one of: ', errorDependencies);
});
});
},
/**
* Clears the refBox of refBoxRows, except for dummy rows.
* @return {Boolean} false if refBox wasn't found
*/
clearRefBox: function()
{
var box = this.getReferenceBox();
if(box == null)
{
this.log("Ref box is not loaded yet.");
return false;
}
$("tr:not('tr#dummyRef')", box).remove();
return true;
},
/** Inserts ref text into MW edit box.
* @param {String} ref Reference text to insert
* @param {Boolean} full Insert the full reference text if true, citation otherwise.
* @return {Boolean} false if errors
*/
insertRefIntoMWEditBox: function(ref, full)
{
var txtarea = this.getTextbox();
if(!txtarea)
{
this.log("insertRefIntoMWEditBox: txtarea is null");
return false;
}
txtarea = $(txtarea);
var insertionText = ref.getInsertionText(full);
// Replace existing selection (if any), then scroll
txtarea.textSelection('encapsulateSelection',
{
peri: insertionText,
replace: true
});
var caretPos = txtarea.textSelection('getCaretPosition', {startAndEnd: true});
// This is slightly redundant. It is called primarily for the scrollig workaround
this.highlightLengthAtIndex(caretPos[0], caretPos[1] - caretPos[0]);
this.includeProveItEditSummary();
},
/**
* Modifies reference object from user-edited GUI. The reference object is mutated in place, so the return value is only for convenience.
*
* @param {Node} editPane the raw element of the editPane
* @param {AbstractReference} ref the original citation object we're modifying
*
* @return {AbstractReference} same ref that was passed in
*/
changeRefFromEditPane: function(ref, editPane)
{
var paramBoxes = $(editPane).find("div.input-row");
var refName = $('#editrefname').val();
ref.name = refName != "" ? refName : null; // Save blank names as null
// Clear old params
ref.params = {};
var paramName, paramVal;
for (var i = 0; i < paramBoxes.length; i++)
{
var paramRow = paramBoxes[i];
var valueTextbox = $(paramRow).find(".paramvalue")[0];
if($(paramRow).hasClass("addedrow")) // Added with "Add another field"
{
paramName = $.trim($(paramRow).find(".paramdesc")[0].value);
}
else
{
paramName = valueTextbox.id.substring(this.EDIT_PARAM_PREFIX.length);
}
this.log("paramName: " + paramName);
paramVal = $.trim(valueTextbox.value);
this.log("paramVal: " + paramVal);
if (paramName != "" && paramVal != "")
{
ref.params[paramName] = paramVal;
}
}
if (ref.toString() != ref.orig)
{
ref.save = false;
}
ref.update();
return ref;
},
/**
* Creates refBoxRow, updates numbering for all refBoxRows, replaces old refBoxRow with new one, and updates ref text in MWEditBox.
* @param {AbstractReference} ref the ref we want to save.
*/
saveRefFromEdit: function(ref)
{
if(!ref.save)
{
var newRichItem = this.makeReferenceBoxRow(ref, true);
var oldRichItem = $('.selected', this.getReferenceBox()).get(0);
var oldNumber = $('td.number', oldRichItem).text();
$('td.number', newRichItem).text(oldNumber); // preserve old numbering
oldRichItem.parentNode.replaceChild(newRichItem, oldRichItem);
$(newRichItem).addClass('selected');
ref.updateInText();
this.includeProveItEditSummary();
}
},
/**
* Updates the edit pane when you choose a reference to edit.
* @param {AbstractReference} ref the ref that was chosen.
*/
updateEditPane: function(ref)
{
$('#editrefname').val(ref.name || "");
// Don't contaminate actual object with junk params.
var tempParams = {};
for(var param in ref.params) {
tempParams[param] = ref.params[param];
}
// Add default params with blank values.
var defaults = ref.getDefaultParams();
for(var i = 0; i < defaults.length; i++)
{
if(!tempParams[defaults[i]])
{
tempParams[defaults[i]] = "";
}
}
var required = ref.getRequiredParams();
var paramNames = [];
for(var item in tempParams) //First run through just to get names.
{
paramNames.push(item);
}
var sorter = ref.getSorter();
if(sorter)
{
paramNames.sort(sorter);
}
else
{
paramNames.sort();
}
/* Sort them to provide consistent interface. Uses custom sort order (which is easily tweaked)
where possible.
Javascript does destructive sorting, which in this case, is convenient...
*/
$('#edit-fields').children('.paramlist').children().remove('div:not(.hidden)'); // clear all fields in the edit box (except the hidden ones)
for(var j = 0; j < paramNames.length; j++)
{
this.addPaneRow($("#edit-pane").get(), tempParams, this.getDescriptions(), paramNames[j], required[paramNames[j]], true);
}
var acceptButton = $('#edit-buttons .accept');
var acceptEdit = function()
{
proveit.changeRefFromEditPane(ref, $("#edit-pane").get());
proveit.saveRefFromEdit(ref);
$("#edit-pane").hide();
$("#view-pane").show();
};
// Without setTimeout, scoll reset doesn't work in Firefox.
setTimeout(function()
{
// Reset scroll
$('#edit-fields').scrollTop(0);
}, 0);
acceptButton.off('click.proveit').on('click.proveit', acceptEdit);
},
/**
* Add a row to an editPane or addPane.
* @param {Node} root root element for pane
* @param {Object} params the param object from the reference, or null for added rows.
* @param {Object} descs description object to use, or null for no description
* @param {String} item the current param name
* @param {Boolean} req true if current param name is required, otherwise not required.
* @param {Boolean} fieldType true for label, false for textbox.
*/
addPaneRow: function(root, params, descs, item, req, fieldType)
{
var id = fieldType ? "preloadedparamrow" : "addedparamrow";
var newline = $('#'+id).clone(); // clone the hidden row
$(newline).attr('id',''); // clear the ID (can't have two elements with same ID)
//this.activateRemoveField(newline);
var paramName = $('.paramdesc', newline).eq(0);
var paramValue = $('.paramvalue', newline).eq(0);
$('.paramlist', root).append(newline);
if(req) // if field is required...
{
$(paramName).addClass('required'); // visual indicator that label is required
$('.delete-field', newline).remove(); // don't let people remove required fields
}
else
{
this.activateRemoveField(newline);
}
if(fieldType) // the description/name is a label (not a textbox)
{
paramName.attr("for", this.EDIT_PARAM_PREFIX + item);
paramValue.attr('id',this.EDIT_PARAM_PREFIX + item);
var desc = descs[item];
if(!desc)
{
this.log("Undefined description for param: " + item + ". Using directly as description.");
desc = item;
}
$(paramName).text(desc).attr('title', item);
$(paramValue).val(params[item]);
}
else
{
// added a new row, so make it fancy
$(newline).show('highlight',{},'slow');
$('.inputs', root).scrollTop(100000);
}
},
/*
* these are the current style and insert values to denote which one is
* currently active
*/
/**
* true signifies cite-style references, citation-style otherwise. Used when creating a reference.
* @type Boolean
*/
togglestyle: true,
// TODO: This should be eliminated if only name only inserts are allowed.
/** true signifies full references, name-only otherwise. Used when inserting.
* Note that new references are always inserted in full.
*
* @type Boolean
*/
toggleinsert: false,
/* Cross-Browser Split 1.0.1
(c) Steven Levithan <stevenlevithan.com>; MIT License
http://blog.stevenlevithan.com/archives/cross-browser-split
An ECMA-compliant, uniform cross-browser split method
*/
/**
* Cross-browser implementation of ECMAScript String.prototype.split function.
*
* @param {String} str input string to split
* @param separator separator to split on, as RegExp or String
* @param {Number} limit limit on number of splits. If the parameter is absent, no limit is imposed.
* @return {Array} array resulting from split
*/
split: function (str, separator, limit)
{
// if `separator` is not a regex, use the native `split`
if (Object.prototype.toString.call(separator) !== "[object RegExp]") {
return proveit.split._nativeSplit.call(str, separator, limit);
}
var output = [],
lastLastIndex = 0,
flags = (separator.ignoreCase ? "i" : "") +
(separator.multiline ? "m" : "") +
(separator.sticky ? "y" : ""),
separator = RegExp(separator.source, flags + "g"), // make `global` and avoid `lastIndex` issues by working with a copy
separator2, match, lastIndex, lastLength;
str = str + ""; // type conversion
if (!proveit.split._compliantExecNpcg) {
separator2 = RegExp("^" + separator.source + "$(?!\\s)", flags); // doesn't need /g or /y, but they don't hurt
}
/* behavior for `limit`: if it's...
- `undefined`: no limit.
- `NaN` or zero: return an empty array.
- a positive number: use `Math.floor(limit)`.
- a negative number: no limit.
- other: type-convert, then use the above rules. */
if (limit === undefined || +limit < 0) {
limit = Infinity;
} else {
limit = Math.floor(+limit);
if (!limit) {
return [];
}
}
while (match = separator.exec(str)) {
lastIndex = match.index + match[0].length; // `separator.lastIndex` is not reliable cross-browser
if (lastIndex > lastLastIndex) {
output.push(str.slice(lastLastIndex, match.index));
// fix browsers whose `exec` methods don't consistently return `undefined` for nonparticipating capturing groups
if (!proveit.split._compliantExecNpcg && match.length > 1) {
match[0].replace(separator2, function () {
for (var i = 1; i < arguments.length - 2; i++) {
if (arguments[i] === undefined) {
match[i] = undefined;
}
}
});
}
if (match.length > 1 && match.index < str.length) {
Array.prototype.push.apply(output, match.slice(1));
}
lastLength = match[0].length;
lastLastIndex = lastIndex;
if (output.length >= limit) {
break;
}
}
if (separator.lastIndex === match.index) {
separator.lastIndex++; // avoid an infinite loop
}
}
if (lastLastIndex === str.length) {
if (lastLength || !separator.test("")) {
output.push("");
}
} else {
output.push(str.slice(lastLastIndex));
}
return output.length > limit ? output.slice(0, limit) : output;
},
// TODO: Remove the split code, and just use a regular regex (with two main groups for name and val), iteratively. Regex.find? Make name and val indices match, and rework calling code as needed. Also, check how this was done in the original code.
/**
* Overly clever regex to parse template string (e.g. |last=Smith|first=John|title=My Life Story) into name and value pairs.
*
* names is an array of all names, and values is an array of all values. They have equal lengths.
*
* @param {String} workingString template string to parse.
* @return {Object} object with two properties, names and values.
*/
splitKeysAndValues: function (workingString)
{
var split = {};
// The first component is "ordinary" text (no pipes), while the second is a correctly balanced wikilink, with optional pipe. Any combination of the two can appear.
split.names = proveit.split(workingString.substring(workingString.indexOf("|") + 1), /=(?:[^|]*?(?:\[\[[^|\]]*(?:\|(?:[^|\]]*))?\]\])?)+(?:\||\}\})/);
split.names.length--; // Remove single empty element at end
split.values = proveit.split(workingString.substring(workingString.indexOf("=") + 1, workingString.indexOf("}}")), /\|[^|=]*=/);
return split;
},
/**
* Scan for references in the MWEditBox, and create a reference object and refBoxRow for each.
*/
scanForReferences: function()
{
// these are strings used to allow the correct parsing of the ref
var workingstring;
var cutupstring;
this.clearRefBox();
var textValue = this.getTextboxText();
// since we should pick the name out before we get to the reference type, here's a variable to hold it
var name;
// key - name
// value -
// object - key - "reference", value - reference obj . Avoids repeating same object in references array.
// key - "strings", value - array of orig strings
var citations = {};
// Array of reference objects. At end of function, addNewElement called on each.
var references = [];
// allRefs should count opening refs, but not ref citation (not <ref name="..."" />)
var allRefs = textValue.match(/<[\s]*ref[^\/>]*>/gi);
// currentScan holds the parsed (match objects) list of references. Regex matches full or name-only reference.
var currentScan = textValue.match(/<[\s]*ref[^>]*>(?:[^<]*<[\s]*\/[\s]*ref[\s]*>)?/gi); // [^<]* doesn't handle embedded HTML tags (or comments) correctly.
// if there are results,
if (currentScan)
{
for (var i = 0; i < currentScan.length; i++)
{
var reference = this.makeReference(currentScan[i]);
if(reference) // Full reference object
{
name = reference.name;
if(!name) // with no name, no possibility of repeat name.
{
references.push(reference);
}
}
else // Not full reference. Possibly citation.
{
var match = currentScan[i].match(this.REF_REGEX);
name = match && (match[1] || match[2] || match[3]);
}
if(name)
{
if(!citations[name])
{
// Create array of original reference strings
citations[name] = {};
if(!citations[name].strings)
{
citations[name].strings = [];
}
}
if(reference && !citations[name].reference) // reference, and not already one for this name
{
citations[name].reference = reference;
references.push(reference);
}
// Add to array
citations[name].strings.push(currentScan[i]);
}
}
}
for(var j = 0; j < references.length; j++)
{
if(references[j].name)
{
var citation = citations[references[j].name];
references[j].setCitationStrings(citation.strings);
}
this.addNewElement(references[j]);
}
},
/**
* Regex for parsing any reference text.
* @type RegExp
*/
REF_REGEX: /<[\s]*ref[\s]*name[\s]*=[\s]*(?:(?:\"(.*?)\")|(?:\'(.*?)\')|(?:(.*?)))[\s]*\/?[\s]*>/,
/**
* Factory function for references. Takes text of a reference, and returns instance of the appropriate class.
* @param {String} refText reference string
* @return {AbstractReference} null if refText isn't a ref, otherwise the reference object
*/
makeReference: function(refText)
{
var isReference = /<[\s]*ref[^>]*>[^<]*\S[^<]*<[\s]*\/[\s]*ref[\s]*>/.test(refText); // Tests for reference (non-citation);
if(!isReference)
{
return null;
}
var citeFunction = refText.match(/{{[\s]*cite/i) ? this.CiteReference : refText.match(/{{[\s]*Citation/i) ? this.CitationReference : this.RawReference;
if(citeFunction != this.RawReference)
{
var workingstring = refText.match(/{{[\s]*(cite|Citation)[\s\S]*?}}/i)[0];
var match = refText.match(this.REF_REGEX);
if(match && match != null)
{
var name = match[1] || match[2] || match[3]; // 3 possibilities, corresponding to above regex, are <ref name="foo">, <ref name='bar'>, and <ref name=baz>
}
var cutupstring = workingstring.split(/\|/g);
// This little hack relies on the fact that 'e' appears first as the last letter of 'cite', and the type is next.
if(citeFunction == this.CiteReference)
{
var beforeBar = cutupstring[0];
var typeStart = beforeBar.toLowerCase().indexOf('e');
// First end curly brace
var rightCurly = beforeBar.indexOf('}');
// Usually, rightCurly will be -1. But this takes into account empty references like <ref>{{cite web}}</ref>
var typeEnd = rightCurly != -1 ? rightCurly : beforeBar.length;
// grab the type, then trim it.
var type = $.trim(beforeBar.substring(typeStart + 1, typeEnd));
}
}
// type may be undefined, but that's okay.
var citation = new citeFunction({"name": name, "type": type, "save": true, "inMWEditBox": true, "orig": refText});
if(citeFunction != this.RawReference)
{
var split = this.splitKeysAndValues(workingstring);
var names = split.names;
var values = split.values;
for (var j = 0; j < names.length; j++)
{
/* Drop blank space, and |'s without params, which are never correct for
citation templates.*/
var paramName = $.trim(names[j]).replace(/(?:\s*\|)*(.*)/, "$1");
var paramVal = $.trim(values[j]);
// Should there be a setParam function? It could handle empty values, and even drop (siliently or otherwise) invalid parameters. Alternatively, should params be passed in the constructor?
if (paramVal != "")
{
citation.params[paramName] = paramVal;
}
}
}
return citation;
},
// TODO: Use https://gerrit.wikimedia.org/r/#/c/67166/ when merged.
/**
* Date-formatting class
*
* @param {String} format one of the format strings supported by MW core.
* Currently, the supported values are 'default', 'mdy', 'dmy', 'ymd', and 'ISO 8601'.
* If an unknown value is passed, it will use wgDefaultDateFormat.
*/
DateFormatter: function (format) {
// 1-indexed (due to filler item at 0), in page content language.
var monthNames = mw.config.get('wgMonthNames');
var supportedFormats = ['mdy', 'dmy', 'ymd', 'ISO 8601'];
if($.inArray(format, supportedFormats) === -1) {
format = mw.config.get('wgDefaultDateFormat');
}
function getMonthName(date) {
return monthNames[date.getMonth() + 1];
}
this.formatAsMdy = function(date) {
return getMonthName(date) + ' ' + date.getDate() + ', ' + date.getFullYear();
};
this.formatAsDmy = function(date) {
return date.getDate() + ' ' + getMonthName(date) + ' ' + date.getFullYear();
};
this.formatAsYmd = function(date) {
return date.getFullYear() + ' ' + getMonthName(date) + ' ' + date.getDate();
};
this.formatAsISO8601 = function(date) {
return date.getFullYear() + '-' +
(date.getMonth() < 9 ? '0' : '') + (date.getMonth() + 1) + '-' +
(date.getDate() < 10 ? '0' : '') + date.getDate();
};
var formatters = {
mdy: this.formatAsMdy,
dmy: this.formatAsDmy,
ymd: this.formatAsYmd,
'ISO 8601': this.formatAsISO8601
};
/**
* Formats date according to stored preference
*
* @param {Date} date date to format
*
* @return {String} formatted date as String
*/
this.format = function(date) {
return formatters[format](date);
};
},
/**
* Root reference type. Parent of RawReference, CiteReference, and CitationReference.
* @class AbstractReference
* @for proveit
* @constructor
* @param {Object} argObj argument object with keys for each option
*/
AbstractReference: function(argObj)
{
// CiteReference has a non-trivial override of this. This is defined early (and conditionally) because it is used in the constructor.
if(!this.setType)
{
/**
* @param {String} type type of reference
*/
this.setType = function(type)
{
this.type = type;
};
}
/**
* Update citation strings after changing reference. This runs after modifying a reference's fields (name, params), but before changing orig
*/
this.update = function()
{
var newCiteText = this.toString();
var strings = this.getCitationStrings();
/*
* Update main citation in strings list.
*
* TODO:
* Use strings array here to find and update citations that are not main references. As is, they are orphaned.
* Both array and textbox should be updated.
* It may be enough to just set all non-main citations in text and array to this.getInsertionText(false).
* However, if they remove the name entirely (not recommended), that would be a problem.
*/
if(strings.length > 0) // This implies there was a name before
{
for(var i = 0; i < strings.length; i++)
{
// If we find the full citation as a citation, update to the new text.
if(strings[i] == this.orig)
{
// this.orig itself is updated in updateInText
strings[i] = newCiteText;
}
}
}
else if(this.name != null) // They have added a name, so we should have a main citation.
{
// Now that it has a name, it is a citation to itself.
strings.push(newCiteText);
}
};
/**
* <ref name /> for reference
* @type String
*/
this.name = argObj.name != "" ? argObj.name : null; // Save blank names as null
/*
type of reference, e.g. cite web, cite news. Also used (including for CitationReference objects) to determine default fields.
*/
this.setType(argObj.type);
//TODO: Re-examine whether both (or indeed either) of save or inMWEditBox are really necessary. Can it be determined from context?
/**
* flag to determine whether citation must be saved. false indicates "dirty" citation that has yet to be updated in text and metadata.
* @type Boolean
*/
this.save = argObj.save;
/**
* true if and only if the ref is in the MW edit box with the same value as this object's orig.
* @type Boolean
*/
this.inMWEditBox = argObj.inMWEditBox;
/**
* original wikitext for reference
* @type String
*/
this.orig = argObj.orig;
/**
* mapping of parameter names to values
* @type Object
*/
this.params = {};
/**
* Convenience method. Returns sorter for parameters.
* @return {Function} sorter for parameters
*/
this.getSorter = function()
{
var thisCite = this; // Make closure work as intended.
// Sorter uses paramSortKey first, then falls back on alphabetical order.
return function(paramA, paramB)
{
var aInd = thisCite.getSortIndex(paramA);
var bInd = thisCite.getSortIndex(paramB);
if(aInd != -1 && bInd != -1)
{
return aInd - bInd;
}
else
{
proveit.log('Parameter missing from getSortIndex, which causes the sort to be invalid. paramA: ', paramA, ', aInd: ', aInd, ', paramB: ', paramB, ', bInd: ', bInd);
if(paramA < paramB)
{
return -1;
}
else if(paramA == paramB)
{
return 0;
}
else
{
return 1;
}
}
};
};
/**
* Returns true if this reference is valid, false otherwise.
* Assume all AbstractReference objects are valid. Can be overridden in subtypes.
* @return {Boolean} AbstractReference.isValid always returns true
*/
this.isValid = function(){return true;};
/**
* Generates label for reference using title, author, etc.
* @return {String} the label that was generated
*/
this.getLabel = function()
{
var label = "";
if (this.params.author)
{
label = this.params.author + "; ";
}
else if (this.params.last)
{
label = this.params.last;
if (this.params.first)
{
label += ", " + this.params.first;
}
label += "; ";
}
if (this.params.title)
{
label += this.params.title;
}
if(label == "")
{
var value;
for (value in this.params)
{
break;
}
if(value) // There could be no parameters
{
label = value;
}
}
return label;
};
/**
* Gets insertion text (for edit box).
*
* TODO: Generate a regex object instead (getInsertionRegExp), so highlighting would not fail due to trivial changes (e.g. spacing).
* @param {Boolean} full If true, insert full text, otherwise ref name only
* @return {String} insertion text
*/
this.getInsertionText = function(full)
{
if(full)
{
return this.toString();
}
else
{
if(this.name)
{
return "<ref name=\"" + this.name + "\" />";
}
else
{
throw new Error("getInsertionText: ref.name is null");
}
}
};
/**
* Updates this reference in the edit box.
*/
this.updateInText = function()
{
var txtarea = proveit.getTextbox();
if (!txtarea || txtarea == null)
return;
txtarea.focus();
var text = proveit.getTextboxText();
text = text.replace(this.orig, this.toString());
// Do replacement in textarea.
txtarea.value = text;
// Baseline for future modifications
this.orig = this.toString();
this.save = true;
proveit.highlightTargetString(this.toString());
};
/**
* Internal helper method for toString.
* @param {String} template template for ref (currently "cite" or "Citation"
* @param {Boolean} includeType true to include this.type, false otherwise
* @return {String} string for current reference
*/
this.toStringInternal = function(template, includeType)
{
if(this.name)
{
var returnstring = "<ref name=\"" + this.name + "\">";
}
else
{
var returnstring = "<ref>";
}
returnstring += "{{" + template + (includeType ? " " + this.type : "");
for (var name in this.params)
{
returnstring += " | " + name + "=" + this.params[name];
}
returnstring += "}}</ref>";
return returnstring;
};
/**
* Array of citation strings for this reference.
* @type Array
*/
this.citationStrings = [];
/**
* Sets citationStrings to an array
* @param {Array} strings array of citation strings, not null
*/
this.setCitationStrings = function(strings)
{
this.citationStrings = strings;
};
/**
* Gets array of citationStrings.
* @return {Array} (possibly empty) array of citation strings. Will not return null.
*/
this.getCitationStrings = function()
{
return this.citationStrings;
};
/**
* Get icon URL for reference
* @return {String} icon URL
*/
this.getIcon = function()
{
return '//upload.wikimedia.org/wikipedia/commons/d/dd/Silk-Page_white.png';
};
},
/**
* Constructor for CiteReference type.
* @class CiteReference
* @for proveit
* @constructor
* @extends AbstractReference
* @param {Object} argObj the argument object, with keys for each option
*/
CiteReference: function(argObj)
{
/* This is basically a fast representation of the template redirects, along with
* self-mappings.
*/
var typeNameMappings =
{
web: "web",
book: "book",
journal: "journal",
conference: "conference",
encyclopedia: "encyclopedia",
news: "news",
newsgroup: "newsgroup",
paper: "journal",
"press release": "press release",
"pressrelease": "press release",
interview: "interview",
episode: "episode",
"AV media": "AV media",
DVD: "AV media",
audio: "AV media",
"av media": "AV media",
cd: "AV media",
dvd: "AV media",
media: "AV media",
movie: "AV media",
"music video": "AV media",
video: "AV media",
visual: "AV media"
};
// Sets the type (e.g. web for cite web), applying the mappings. This is up top because it is used in AbstractReference constructor.
this.setType = function(rawType)
{
var mappedType = typeNameMappings[rawType];
if(mappedType != null)
this.type = mappedType;
else
this.type = rawType; // Use naive type as fallback.
};
/**
* Returns the type for display purposes, based on description messages. For example, for "AV media" it currently returns "Audiovisual work".
*
* @return {String} type for display
*/
this.getTypeForDisplay = function()
{
return proveit.getDescriptions()[this.type];
};
proveit.AbstractReference.call(this, argObj);
// TODO: Should CiteReference.getSortIndex and CitationReference.getSortIndex be merged into AbstractCitation? Less fine-grained, but simpler to maintain.
/**
* Returns the sort index for a given parameter
* @param {String} param parameter name
* @return {Number} sort index if found, otherwise -1
*/
this.getSortIndex = function(param)
{
// This is the order fields will be displayed or outputted.
return $.inArray(param, [
"url",
"title",
"trans_title",
"encyclopedia",
"publisher",
"work",
"date",
"agency",
"accessdate",
"author",
"last",
"first",
"subject",
"subjectlink",
"inventor",
"editor",
"author2",
"last2",
"first2",
"subject2",
"subjectlink2",
"author3",
"last3",
"first3",
"subject3",
"subjectlink3",
"author4",
"last4",
"first4",
"subject4",
"author5",
"last5",
"first5",
"author6",
"last6",
"first6",
"author7",
"last7",
"first7",
"author8",
"last8",
"first8",
"author9",
"last9",
"first9",
"authorlink",
"coauthors",
"interviewer",
"cointerviewers",
"type",
"newsgroup",
"journal",
"booktitle",
"program",
"episodelink",
"series",
"serieslink",
"credits",
"network",
"station",
"callsign",
"city",
"airdate",
"began",
"ended",
"season",
"seriesno",
"number",
"minutes",
"transcript",
"transcripturl",
"people",
"year",
"month",
"article",
"contribution",
"format",
"medium",
"newspaper",
"conference",
"volume",
"edition",
"issue",
"location",
"pages",
"page",
"language",
"isbn",
"issn",
"oclc",
"doi",
"pmid",
"id",
"archiveurl",
"archivedate",
"deadurl",
"time",
"quote",
"ref"
]);
};
/**
* Returns this reference as a string.
* @return {String} reference as string
*/
this.toString = function()
{
return this.toStringInternal("cite", true);
};
// References without these parameters will be flagged in red.
// True indicates required (null, or undefined, means not required)
var requiredParams =
{
web: { "url": true, "title": true},
book: { "title": true },
journal: { "title": true },
conference: { "title": true },
encyclopedia: { "title": true, "encyclopedia": true },
news: { "title": true, "work": true, "date": true },
newsgroup: { "title": true },
"press release" : { "title": true },
interview: { "last": true }, // TODO: Interview requires last *or* subject. Currently, we can't represent that.
episode: { "title": true },
"AV media": { "title": true }
};
/**
* Return required parameters for this citation type.
* @return {Object} object with required parameters as keys and true as value; empty object for unknown type
*/
this.getRequiredParams = function()
{
var curReq = requiredParams[this.type];
if(curReq)
return curReq;
else
return {}; // Return empty object rather than null to avoid dereferencing null.
};
// These paramaters will be auto-suggested when editing.
var defaultParams =
{
web: [ "url", "title", "author", "accessdate", "work", "publisher", "date", "pages"],
book: [ "title", "author", "authorlink", "year", "isbn", "publisher", "location", "pages", "url" ],
journal: [ "title", "author", "journal", "volume", "issue", "year", "month", "pages", "url", "doi", "pmid" ],
conference: [ "conference", "title", "booktitle", "author", "editor", "year", "month", "url", "id", "accessdate", "location", "pages", "publisher" ],
encyclopedia: [ "title", "encyclopedia", "author", "editor", "accessdate", "edition", "year",
"publisher", "volume", "location", "pages" ],
news: [ "title", "author", "url", "work", "date", "accessdate", "pages", "location", "agency" ],
newsgroup: [ "title", "author", "date", "newsgroup", "id", "url", "accessdate" ],
"press release" : [ "title", "url", "publisher", "date", "accessdate" ],
interview: ["last", "first", "subjectlink", "interviewer", "title", "callsign", "city", "date", "program", "accessdate"],
episode: ["title", "series", "credits", "airdate", "city", "network", "season"],
"AV media": ["people", "date", "url", "title", "medium", "location", "publisher"]
};
/**
* Returns default parameters (to be suggested when editing) for current reference
* @return {Array} array of default parameter names; empty array if unknown
*/
this.getDefaultParams = function()
{
var curDefault = defaultParams[this.type];
if(curDefault)
return curDefault;
else
return []; // Return empty array rather than null to avoid dereferencing null.
};
this.isValid = function()
{
if(this.type == '')
{
return false;
}
var req = this.getRequiredParams();
var i = 0;
var allFound = true;
for(var reqParam in req)
{
/* Ignore parameters in req object that are null, undefined, or false.
They are not required. */
if(!req[reqParam])
continue;
allFound &= (reqParam in this.params);
if(!allFound)
break;
}
return allFound;
};
var iconMapping =
{
web: "//upload.wikimedia.org/wikipedia/commons/f/f0/Silk-Page_white_world.png",
book: "//upload.wikimedia.org/wikipedia/commons/1/1e/Silk-Book.png",
journal: "//upload.wikimedia.org/wikipedia/commons/f/f8/Silk-Page_white_text.png",
news: "//upload.wikimedia.org/wikipedia/commons/3/32/Silk-Newspaper.png",
newsgroup: "//upload.wikimedia.org/wikipedia/commons/5/5c/Silk-Comments.png",
"press release": "//upload.wikimedia.org/wikipedia/commons/b/bd/Silk-Transmit_blue.png",
interview: "//upload.wikimedia.org/wikipedia/commons/f/f7/Silk-Telephone.png",
episode: "//upload.wikimedia.org/wikipedia/commons/b/b2/Silk-Television.png",
"AV media": "//upload.wikimedia.org/wikipedia/commons/1/1a/Silk-film.png"
};
var superGetIcon = this.getIcon;
this.getIcon = function()
{
var icon = iconMapping[this.type];
if(icon)
{
return icon;
}
return superGetIcon.call(this);
};
},
/**
* A function for citation style refs.
* @class CitationReference
* @for proveit
* @constructor
* @extends AbstractReference
* @param {Object} argObj argument object with keys for each option
*/
CitationReference: function(argObj) {
proveit.AbstractReference.call(this, argObj);
// None currently required;
var requiredParams = {};
// These paramaters will be auto-suggested when editing.
var defaultParams =
{
web: [ "url", "author", "title", "date", "accessdate"],
news: [ "author", "title", "newspaper", "url", "publication-place", "volume", "issue", "date", "pages"],
encyclopedia: ["author", "editor", "contribution", "title", "publisher", "place", "year", "volume", "pages"],
book: ["author", "title", "publisher", "place", "year"],
journal: ["author", "title", "journal", "volume", "issue", "year", "pages"],
patent: ["inventor", "title", "issue-date", "patent-number", "country-code"]
};
/**
* Returns the sort index for a given parameter
* @param {String} param parameter name
* @return {Number} sort index if found, otherwise -1
*/
this.getSortIndex = function(param)
{
// This is the order fields will be displayed or outputted.
return $.inArray(param, [
"last",
"first",
"url",
"author",
"editor",
"contribution",
"author-link",
"last2",
"first2",
"author2-link",
"publication-date",
"inventor",
"title",
"issue-date",
"patent-number",
"country-code",
"journal",
"volume",
"newspaper",
"issue",
"date",
"publisher",
"place",
"year",
"edition",
"publication-place",
"series",
"version",
"pages",
"page",
"id",
"isbn",
"doi",
"oclc",
"accessdate"
]);
};
/**
* Returns this reference as a string.
* @return {String} reference as string
*/
this.toString = function()
{
return this.toStringInternal("Citation", false);
};
/**
* Return required parameters for this citation type.
* @return {Object} object with required parameters as keys and true as value; empty object for unknown type
*/
this.getRequiredParams = function()
{
return requiredParams;
};
/**
* Returns default parameters (to be suggested when editing) for current reference
* @return {Array} array of default parameter names; empty array if unknown
*/
this.getDefaultParams = function()
{
if(this.type)
{
return defaultParams[this.type];
}
else
{
return ["url", "title", "author", "date", "publisher"]; // Can't determine more specific defaults when editing a pre-existing Citation.
}
};
},
/**
* Constructor for RawReference type.
* @class RawReference
* @for proveit
* @constructor
* @extends AbstractReference
* @param {Object} argObj the argument object, with keys for each option
*/
RawReference: function(argObj)
{
proveit.AbstractReference.call(this, argObj);
this.type = 'raw';
/**
* Returns this reference as a string.
* @return {String} reference as string
*/
this.toString = function()
{
return this.orig;
};
this.params['title'] = this.orig;
this.getIcon = function()
{
return 'https://upload.wikimedia.org/wikipedia/commons/d/db/Silk-Page_white_code_red.png';
};
this.getTypeForDisplay = function()
{
return proveit.getDescriptions()['raw'];
};
},
// TODO: This should be unified with changeRefFromEditPane
/**
* Convert the current contents of the add citation panel to a reference (i.e CiteReference(), CitationReference())
* @for proveit
* @param {Node} box typepane root of add GUI (pane for specific type, e.g. journal)
* @return {AbstractReference} ref or null if no panel exists yet.
*/
getReferenceFromAddPane: function(box)
{
var $box = $(box);
var type = $box.data('proveitRefType');
// get <ref> name
var refName = $('#addrefname').val();
var citeFunc = this.togglestyle ? this.CiteReference : this.CitationReference;
var ref = new citeFunc({"name": refName, "type": type});
var paramName, paramVal;
var paramList = $(".paramlist", box)[0];
var paramRows = $('div', paramList);
for (var i = 0; i < paramRows.length; i++)
{
var paramRow = paramRows[i];
var valueTextbox = $(".paramvalue", paramRow)[0];
if($(paramRow).hasClass("addedrow")) // Added with "Add another field"
{
paramName = $.trim($(".paramdesc", paramRow)[0].value);
}
else
{
paramName = valueTextbox.id.substring(this.NEW_PARAM_PREFIX.length);
}
paramVal = $.trim(valueTextbox.value);
if(paramName != "" && paramVal != "")
{ // Non-blank
ref.params[paramName] = paramVal;
}
}
ref.update();
return ref;
},
/**
* Called from the add citation panel, this is the function used to
* add the actual citation.
*
* @param {AbstractReference} ref reference being added
*/
addReference: function(ref) {
// get this working, lots of typing here.
this.addNewElement(ref);
ref.orig = ref.toString();
/*
* Cycle through the boxes and grab the id's versus the values, watch
* for the final box and make sure to grab the type as well
*/
this.insertRefIntoMWEditBox(ref, true); // true means insert full text here, regardless of global toggle.
ref.save = true;
ref.inMWEditBox = true;
},
/**
* Clear all rows of passed in add citation panes.
* @param {Node} citePanes raw DOM element
*/
clearCitePanes: function(citePanes)
{
if(citePanes.hasChildNodes())
{
citePanes.removeChild(citePanes.firstChild);
}
},
/**
* Add event handler to Delete Field button in Add/Edit Reference panes
* @param {Node} fieldRow the fieldRow DOM element to remove
*/
activateRemoveField: function(fieldRow) {
$('.delete-field', fieldRow).click(function() {
$(fieldRow).hide(
'highlight',{},'slow',
function() {
$(fieldRow).remove();
}
);
});
},
/**
* Changes the panel for the add reference panel to the correct type of entry
* @param {Node} menu Raw HTML menu element
*/
changeAddPane: function(menu) {
// Reset scroll
$('#add-fields').scrollTop(0);
$(menu.parentNode).show(); // cite/citation vbox.
var citePanes = $(".addpanes", menu.parentNode.parentNode).get(0);
this.clearCitePanes(citePanes);
var newRefType = menu.value;
var genPane = document.getElementById("dummyCitePane").cloneNode(true);
var $genPane = $(genPane).attr('id', '');
$genPane.data('proveitRefType', newRefType);
// name the ref-name-row
$('.ref-name-row', $genPane).children('input').attr('id','addrefname');
$('.ref-name-row', $genPane).children('label').attr('for','addrefname');
// Somewhat hackish. What's a better way?
var newRef;
if(menu.id == "citemenu")
{
newRef = new this.CiteReference({});
}
else
{
newRef = new this.CitationReference({});
}
newRef.type = newRefType;
var descs = this.getDescriptions();
var defaultParams = newRef.getDefaultParams().slice(0); // copy
defaultParams.sort(newRef.getSorter());
//var required = newRef.getRequiredParams();
// Possibly, Cite objects should automatically include default parameters in their param maps. That would seem to make this simpler.
for(var i = 0; i < defaultParams.length; i++)
{
newRef.params[defaultParams[i]] = "";
}
// Should there be a getParamKeys or similar function for this, or even getSortedParamKeys?
var newParams = [];
for(param in newRef.params)
{
newParams.push(param);
}
newParams.sort(newRef.getSorter());
var required = newRef.getRequiredParams();
var paramList = $(".paramlist", $genPane)[0];
for(var i = 0; i < newParams.length; i++)
{
var param = newParams[i];
var paramBox;
if(descs[param])
{
paramBox = document.getElementById("preloadedparamrow").cloneNode(true);
var label = $('.paramdesc', paramBox);
if(required[param])
{
label.addClass("required");
$('.delete-field', paramBox).remove(); // don't let people remove required fields
}
else
{
this.activateRemoveField(paramBox);
}
label.text(descs[param]);
// Basically the same code as nameHbox above
label.attr("for", this.NEW_PARAM_PREFIX + param);
if(param == 'accessdate')
$('.paramvalue', paramBox).val(this.dateFormatter.format(new Date));
}
else
{
// Throwing an error here doesn't make sense if user-added fields can be copied over.
// throw new Error("Undefined description for param: " + param);
paramBox = document.getElementById("addedparamrow").cloneNode(true);
var nameTextbox = $(".paramdesc", paramBox)[0];
nameTextbox.setAttribute("value", param);
}
paramBox.id = "";
this.activateRemoveField(paramBox);
$(".paramvalue", paramBox)[0].id = this.NEW_PARAM_PREFIX + param;
//paramBox.childNodes[2].value = newRef.params[param]; // Causes parameters to disappear. Why?
paramList.appendChild(paramBox);
}
$(citePanes).prepend($genPane);
},
/**
* Creates and returns a hidden element holding the template elements
* (placeholder elements later cloned and filled with real data)
*
* @return {jQuery} $root Hidden root element holding templates
*/
createTemplateElement: function() {
var $root = $('<div>', {
id: 'proveit-templates'
});
// Dummy cite pane
var dummyCite = $('<div>', {
id: 'dummyCitePane',
"class": 'typepane'
});
var $addRefNameRow = this.createReferenceNameRow();
//$('input', $addRefNameRow).attr('id', 'addrefname');
//$('label', $addRefNameRow).attr('for', 'addrefname');
dummyCite.append($addRefNameRow);
dummyCite.append($('<div>', {"class": 'paramlist'}));
$root.append(dummyCite);
var preloadedparam = $('<div>', {
id: 'preloadedparamrow',
"class": 'preloadedrow input-row'
}).append($('<label>', {
"class": 'paramdesc'
}));
var paramvalue = $('<input>', {
"class": 'paramvalue',
tabindex: 0
});
preloadedparam.append(paramvalue);
var deleteButton = $('<button>', {
"class": 'delete-field',
tabindex: -1
}).text('delete field');
deleteButton.button({
icons: {
primary: 'ui-icon-close'
},
text: false
});
preloadedparam.append(deleteButton);
$root.append(preloadedparam);
var addedparam = $('<div>', {
id: 'addedparamrow',
"class": 'addedrow input-row'}).
append($('<input>', {
"class": 'paramdesc',
tabindex: 0
})).
append(paramvalue.clone()).
append(deleteButton.clone());
$root.append(addedparam);
return $root;
},
/**
* Creates a row to be used to input name attribute of the ref (<ref name="..." />)
*
* @return {jQuery} <ref> name row
*/
createReferenceNameRow: function() {
// div.ref-name-row
var $refNameRow = $('<div>', {
"class": 'ref-name-row',
tabindex: -1
});
var refLabel = $('<label>', {
"for": 'editrefname',
title: 'This is a unique identifier that can be used to refer to this reference elsewhere on the page.',
"class": 'paramdesc'
}).text('<ref> name');
$refNameRow.append(refLabel);
$refNameRow.append($('<input>', {
id: 'editrefname',
"class": 'paramvalue',
tabindex: 0
}));
return $refNameRow;
},
/**
* Create ProveIt HTML GUI
*/
createGUI: function()
{
if(this.getGUI().length > 0)
{
// GUI already created
return false;
}
// more JqueryUI CSS: http://blog.jqueryui.com/2009/06/jquery-ui-172/
var gui = $('<div>', {id: this.GUI_ID});
var $tabs = $('<div>', {id: 'proveit-tabs'});
var created = $('<h1>');
var createdLink = $('<a>').attr({title: 'Created by the ELC Lab at Georgia Tech',
href: 'http://proveit.cc.gatech.edu',
target: '_blank'});
// Main logo in upper-right
var logo = $('<img>' ).attr( {src: 'https://upload.wikimedia.org/wikipedia/commons/0/0d/ProveIt_user_interface_logo.png', alt: 'ProveIt', height: 30, width: 118 } );
createdLink.append(logo);
created.append(createdLink);
// Minimize/maximize button
var showHideButton = $('<button>', {
id: 'proveit-show-hide-toggle'
} ).text('show/hide');
created.append(showHideButton);
$tabs.append(created);
var header = $('<ul>');
var view = $('<li>');
// View tab link
var viewTab = $('<a/>', {id: 'proveit-view-tab', "class": 'tab-link', href: '#proveit-view-edit-panel'}).text('References (');
var numRefs = $('<span>').attr({id: 'numRefs'}).text('0');
viewTab.append(numRefs, ')');
view.append(viewTab);
header.append(view);
var add = $('<li>');
// Add tab link
var addTab = $('<a>').attr({id: 'proveit-add-tab', "class": 'tab-link', href: '#proveit-add-panel'}).text('Add a Reference');
add.append(addTab);
header.append(add);
$tabs.append(header);
// View and edit panel
var viewEditPanel = $('<div>', {id: 'proveit-view-edit-panel'});
// View pane used for displaying references; within view tab
var viewPane = $('<div>', {id: 'view-pane'});
var viewScroll = $('<div>', {"class": 'scroll',
style: 'height: 210px;'});
// Ref list root element
var refTable = $('<table>', {id: 'refs'});
var dummyRef = $('<tr>', {id: 'dummyRef',
style: 'display: none;'});
dummyRef.append($('<td>', {"class": 'number'})).
append($('<td>', {"class": 'type'})).
append($('<td>', {"class": 'title'}));
//append($('<td>', {"class": 'details'}));
var editTd = $('<td>', {"class": 'edit'}).
append($('<button>', {text: 'edit'}));
dummyRef.append(editTd);
refTable.append(dummyRef);
viewScroll.append(refTable);
viewPane.append(viewScroll);
viewEditPanel.append(viewPane);
// div#edit-pane, within view tab
var editPane = $('<div>', {id: 'edit-pane', style: 'display: none'});
// div#edit-fields
var editFields = $('<div>', {id: 'edit-fields',
"class": 'inputs scroll',
style: 'height: 170px',
tabindex: -1});
var refNameRow = this.createReferenceNameRow();
// div.paramlist
var paramList = $('<div/>', {"class": 'paramlist'});
editFields.append(refNameRow);
editFields.append(paramList);
editPane.append(editFields);
// div#edit-buttons, part of edit pane
var editButtons = $('<div/>', {id: 'edit-buttons'});
var addFieldButton = $('<button/>', {style: 'margin-right: 50px;'}).
append('add field');
editButtons.append(addFieldButton);
var reqSpan = $('<span/>', {"class": 'required',
text: 'bold'});
editButtons.append(reqSpan).
append(' = required field');
var saveButton = $('<button/>', {"class": 'right-side accept',
text: 'update edit form'});
editButtons.append(saveButton);
var cancelButton = $('<button/>', {"class": 'right-side cancel',
text: 'cancel'});
editButtons.append(cancelButton);
editPane.append(editButtons);
viewEditPanel.append(editPane);
$tabs.append(viewEditPanel);
// Add panel
var addPanel = $('<div/>', {id: 'proveit-add-panel'});
var addFields = $('<div/>', {id: 'add-fields',
"class": 'inputs scroll',
style: 'height: 170px',
tabindex: -1});
var cite = $('<div/>', {style: 'display: none',
id: 'cite',
"class": 'input-row'});
var refCiteTypeLabel = $('<label/>', {'for': 'citemenu',
"class": 'paramdesc required',
text: 'Reference type'});
cite.append(refCiteTypeLabel);
var citemenu = $('<select/>', {id: 'citemenu',
change: function()
{
proveit.changeAddPane(citemenu.get(0));
}});
var citeTypes = this.CiteReference.getTypes();
var descs = this.getDescriptions();
for(var i = 0; i < citeTypes.length; i++)
{
citemenu.append($('<option/>', {value: citeTypes[i],
text: descs[citeTypes[i]]}));
}
cite.append(citemenu);
addFields.append(cite);
addFields.append($('<div/>', {"class": 'addpanes',
id: 'citepanes',
tabindex: -1}));
var citation = $('<div/>', {style: 'display: none',
id: 'citation',
"class": 'input-row'});
var refCitationTypeLabel = refCiteTypeLabel.clone().attr('for', 'citationmenu');
citation.append(refCitationTypeLabel);
var citationmenu = $('<select/>', {id: 'citemenu',
change: function()
{
proveit.changeAddPane(citationmenu.get(0));
}});
var citationTypes = ['web', 'book', 'journal', 'encyclopedia', 'news', 'patent'];
for(var j = 0; j < citationTypes.length; j++)
{
citationmenu.append($('<option/>', {value: citationTypes[i],
text: descs[citationTypes[i]]}));
}
citation.append(citationmenu);
addFields.append(citation).
append($('<div/>', {"class": 'addpanes',
id: 'citationpanes', style: 'display: none;'}));
addPanel.append(addFields);
// Add buttons, part of add tab
var addButtons = $('<div/>', {id: 'add-buttons'});
addButtons.append($('<button/>', {style: 'margin-right: 50px;',
text: 'add field'})).
append(reqSpan.clone()).
append(" = required").
append(saveButton.clone().text('insert into edit form')).
append(cancelButton.clone());
addPanel.append(addButtons);
$tabs.append(addPanel);
gui.append($tabs);
$(document.body).prepend(gui);
var cancelEdit = function() {
$("#edit-pane").hide();
$("#view-pane").show();
};
// set up tabs
$tabs.tabs({
collapsible: true,
active: false, // Initially all collapsed
beforeActivate: function(event, ui)
{
// TODO: Select just-added item in reference list, upon moving from add tab to view tab
// Is this event caused by a click on a tab?
var isClickOnTab = event.currentTarget && $(event.currentTarget).is('.tab-link');
// Moving to add (including maximizing)
if(ui.newPanel.is(addPanel))
{
cancelEdit();
proveit.changeAddPane(document.getElementById(proveit.togglestyle ? 'citemenu' : 'citationmenu'));
}
if(ui.newPanel.length === 0)
{
if(isClickOnTab)
{
// Don't allow collapsing by clicking a tab.
event.preventDefault();
// Clicked view tab when either view or edit was showing
if(ui.oldPanel.is(viewEditPanel))
{
// Cancel the edit and show reference list
cancelEdit();
}
} else
{
// They clicked the show/hide button; let it collapse and update the icon.
showHideButton.button("option", "icons", { primary: 'ui-icon-triangle-1-n' } );
}
} else
{
// There is a visible new panel; update the icon.
showHideButton.button("option", "icons", { primary: 'ui-icon-triangle-1-s' } );
}
}
});
// add panel buttons
$("#add-buttons button:first").button({
icons: {
primary: 'ui-icon-circle-plus'
}
}).click(function()
{
proveit.addPaneRow(document.getElementById("proveit-add-panel"));
})
.next().next().button({
icons: {
primary: 'ui-icon-circle-check',
secondary: 'ui-icon-circle-arrow-e'
}
}).click(function()
{
proveit.addReference(proveit.getReferenceFromAddPane($('#proveit-add-panel .typepane').get(0)));
$tabs.tabs( { active: 0 } ); // Activate view panel
$("div.scroll, #view-pane").scrollTop(100000); // scroll to new ref
}).next().
button({
icons: {
primary: 'ui-icon-circle-close'
}
}).click(function()
{
$tabs.tabs( { active: 0 } ); // Activate view panel
});
// cancel buttons
$("button.cancel").click(cancelEdit);
// edit panel buttons
$("#edit-buttons button:first").button({
icons: {
primary: 'ui-icon-circle-plus'
}
}).click(function()
{
proveit.addPaneRow($("#edit-pane"));
}).
next().next().
button({
icons: {
primary: 'ui-icon-circle-check'
}
}).next().button({
icons: {
primary: 'ui-icon-circle-close'
}
});
// create the minimize button
showHideButton.button({
icons: {
primary: 'ui-icon-triangle-1-n'
},
text: false
});
var viewAndAdd = $(viewEditPanel).add(addPanel);
this.viewAndAddPanes = viewAndAdd;
var prevActiveTabPaneIndex = 0;
function minimize()
{
prevActiveTabPaneIndex = $tabs.tabs('option', 'active');
// Collapse all tabs
$tabs.tabs('option', 'active', false);
}
function maximize()
{
$tabs.tabs('option', 'active', prevActiveTabPaneIndex);
}
this.toggleViewAddVisibility = function()
{
// All tabs collapsed
if($tabs.tabs('option', 'active') === false) {
maximize();
} else {
minimize();
}
};
showHideButton.click(this.toggleViewAddVisibility);
this.scanForReferences();
$("#refs tr").eq(0).click().click(); // select first item in list. TODO: Why two .click?
// alternate row colors
$("#refs tr:even").addClass('light');
$("#refs tr:odd").addClass('dark');
gui.append(this.createTemplateElement());
},
/**
* A reference to the set containing two items, the view and add tabs. Will be initialized by createGUI, so it is non-null if ProveIt is visible
*
* @type {$NodeSet}
*/
viewAndAddPanes: null,
/*
* Gets jQuery set for ProveIt GUI, which will be empty if ProveIt has not initialized
*
* @return {$Node} root of ProveIt
*/
getGUI: function()
{
return $('#' + this.GUI_ID);
},
/**
* Hides ProveIt completely
*/
hide: function()
{
this.getGUI().hide();
},
/**
* Show ProveIt
*/
show: function()
{
this.createGUI();
this.getGUI().show();
},
/**
* Toggle overall visiblility. If currently hidden, go to minimized. If minimized, maximize. If maximize, hide
*/
toggleVisibility: function()
{
if(this.getGUI().is(':visible'))
{
if(this.viewAndAddPanes.is(':visible')) // maximized
{
this.hide();
}
/*
* If previously maximized, we minimize after hiding, so when we show, it will already be minimized.
* If minimized, we maximize
*/
this.toggleViewAddVisibility();
}
else
{
this.show();
}
},
/**
* Toggle visibility of view and add panes. Initialized by createGUI
*
* @method toggleViewAddVisibility
*/
toggleViewAddVisibility: null,
/**
* Generates refbox row and all children, to be used by addNewElement, and when updating
*
* @param {AbstractReference} ref reference to generate from
* @param {Boolean} isReplacement if true, this replaces another refbox item, so no number will be assigned, and the count will not be updated.
* @return {Node} new refbox row for refbox
*/
makeReferenceBoxRow: function(ref, isReplacement)
{
var refName = ref.name; //may be null or blank
//var refbox = this.getReferenceBox();
var newchild = $('<tr><td class="number"></td><td class="type"></td><td class="title"></td><td class="edit"></td></tr>').get(0);
// removed <span class="pointers"></span>
// removed <td class="details"></td>
if(!ref.isValid())
{
// Flag as invalid.
$(newchild).addClass('invalid');
}
// grab the nodes that need changed out of it
var neweditimage = $('.edit button', newchild).get(0);
var thisproveit = this;
var title = '';
var shortTitle = '';
if(ref.params['title'] != null)
{
title = ref.params['title'];
shortTitle = this.truncateTitle(title);
}
$('td.title', newchild).text(shortTitle);
$('td.title', newchild).attr('title', title);
// deal with variations of date info
var formattedYear = '';
if(ref.params['year'])
formattedYear = ref.params['year'];
else if (ref.params['date'])
{
var yearMatch = ref.params['date'].match(/^([12]\d{3})/);
if(yearMatch)
{
formattedYear = yearMatch[1];
}
}
//$('td.year', newchild).text(formattedYear);
// deal with variations of author info
var formattedAuthor = '';
if(ref.params['author'])
formattedAuthor = ref.params['author'];
else if (ref.params['last'])
{
// if(ref.params['first'])
// formattedAuthor = ref.params['last'] + ', ' + ref.params['first'];
// else
formattedAuthor = ref.params['last'];
}
if(ref.params['coauthors'] || ref.params['last2'])
formattedAuthor += ' <i>et al.</i>';
// build the "details" cell based on presence of author/year data
// var details = '';
// if (formattedYear != '' && formattedAuthor != '')
// details = '(' + formattedAuthor + ', ' + formattedYear + ')';
// else if (formattedYear != '')
// details = '(' + formattedYear + ')';
// else if (formattedAuthor != '')
// details = '(' + formattedAuthor + ')';
// $('td.details', newchild).html(details);
// generate a URL based on ref type
var icon = ref.getIcon(), url = '', refType = ref.type;
switch(refType)
{
case 'web':
url = ref.params['url'];
break;
case 'book':
if(ref.params['isbn'] != null)
url = mw.util.getUrl( 'Special:BookSources', { isbn: ref.params['isbn'] } );
break;
case 'journal':
case 'conference':
if(ref.params['doi'] != null)
url = 'http://dx.doi.org/' + ref.params['doi'];
break;
case 'news':
url = ref.params['url'];
break;
case 'episode':
url = 'http://www.imdb.com/find?s=ep&q=' + escape(ref.params['title']);
break;
}
$('td.type', newchild).css('background-image','url('+icon+')');
var authorByline = '', yearByline = '', refTypeByline = '';
if(formattedAuthor != '')
authorByline = 'By: <span class="author">' + formattedAuthor + '</span>';
if(formattedYear != '')
yearByline = 'Date: <span class="date">' + formattedYear + '</span>';
if(refType != null)
{
var displayType = ref.getTypeForDisplay(), formattedRefType = displayType;
$('td.type', newchild).attr('title', displayType);
if(url != '')
formattedRefType = '<a href="' + url + '" target="_blank">' + formattedRefType + '</a>';
refTypeByline = 'Type: <span class="type">' + formattedRefType + '</span>';
}
//alert("authorByline: " + authorByline + "\n yearByline: " + yearByline + "\n refTypeByline: " + refTypeByline);
var byline = '', separator = ' | ';
if(refType == 'raw')
{
byline = refTypeByline + separator + mw.html.escape(ref.toString());
}
else if(authorByline != '') // a??
{
if(yearByline != '') // ad?
{
if(refTypeByline != '') // adt
byline = authorByline + separator + yearByline + separator + refTypeByline;
else // ad-
byline = authorByline + separator + yearByline;
}
else // a-?
{
if(refTypeByline != '') // a-t
byline = authorByline + separator + refTypeByline;
else // a--
byline = authorByline;
}
}
else // -??
{
if(yearByline != '') // -d?
{
if(refTypeByline != '') // -dt
byline = yearByline + separator + refTypeByline;
else // -d-
byline = yearByline;
}
else // --?
{
if(refTypeByline != '') // --t
byline = refTypeByline;
// no need for ---
}
}
byline = '<p>' + byline + '</p>';
//alert(byline);
// create expanded <div>
var expanded = $('<div />',{
"class": 'expanded'
});
// append the infobar to the expanded info box
$(expanded).append(byline);
// append the expanded info box to the title <td>
$('td.title', newchild).append(expanded);
if(!isReplacement)
{
// get ref number by counting number of refs (this includes dummy ref, but not the one we're creating)
var numRefs = $('#refs tr').length;
$('td.number', newchild).text(numRefs);
$('#numRefs').text(numRefs); // update the number of refs in the view tab
}
// event handler for selecting a ref)
$(newchild).click(function() {
thisproveit.highlightTargetString(ref.orig);
//thisproveit.highlightTargetString(ref.orig);
$("#refs tr").removeClass('selected');
$(newchild).addClass('selected');
});
var doEdit = function() {
thisproveit.updateEditPane(ref);
$("#view-pane").hide();
$("#edit-pane").show();
};
var citationStrings = ref.getCitationStrings();
//var pointers = $('.pointers', newchild);
var allCitations = $('<span class="all-citations" />');
for(var i = 0; i < citationStrings.length; i++)
{
var dividend = i + 1;
var colName = "";
while(dividend > 0)
{
var mod = --dividend % 26;
colName = String.fromCharCode(97 + mod) + colName; // a = 97
dividend = Math.floor(dividend / 26);
}
var citationHolder = $('<a href="#">' + colName + '</a>');
// Bind i
var clickFunc = (function(i)
{
return function()
{
var last = 0, j = 0;
var text = proveit.getTextboxText();
for(j = 0; j < i; j++)
{
last = text.indexOf(citationStrings[j], last);
// Shouldn't happen. Indicates citation strings are out of date.
if(last == -1)
{
proveit.log("citationStrings[" + j + "]: " + citationStrings[j] + " not found. Returning.");
return false;
}
last += citationStrings[j].length;
}
var startInd = text.indexOf(citationStrings[i], last);
if(startInd == -1)
{
proveit.log("citationStrings[" + i + "]: " + citationStrings[i] + " not found.");
}
else
{
proveit.highlightLengthAtIndex(startInd, citationStrings[i].length);
}
return false;
};
})(i);
citationHolder.click(clickFunc);
allCitations.append(citationHolder);
}
if(citationStrings.length > 1)
{
var newP = $('<p />');
newP.append('This reference is cited in the article <span class="num-citations">' + citationStrings.length + ' times</span>: ').append(allCitations);
expanded.append(newP);
}
// edit buttons
if(ref.type != 'raw')
{
// SMALL EDIT BUTTON
// create button
var smallEditBtn = $('<button />',{
text: 'edit'
});
// transform button
$(smallEditBtn).button({
icons: {
primary: 'ui-icon-pencil'
},
text: false
});
// button click event handler
smallEditBtn.click(doEdit);
// append button
$('.edit', newchild).append(smallEditBtn);
// LARGE EDIT BUTTON
// create button
var editBtn = $('<button />',{
"class": 'edit',
text: 'edit this reference'
});
// transform button
$(editBtn).button({
icons: {
primary: 'ui-icon-pencil'
},
text: true
});
// button click event handler
editBtn.click(doEdit);
// append button
expanded.append(editBtn);
// ROW EVENT HANDLER
$(newchild).dblclick(doEdit);
}
else
{
// needed to keep all rows the same height
$('.edit', newchild).append(' ');
}
// ibid button
if(citationStrings.length > 0)
{
// create button
var ibidBtn = $('<button />',{
"class": 'insert',
text: 'insert this reference at cursor'
});
// transform button
$(ibidBtn).button({
icons: {
primary: 'ui-icon-arrowthick-1-e'
},
text: true
});
// button click event handler
ibidBtn.click(function(){
thisproveit.insertRefIntoMWEditBox(ref, false);
return false;
});
// append button
expanded.append(ibidBtn);
}
return newchild;
},
/**
* Truncates title to fit ProveIt refbox row.
* @param {String} title title to truncate
* @return {String} truncated title
*/
truncateTitle: function(title)
{
var MAX_LENGTH = 86;
var truncated = title;
if(title.length > MAX_LENGTH)
{
truncated = truncated.substring(0, MAX_LENGTH);
var lastSpacePos = truncated.lastIndexOf(' ');
if(lastSpacePos != -1)
{
truncated = truncated.substr(0, lastSpacePos);
truncated += " ...";
}
}
return truncated;
},
/**
* Only to be used internally to add the citations to the list
*
* @param {AbstractReference} ref the reference to add
*/
addNewElement: function(ref)
{
var refbox = this.getReferenceBox();
$(refbox).append(this.makeReferenceBoxRow(ref, false));
}
}, window.proveit);
/**
* Static method. Returns valid Cite reference types
* @for CiteReference
* @static
* @return {Array} array of cite method types
*/
proveit.CiteReference.getTypes = function()
{
return ["web", "book", "journal", "conference", "encyclopedia", "news", "newsgroup", "press release", "interview", "episode", "AV media"];
};
proveit.split._compliantExecNpcg = /()??/.exec("")[1] === undefined; // NPCG: nonparticipating capturing group
proveit.split._nativeSplit = String.prototype.split;
proveit.setup();
}( mediaWiki, jQuery ) );
// Local Variables:
// js2-basic-offset: 8
// End:
// </nowiki>
jtjc1y3eqympiqm1u9eagp9nksateml
MediaWiki:Gadget-refToolbarBase.js
8
46320
123403
110504
2026-11-02T19:50:25Z
Maintenance script
3102
Use thumb.wikimedia.org for thumbnails ([[phab:T427465]], Operator: Ladsgroup)
123403
javascript
text/javascript
/* jshint asi: true */
/* global mw, $, CiteTB, citeTemplate, citeErrorCheck */
if ( window.CiteTB === undefined ) {
window.CiteTB = {
"Templates" : {}, // All templates
"Options" : {}, // Global options
"UserOptions" : {}, // User options
"DefaultOptions" : {}, // Script defaults
"ErrorChecks" : {} // Error check functions
};
}
if (typeof mw.usability == 'undefined') {
mw.usability = {};
mw.usability.getMsg = function(m) { return mw.messages.get(m); }
mw.usability.addMessages = function(msgs) { mw.messages.set(msgs); };
}
// Object for cite templates
window.citeTemplate = function (templatename, shortform, basicfields, expandedfields) {
// Properties
this.templatename = templatename; // The template name - "cite web", "cite book", etc.
this.shortform = shortform; // A short form, used for the dropdown box
this.basic = basicfields; // Basic fields - author, title, publisher...
// Less common - quote, archiveurl - should be everything the template supports minus the basic ones
this.extra = expandedfields;
this.incrementables = {};
// Add it to the list
CiteTB.Templates[this.templatename] = this;
// Methods
this.makeFormInner = function(fields, incrsetup) {
var i=0;
var trs = [];
var autofills = []
for (i=0; i<fields.length; i++) {
var fieldobj = fields[i];
var field = labelfield = fieldobj.field;
var ad = false;
if (incrsetup && fieldobj.increment_group) {
field = fieldobj.field.replace('<N>', '1');
labelfield = fieldobj.field.replace('<N>', '');
if (this.incrementables[fieldobj.increment_group] && !this.incrementables[fieldobj.increment_group].setup) {
// The object has been created, but not fully initialized
this.incrementables[fieldobj.increment_group]['fields'].push(fieldobj)
} else if (!this.incrementables[fieldobj.increment_group]) {
// Object not yet created
this.incrementables[fieldobj.increment_group] = {
'fields': [fieldobj],
'val':1,
'setup': false
};
} else if (this.incrementables[fieldobj.increment_group] && this.incrementables[fieldobj.increment_group].setup) {
// Fully initialized from a previous invocation of this function, just resetting the number
this.incrementables[fieldobj.increment_group].val = 1
}
} else if (fieldobj.increment_group) {
// Adding a new row
incrval = this.incrementables[fieldobj.increment_group].val;
field = fieldobj.field.replace('<N>', incrval.toString());
labelfield = fieldobj.field.replace('<N>', '');
}
if ($.inArray(field, CiteTB.getOption('autodate fields')) != -1 ) {
im = $('<img />').attr('src', '//thumb.wikimedia.org/wikipedia/commons/thumb/7/7b/Nuvola_apps_date.svg/20px-Nuvola_apps_date.svg.png');
im.attr('alt', mw.usability.getMsg('cite-insert-date')).attr('title', mw.usability.getMsg('cite-insert-date'));
var ad = $('<a />').attr('href', '#');
ad.append(im);
ad.attr('id', 'cite-date-'+CiteTB.escStr(this.shortform)+'-'+field);
$( document ).on( 'click', '#cite-date-'+CiteTB.escStr(this.shortform)+'-'+field, CiteTB.fillAccessdate );
}
if (fieldobj.autofillid) {
var autotype = fieldobj.autofillid;
im = $('<img />').attr('src', '//thumb.wikimedia.org/wikipedia/commons/thumb/1/17/System-search.svg/20px-System-search.svg.png');
im.attr('alt', mw.usability.getMsg('cite-autofill-alt')).attr('title', mw.usability.getMsg('cite-autofill-alt'));
var ad = $('<a />').attr('href', '#');
ad.append(im);
ad.attr('id', 'cite-auto-'+CiteTB.escStr(this.shortform)+'-'+field+'-'+autotype);
autofills.push('#cite-auto-'+CiteTB.escStr(this.shortform)+'-'+field+'-'+autotype);
}
if (fieldobj.increment_button) {
var incrtype = fieldobj.increment_group;
im = $('<img />').attr('src', '//thumb.wikimedia.org/wikipedia/commons/thumb/b/b9/Nuvola_action_edit_add.svg/20px-Nuvola_action_edit_add.svg.png');
im.attr('alt', mw.usability.getMsg('cite-increment-alt')).attr('title', mw.usability.getMsg('cite-increment-alt'));
var ad = $('<a />').attr('href', '#');
ad.append(im);
ad.attr('id', 'cite-incr-'+CiteTB.escStr(this.shortform)+'-'+incrtype);
}
var display = mw.usability.getMsg('cite-'+labelfield+'-label');
if (typeof display !== 'string') {
if (fieldobj.label) {
display = CiteTB.fixStr(fieldobj.label);
} else {
display = CiteTB.fixStr(labelfield)
}
}
var tooltip = fieldobj.tooltip ? $('<abbr />').attr('title', mw.usability.getMsg(fieldobj.tooltip)).html('<sup>?</sup>') : false;
var input = '';
if (ad) {
input = $('<input tabindex="1" style="width:85%" type="text" />');
} else {
input = $('<input tabindex="1" style="width:100%" type="text" />');
}
input.attr('id', 'cite-'+CiteTB.escStr(this.shortform)+'-'+field);
if (fieldobj.autofillprop) {
classname = 'cite-'+CiteTB.escStr(this.shortform)+'-'+fieldobj.autofillprop
if (fieldobj.increment_group) {
input.addClass('cite-'+CiteTB.escStr(this.shortform)+'-incr-'+fieldobj.increment_group);
classname+='-'+this.incrementables[fieldobj.increment_group].val.toString();
}
input.addClass(classname);
}
var label = $('<label />');
label.attr('for', 'cite-'+CiteTB.escStr(this.shortform)+'-'+field).text(display);
if (tooltip) {
label.append(tooltip);
}
var style = 'text-align:right; width:20%;';
if (i%2 == 1) {
style += ' padding-left:1em;';
} else {
var tr = $('<tr />');
}
var td1 = $('<td class="cite-form-td" />').attr('style', style);
td1.append(label);
tr.append(td1);
var td2 = $('<td class="cite-form-td" style="width:30%" />');
td2.append(input);
if (ad) {
td2.append(ad);
}
tr.append(td2);
if (i%2 == 0) {
trs.push(tr);
}
}
var needsetup = false;
for (g in this.incrementables) {
if (!this.incrementables[g].setup) {
needsetup = true;
$( document ).on( 'click', '#cite-incr-'+CiteTB.escStr(this.shortform)+'-'+g, CiteTB.incrementFields );
this.incrementables[g].setup = true;
}
}
if (needsetup || $.isEmptyObject(this.incrementables)) {
for(i=0; i<autofills.length; i++) {
$( document ).on( 'click', autofills[i], CiteTB.initAutofill );
}
}
return trs;
}
// gives a little bit of HTML so the open form can be identified
this.getInitial = function() {
var hidden = '<input type="hidden" class="cite-template" value="' + this.templatename + '"/>';
return hidden;
}
// makes the form used in the dialog boxes
this.getForm = function() {
var main = $("<div class='cite-form-container' />");
var form1 = $('<table style="width:100%; background-color:transparent;" class="cite-basic-fields" />');
var i=0;
var trs = this.makeFormInner(this.basic, true);
for (var i=0; i<trs.length; i++) {
form1.append(trs[i]);
}
var form2 = $('<table style="width:100%; background-color:transparent; display:none" class="cite-extra-fields">');
trs = this.makeFormInner(this.extra, true);
for (var i=0; i<trs.length; i++) {
form2.append(trs[i]);
}
main.append(form1).append(form2);
var form3 = $('<table style="width:100%; background-color:transparent;padding-top:1em" class="cite-other-fields">');
var tr = $('<tr />');
var td1 = $('<td class="cite-form-td" style="text-align:right; width:20%" />');
var label1 = $('<label />');
label1.attr('for', "cite-"+CiteTB.escStr(this.shortform)+'-name').text(mw.usability.getMsg('cite-name-label'));
td1.append(label1);
var td2 = $('<td class="cite-form-td" style="width:30%" />');
var input1 = $('<input tabindex="1" style="width:100%" type="text" />');
input1.attr('id', 'cite-'+CiteTB.escStr(this.shortform)+'-name');
td2.append(input1);
var td3 = $('<td class="cite-form-td" style="text-align:right; padding-left:1em; width:20%">');
var label2 = $('<label />');
label2.attr('for', 'cite-'+CiteTB.escStr(this.shortform)+'-group').text(mw.usability.getMsg('cite-group-label'));
td3.append(label2);
var td4 = $('<td class="cite-form-td" style="width:30%" />');
var input2 = $('<input tabindex="1" style="width:100%" type="text" />');
input2.attr('id', 'cite-'+CiteTB.escStr(this.shortform)+'-group');
td4.append(input2);
tr.append(td1).append(td2).append(td3).append(td4);
form3.append(tr);
main.append(form3);
var extras = $('<div />');
extras.append('<input type="hidden" class="cite-form-status" value="closed" />');
var hidden = $('<input type="hidden" class="cite-template" />');
hidden.val(this.templatename);
extras.append(hidden);
var span1 = $('<span class="cite-preview-label" style="display:none;" />');
span1.text(mw.usability.getMsg('cite-raw-preview'));
extras.append(span1).append('<div class="cite-ref-preview" style="padding:0.5em; font-size:110%" />');
var span2 = $('<span class="cite-prev-parsed-label" style="display:none;" />');
span2.text(mw.usability.getMsg('cite-parsed-label'));
extras.append(span2).append('<div class="cite-preview-parsed" style="padding-bottom:0.5em; font-size:110%" />');
var link = $('<a href="#" class="cite-prev-parse" style="margin:0 1em 0 1em; display:none; color:darkblue" />');
link.text(mw.usability.getMsg('cite-form-parse'));
extras.append(link);
main.append(extras);
return main;
}
}
/* Class for error checks
FIXME: DOCS OUT OF DATE
type - type of error check - current options:
* 'refcheck' - apply a function on each ref individually
* function should accept a ref object, return a string
* 'reflist' - apply a function on the entire ref list
* function should accept an array of ref objects, return an array of strings
* 'search' - apply a function ro the page text
* function should accept the page text as a string, return an array of strings
The strings returned by the function should be valid HTML
func - The function described above
testname - Name of the error check, must not contain spaces
desc - A short description of the test
*/
window.citeErrorCheck = function (obj) {
this.obj = obj
CiteTB.ErrorChecks[this.obj.testname] = this;
this.run = function() {
var errors = [];
switch(this.obj['type']) {
case "refcheck":
CiteTB.loadRefs();
for(var i=0; i<CiteTB.mainRefList.length; i++) {
var e = this.obj.func(CiteTB.mainRefList[i]);
if (e) {
errors.push(e);
}
}
break;
case "reflist":
CiteTB.loadRefs();
errors = this.obj.func(CiteTB.mainRefList);
break;
case "search":
var func = this.obj.func
CiteTB.getPageText(function(text) {
errors = func(text);
});
break;
}
return errors;
}
this.getRow = function() {
var row = $("<li />");
var check = $("<input type='checkbox' name='cite-err-test' />");
check.attr('value', this.obj.testname);
var label = $("<label />").html(mw.usability.getMsg(this.obj.desc));
label.attr('for', this.obj.testname);
row.append(check).append(' – ').append(label);
return row;
}
}
$('head').trigger('reftoolbarbase');
kdju8pm2fcdxm36w9h7pn0ady5s2w2w
MediaWiki:Gadget-mobile-sidebar.js
8
46399
123402
110718
2026-11-02T19:50:24Z
Maintenance script
3102
Use thumb.wikimedia.org for thumbnails ([[phab:T427465]], Operator: Ladsgroup)
123402
javascript
text/javascript
/* _____________________________________________________________________________
* | |
* | === WARNING: GLOBAL GADGET FILE === |
* | Changes to this page affect many users. |
* | Please discuss changes on the talk page or on [[WT:Gadget]] before editing. |
* |_____________________________________________________________________________|
*
* Copied from [[meta:User:Brion VIBBER/mobile-sidebar.js]] as of last update (2014-10-13, [[meta:Special:Permalink/10185490]])
* See also https://github.com/brion/MediaWiki-MobileSidebar
*
* Mobile sidebar preview gadget
*
* Quick hack to show how pages look on mobile
* while browsing the desktop site.
*
* Brion Vibber <bvibber@wikimedia.org>
* 2014-10-10
* Cleaned up and enhanced by prtksxna
* Further cleaned up by Brion :D
*/
$(function () {
// Old iPhone size, the minimum we usually see
var width = 320, height = 480;
// @todo possibly make size selectable from some options...
// Note that pixel sizes are deceiving on mobile, as there's often a
// density factor. For instance 480x800 screens at 1.5x would cover
// only 320x533 or so. And let's not even get into the iPhone 6 Plus!
function showSidebar() {
localStorage['mw-mobile-sidebar-state'] = 'show';
var $content = $('#content');
var top = $content.position().top,
page = mw.config.get('wgPageName'),
src = '/wiki/' + encodeURIComponent(page) + '?useformat=mobile',
lang = mw.config.get('wgContentLanguage');
var $container = $('<div>').attr('id', 'mobile-sidebar');
var $mobileLink = $('<a>')
.text( 'Mobile' )
.addClass ( 'mobile_link' )
.attr( 'href', src )
.attr( 'target', '_blank')
.appendTo( $container );
var $egg = $( '<div>' )
.addClass( 'egg' )
.append(
$( '<img>' ).attr( 'src', 'https://thumb.wikimedia.org/wikipedia/commons/thumb/8/81/Wikimedia-logo.svg/240px-Wikimedia-logo.svg.png' ),
$( '<p>' ).html( 'If lost please return to <a href="https://meta.wikimedia.org/wiki/User:Brion_VIBBER">Brion Vibber</a>' )
)
.appendTo( $container )
.hide();
// @todo detect scrollbars and compensate width
var $frame = $('<iframe>')
.attr('src', src)
.css('width', width + 'px')
.css('height', height + 'px')
.appendTo($container);
var $close = $('<a>')
.html(' ×')
.addClass('close')
.click( hideSidebar )
.appendTo( $container );
$container.on( 'dblclick', function () {
$egg.toggle();
$mobileLink.toggle();
$close.toggle();
$frame.toggle();
} );
var frame = $frame[0];
$frame.on('load',function () {
// avoid TypeError: null is not an object (evaluating 'frame.contentDocument.querySelector')
if(!frame.contentDocument) return;
// Compensate for scrollbars on browsers that add them
var scrollBarWidth = width - frame.contentDocument.querySelector('body').clientWidth;
if ( scrollBarWidth > 0 ) {
$frame.css( 'width', ( width + scrollBarWidth ) + 'px' );
}
// Handle link navigation within the mobile preview doc
$(frame.contentDocument).on('click', 'a', function (e) {
e.preventDefault();
if ($(this).attr('href') && $(this).attr('href').indexOf('#') !== 0) {
window.location = this.href;
}
});
});
if ( mw.config.get( 'skin' ) === 'vector-2022' && window.innerWidth >= 1800 && document.body.classList.contains( 'vector-feature-limited-width-enabled' ) ) {
// no need to shift content as Vector 2022 limited content width is enabled and active
} else {
$('#content').css('margin-right', '360px');
}
$('#content').after($container);
}
function hideSidebar() {
localStorage['mw-mobile-sidebar-state'] = 'hidden';
$('#mobile-sidebar').remove();
$('#content').css('margin-right', '0');
}
function toggleState() {
if (localStorage['mw-mobile-sidebar-state'] !== 'hidden') {
hideSidebar();
} else {
showSidebar();
}
}
if (mw.config.get('wgAction') == 'view') {
var item = mw.util.addPortletLink( 'p-views', '#', 'Mobile', 'ca-mobile', 'Toggle mobile view sidebar' );
if ( item ) {
item.classList.remove( 'vector-tab-noicon' );
if ( mw.config.get( 'skin' ) === 'vector-2022' ) {
item.querySelector('a').classList.add( 'mw-ui-icon', 'mw-ui-icon-element',
'mw-ui-button', 'mw-ui-quiet', 'mw-ui-icon-mobile', 'mw-ui-icon-small' );
} else {
item.classList.add( 'icon' );
}
$(item).click( toggleState );
}
if (localStorage['mw-mobile-sidebar-state'] == 'hidden') {
hideSidebar();
} else {
showSidebar();
}
}
});
7fcdw36awhtu9l4pkyibwxkb3ugcl7t
Wikipedia talk:Vyakuchitika pa Chikaya
5
49966
123397
123355
2026-11-02T19:30:45Z
Watisoni Banda
10141
/* 5. Ivyo tikukhumba kupulika kufuma kwa ŵanthu ŵa Wikipedia ya Chitumbuka */ Zgolo
123397
wikitext
text/x-wiki
{{Pamaso pa yakuchitika vyapa Chikaya}}
== Kudumbiskana za ntchito ya kukuzga Wikipedia ya Chitumbuka: Masambiro na ma editathon mu 2027 ==
Monile mose!
Nkhukhumba kumanyiska ŵalembi wose na ŵanthu ŵa Wikipedia ya Chitumbuka za ntchito iyo tikunozga, ndipo nkhupempha kuti mupeleke maghanoghano, ulongozgi na masachizgo ghani pambere tindatume pempho ku WMF kwizira mu pulogiramu ya Rapid Fund.
=== 1. Za ntchito iyi ===
Ntchito iyi yikuchemeka '''Kukuzga Wikipedia ya Chitumbuka: Masambiro na ma editathon ku Gauteng na pa intaneti'''.
Chilato chikuru cha ntchito iyi nkhukwezga chiŵelengero cha ŵanthu ŵalembi pa Wikipedia ya Chitumbuka, mwa kusambizga ŵanthu awo ŵakuyowoya Chitumbuka umo ŵangajulira na kunozga nkhani pa Wikipedia.
Tikukhumba kuti ntchito iyi yichitike kwamba pa 1 Febuluwale m'paka pa 30 Epulero 2027.
=== 2. Ivyo tikukhumba kuchita ===
* Kuchita masambiro ghatatu mwakuonana maso na maso umo munthu wangagwiliskira ntchito Wikipedia mu malo gha Randburg, Diepsloot na Olivenhoutbosch mu chigaŵa cha Gauteng.
* Kuchita masambiro na kudumbiskana pa intaneti kuti ŵanthu awo ŵakukhala kuwaro kwa Gauteng, kusazgapo ŵanthu ŵa ku Malawi, Zambia na ku vyaru vinyake, nawo ŵatorepo luwande.
* Kusambizga ŵanthu umo ŵangapangira na kunozga nkhani pa Wikipedia ya Chitumbuka.
* Kusambizga umo ŵangagwiliskira ntchito vyakulembera vyakugomezgeka, kuŵika maumboni na kulondezga fundo za Wikipedia zakukhwaskana na kuleka kutemwera na kugwiliskira ntchito uthenga wakugomezgeka.
* Kuchita editathon yakunozga na kukuzga nkhani pa Wikipedia ya Chitumbuka.
Tikukhumba kuti ŵanthu pafupifupi 45 ŵatorepo chigaŵa.
Wikipedia ya Chitumbuka ndiyo yizamukhala pa mtima pa ntchito iyi. Wikipedia ya Chingelezi na Wikipedia ya Chinyanja zingagwiliskirika ntchito pa masambiro ghanyake gha kafukufuku, kusanga maumboni ghakugomezgeka na kung'anamura nkhani.
=== 3. Gulu la ŵanthu awo ŵazamugwira ntchito iyi ===
Pa sono, ntchito iyi yikunozgekera na gulu la ŵanthu ŵatatu:
* [[User:Tumbuka Arch]] (Ine, nga ni munthu uyo wazamulongozga na kurongosora ntchito iyi, kusazgapo kusunga na kugwiliskira ntchito ndalama).
* [[User:Watisoni Banda]]
* [[User:Maystril]]
Tizamugwira ntchito pamoza pa kunozga ndondomeko, kusambizga, kovwira ŵanthu awo ŵatorepo chigaŵa, na kulutilira kuŵawovwira pa ntchito za pa intaneti.
=== 4. Ndalama izo tikukhumba kupempha ===
Tikughanaghana kupempha ndalama zakukwana US$2,800 ku WMF kwizira mu pulogiramu ya Rapid Fund.
Ndalama izi zizamutovwira kulipira vyakukhumbikwa pa ntchito iyi, nga ni:
* Malo ghakuchitirako masambiro.
* Ulendo wa awo ŵakulongozga na kunozga masambiro.
* Chakurya na vyakumwa vya ŵanthu awo ŵatorepo chigaŵa.
* Intaneti na data yakovwira pa masambiro gha pa intaneti.
* Mabuku na vyakuthandazga vya masambiro.
* Kutegherezga na kovwira ŵanthu awo ŵasambirenge.
Ili ni pempho ilo lichali kunozgekera. Ndalama zindapelekeke, ndipo ntchito iyi yindambe.
=== 5. Ivyo tikukhumba kupulika kufuma kwa ŵanthu ŵa Wikipedia ya Chitumbuka ===
Tikupempha ŵalembi wose na ŵanthu ŵanyake ŵakukhumba kukuzga Wikipedia ya Chitumbuka kuti ŵapeleke maghanoghano ghawo pa mafumbo agha:
1 Kasi ni mitu wuli panji nkhani wuli izo tikwenera kuŵika pa mtima chomene pa Wikipedia ya Chitumbuka?
2 Kasi masambiro agha ghangawovwira wuli pakukuzga Wikipedia yithu?
3 Kasi pali magulu ghanyake gha ŵanthu ŵakuyowoya Chitumbuka panji ŵalembi ŵanyake awo tikwenera kuŵachema kuti ŵatorepo chigaŵa?
4 Kasi tingachita wuli kuti ŵanthu awo ŵasambirenge ŵalutilire kulemba na kunozga Wikipedia para masambiro ghamara?
4 Kasi pali ntchito zinyake izo tikwenera kudumbiskana panji kugwilira pamoza nazo?
Chonde lembani maghanoghano, ulongozgi, masachizgo panji ivyo mukuwona kuti vingasintha pa ndondomeko iyi.
Tili ŵakunozgeka kusintha na kunozga pempho ili kuyana na maghanoghano agho ŵanthu ŵapeleke pambere tindatume pempho la ndalama.
Chilato chithu nkhuchita ntchito iyi pamoza kuti tikuzge Wikipedia ya Chitumbuka na kukhozga gulu la ŵanthu awo ŵakulembapo.
Yewo chomene chifukwa cha nyengo yinu na kovwira kwinu.
[[user:Tumbuka Arch|<span style='color: #FFFFFF;background-color: #191970;'>'''''Tumbuka Arch'''''</span>]][[user talk:Tumbuka Arch|'''<span style='color: #B20000;background-color: #FFFFFF;'><sup>★</sup><sub>★</sub><sup>★</sup></span>''']] 11:40, 31 Zimya 2026 (UTC)
:* Ndine wakukondwa kuŵa nawo lumoza pa ulendo uwu wakupempha wovwili wakuti tilutiske chiyowoyero chithu panthazi kwizila mwakulemba ma articles na kusambizga ŵanthu ŵanyake kutolapo luwande.
:Taŵanthu ise tilipo ŵatatu ise tikuyimila nkhumano iyi ya Tumbuka Editathon kuno ku South Africa.
:Ine nkhukolelanako nalo pempho ili chifukwa lipangiskenge ŵanthu ŵaChitumbuka kulemba pa Wikipedia, uko nkhutandazga zeru mwa ulele.
: I highly recommend this project request because at the end and finally, we will have more Tumbuka speakers contributing to the Wikipedia, sharing knowledge for free. I am one of the 3 people who would be managing this application, activities, along Tumbuka Arch who is the main coordinator of the project, while Maystril will be also be doing other supervision works. [[User:Watisoni Banda|Watisoni Banda]] ([[User talk:Watisoni Banda|pakuchezgela]]) 19:30, 2 Thukila 2026 (UTC)
oy9xi4p9bip73t0lfqsi9kcq3aqvncd
User talk:Watisoni Banda
3
49986
123398
2026-11-02T19:33:18Z
Tumbuka Arch
6863
/* Tamupokelelani */ new section
123398
wikitext
text/x-wiki
== Tamupokelelani ==
Monile akulu, tiyeni tiwikepo mtima pakutukula Wikipediya yithu iyi kweneso ndimwe wakuongeka pakutolapo luwande. [[user:Tumbuka Arch|<span style='color: #FFFFFF;background-color: #191970;'>'''''Tumbuka Arch'''''</span>]][[user talk:Tumbuka Arch|'''<span style='color: #B20000;background-color: #FFFFFF;'><sup>★</sup><sub>★</sub><sup>★</sup></span>''']] 19:33, 2 Thukila 2026 (UTC)
atkow14424q89qv1n8vpkmkbp7dz2p4
123399
123398
2026-11-02T19:36:14Z
Watisoni Banda
10141
/* Tamupokelelani */ Zgolo
123399
wikitext
text/x-wiki
== Tamupokelelani ==
Monile akulu, tiyeni tiwikepo mtima pakutukula Wikipediya yithu iyi kweneso ndimwe wakuongeka pakutolapo luwande. [[user:Tumbuka Arch|<span style='color: #FFFFFF;background-color: #191970;'>'''''Tumbuka Arch'''''</span>]][[user talk:Tumbuka Arch|'''<span style='color: #B20000;background-color: #FFFFFF;'><sup>★</sup><sub>★</sub><sup>★</sup></span>''']] 19:33, 2 Thukila 2026 (UTC)
:Naonga chomene apo. Tili tose ndipo tiyeni tiwikepo nadi mtima pakulemba ma articles ghanandi kweneso ghaphindu. [[User:Watisoni Banda|Watisoni Banda]] ([[User talk:Watisoni Banda|pakuchezgela]]) 19:36, 2 Thukila 2026 (UTC)
ix62yrxls6b5fzuulfws947amamlb2q