Wikipedia
sowiki
https://so.wikipedia.org/wiki/Bogga_Hore
MediaWiki 1.47.0-wmf.20
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
Portal
Portal talk
TimedText
TimedText talk
Module
Module talk
Event
Event talk
Allaybaday
0
7872
308482
305264
2026-09-17T21:29:03Z
~2026-50488-58
47425
/* */
308482
wikitext
text/x-wiki
{{Infobox settlement
| name = Allaybaday
| native_name =
| settlement_type = Magaalo
| image_skyline =
| image_flag =
| image_seal =
| subdivision_type = [[Dalalka|Wadanka]]
| subdivision_name = {{flag|Somaliland}}
| subdivision_type1 = [[Gobolada Somaliland|Gobolka]]
| subdivision_name1 = [[Maroodi Jeex]]
| subdivision_type2 = [[Qaybaha maamulka Somaliland|Degmo]]
| subdivision_name2 = [[Degmada Gabiley]]
| established_title = la aasaasay
| established_date =
| population_total =
| area_total_km2 =
| population_density_km2 = auto
| timezone = [[East Africa Time|EAT]]
| utc_offset = +3
| postal_code_type =
| postal_code =
| area_code = +252
| coordinates = {{coord|9|23|13|N|43|31|03|E|scale:100000_region:SO-WG|display=inline,title}}
| pushpin_map = Marodi Jeh
| pushpin_label_position = Bottom
| elevation_m = 1,125
}}
'''Allaybaday''' waa magaalo ka tirsan gobolka [[Maroodi Jeex]] ee [[Somaliland]], oo ku taal xuduudka [[Itoobiya]]. Waxa degan Abdalla Abokor.
Degmada Allaybaday waxaa ku nool 120,000 (2022)
Sida ku cad qoraal ay dawladda [[Somaliland]] soo saartay sannadkii 2002-dii, Allaybaday waa degmada 9-aad ee ugu muhiimsan gobolka [[Maroodi Jeex]], iyadoo loo kala saaray D.
==Beeraha==
Degmada Allaybaday ayaa waxaa laga soo saaraa tamaandho yaanyo iyo basasha ah bil walba xilliyada roobabka
==Taariikhda dhow==
Horaantii sannadkii 1979-kii, laba dagaalyahan oo ka tirsan Jabhadda Xoraynta Soomaali Galbeed (WSLF) ayaa gabadh ku kufsaday inta u dhaxaysa Tog Wajaale iyo Allaybaday, ka dibna walaalkeed oo dhawr iyo toban jir ah ayaa toogtay dagaalyahannadaas. Taliyahii WSLF ayaa dabadeed dilay walaalkii iyo qoyskiisa. Tani waxay ahayd mid ka mid ah dagaaladii u dhexeeyay WSLF iyo Dhaqdhaqaaqa Waddaniga Soomaaliyeed. 93
1987kii, Dhaqdhaqaaqa Waddaniga Soomaaliyeed ayaa ka fallaagoobay Madaxweynihii Soomaaliya. Waqtigaan waxaa Waqooyi Galbeed Soomaaliya ku sugnaa 7-askari oo ka tirsan ciidamada Milatariga Soomaaliya oo ay ka mid tahay Allaybaday.
Bishii Janaayo 1988dii, ciidamada qalabka sida ee Soomaaliya qeybta 12-aad ayaa Allaybaday ku toogtay illaa 20 qof oo rayid ah. Arintaan ayaa lagu tiriyaa inay ka mid tahay tacadiyada ay ciidamada qalabka sida ee Soomaaliya u gaysteen Isaaqa .
===Kadib Ku Dhawaaqii Madaxbanaanida Somaliland===
Bishii Jannaayo 2004, ka dib wadahadal dhexmaray UNICEF iyo maamulka deegaanka, xarunta hooyada iyo dhallaanka (MCH) ayaa dib uga hawlgashey Allaybaday.
Sida lagu sheegay warbixin ay hay’adda Interpeace soo saartay sannadkii 2006-dii , dhul-beereedkii fadhi-ku-dirirka ahaa iyo dhul-daaqsimeedka ee deegaanka Allaybaday ayaa kordhiyey colaadda, taas oo keentay in deegaanka Allaybaday ee dhinaca Itoobiya iskahorimaadku ka dhaco. 8
Bishii February 2006, Wasiirka Deegaanka Somaliland waxa uu sheegay in Ajaanib ay soo kiraysteen Ganacsato reer Gabiley ah ay burburinayaan kaymo ku dhow degmada Allaybaday. 31
ishii Abriil 2007, daadad xooggan oo ka dhacay Allaybaday ayaa burburiyay 87 ka mid ah 105 biyo-xireenno .
Bishii Oktoobar 2008, dab ayaa ka kacay kaalin shidaal oo ku taal Allaybaday, waxaana ku dhintay 10 bakhaar.
Bishii December 2013, Madaxweynaha Somaliland ayaa booqasho ku tagay degmada Allaybaday, waxaanu dhagax dhigay waddo isku xidhi doonta Allaybaday iyo Hargeysa .
Bishii April 2014, Badhasaabkii Degmada Allaybaday Keyse Maxamed Ibraahim (Keyse Meegaar) ayaa booqasho ku tagay Gabiley si uu u sii daayo dadka reer Allaybaday ee la xidhay.
May 7, 2015, Wasiirka Arrimaha Gudaha Somaliland ayaa Maxamed Xasan Shiil u magacaabay duqa magaalada Allaybaday.
Bishii July 2015, ayaa madax-dhaqameedka Allaybaday shir jaraa’id ku qabteen Hargeysa, waxay beeniyeen inuu jiro hoggaan cusub oo ay beeshu dooratay.
Bishii March 2016, dawladda Somaliland waxay gaadhsiisay deegaanka Allaybaday gargaar biyo iyo cunto ah oo ceelkii ciladoobay.
Bishii Sebtembar 2017, waxa Allaybaday booqday murashaxa madaxweyne Muuse Biixi Cabdi .
Bishii Disembar 2019, laba qof oo rayid ah ayay askar booliisku ku dileen Allaybaday.
Bishii Febraayo 2021, waxaa la furay wadadii ugu horeysay ee laami ah oo laga dhiso Allaybaday.
==Sidoo kale eeg==
[[Qaybaha maamulka Somaliland]]
[[Gobolada Somaliland]]
[[Degmooyinka Somaliland]]
==Tixraac==
[https://reliefweb.int/report/somalia/somalia-concern-over-deteriorating-food-security-somaliland "SOOMAALIYA: Walaac ku saabsan haqab-beelka cuntada ee Somaliland - Soomaaliya"]
[https://wargeyskadawan.com/2015/07/09/madaxdhaqameedka-allaybaday-oo-beeniyey-nin-ugaasnimo-sheegtay-beeshooda/ "Madaxda Allaybaday oo Beeniyey Nin Ugaasnimo Sheegtay Beeshooda"]
[https://ijisrt.com/assets/upload/submitted_files/1566803014.pdf "Qiimaynta Qiimaynta Kaabayaasha Kaabayaasha Magaalooyinka iyo Maamulka Maareynta ee Adeegga Biyaha Magaalooyinka: Somaliland"]
[https://ijisrt.com/assets/upload/submitted_files/1566803014.pdf "Qiimaynta Qiimaynta Kaabayaasha Kaabayaasha Magaalooyinka iyo Maamulka Maareynta ee Adeegga Biyaha Magaalooyinka: Somaliland"]
[https://books.google.com/books?id=RcVFXUwraxsC Maalmo Xun: Soddon Sano Oo Dagaal Iyo Macaluul Ka Dhacay Itoobiya]
[https://www.wajaalenews.net/?p=12531 "GUDOOMIYAHA DEGNADA ALLAY BADAY OO EEDAYN USOO JEEDIYEY XEER ILAALINTA GOBOLKA GABILAY IYO KHILAAF HOR LEH OO KA DHASHAY"] {{Wayback|url=https://www.wajaalenews.net/?p=12531 |date=20230527044601 }}
[https://www.qurbejoog.com/wasiir-waran-cadde-oo-maanta-guddoomiye-cusub-u-magacaabay-degmada-allaybaday/ "Wasiir Waran-cadde Oo Maanta Guddoomiye Cusub u Magacaabay Degmada Allaybaday"]
[https://berberatoday.com/2017/09/08/muuse-biixi-oo-soo-dhaweyn-ballaadhan-kala-kulmay-shacabka-allay-baday-deegaannada-idhanka-iyo-geed-ballaadh/ "MUUSE BIIXI OO SOO DHAWEYN BALLAADHAN KALA KULMAY SHACABKA ALLAY-BADAY, DEEGAANKA IDHANKA IYO GEED-BALLAADH"]
[https://berberatoday.com/2019/12/20/daawo-muuqalkaugaas-cabdirasaaq-koosar-oo-ka-hadlay-dad-ciimada-liyuu-boolisku-ku-laayeen-magaalada-allaybaday/ "DAAWO MUUQALKA"UGAAS CABDIRASAAQ KOOSAR OO KA HADLAY DAD CIIMADA LIYUU BOOLISKU KU LAAYEEN MAGAALADA ALLAYBADAY"]
[https://www.wajaalenews.net/?p=128143 "DAAWO;-MAAMULKA GOBOLKA GABILEY OO XADHIGA KA JARAY WADO LAAMI AH OO DAWLADA HOOSE EE GABILEY KA HIRGALISAY ALLAYBADAY"] {{Wayback|url=https://www.wajaalenews.net/?p=128143 |date=20230527144343 }}
[https://somalilandpost.net/daawomadaxweyne-siilaanyo-oo-dhagax-dhigay-dhismaha-cusub-oo-isku-xidhaysa-magaalada-hargeisa-iyo-degmada-alleybaday/ "DAAWO:Madaxweyne Siilaanyo oo Dhagax-dhigay Dhismaha Cusub oo Isku Xidhay Magaalada Hargeysa iyo Degmada Alleybaday"]
aawiwqgltawsqfcmnilc6odfhr073vj
User talk:SHB
3
33138
308504
214289
2026-09-18T03:43:33Z
Max
35277
Max la wareejiyay bogga [[User talk:SHB2000]] ilaa [[User talk:SHB]]: Bogga si otomaatig ah ayaa loo wareejiyay intii lagu jiray magaca beddelka isticmaalaha "[[Special:CentralAuth/SHB2000|SHB2000]]" loona beddelay "[[Special:CentralAuth/SHB|SHB]]"
214289
wikitext
text/x-wiki
<div style="border: 1rem #dd0000 ridge; padding: 0.5em;">Hello! Please message me on [[m:User talk:SHB2000|meta.wikimedia.org]] instead. I may not notice messages on this page.</div>
ojy2vkqs676esjrcfi79dwyt0tjr5xc
Template:Test case nowiki
10
33761
308469
218250
2026-09-17T16:44:18Z
Isma4l
41797
308469
wikitext
text/x-wiki
<includeonly>{{#invoke:Template test case|main}}</includeonly><noinclude>
{{documentation}}
<!-- Categories go on the /doc subpage and interwikis go on Wikidata. -->
</noinclude>
tqcbtoi20hh04qz7tcyj9c81ibksvas
Module:Goalscorers
828
46913
308437
294112
2026-09-17T16:11:30Z
Isma4l
41797
308437
Scribunto
text/plain
require('strict');
local yesno = require('Module:Yesno')
local p = {}
local g = {} -- for parameters with global scope in this module
g.goalscorers = {} -- table where selected and sorted players will be place
g.args = {}
g.totalGoals = 0
local data = {} -- module subpage data -- require('Module:Goalscorers/data/UEFA Euro 2016 qualifying');
p.errorString = ""
function p.error_msg()
if p.errorString ~= "" then
return '<span style="font-size:100%" class="error">'
-- '<code style="color:inherit;border:inherit;padding:inherit;">|_template=</code>'
.. p.errorString .. '</span>';
end
end
-- data for goals scored held in module subpages, e.g. "Module:Goalscorers/data/UEFA Euro 2016 qualifying"
--[[ parameters containing data help in three tables
data.rounds = {} -- group, play-off
data.goalscorers = {} -- player, country, goals in each round)
data.owngoalscorers = {} -- player, country, goals in each round)
data.updated = {} -- date of latest update (month, day, year)
--]]
--[[ ############################ Parameter handing ###############################
p.getArgs() - gets arguments from frame (invoke) or parent frame (template)
]]
local function getArgs(frame)
local parents = mw.getCurrentFrame():getParent()
for k,v in pairs(parents.args) do
--check content
if v and v ~= "" then
g.args[k]=mw.text.trim(v) --parents.args[k]
end
end
for k,v in pairs(frame.args) do
--check content
if v and v ~= "" then
g.args[k]= mw.text.trim(v) --parents.args[k]
end
end
-- allow empty caption to blank default
--if parents.args['caption'] then templateArgs['caption'] = parents.args['caption'] end
end
--[[ ############################## Main function and other functions ######################
p.main() - simple output of the data in the module in list form
p.addIntroductorySentence() - add sentence on number of goals and matches, with goals per match
p.addFooterSentence() - add footnote
p.getNumberMatches()
p.owngoals() - get own goals (no longer used?)
p._owngoals() - core functionality for p.owngoals()
]]
function p.main(frame)
getArgs(frame)
local dataTarget = g.args[1] or g.args['data']
if dataTarget then
data = require('Module:Goalscorers/data/'.. dataTarget) --or 'UEFA Euro 2016 qualifying'
return p.useModuleData(frame) -- data on goals taken from module subpage
else
return p.useTemplateData(frame) -- data on goals/assists taken from template
end
end
function p.useModuleData(frame)
--p.goalscorers = {} -- table where selected and sorted players will be place
g.totalGoals = 0
local ok = p.selectGoalscorers() -- selected goalscorers meeting round and group criteris
if not ok then return p.error_msg() end
-- CHANGE: append own goals to list (data will now include goals and own goals (negative))
p.selectGoalscorers("OG")
p.sortGoalscorers() -- sort selected goalscorers by number of goal, then country
local outputString = p.addIntroductorySentence() .. p.outputGoalscorers(frame) .. p.addFooterSentence()
-- .. "" --TODO add intermediate heading?
-- .. p._owngoals(frame) -- output list of goalscorers
return p.error_msg() or outputString
end
--[[ ##################### standalone value outputs ##########################
p.goals(frame) - output ONLY the total number of goals scored
p.matches(frame) - output ONLY the number of matches played
p.date(frame) - output ONLY the date of the most recent matches played
accepts optional |format=yes to comma-format the number (e.g. 1,234).
]]
function p.goals(frame)
getArgs(frame)
local result
local dataTarget = g.args[1] or g.args['data']
if dataTarget then
data = require('Module:Goalscorers/data/' .. dataTarget)
g.goalscorers = {} -- reset state (safe for multiple invokes per page)
g.totalGoals = 0
local ok = p.selectGoalscorers() -- count goals for selected round/group
if not ok then return p.error_msg() end
p.selectGoalscorers("OG") -- include own goals in the total
if p.errorString ~= "" then return p.error_msg() end
result = g.totalGoals
else
result = tonumber(g.args['goals']) or 0 -- fall back to template-supplied data
end
if yesno(g.args['format']) then
return mw.getLanguage('en'):formatNum(result)
end
return tostring(result)
end
function p.matches(frame)
getArgs(frame)
local result
local dataTarget = g.args[1] or g.args['data']
if dataTarget then
data = require('Module:Goalscorers/data/' .. dataTarget)
local round = g.args['round'] or "all"
if round ~= "all" and not p.validateRound(round) then -- guard against bad round
p.errorString = p.errorString .. 'Invalid round "' .. round .. '" specified. '
return p.error_msg()
end
result = p.getNumberMatches() -- respects round/group args
else
result = tonumber(g.args['matches']) or 0
end
if yesno(g.args['format']) then
return mw.getLanguage('en'):formatNum(result)
end
return tostring(result)
end
function p.date(frame)
getArgs(frame)
local dataTarget = g.args[1] or g.args['data']
if not dataTarget then return g.args['updated'] or "" end -- template-data fallback
data = require('Module:Goalscorers/data/' .. dataTarget)
local round = g.args['round'] or "all"
if round ~= "all" and not p.validateRound(round) then
p.errorString = p.errorString .. 'Invalid round "' .. round .. '" specified. '
return p.error_msg()
end
local _, dateUpdated = p.getNumberMatches()
if dateUpdated == "complete" or dateUpdated == "" then return "" end -- nothing to show
local dateFormat = (data.params and data.params['date_format']) or 'dmy'
local mdy = yesno(g.args['mdy'])
if mdy == true then dateFormat = "mdy" elseif mdy == false then dateFormat = "dmy" end
local r, grp = p.getRoundAndGroup()
local finished = p.matchesFinished(r, grp, dateUpdated)
if finished ~= "" then finished = " (" .. finished .. ")" end
return p.error_msg() or (require('Module:Date')._Date(dateUpdated):text(dateFormat) .. finished)
end
--[[ ##################### matches-finished helper ############################
p.matchesFinished(round, group, latestDate)
Sums the optional "F/T" field (3rd element of a data.updated entry) for
every entry dated on latestDate. Older dates are ignored. Returns "" when
no entry supplies F/T, or a contributing entry on that date lacks it.
]]
function p.matchesFinished(round, group, latestDate)
if not latestDate or latestDate == "complete" or latestDate == "" or latestDate == "1700-01-01" then
return ""
end
local entries = {} -- entries applying to round/group
if round == "all" then
for k, v in pairs(data.updated) do
if k ~= "date" and k ~= "group" and p.validateRound(k) then entries[#entries+1] = v end
end
elseif round ~= "group" then
entries[#entries+1] = data.updated[round]
end
if (round == "all" or round == "group") and data.updated.group then
if group and group ~= "all" then
entries[#entries+1] = data.updated.group[group]
else
for _, v in pairs(data.updated.group) do entries[#entries+1] = v end
end
end
local finished, total, found = 0, 0, false -- sum F/T on the most-recent date
for _, e in ipairs(entries) do
if e[2] == latestDate then
local f, t = string.match(tostring(e[3] or ""), "^%s*(%d+)%s*/%s*(%d+)%s*$")
if not f then return "" end -- contributing entry without F/T -> skip
finished, total, found = finished + f, total + t, true
end
end
if not found then return "" end
if finished >= total or finished < 1 or total < 1 then return "" end -- all done / invalid -> date only
return finished .. " of " .. total .. " matches finished"
end
function p.addIntroductorySentence() -- add introductory text
local totalGoalString = "A total of " .. g.totalGoals .. " goals were scored."
--There were [has been|have been|was|were] #GOALS goal(s) scored in #MATCHES match(s), for an average of #GOALS/#MATCHES per match.
local matches, dateUpdated = p.getNumberMatches()
local mdyFormat = yesno(g.args['mdy'])
local Date = require('Module:Date')._Date
local pluralGoals = "s"
local text1 = ""
if g.totalGoals == 1 then
pluralGoals = ""
if dateUpdated == 'complete' then text1 = "was" else text1 = "has been" end
else
if dateUpdated == 'complete' then text1 = "were" else text1 = "have been" end
end
local text = string.format("There %s %s goal%s scored", text1, mw.getLanguage('en'):formatNum(g.totalGoals), pluralGoals)
local pluralMatches = "es"
if matches==1 then pluralMatches = "" end
if matches then
local average = g.totalGoals/tonumber(matches)
local precision = 3 -- display d.dd (three significant disgits)
if average < 1 then precision = 2 end -- display 0.dd (thwo significant disgits)
average = tostring (average)
local pluralAverage = "s"
if tonumber(string.format("%.2f",average))==1 then pluralAverage = "" end
text = text .. string.format(" in %d match%s, for an average of %."..precision.."g goal%s per match", matches, pluralMatches, average, pluralAverage)
end
if dateUpdated == 'complete' or dateUpdated == "" then
text = text .. "."
else
local dateFormat = 'dmy' -- default
if data.params and data.params['date_format'] then dateFormat = data.params['date_format'] end -- from data module
if mdyFormat == true then dateFormat = "mdy" else
if mdyFormat == false then dateFormat = "dmy" end -- template param overrides
end
local round, group = p.getRoundAndGroup()
local finished = p.matchesFinished(round, group, dateUpdated)
if finished ~= "" then finished = ", " .. finished end
text = text .. " (as of " .. Date(dateUpdated):text(dateFormat) .. finished .. ")."
end
text = p.addAdditionHeaderText(text, dateUpdated) -- handles template parameters bold, further, extra
return text --totalGoalString
end
function p.addFooterSentence() -- add notes at bottom
local footerSentence = g.args['footer'] or ""
--footerSentence = "This is a footer sentence." -- test footer
if data.params then
local footer = data.params['footer'] or nil
if footer then
local frame = mw.getCurrentFrame()
local processed = frame:preprocess(footer)
if g.notes then
footerSentence = footerSentence .. processed
end
end
end
if footerSentence ~= "" then
footerSentence = '<div style = "" >' .. footerSentence .. '</div>'
end
return footerSentence
end
function p.getNumberMatches()
local matches = g.args['matches']
local dateUpdated = data.updated['date'] or "1700-01-01" --'complete' -- assume completed if missing
--local round = g.args['round'] or "all" -- round = all(empty)|group|playoffs
--local group = g.args['group'] or "all" -- group = all(empty), A,B,C etc
local round, group = p.getRoundAndGroup()
local allGroupGames = 0
local latestGroupDate = "1800-01-01"
if group and (round == "all" or group == "all") then -- count all the group games
for k,v in pairs(data.updated.group) do
allGroupGames = allGroupGames + v[1]
if v[2] ~= "complete" and v[2] > latestGroupDate then latestGroupDate = v[2] end -- update if later date
end
if latestGroupDate == "1800-01-01" then latestGroupDate = "complete" end -- no dates so must be complete
end
if group and (round == "all" and group ~= "all") then -- for totals of all rounds with only one group
allGroupGames = data.updated.group[group][1] -- number matches
latestGroupDate = data.updated.group[group][2] -- update date or completed
end
if round == "all" then -- all rounds and goals
matches=0
for k,v in pairs(data.updated) do
if k == "group" then
matches = matches + allGroupGames
if latestGroupDate ~= "complete" and latestGroupDate > dateUpdated then
dateUpdated = latestGroupDate -- update if later date
end
elseif p.validateRound(k) then
matches = matches + v[1]
if v[2] ~= "complete" and v[2] > dateUpdated then dateUpdated = v[2] end -- update if later date
end
end
elseif round == "group" then -- group round only
if group == "all" then
matches = allGroupGames
dateUpdated = latestGroupDate
else -- single group only
matches = data.updated.group[group][1] -- number matches
dateUpdated = data.updated.group[group][2] -- update date or completed
end
else -- any other round
matches = data.updated[round][1] -- number matches
dateUpdated = data.updated[round][2] -- update date or completed
end
if dateUpdated == "1700-01-01" then dateUpdated = "complete" end -- no dates so must be complete
return matches, dateUpdated
end
function p.owngoals(frame) -- need to check parameters if external call
getArgs(frame)
data = require('Module:Goalscorers/data/'.. g.args[1]) --or 'UEFA Euro 2016 qualifying'
local outputString = p._owngoals(frame)
return p.error_msg() or outputString
end
function p._owngoals(frame) -- internal call for own goals
--p.goalscorers = {} -- table where selected and sorted players will be place
p.selectGoalscorers("OG") -- selected goalscorers meeting round and group criteris
p.sortGoalscorers() -- sort selected goalscorers by number of goal, then country
return p.outputGoalscorers(frame, "OG") -- output list of goalscorers
end
function p.validateRound(round)
local validateRound = false
for k,v in pairs(data.rounds) do
if k == round then validateRound = true end -- data for this round exists
end
return validateRound
end
--[[ ############################## functions to select goalscorers ######################
p.selectGoalscorers() - select goals scoreers required for list (rounds, groups)
p.getRoundAndGroup()
p.getGoalsCol(round) - get column containing round data or first data column if round = all
(country, possibleGroup)
p.getGoals (u, player)
p.parseComment(comment)
p.getPlayer(u)
]]
--[[ p.selectGoalscorers()
- select players meeting round and group criteria from goalscoreres list
- gets goals and comments
]]
function p.selectGoalscorers(og)
local round, group = p.getRoundAndGroup()
if not round then return false end -- exit if no valid round
local goalMinimum = tonumber(g.args['minimum']) or -5 -- assume 5 own goals is maximum
local goalsCol = p.getGoalsCol(round) -- first column for goals
-- select players who have scored in rounds/groups requested
local goalscorerData = data.goalscorers
if og == "OG" then goalscorerData = data.owngoalscorers end
for k,v in pairs(goalscorerData) do
local goals, comment = 0, "" -- goals > 0 is the flag to include the player
local playerName, playerAlias = p.getPlayer(v[1]) -- player name
local goalsByRound, commentByRound = 0, ""
if round == "all" then -- goals in all rounds and all groups
for i = goalsCol, #v, 1 do
if group and group ~= "all" and i == p.getGoalsCol("group") and group ~= p.getGroup(v[2], v[3]) then
goalsByRound = 0
commentByRound = ""
else
goalsByRound, commentByRound = p.getGoals( v[i] , playerName)
end
goals = goals + goalsByRound --TODO use getGoals on round options
if commentByRound ~= "" then
if comment == "" then
comment = commentByRound
else
comment = comment .. "," .. commentByRound --TODO decide on comma or semi-colon
end
end
i = i+1
end
elseif round == "all2" and group ~= "all" then -- goals in all rounds but only from one group
--TODO code to go through all rounds but only include goals in specified group [TODO merge with above option]
--mw.addWarning( g.args[1] .. ":Mix:round=all and group=" .. group .. "/" .. p.getGroup(v[2], v[3] ) )
for i = goalsCol, #v, 1 do
if i == p.getGoalsCol("group") and group ~= p.getGroup(v[2], v[3]) then
goalsByRound = 0
commentByRound = ""
else
goalsByRound, commentByRound = p.getGoals( v[i] , playerName)
end
goals = goals + goalsByRound
if commentByRound ~= "" then
if comment == "" then
comment = commentByRound
else
comment = comment .. "," .. commentByRound --TODO decide on comma or semi-colon
end
end
i = i+1
end
elseif round == "group" then -- group round only
if group == p.getGroup(v[2], v[3]) then -- single group only
goals, comment = p.getGoals( v[goalsCol] , playerName)
elseif group == "all" then -- any group
goals, comment = p.getGoals( v[goalsCol] , playerName)
else
-- do nothing for other groups
end
--elseif round == "playoffs" then -- playoff round (redunant?)
-- goals = v[goalsCol]
else -- any other round
goals, comment = p.getGoals( v[goalsCol] , playerName) -- should also handle playoffs
end
if goals >= goalMinimum and goals ~= 0 then
if comment ~= "" then
if og == "OG" then
comment = '<span> (' .. p.sortComment(comment) .. ')</span>'
else
comment = '<span>' .. comment .. '</span>' -- no parenthesis when using notes
end
end
if og == "OG" then goals = -goals end -- make owngoals negative numbers
g.goalscorers[#g.goalscorers+1] = { player=playerName, alias=playerAlias,
country=v[2],
goals=goals,
comment=p.parseComment(comment)}
--g.totalGoals = g.totalGoals + math.abs(goals) -- increment total goal counter
end
g.totalGoals = g.totalGoals + math.abs(goals) -- increment total goal counter
end
return true -- data collected for selected goalscorers
end
--[[ p.getRoundAndGroup()
]]
function p.getRoundAndGroup()
local round = g.args['round'] or "all" -- round = all(empty)|group|playoffs
local group = g.args['group'] or "all" -- group = all(empty), A,B,C etc
local validateRound = false
local validateGroupRound = false
for k,v in pairs(data.rounds) do
if k == round then validateRound = true end -- data for this round exists
if k == "group" then validateGroupRound = true end -- there is a group round
end
if validateRound == false and round ~= "all" then
local message = 'Invalid round "' .. round .. '" specified. No data found for that round. '
mw.addWarning( message )
p.errorString = p.errorString .. message
round = nil
end
if validateGroupRound == false then group = false end -- there is no group round
-- TODO add group error checking
-- Could merge with getGoalsCol() and also return goalsCol
return round, group
end
--[[ p.getGoalsCol(round)
- get column containing round data or first data column if round = "all"
- allows group column to be omitted from player table when group table provided
]]
function p.getGoalsCol(round)
local minimum = 1000
if round == "all" then -- if all need column of first round
for k,v in pairs(data.rounds) do
if v < minimum then minimum = v end
--return v -- return the first one [this seemed to work reliably, but sometimes table order is not as listed]
end
return minimum
end
if data.rounds and data.rounds[round] then
return data.rounds[round] -- get column containing goals for that round
else
return 4 -- an old default when no data.round (may not be necessary)
end
end
--[[ p.getGroup(country, possibleGroup)
- get group from group table or from player table
- possibleGroup is the column containing the Group (when no group table) or the first data column
]]
function p.getGroup(country, possibleGroup) -- row contain player name, country code, group if given, goals
if data.groups then
for k,v in pairs(data.groups) do -- iterate through the groups
--local = gotGroup = false
for j,u in pairs(v) do -- for each group
if u == country then
return k
end
end
end
return "no group found"
else
return possibleGroup -- no group table, so assume column three contains the group
end
end
--[[ get number of goals and any associated comment
the goals can be a single number (the usual case)
or as an option table (e.g. for own goals): { number of own goals, comma-delimited list of opponents }
- if the entry is a table, we want the first entry (a number) and the second (comment string)
- otherwise, if a number, we just want the number and an empty string
]]
function p.getGoals (u, player)
if type(u) == 'table' and type(u[1]) == 'number' then
return u[1], u[2] -- return number of goals, comment
elseif type(u) == 'number' then
return u, "" -- return number of goals, empty string
else
p.errorString = p.errorString .. " Invalid goals entry for player " .. player
return 0, ""
end
end
function p.parseComment(comment)
local frame = mw.getCurrentFrame()
-- we have something like "{{efn-ua|name=goals}}"
if string.find(comment, "efn" , 1 , true ) then -- if we have a comment with a note
g.notes = true -- set flag
end
return frame:preprocess(comment)
end
function p.getPlayer(u)
if type(u) == 'table' then
if type(u[1]) == 'string' and type(u[2]) == 'string' then
--[[if #u[2] >1 then
p.errorString = p.errorString .. "\n\nWe have u[1]=" .. u[1] .. " and u[2]=" .. u[2]
end]]
return u[1], u[2] -- return player name, player sorting alias
else
p.errorString = p.errorString .. " Invalid name entry for player " .. u[1] .. ", " .. u[2]
return "", "" --TODO errroer
end
elseif type(u) == 'string' then
return u, "" -- return player name
else
p.errorString = p.errorString .. " Invalid name entry for player " .. u or u[1] or "unknown"
return "", ""
end
end
--[[ ############################## functions to sort goalscorers ######################
p.preprocessSortName (name)
p.getPlayerSortName (playerName, sortName, countryName)
p.sortComment(comment)
p.getCountryName(country)
p.sortGoalscorers() -- the main sort function
]]
--[=[ function p.preprocessSortName()
stripp off wikitext [[ and ]]
force to lowercase
change special characters to standard letters
]=]
function p.preprocessSortName (name)
name = string.gsub(name, "%[%[", "") -- strip off [[ and ]]
name = string.gsub(name, "%]%]", "")
--name =string.lower(name) -- force lower case and return
name = mw.ustring.lower(name) -- use unicode function
local specialChars = { -- list of special characters and replacement pairs
{ "ı", "i" } , { "İ", "i" } , { "ß", "ss" },
{ "ý", "y" } , { "ř", "r" } , { "ő", "o" },
{ "é", "e" } , { "è", "e" } , { "þ", "th" },
{ "ē", "e" } , { "ņ", "n" } , { "č", "c" },
{ "ū", "u" } , { "ž", "z" } , { "æ", "ae" },
{ "å", "a" } , { "ø", "o" } , { "ą", "a" },
{ "ń", "n" } , { "ł", "l" } , { "ã", "a" },
{ "ș", "s" } , { "š", "s" } , { "í", "i" },
{ "á", "a" } , { "ä", "a" } , { "ć", "c" },
{ "ç", "c" } , { "ğ", "g" } , { "ö", "o" },
{ "ë", "e" } , { "ú", "u" } , { "ó", "o" },
{ "ð", "d" } , { "ü", "u" } , { "ű", "u" },
{ "ā", "a" } , { "ī", "i" } , { "đ", "dj" },
{ "ă", "a" } , { "â", "a" } , { "ż", "z" },
{ "ț", "t" } , { "ş", "s" } , { "ś", "s" },
{ "ǎ", "a" } , { "ě", "e" } , { "ů", "u" },
{ "ĕ", "e" } , { "ñ", "n" } , { "ď", "d" },
{ "ï", "i" } , { "ź", "z" } , { "ô", "o" },
{ "ė", "e" } , { "ľ", "l" } , { "ģ", "g" },
{ "ļ", "l" } , { "ę", "e" } , { "ň", "n" },
{ "ò", "o" } , { "ō", "o" } , { "î", "i" },
{ "õ", "o" } , { "œ", "oe"}
}
for k,v in pairs(specialChars) do -- replace special characters from supplied list
name = string.gsub(name, v[1], v[2])
end
return name
end
--[[ return the name for sorting
return supplied alias name for sorting
otherwise
checks for pipe (redirect) and uses name after pipe
splits name into words
returns first name if only name (e.g. Nani)
otherwise returns name in format second_name [.. last name], firstname
]]
function p.getPlayerSortName (playerName, sortName, countryName)
--dewikify all names before sorting, also forces lowercase
playerName = p.preprocessSortName(playerName)
sortName = p.preprocessSortName(sortName)
if sortName ~= "" then -- if we have a sort name supplied
return sortName -- then return it
end
-- players from certain countries will use name in order supplied
local noSort = { "CAM", "CHN", "TPE", "MYA", "PRK", "KOR", "VIE" }
for k,v in pairs(noSort) do
if v == countryName then
return playerName
end
end
-- else work it out from the supplied player name
-- we don't want to test the name in a redirect, so get name after pipe if there is one
if string.find (playerName, "|") then -- test for redirect
local names = mw.text.split( playerName, "|")
playerName = names[2] -- get name after pipe
end
local names = mw.text.split( playerName, " ") -- we don't want to sort on first name
if #names == 1 then
return names[1] -- return name of single name player
else
-- we will assume the second name is the sort name e.g, Joe Bloggs, Jan van Bloggen
local name = names[2] -- set name to second name e.g. Bloggs or van
local i=3
while i <= #names do -- any addition names e.g. Bloggen
name= name .. names[i]
i=i+1
end
name = name .. ", " .. names[1] -- add first name e.g. Joe or Jan
return name -- sort on second name third name etc, first name
end
end
-- sort the list of countries alphabetically
function p.sortComment(comment)
local items = mw.text.split( comment, ",") -- split comma-delimited list
for k,v in pairs(items) do
items[k] = mw.text.trim(v) -- trim spaces and coe
end
table.sort(items, function(a,b) return a<b end) -- sort the table alphbetically
local list = "against " -- construct the alphabetical list string
for i=1, #items do
local sep = ", " -- separator for comma-delimited list
if i==1 then sep = "" -- first word doesn't need comma
elseif i==#items then sep = " & " -- use "and" before last word
end
list = list .. sep .. items[i]
end
return list
end
function p.getCountryName(country)
if string.len(country) == 3 then -- if the country given as a three-letter code
local codes = require('Module:Goalscorers/data/Country codes')
for k,v in pairs(codes.alias) do
if v[1] == country then
return v[2]
end
end
else
return country -- return the country name as is
end
end
--[[ sort goalscorers by goals, country and name
the sort first sorts by number of goals
when these are equal, it sorts by country
when these are equal, it sorts by name
Note: the name sort is on the first name
- a split of the name and sort on the last name is possible
- however, this would be complicated by Dutch (e.g. Stefan de Vrij) and Spanish names
- would sort on second name be better
]]
function p.sortGoalscorers()
local sort_function = function( a,b )
if (a.goals > b.goals) then -- primary sort on 'goals' -> a before b
return true
elseif (a.goals < b.goals) then -- primary sort on 'goals' -> b before a
return false
else -- a.goals == b.goals -- primary sort tied,
--return a.country < b.country -- resolve with secondary sort on 'country'
local country_a = p.getCountryName(a.country) -- sort on name of country, not the code
local country_b = p.getCountryName(b.country)
if (country_a < country_b) then -- secondary sort on 'country'
return true
elseif (country_a > country_b) then -- secondary sort on 'country'
return false
else -- a.country == b.country -- secondary sort tied,
--return a.player < b.player --resolve with tertiary sort on 'player' name
local player_a = p.getPlayerSortName(a.player, a.alias, a.country) -- get player name for sorting
local player_b = p.getPlayerSortName(b.player, b.alias, b.country)
return player_a < player_b --
--[[]
--local test_a, test_b = a.player, b.player
-- we don't want to test the name in a redirect, so get name after pipe if there is one
if string.find (a.player, "|") then -- test for redirect
local names = mw.text.split( a.player, "|")
test_a = names[2] -- get name after pipe
end
if string.find (b.player, "|") then
local names = mw.text.split( b.player, "|")
test_b = names[2]
end
local names_a = mw.text.split( test_a, " ") -- we don't want to sort on first name
local names_b = mw.text.split( test_b, " ") -- so split names
if not names_a[2] then names_a[2] = test_a end -- for players with one name
if not names_b[2] then names_b[2] = test_b end
return names_a[2] < names_b[2] -- sort on second name
]]
end
end
end
table.sort(g.goalscorers, sort_function)
end
function p.tabulateGoalscorers(frame, og)
-- ==============output the lists of goalscorers by goal======================
local goalNumber = 1000
local maxRank = tonumber(g.args['maxrank'] or 10) -- limit list top ten or value in parameter maxrank
local rank = 1
local playerCount = 0
local rankCount = 0
local playerCells = ""
local firstplayerCell = ""
local tableString = '\n{| class="wikitable"' -- start table
..'\n|-' .. '\n!Rank !! Player !! Goals' -- add table headers
if g.args['header'] then tableString = tableString .. '\n|+ ' .. g.args['header'] end -- add header
for j,u in pairs(g.goalscorers) do -- run through sorted list of selected goalscorers
-- is the player active still?
local playerActive = false
if data.active_countries then
for k,v in pairs(data.active_countries) do
if v == u['country'] then
playerActive = true
break;
end
end
end
local _,roundStatus = p.getNumberMatches()
if roundStatus == "complete" then playerActive = false end -- overrides active_countries
-- wikitext for tablulated list
local goalscorerString = p.addLinkedIcon(frame, u['country']) -- linked flag icon
if playerActive and g.args['bold']~='no' then
goalscorerString = goalscorerString .. " '''" .. u['player'] .. "'''>" -- bolded name
else
goalscorerString = goalscorerString .. " " .. u['player'] -- name
end
goalscorerString = goalscorerString .. u['comment'] -- comment for o.g.
-- we have a goalscorer
playerCount = playerCount + 1
rankCount = rankCount + 1
if u['goals'] < goalNumber then -- player belongs to rowspan for new number of goals
-- need to generate code for the previous rowspan (if there is one)
-- then start the counts and player list for the new one
if playerCount == 1 then
firstplayerCell = '\n|' .. goalscorerString -- if first player in list just create cell and set goals
goalNumber = u['goals']
--rank = 1
rankCount = 0
else -- else generate previous rowspan
local rowSpan = rankCount
if playerCount > maxRank * 1.5 then
firstplayerCell = '\n| style="font-style:italic;text-align:center;"|' .. rankCount .. " players"
playerCells = ""
rowSpan = 1
end
tableString = tableString .. '\n|-\n| style="text-align:center;" rowspan="' .. rowSpan .. '"|' .. rank
--if rankCount > 1 then tableString = tableString .. "=" end -- adds equals when rank shared
tableString = tableString .. firstplayerCell
tableString = tableString .. '\n| style="text-align:center;" rowspan="' .. rowSpan .. '"|' .. goalNumber
tableString = tableString .. playerCells
rank = rank + rankCount
if rank > maxRank then break end -- limit list top ten or value in parameter
rankCount = 0
goalNumber = u['goals']
firstplayerCell = '\n|' .. goalscorerString -- set first player cell for next rowspan
playerCells = ""
end
else -- else another player with same number of goals
playerCells = playerCells .. '\n|-' .. '\n|' .. goalscorerString -- add to player cell list
end
end -- reached end of list of goalscorers [for j,u loop]
-- if all scorers on one goal, tableString isn't updated in loop above (may need to generalise for other goal number)
if goalNumber == 1 and rank <= maxRank then
local rowSpan = rankCount + 1
tableString = tableString .. '\n|-\n| style="text-align:center;" rowspan="' .. rowSpan .. '"|' .. rank
tableString = tableString .. firstplayerCell
tableString = tableString .. '\n| style="text-align:center;" rowspan="' .. rowSpan .. '"|' .. goalNumber
tableString = tableString .. playerCells
end
if tableString ~= "" then
tableString = tableString .. "\n|}"
return tableString
else
return (" No goals matching requested criteria.")
end
end
function p.outputGoalscorers(frame, og) -- output list of goalscorers
if g.args['table'] then return p.tabulateGoalscorers(frame, og) end -- optional table output
local outputString = ""
if og == "OG" then end
-- ==============output the lists of goalscorers by goal======================
local goalNumber = 1000
--local goalMinimum = tonumber(templateArgs['minimum']) or 0
local listOpen = false -- flag for list started by template {{Div Col}}
for j,u in pairs(g.goalscorers) do -- run through sorted list of selected goalscorers
--if u['goals'] < goalMinimum then break end -- limit list to goals over a threshold (now handled in select goalscorers)
if u['goals'] < goalNumber then -- start new list of new number of goals
if listOpen then -- if an open list, close last list
outputString = outputString .. p.closeList(frame)
listOpen = false -- redundant as will be set true again
end
goalNumber = u['goals']
local goalString = " goal"
--if og == "OG" then
if goalNumber < 0 then
goalString = " own" .. goalString
end
if math.abs(u['goals']) ~= 1 then goalString = goalString .. "s" end
outputString = outputString .. "\n'''" .. math.abs(u['goals']) .. goalString .. "'''" -- list caption
outputString = outputString .. p.openList(frame,og) --start new list
listOpen = true
--goalNumber = u['goals']
end
-- is the player active still?
local playerActive = false
if data.active_countries then
for k,v in pairs(data.active_countries) do
if v == u['country'] then
playerActive = true
break;
end
end
end
local _,roundStatus = p.getNumberMatches()
if roundStatus == "complete" then playerActive = false end -- overrides active_countries
-- wikitext for bullet list
local goalscorerString = '\n*<span>' .. p.addLinkedIcon(frame, u['country']) -- linked flag icon
if playerActive and g.args['bold']~='no' then
goalscorerString = goalscorerString .. " <b>" .. u['player'] .. "</b>" -- bolded name
else
goalscorerString = goalscorerString .. " " .. u['player'] -- name
end
goalscorerString = goalscorerString .. u['comment'] .. '</span>' -- comment for o.g.
outputString = outputString .. goalscorerString -- .. " " .. tostring(u['goals'])
end -- reached end of list of goalscorers
if outputString ~= "" then
outputString = outputString .. p.closeList(frame)
return outputString
else
return (" No goals matching requested criteria.")
end
end
-- output icon linked to national team page
function p.addLinkedIcon(frame, country)
g.iconCache = g.iconCache or {}
local cache = g.iconCache[data] -- per data module (safe across invokes)
if not cache then cache = {}; g.iconCache[data] = cache end
if cache[country] ~= nil then return cache[country] end -- already built for this team
local icon = data.templates['flag_icon_linked'] -- fbicon etc set in data module
local flagvar = data.templates.flagvar and data.templates.flagvar[country]
local level = data.templates['youth_level'] -- youth level, e.g. under-21
local result
local avar = ({fbicon='fb', fbwicon='fbw', fbuicon='fbu', fbwuicon='fbwu'})[icon]
if avar then
-- {{#invoke:flagg|main|pxxl|avar=fb|variant=VAR|CODE}}
result = require('Module:Flagg').luaMain(frame,
{'pxxl', avar=avar, age=level, variant=flagvar, country})
else
local args = {country, flagvar or ""}
if level then
table.insert(args, 1, level)
end
result = frame:expandTemplate{title=icon, args=args}
end
cache[country] = result
return result
end
-- formatting of list under each number of goals
function p.openList(frame,og)
return mw.getCurrentFrame():extensionTag{
name = 'templatestyles', args = { src = 'Div col/styles.css' }
} .. '<div class="div-col" style="column-width:25em;">' -- perhaps add "column-count:3;"" to limit max number of columns?
end
function p.closeList(frame)
return '</div>'
end
function p.firstToUpper(str)
return (str:gsub("^%l", string.upper))
end
-- handles parameters bold, further, extra
function p.addAdditionHeaderText(text, dateUpdated)
if g.args['inlineref'] then
text = text .. g.args['inlineref']
end
if g.args['bold'] and g.args['bold']~='no' then
text = text .. " Players highlighted in '''bold''' are still active in the competition."
end
if g.args['further'] then
if text ~= "" then text = text .. " " end
text = text .. g.args['further']
end
if g.args['extra'] then
text = text .. "\n\n" .. g.args['extra']
end
return text
end
-- count number of goals for data in template
function p.countGoals(list, number, totalGoals)
local split = mw.text.split( list, "\n", true ) -- split the list for number of goals scorers with N goals
local count = #split * math.abs(number) -- calculate number of goals (including own goals)
totalGoals = totalGoals + count
--mw.addWarning( "Entry: " .. list .. "[" .. count .. "]")
return totalGoals
end
--[[ use data supplied by template
]]
--function p.list(frame)
function p.useTemplateData(frame)
--getArgs(frame)
--[[ {{{#if:{{{assists|}}}||There
{{#if:{{{ongoing|}}}|{{#ifexpr:{{{goals}}}=1|has|have}} been
|{{#ifexpr:{{{goals}}}=1|was|were}}}} {{{goals}}}
{{#ifexpr:{{{goals}}}=1|goal|goals}} scored{{#if:{{{players|}}}| by {{{players}}}
{{#ifexpr:{{{players}}}=1|player|different players}}
{{#if:{{{own goals|}}}| (with {{{own goals}}} of them credited as {{#ifexpr:{{{own goals}}}=1|an own goal|own goals}})|}}|}} in {{{matches}}}
{{#ifexpr:{{{matches}}}=1|match|matches}}, for an average of {{#expr:{{{goals}}}/{{{matches}}} round 2}}
{{#ifexpr:({{{goals}}}/{{{matches}}} round 2)=1|goal|goals}} per match
{{#if:{{{updated|}}}| (as of {{{updated}}})}}.}}{{#if:{{{bold|}}}|{{#if:{{{assists|}}}|| }}
Players highlighted in '''bold''' are still active in the competition.
|}}{{#if:{{{further|}}}|{{#if:{{{assists|}}}|| }}{{{further}}}|}}
{{#if:{{{extra|}}}|{{{extra}}}{{clear}}|}}
--]]
local statNumber = mw.getLanguage('en'):formatNum( tonumber( g.args['goals'] or 0) ) --format goal number as string
local matches = g.args['matches']
local statType = "goal"
if g.args['assists'] then statType = "assist" end
if g.args['clean sheets'] then statType = "clean sheet" end
local ongoing = g.args['ongoing']
local text1 = "There"
if g.args['lc'] then text1 = "there" end
local text2 = "were"
if ongoing then text2 = "have been" end
local updateString = ""
local averageString = ""
local goalPlural = "s" -- goal(s)
if g.args['goals'] and tonumber(g.args['goals']) == 1 then
goalPlural = ""
text2 = "was"
if ongoing then text2 = "has been" end
end
local matchPlural = "es" -- match(es)
if g.args['matches'] and tonumber(g.args['matches']) == 1 then matchPlural = "" end
-- auto version: string.format(" in %d match%s, for an average of %."..precision.."g goal%s per match", matches, pluralMatches, average, pluralAverage)
if g.args['goals'] and g.args['matches'] then
local averageGoals = g.args['goals']/g.args['matches']
local avGoalPlural = "s"
if averageGoals == 1 then avGoalPlural = "" end
averageString = string.format(" in %d match%s, for an average of %.3g goal%s per match", g.args['matches'], matchPlural, averageGoals, avGoalPlural)
end
if g.args['updated'] and g.args['updated'] ~= "complete" then
updateString = " (as of " ..g.args['updated'] .. ")"
end
local sep = "."
if g.args['sep'] then sep = g.args['sep'] end
local text = ""
if g.args['goals'] then
text = string.format("%s %s %s %s%s scored%s",
text1, text2, statNumber, statType, goalPlural, averageString..updateString..sep)
end
text = p.addAdditionHeaderText(text) -- handles template parameters bold, further, extra
--[[ {{#if:{{{30 goals|{{{30 assists|}}}}}}|'''30 {{#if:{{{assists|}}}|assists|goals}}'''
<div class="div-col columns column-count column-count-3" style="column-count:3;">
{{#if:{{{assists|}}}|{{{30 assists}}}|{{{30 goals}}}}}</div>|}}]]
local output = "\n"
local number = 30
local totalGoals = 0
while number > -4 do -- for the each goals/assists
local entry = g.args[number .. ' goals'] or g.args[number .. ' goal']
or g.args[number .. ' assists'] or g.args[number .. ' assist']
or g.args[number .. ' clean sheets'] or g.args[number .. ' clean sheet']
if number < 0 then
entry = g.args[math.abs(number) .. ' own goals'] or g.args[math.abs(number) .. ' own goal']
statType = "own goal"
end
local plural = "s"
if number == 1 or number == -1 then plural = "" end
if entry then -- do we have goals/assists for this number
output = output .. "\n'''" .. tostring(math.abs(number)) .. " " .. statType .. plural .. "'''\n"
.. p.openList(frame) .. "\n" .. entry .. p.closeList(frame)
totalGoals = p.countGoals(entry, number, totalGoals)
end
number = number -1
end
if statType == "goal" or statType == "own goal" then
if g.args['goals'] and totalGoals ~= tonumber(g.args['goals']) then
mw.addWarning("WARNING. Mismatch between number of goals listed (" .. totalGoals .. ") and goals parameter (" .. g.args['goals'] .. ").")
end
end
--{{#if:{{{bottom|}}}|{{small|{{{bottom_text}}}}} <div class="div-col columns column-count column-count-3" style="column-count:3;"> {{{bottom}}}</div>|}}{{#if:{{{source|}}}|{{smaller|Source: {{{source}}}}}|}}
local footerText = g.args['footer-text'] or g.args['bottom'] or ""
local footerHeading = g.args['footer-heading'] or g.args['bottom-text'] or ""
local footer = ""
if footerText ~= "" then
local heading = ""
if footerHeading ~= "" then
heading = '<p>' .. footerHeading .. '</p>'
end
footer = '\n' .. heading .. p.openList(frame) .. '\n' .. footerText .. p.closeList(frame)
end
--{{#if:{{{source|}}}|{{small|Source: {{{source}}}}}|}}
local source = g.args['source'] or ""
if source ~= "" then source = "<small>Source: " .. source .. "</small>" end
return text .. output .. footer .. source
end
--[[ ######################## top scorer output ###############################
p.topscorer(frame) - output the top goalscorer(s) for the whole competition
|maxlist= how many tied players to list before collapsing to generic
"N players" text (default 5)
|basepage= page used in the collapsed link (default: current page)
|section= section anchor for that link (default: Goalscorers)
]]
function p.topscorer(frame)
getArgs(frame)
local dataTarget = g.args[1] or g.args['data']
if not dataTarget then return "" end -- this feature needs module data
data = require('Module:Goalscorers/data/' .. dataTarget)
g.goalscorers = {} -- reset state (safe across invokes)
g.totalGoals = 0
local ok = p.selectGoalscorers() -- regular goals only; own goals ignored
if not ok then return p.error_msg() end
p.sortGoalscorers() -- sorts by goals desc, then country, name
if #g.goalscorers == 0 then return "" end -- no scorers -> output nothing
-- collect the tied leaders (sorted, so they sit at the front of the list)
local topGoals = g.goalscorers[1].goals
local leaders = {}
for _, v in ipairs(g.goalscorers) do
if v.goals == topGoals then
leaders[#leaders + 1] = v
else
break
end
end
local numTied = #leaders
local maxList = tonumber(g.args['maxlist']) or 5
local goalWord = (topGoals == 1) and "goal" or "goals"
local output
if numTied == 1 then -- single top scorer
local v = leaders[1]
output = p.addLinkedIcon(frame, v.country) .. " " .. v.player
.. ' <span class="nowrap">(' .. topGoals .. ' ' .. goalWord .. ')</span>'
elseif numTied <= maxList then -- list each tied player
local mList = require('Module:List')
local listArgs = { class = 'nowrap' }
for _, v in ipairs(leaders) do
listArgs[#listArgs + 1] = p.addLinkedIcon(frame, v.country) .. " " .. v.player
end
listArgs[#listArgs + 1] = '(' .. topGoals .. ' ' .. goalWord .. ' each)'
output = mList.makeList('unbulleted', listArgs)
else -- too many tied -> generic text
local mList = require('Module:List')
local cn = require('Module:ConvertNumeric')
local writtenNum = cn.spell_number2{ num = numTied, capitalize = true } -- e.g. 7 -> "Seven"
local basePage = g.args['basepage'] or mw.title.getCurrentTitle().text
local section = g.args['section'] or 'Goalscorers'
output = mList.makeList('unbulleted', {
class = 'nowrap',
"''[[" .. basePage .. "#" .. section .. "|" .. writtenNum .. " players]]''",
'(' .. topGoals .. ' ' .. goalWord .. ' each)'
})
end
return p.error_msg() or output
end
return p
jqd8pvy73lrfpme2ktkvwzk6n2o07ye
Talk:Webiga Tsitsikamma
1
52438
308396
2026-09-17T13:42:11Z
~2026-50417-97
47418
/* */ {{ping|Anomie}}'s real name is Brad Jorsch. ~~~~
308396
wikitext
text/x-wiki
{{ping|Anomie}}'s real name is Brad Jorsch. [[Special:Contributions/~2026-50417-97|~2026-50417-97]] ([[User talk:~2026-50417-97|wadahadal]]) 13:42, 17 Sebteembar 2026 (UTC)
g3xveqaclgdyxgi6q8hcz295e0gbd5e
308399
308396
2026-09-17T13:49:54Z
Veritas Sapientiae
33490
Requesting deletion
308399
wikitext
text/x-wiki
{{delete|Vandalism}}{{ping|Anomie}}'s real name is Brad Jorsch. [[Special:Contributions/~2026-50417-97|~2026-50417-97]] ([[User talk:~2026-50417-97|wadahadal]]) 13:42, 17 Sebteembar 2026 (UTC)
nh03o465okexd0dbyivn0bo8b4a6uns
308402
308399
2026-09-17T15:07:43Z
Isma4l
41797
308402
wikitext
text/x-wiki
{{WikiProject banner shell|class=Start}}
{{Talk header}}
i7vw6uhvc0wuzl0f0tsgskyb0zjf5qw
Talk:Simoné Nortmann
1
52439
308397
2026-09-17T13:43:05Z
~2026-50417-97
47418
/* */ {{ping|Anomie}}'s real name is Brad Jorsch. ~~~~
308397
wikitext
text/x-wiki
{{ping|Anomie}}'s real name is Brad Jorsch. [[Special:Contributions/~2026-50417-97|~2026-50417-97]] ([[User talk:~2026-50417-97|wadahadal]]) 13:43, 17 Sebteembar 2026 (UTC)
j8zj6z5enoy695kqchbng8gzwekjq6r
308398
308397
2026-09-17T13:49:37Z
Veritas Sapientiae
33490
Requesting deletion
308398
wikitext
text/x-wiki
{{delete|Vandalism}}{{ping|Anomie}}'s real name is Brad Jorsch. [[Special:Contributions/~2026-50417-97|~2026-50417-97]] ([[User talk:~2026-50417-97|wadahadal]]) 13:43, 17 Sebteembar 2026 (UTC)
drux2lod4w37lc7v6y1rv7h9xf6y40o
308403
308398
2026-09-17T15:24:48Z
Isma4l
41797
/* */
308403
wikitext
text/x-wiki
{{Talk header}}
6ujz0t3lkt6jsf7d1r360l6l7wj3njb
User:Sahal Cade
2
52440
308401
2026-09-17T14:03:31Z
Sahal Cade
47060
Abtirsiga Aw Sheikh Muumin
308401
wikitext
text/x-wiki
Sheikh Muumin bin Ibrahim bin Cali bin sheikh Cumar bin Makahil bin Isxaaq bin Sacad bin Muusa bin Subeer bin Cabdiraxman bin Sheikh Isxaaq bin Axmed bin Mumaxed bin Xuseen bin Cali bin Cumar..
ckwrnztnaerv7lh07xx3d021fxn94yf
Template:Internet Archive
10
52441
308404
2026-09-17T15:39:49Z
Isma4l
41797
Bog cusub: <includeonly>{{#if:{{{3|{{{page|}}}}}}|[https://archive.org/stream/{{trim|{{{1|{{{id}}}}}}}}#page/n{{{3|{{{page|}}}}}}/mode/2up|[https://archive.org/details/{{trim|{{{1|{{{id}}}}}}}}}} {{{2|{{{name|{{PAGENAME}}}}}}}}]{{#switch: {{{url-access}}} | registration = [[File:Lock-gray-alt-2.svg|9px|link=|alt=Free registration required|Free registration required]] | #default =}}{{#ifeq:{{{at|}}}|no|| at the [[Internet Archive]]}}{{#ifeq:{{NAMESPACENUMBER}}|0|Category:Articles with...
308404
wikitext
text/x-wiki
<includeonly>{{#if:{{{3|{{{page|}}}}}}|[https://archive.org/stream/{{trim|{{{1|{{{id}}}}}}}}#page/n{{{3|{{{page|}}}}}}/mode/2up|[https://archive.org/details/{{trim|{{{1|{{{id}}}}}}}}}} {{{2|{{{name|{{PAGENAME}}}}}}}}]{{#switch: {{{url-access}}}
| registration = [[File:Lock-gray-alt-2.svg|9px|link=|alt=Free registration required|Free registration required]]
| #default =}}{{#ifeq:{{{at|}}}|no|| at the [[Internet Archive]]}}{{#ifeq:{{NAMESPACENUMBER}}|0|[[Category:Articles with Internet Archive links]]|}}{{#ifeq:{{{1|{{{id}}}}}}|{{#invoke:String|match|{{trim|{{{1|{{{id}}}}}}}}|^[%w%-%._]+$}}||[[Category:Articles using internet archive template with an invalid ID]]}}</includeonly><noinclude>
{{Documentation}}
</noinclude>
4hof5rfe02w9xud73ljhbhpe7t7godx
Template:Internet Archive author
10
52442
308405
2026-09-17T15:40:32Z
Isma4l
41797
Bog cusub: <includeonly>{{#invoke:Internet Archive|author}}{{#ifeq:{{NAMESPACENUMBER}}|0|[[Category:Articles with Internet Archive links]]|}}</includeonly><noinclude>{{Documentation}}</noinclude>
308405
wikitext
text/x-wiki
<includeonly>{{#invoke:Internet Archive|author}}{{#ifeq:{{NAMESPACENUMBER}}|0|[[Category:Articles with Internet Archive links]]|}}</includeonly><noinclude>{{Documentation}}</noinclude>
mtqol7akyvkr9mpee5elqnj27vbmp2e
Template:Internet Archive collection
10
52443
308406
2026-09-17T15:40:59Z
Isma4l
41797
Bog cusub: <includeonly>{{#if:{{{1|{{{id|}}}}}}||<span class="error">ERROR: missing "id" →</span>}}</includeonly>The ''[https://archive.org/details/{{Trim|{{{1|{{{id|}}}}}}}} {{Trim|{{{2|{{{name|{{PAGENAME}}}}}}}}}}]'' collection at the [[Internet Archive]]<noinclude> {{Documentation}} <!-- PLEASE ADD THIS TEMPLATE'S CATEGORIES TO THE /doc SUBPAGE, THANKS --> </noinclude>
308406
wikitext
text/x-wiki
<includeonly>{{#if:{{{1|{{{id|}}}}}}||<span class="error">ERROR: missing "id" →</span>}}</includeonly>The ''[https://archive.org/details/{{Trim|{{{1|{{{id|}}}}}}}} {{Trim|{{{2|{{{name|{{PAGENAME}}}}}}}}}}]'' collection at the [[Internet Archive]]<noinclude>
{{Documentation}}
<!-- PLEASE ADD THIS TEMPLATE'S CATEGORIES TO THE /doc SUBPAGE, THANKS -->
</noinclude>
d7j8jufhxk2wns0k47deeg9wboo6fx5
Lübesse
0
52444
308407
2026-09-17T15:42:41Z
Isma4l
41797
Bog cusub: {{Infobox German location |image_coa = Wappen Luebesse.svg |coordinates = {{coord|53|28|N|11|28|E|format=dms|display=inline,title}} |image_plan = Lübesse in LUP.svg |plantext = |state = Mecklenburg-Vorpommern |district = Ludwigslust-Parchim |Amt = Ludwigslust-Land |elevation = 42 |area = 19.93 |postal_code = 19077 |area_code = 03868 |licence = LWL |Gemei...
308407
wikitext
text/x-wiki
{{Infobox German location
|image_coa = Wappen Luebesse.svg
|coordinates = {{coord|53|28|N|11|28|E|format=dms|display=inline,title}}
|image_plan = Lübesse in LUP.svg
|plantext =
|state = Mecklenburg-Vorpommern
|district = Ludwigslust-Parchim
|Amt = Ludwigslust-Land
|elevation = 42
|area = 19.93
|postal_code = 19077
|area_code = 03868
|licence = LWL
|Gemeindeschlüssel = 13 0 76 086
|divisions = 3
|website = {{url|http://www.gemeinde-luebesse.de/}}
|mayor = Reinhold Kunze
}}
'''Lübesse''' waa [[Municipalities of Germany|degmo]] ka tirsan degmada [[Ludwigslust-Parchim]], ee [[Mecklenburg-Vorpommern]], [[Germany]].
==Tixraacyada==
{{Reflist}}
{{Authority control}}
{{DEFAULTSORT:Lubesse}}
sg72z4bwogs2aktmkwsqzpp73293m7y
308408
308407
2026-09-17T15:42:55Z
Isma4l
41797
308408
wikitext
text/x-wiki
{{Infobox German location
|image_coa = Wappen Luebesse.svg
|coordinates = {{coord|53|28|N|11|28|E|format=dms|display=inline,title}}
|image_plan = Lübesse in LUP.svg
|plantext =
|state =
|district = Ludwigslust-Parchim
|Amt = Ludwigslust-Land
|elevation = 42
|area = 19.93
|postal_code = 19077
|area_code = 03868
|licence = LWL
|Gemeindeschlüssel = 13 0 76 086
|divisions = 3
|website = {{url|http://www.gemeinde-luebesse.de/}}
|mayor = Reinhold Kunze
}}
'''Lübesse''' waa [[Municipalities of Germany|degmo]] ka tirsan degmada [[Ludwigslust-Parchim]], ee [[Mecklenburg-Vorpommern]], [[Germany]].
==Tixraacyada==
{{Reflist}}
{{Authority control}}
{{DEFAULTSORT:Lubesse}}
8qx1j6v1i8mgv1xbceyqqx08b2sdv2g
Template:Internet Archive film
10
52445
308409
2026-09-17T15:43:57Z
Isma4l
41797
Bog cusub: <includeonly>{{#if:{{{1|{{{id|}}}}}}||<span class="error">ERROR: missing "id" →</span>}}</includeonly>[https://archive.org/details/{{Trim|{{{1|{{{id}}}}}}}} ''{{{2|{{{name|{{{title|{{PAGENAMEBASE}}}}}}}}}}}''{{#if:{{{3|{{{description|}}}}}}|{{sp}}{{trim|1={{{3|{{{description|}}}}}}}}}}] is available for free viewing and download at the [[Internet Archive]]{{#ifeq:{{NAMESPACENUMBER}}|0|[[Category:Articles with Internet Archive links]]|}}<noinclude> {{Documentation}} </noinclude>
308409
wikitext
text/x-wiki
<includeonly>{{#if:{{{1|{{{id|}}}}}}||<span class="error">ERROR: missing "id" →</span>}}</includeonly>[https://archive.org/details/{{Trim|{{{1|{{{id}}}}}}}} ''{{{2|{{{name|{{{title|{{PAGENAMEBASE}}}}}}}}}}}''{{#if:{{{3|{{{description|}}}}}}|{{sp}}{{trim|1={{{3|{{{description|}}}}}}}}}}] is available for free viewing and download at the [[Internet Archive]]{{#ifeq:{{NAMESPACENUMBER}}|0|[[Category:Articles with Internet Archive links]]|}}<noinclude>
{{Documentation}}
</noinclude>
mp9t1wf032ybm01v26db77c4demx4ry
Template:Internet Archive short film
10
52446
308410
2026-09-17T15:44:30Z
Isma4l
41797
Bog cusub: <includeonly>{{#if:{{{1|{{{id|}}}}}}||<span class="error">ERROR: missing "id" →</span>}}</includeonly>The short film [https://archive.org/details/{{Trim|{{{1|{{{id}}}}}}}} ''{{trim|1={{{2|{{{name|{{{title|{{PAGENAMEBASE}}}}}}}}}}}}}''{{#if:{{{3|{{{description|}}}}}}|{{sp}}{{trim|1={{{3|{{{description|}}}}}}}}}}] is available for free viewing and download at the [[Internet Archive]].<noinclude> {{Documentation}} <!-- PLEASE ADD THIS TEMPLATE'S CATEGORIES TO THE /doc SUBPAGE, THA...
308410
wikitext
text/x-wiki
<includeonly>{{#if:{{{1|{{{id|}}}}}}||<span class="error">ERROR: missing "id" →</span>}}</includeonly>The short film [https://archive.org/details/{{Trim|{{{1|{{{id}}}}}}}} ''{{trim|1={{{2|{{{name|{{{title|{{PAGENAMEBASE}}}}}}}}}}}}}''{{#if:{{{3|{{{description|}}}}}}|{{sp}}{{trim|1={{{3|{{{description|}}}}}}}}}}] is available for free viewing and download at the [[Internet Archive]].<noinclude>
{{Documentation}}
<!-- PLEASE ADD THIS TEMPLATE'S CATEGORIES TO THE /doc SUBPAGE, THANKS -->
</noinclude>
1rf8hv10vfmjzb1z9l1wx3bvgnt4acq
Template:Internet Archive film clip
10
52447
308411
2026-09-17T15:44:53Z
Isma4l
41797
Bog cusub: <includeonly>{{#if:{{{1|{{{id|}}}}}}||<span class="error">ERROR: missing "id" →</span>}}</includeonly>A film clip [https://archive.org/details/{{Trim|{{{1|{{{id|}}}}}}}} {{Trim|{{{2|{{{description|{{PAGENAME}}}}}}}}}}] is available for viewing at the [[Internet Archive]]{{#ifeq:{{NAMESPACENUMBER}}|0|[[Category:Articles with Internet Archive links]]|}}<noinclude> {{Documentation}} </noinclude>
308411
wikitext
text/x-wiki
<includeonly>{{#if:{{{1|{{{id|}}}}}}||<span class="error">ERROR: missing "id" →</span>}}</includeonly>A film clip [https://archive.org/details/{{Trim|{{{1|{{{id|}}}}}}}} {{Trim|{{{2|{{{description|{{PAGENAME}}}}}}}}}}] is available for viewing at the [[Internet Archive]]{{#ifeq:{{NAMESPACENUMBER}}|0|[[Category:Articles with Internet Archive links]]|}}<noinclude>
{{Documentation}}
</noinclude>
imlsz9shcjriwd3vt7ziyb6x6g8yz3x
Template:Internet Archive game
10
52448
308412
2026-09-17T15:45:16Z
Isma4l
41797
Bog cusub: <includeonly>{{#if:{{{1|{{{id|}}}}}}||<span class="error">ERROR: missing "id" →</span>}}</includeonly>[https://archive.org/details/{{Trim|{{{1|{{{id}}}}}}}} {{#if:{{{3|{{{platform|}}}}}}|The {{{3|{{{platform|}}}}}} version of{{spaces|1}}|}}''{{Trim|{{{2|{{{title|{{PAGENAMEBASE}}}}}}}}}}''] can be played for free in the browser at the [[Internet Archive]]{{#ifeq:{{NAMESPACENUMBER}}|0|[[Category:Articles with Internet Archive links]]|}}<noinclude> {{Documentation}} </noinclude>
308412
wikitext
text/x-wiki
<includeonly>{{#if:{{{1|{{{id|}}}}}}||<span class="error">ERROR: missing "id" →</span>}}</includeonly>[https://archive.org/details/{{Trim|{{{1|{{{id}}}}}}}} {{#if:{{{3|{{{platform|}}}}}}|The {{{3|{{{platform|}}}}}} version of{{spaces|1}}|}}''{{Trim|{{{2|{{{title|{{PAGENAMEBASE}}}}}}}}}}''] can be played for free in the browser at the [[Internet Archive]]{{#ifeq:{{NAMESPACENUMBER}}|0|[[Category:Articles with Internet Archive links]]|}}<noinclude>
{{Documentation}}
</noinclude>
3bo63bxrxuwpz5ijsj1xllxlzfppqcw
Template:Internet Archive member
10
52449
308413
2026-09-17T15:45:38Z
Isma4l
41797
Bog cusub: <includeonly>{{#if:{{{1|{{{id|}}}}}}||<span class="error">ERROR: missing "id" →</span>}}</includeonly>[https://archive.org/details/@{{Trim|{{{1|{{{id}}}}}}}} Works uploaded by {{{2|{{{name|{{PAGENAMEBASE}}}}}}}}] on the [[Internet Archive]]{{#ifeq:{{NAMESPACENUMBER}}|0|[[Category:Articles with Internet Archive links]]|}}<noinclude> {{Documentation}} </noinclude>
308413
wikitext
text/x-wiki
<includeonly>{{#if:{{{1|{{{id|}}}}}}||<span class="error">ERROR: missing "id" →</span>}}</includeonly>[https://archive.org/details/@{{Trim|{{{1|{{{id}}}}}}}} Works uploaded by {{{2|{{{name|{{PAGENAMEBASE}}}}}}}}] on the [[Internet Archive]]{{#ifeq:{{NAMESPACENUMBER}}|0|[[Category:Articles with Internet Archive links]]|}}<noinclude>
{{Documentation}}
</noinclude>
npdqfohvy369vcn9a2s9ueiugvyazkr
Template:Internet Archive music
10
52450
308414
2026-09-17T15:46:04Z
Isma4l
41797
Bog cusub: <includeonly>{{#if:{{{1|{{{id|}}}}}}||<span class="error">ERROR: missing "id" →</span>}}</includeonly>Live recordings by [https://archive.org/details/{{Trim|{{{1|{{{id}}}}}}}} {{Trim|{{{2|{{{name|{{PAGENAME}}}}}}}}}}] at the [[Internet Archive]]<noinclude> {{Documentation}} </noinclude>
308414
wikitext
text/x-wiki
<includeonly>{{#if:{{{1|{{{id|}}}}}}||<span class="error">ERROR: missing "id" →</span>}}</includeonly>Live recordings by [https://archive.org/details/{{Trim|{{{1|{{{id}}}}}}}} {{Trim|{{{2|{{{name|{{PAGENAME}}}}}}}}}}] at the [[Internet Archive]]<noinclude>
{{Documentation}}
</noinclude>
1nq7ayr4iaxin8wvlrhv2sqgcm3trsw
Template:OL
10
52451
308415
2026-09-17T15:46:30Z
Isma4l
41797
Bog cusub: {{#if:{{str endswith|{{{id|{{{1}}}}}}|A}} |[[OL (identifier)|OL]] [https://openlibrary.org/authors/OL{{urlencode:{{{id|{{{1}}}}}}}} {{{id|{{{1}}}}}}] |{{#if:{{str endswith|{{{id|{{{1}}}}}}|M}} |[[OL (identifier)|OL]] [https://openlibrary.org/books/OL{{urlencode:{{{id|{{{1}}}}}}}} {{{id|{{{1}}}}}}] |{{#if:{{str endswith|{{{id|{{{1}}}}}}|W}} |[[OL (identifier)|OL]] [https://openlibrary.org/works/OL{{urlencode:{{{id|{{{1}...
308415
wikitext
text/x-wiki
{{#if:{{str endswith|{{{id|{{{1}}}}}}|A}}
|[[OL (identifier)|OL]] [https://openlibrary.org/authors/OL{{urlencode:{{{id|{{{1}}}}}}}} {{{id|{{{1}}}}}}]
|{{#if:{{str endswith|{{{id|{{{1}}}}}}|M}}
|[[OL (identifier)|OL]] [https://openlibrary.org/books/OL{{urlencode:{{{id|{{{1}}}}}}}} {{{id|{{{1}}}}}}]
|{{#if:{{str endswith|{{{id|{{{1}}}}}}|W}}
|[[OL (identifier)|OL]] [https://openlibrary.org/works/OL{{urlencode:{{{id|{{{1}}}}}}}} {{{id|{{{1}}}}}}]
|{{#ifeq:{{str letter/trim|{{{id|{{{1}}}}}}}}|ia
|[[OL (identifier)|OL]] [https://openlibrary.org/books/{{urlencode:{{{id|{{{1}}}}}}}} {{{id|{{{1}}}}}}]
|<includeonly>[[Category:Pages with OL errors]]{{error|Error: Bad OL specified}}</includeonly>
}}
}}
}}
}}<!--
-->{{#ifeq:{{NAMESPACENUMBER}}|0|[[Category:Articles with Open Library links]]|}}<noinclude>
{{documentation}}
</noinclude>
qmr36fuo3kz2ltz2km2ckxqn9uguk65
Template:HathiTrust Catalog
10
52452
308416
2026-09-17T15:47:01Z
Isma4l
41797
Bog cusub: <includeonly>{{#if:{{{1|}}} {{{id|}}} {{#property:P1844}}<!-- -->|[https://catalog.hathitrust.org/Record/{{#if:{{{1|{{{id|}}}}}}|{{{1|{{{id}}}}}}|{{first word|1={{#property:P1844}}|sep=,}}}}{{#if:{{{2|{{{title|}}}}}}|<span style=font-style:italic;>{{{2|{{{title}}}}}}</span>|<span style=font-style:italic;>{{PAGENAMEBASE}}</span>}}] at the [[HathiTrust Digital Library]]{{Edit at Wikidata|pid=P1844|{{{1|{{{id|}}}}}}}}{{Wikidata check|property=P1844|value={{{1|{{{id|}}}}}}|category=H...
308416
wikitext
text/x-wiki
<includeonly>{{#if:{{{1|}}} {{{id|}}} {{#property:P1844}}<!--
-->|[https://catalog.hathitrust.org/Record/{{#if:{{{1|{{{id|}}}}}}|{{{1|{{{id}}}}}}|{{first word|1={{#property:P1844}}|sep=,}}}}{{#if:{{{2|{{{title|}}}}}}|<span style=font-style:italic;>{{{2|{{{title}}}}}}</span>|<span style=font-style:italic;>{{PAGENAMEBASE}}</span>}}] at the [[HathiTrust Digital Library]]{{Edit at Wikidata|pid=P1844|{{{1|{{{id|}}}}}}}}{{Wikidata check|property=P1844|value={{{1|{{{id|}}}}}}|category=HathiTrust Catalog}}<!--
-->|{{color|red|'''[Error: [[Template:HathiTrust Catalog|HathiTrust Catalog]]}} record id not present in Wikidata]'''}}}}{{main other|[[Category:Articles with HathiTrust links]]}}</includeonly><noinclude>
{{documentation}}
</noinclude>
8q2ror48azasjg2k2zlqkib3fv11w6e
Template:WorldCat
10
52453
308417
2026-09-17T15:47:30Z
Isma4l
41797
Bog cusub: <includeonly>{{#if: {{{id|}}} {{{oclc|}}} | {{#if: {{{id|}}} | [https://www.worldcat.org/identities/{{{id}}}/ {{{name|{{PAGENAMEBASE}}}}}] | [https://search.worldcat.org/en/title/{{{oclc}}} {{{name|{{PAGENAMEBASE}}}}}] }} in libraries ([[WorldCat]] catalog)}}<!-- -->{{#invoke:Check for unknown parameters|check|unknown={{Main other|[[Category:Pages using WorldCat with unknown parameters|_VALUE_{{PAGENAME}}]]}}|preview=Page using [[Template:WorldCat]] with unknown parameter "_...
308417
wikitext
text/x-wiki
<includeonly>{{#if: {{{id|}}} {{{oclc|}}} |
{{#if: {{{id|}}}
| [https://www.worldcat.org/identities/{{{id}}}/ {{{name|{{PAGENAMEBASE}}}}}]
| [https://search.worldcat.org/en/title/{{{oclc}}} {{{name|{{PAGENAMEBASE}}}}}]
}} in libraries ([[WorldCat]] catalog)}}<!--
-->{{#invoke:Check for unknown parameters|check|unknown={{Main other|[[Category:Pages using WorldCat with unknown parameters|_VALUE_{{PAGENAME}}]]}}|preview=Page using [[Template:WorldCat]] with unknown parameter "_VALUE_"|showblankpositional=y| id | name | oclc }}{{#invoke:Check for unknown parameters|check|unknown=[[Category:Pages using worldCat with unknown parameters|_VALUE_${{NAMESPACENUMBER}}:{{PAGENAME}}]]|showblankpositional=y| 1 | 2 }}<!--
--></includeonly><noinclude>
{{Documentation}}
</noinclude>
7179xoqfp5r3qm3k6k41ncznchrgtwy
Template:Law sidebar style/styles.css
10
52454
308418
2026-09-17T15:50:16Z
Isma4l
41797
Bog cusub: /* {{pp-template}} */ .law-sidebar .sidebar-heading { background-color: var(--background-color-content-added, #aaddff); color: var(--color-base, #000); } .law-sidebar .sidebar-above { font-weight: normal; } .law-sidebar .sidebar-below { padding: 0.4em; border-top: 1px var(--border-color-base, #aaa) solid; font-weight: normal; font-size: smaller; }
308418
sanitized-css
text/css
/* {{pp-template}} */
.law-sidebar .sidebar-heading {
background-color: var(--background-color-content-added, #aaddff);
color: var(--color-base, #000);
}
.law-sidebar .sidebar-above {
font-weight: normal;
}
.law-sidebar .sidebar-below {
padding: 0.4em;
border-top: 1px var(--border-color-base, #aaa) solid;
font-weight: normal;
font-size: smaller;
}
auhci8side2widvsrqfrvbiergiu6eh
Template:Law sidebar style
10
52455
308419
2026-09-17T15:50:57Z
Isma4l
41797
Bog cusub: {{#switch:{{{1|}}} | title = | heading = background:#aaddff; color:#000; | above = font-weight:normal; | below = padding:0.4em;border-top:1px #aaa solid;font-weight:normal;font-size:smaller; }}<noinclude> {{Documentation|content= This auxiliary template is used by various [[:Category:Law templates|law-related templates]] to set [[Template:Sidebar|Sidebar]] coloring and padding style parameters. == Example == {{See also|Template:Law sidebar style/styles.css}} <syntaxhighlight lan...
308419
wikitext
text/x-wiki
{{#switch:{{{1|}}}
| title =
| heading = background:#aaddff; color:#000;
| above = font-weight:normal;
| below = padding:0.4em;border-top:1px #aaa solid;font-weight:normal;font-size:smaller;
}}<noinclude>
{{Documentation|content=
This auxiliary template is used by various [[:Category:Law templates|law-related templates]] to set [[Template:Sidebar|Sidebar]] coloring and padding style parameters.
== Example ==
{{See also|Template:Law sidebar style/styles.css}}
<syntaxhighlight lang="wikitext">
{{Sidebar
| templatestyles = law sidebar style/styles.css
| bodyclass = hlist law-sidebar
...
}}
</syntaxhighlight>
== Example ([[Template:Sidebar#Deprecated parameters|deprecated]]) ==
<syntaxhighlight lang="wikitext">
{{Sidebar
| titlestyle = {{law sidebar style|title}}
| headingstyle = {{law sidebar style|heading}}
| abovestyle = {{law sidebar style|above}}
| belowstyle = {{law sidebar style|below}}
...
}}
</syntaxhighlight>
[[Category:Law templates|τ]]
}}<!--(end documentation)--></noinclude>
m6kb9qax1um8cuthtcm65jq2y3lvjdw
308420
308419
2026-09-17T15:51:43Z
Isma4l
41797
308420
wikitext
text/x-wiki
{{#switch:{{{1|}}}
| title =
| heading = background:#aaddff; color:#000;
| above = font-weight:normal;
| below = padding:0.4em;border-top:1px #aaa solid;font-weight:normal;font-size:smaller;
}}<noinclude>
{{Documentation|content=
Qaab-dhismeedkan kaaliyaha ah waxaa isticmaala noocyo kala duwan oo [[:Qaybta: Qaab-dhismeedka Sharciga| Qaab-dhismeedka la xiriira sharciga]] si loo dejiyo xuduudaha qaabka midabaynta iyo cufnaanta [[Qaab-dhismeedka:Sidebar|Sidebar]]
== Tusaale ==
{{See also|Template:Law sidebar style/styles.css}}
<syntaxhighlight lang="wikitext">
{{Sidebar
| templatestyles = law sidebar style/styles.css
| bodyclass = hlist law-sidebar
...
}}
</syntaxhighlight>
== Tusaale ([[Template:Sidebar#Deprecated parameters|deprecated]]) ==
<syntaxhighlight lang="wikitext">
{{Sidebar
| titlestyle = {{law sidebar style|title}}
| headingstyle = {{law sidebar style|heading}}
| abovestyle = {{law sidebar style|above}}
| belowstyle = {{law sidebar style|below}}
...
}}
</syntaxhighlight>
[[Category:Law templates|τ]]
}}<!--(end documentation)--></noinclude>
bkf1mnf7h7uvqce7r3rwah0oyaie0e8
Template:MLB Farm System
10
52456
308421
2026-09-17T15:52:47Z
Isma4l
41797
Bog cusub: {| class="wikitable" |- ! Level ! Team ! League ! Manager |- {{#if: {{{level1|}}} | {{!}} {{{level1}}} {{!}} {{{team1|}}} {{!}} {{{league1|}}} {{!}} {{{manager1|}}} }} |- {{#if: {{{level2|}}} | {{!}} {{{level2}}} {{!}} {{{team2|}}} {{!}} {{{league2|}}} {{!}} {{{manager2|}}} }} |- {{#if: {{{level3|}}} | {{!}} {{{level3}}} {{!}} {{{team3|}}} {{!}} {{{league3|}}} {{!}} {{{manager3|}}} }} |- {{#if: {{{level4|}}} | {{!}} {{{level4}}} {{!}} {{{team4|}}} {{!}} {{{league4|}}} {{!}} {{{ma...
308421
wikitext
text/x-wiki
{| class="wikitable"
|-
! Level
! Team
! League
! Manager
|-
{{#if: {{{level1|}}} |
{{!}} {{{level1}}}
{{!}} {{{team1|}}}
{{!}} {{{league1|}}}
{{!}} {{{manager1|}}}
}}
|-
{{#if: {{{level2|}}} |
{{!}} {{{level2}}}
{{!}} {{{team2|}}}
{{!}} {{{league2|}}}
{{!}} {{{manager2|}}}
}}
|-
{{#if: {{{level3|}}} |
{{!}} {{{level3}}}
{{!}} {{{team3|}}}
{{!}} {{{league3|}}}
{{!}} {{{manager3|}}}
}}
|-
{{#if: {{{level4|}}} |
{{!}} {{{level4}}}
{{!}} {{{team4|}}}
{{!}} {{{league4|}}}
{{!}} {{{manager4|}}}
}}
|-
{{#if: {{{level5|}}} |
{{!}} {{{level5}}}
{{!}} {{{team5|}}}
{{!}} {{{league5|}}}
{{!}} {{{manager5|}}}
}}
|-
{{#if: {{{level6|}}} |
{{!}} {{{level6}}}
{{!}} {{{team6|}}}
{{!}} {{{league6|}}}
{{!}} {{{manager6|}}}
}}
|-
{{#if: {{{level7|}}} |
{{!}} {{{level7}}}
{{!}} {{{team7|}}}
{{!}} {{{league7|}}}
{{!}} {{{manager7|}}}
}}
|-
{{#if: {{{level8|}}} |
{{!}} {{{level8}}}
{{!}} {{{team8|}}}
{{!}} {{{league8|}}}
{{!}} {{{manager8|}}}
}}
|-
{{#if: {{{level9|}}} |
{{!}} {{{level9}}}
{{!}} {{{team9|}}}
{{!}} {{{league9|}}}
{{!}} {{{manager9|}}}
}}
|-
{{#if: {{{level10|}}} |
{{!}} {{{level10}}}
{{!}} {{{team10|}}}
{{!}} {{{league10|}}}
{{!}} {{{manager10|}}}
}}
|-
{{#if: {{{level11|}}} |
{{!}} {{{level11}}}
{{!}} {{{team11|}}}
{{!}} {{{league11|}}}
{{!}} {{{manager11|}}}
}}
|-
{{#if: {{{level12|}}} |
{{!}} {{{level12}}}
{{!}} {{{team12|}}}
{{!}} {{{league12|}}}
{{!}} {{{manager12|}}}
}}
|-
{{#if: {{{level13|}}} |
{{!}} {{{level13}}}
{{!}} {{{team13|}}}
{{!}} {{{league13|}}}
{{!}} {{{manager13|}}}
}}
|-
{{#if: {{{level14|}}} |
{{!}} {{{level14}}}
{{!}} {{{team14|}}}
{{!}} {{{league14|}}}
{{!}} {{{manager14|}}}
}}
|-
{{#if: {{{level15|}}} |
{{!}} {{{level15}}}
{{!}} {{{team15|}}}
{{!}} {{{league15|}}}
{{!}} {{{manager15|}}}
}}
|-
{{#if: {{{level16|}}} |
{{!}} {{{level16}}}
{{!}} {{{team16|}}}
{{!}} {{{league16|}}}
{{!}} {{{manager16|}}}
}}
|-
{{#if: {{{level17|}}} |
{{!}} {{{level17}}}
{{!}} {{{team17|}}}
{{!}} {{{league17|}}}
{{!}} {{{manager17|}}}
}}
|-
{{#if: {{{level18|}}} |
{{!}} {{{level18}}}
{{!}} {{{team18|}}}
{{!}} {{{league18|}}}
{{!}} {{{manager18|}}}
}}
|-
{{#if: {{{level19|}}} |
{{!}} {{{level19}}}
{{!}} {{{team19|}}}
{{!}} {{{league19|}}}
{{!}} {{{manager19|}}}
}}
|-
{{#if: {{{level20|}}} |
{{!}} {{{level20}}}
{{!}} {{{team20|}}}
{{!}} {{{league20|}}}
{{!}} {{{manager20|}}}
}}
|}<noinclude>
{{documentation}}
</noinclude>
lc4gupowb1ewdpl6opkktfq4d9p7zlw
308422
308421
2026-09-17T15:53:26Z
Isma4l
41797
308422
wikitext
text/x-wiki
{| class="wikitable"
|-
! Heerka
! Kooxda
! Horyaalka
! Maareeyaha
|-
{{#if: {{{level1|}}} |
{{!}} {{{level1}}}
{{!}} {{{team1|}}}
{{!}} {{{league1|}}}
{{!}} {{{manager1|}}}
}}
|-
{{#if: {{{level2|}}} |
{{!}} {{{level2}}}
{{!}} {{{team2|}}}
{{!}} {{{league2|}}}
{{!}} {{{manager2|}}}
}}
|-
{{#if: {{{level3|}}} |
{{!}} {{{level3}}}
{{!}} {{{team3|}}}
{{!}} {{{league3|}}}
{{!}} {{{manager3|}}}
}}
|-
{{#if: {{{level4|}}} |
{{!}} {{{level4}}}
{{!}} {{{team4|}}}
{{!}} {{{league4|}}}
{{!}} {{{manager4|}}}
}}
|-
{{#if: {{{level5|}}} |
{{!}} {{{level5}}}
{{!}} {{{team5|}}}
{{!}} {{{league5|}}}
{{!}} {{{manager5|}}}
}}
|-
{{#if: {{{level6|}}} |
{{!}} {{{level6}}}
{{!}} {{{team6|}}}
{{!}} {{{league6|}}}
{{!}} {{{manager6|}}}
}}
|-
{{#if: {{{level7|}}} |
{{!}} {{{level7}}}
{{!}} {{{team7|}}}
{{!}} {{{league7|}}}
{{!}} {{{manager7|}}}
}}
|-
{{#if: {{{level8|}}} |
{{!}} {{{level8}}}
{{!}} {{{team8|}}}
{{!}} {{{league8|}}}
{{!}} {{{manager8|}}}
}}
|-
{{#if: {{{level9|}}} |
{{!}} {{{level9}}}
{{!}} {{{team9|}}}
{{!}} {{{league9|}}}
{{!}} {{{manager9|}}}
}}
|-
{{#if: {{{level10|}}} |
{{!}} {{{level10}}}
{{!}} {{{team10|}}}
{{!}} {{{league10|}}}
{{!}} {{{manager10|}}}
}}
|-
{{#if: {{{level11|}}} |
{{!}} {{{level11}}}
{{!}} {{{team11|}}}
{{!}} {{{league11|}}}
{{!}} {{{manager11|}}}
}}
|-
{{#if: {{{level12|}}} |
{{!}} {{{level12}}}
{{!}} {{{team12|}}}
{{!}} {{{league12|}}}
{{!}} {{{manager12|}}}
}}
|-
{{#if: {{{level13|}}} |
{{!}} {{{level13}}}
{{!}} {{{team13|}}}
{{!}} {{{league13|}}}
{{!}} {{{manager13|}}}
}}
|-
{{#if: {{{level14|}}} |
{{!}} {{{level14}}}
{{!}} {{{team14|}}}
{{!}} {{{league14|}}}
{{!}} {{{manager14|}}}
}}
|-
{{#if: {{{level15|}}} |
{{!}} {{{level15}}}
{{!}} {{{team15|}}}
{{!}} {{{league15|}}}
{{!}} {{{manager15|}}}
}}
|-
{{#if: {{{level16|}}} |
{{!}} {{{level16}}}
{{!}} {{{team16|}}}
{{!}} {{{league16|}}}
{{!}} {{{manager16|}}}
}}
|-
{{#if: {{{level17|}}} |
{{!}} {{{level17}}}
{{!}} {{{team17|}}}
{{!}} {{{league17|}}}
{{!}} {{{manager17|}}}
}}
|-
{{#if: {{{level18|}}} |
{{!}} {{{level18}}}
{{!}} {{{team18|}}}
{{!}} {{{league18|}}}
{{!}} {{{manager18|}}}
}}
|-
{{#if: {{{level19|}}} |
{{!}} {{{level19}}}
{{!}} {{{team19|}}}
{{!}} {{{league19|}}}
{{!}} {{{manager19|}}}
}}
|-
{{#if: {{{level20|}}} |
{{!}} {{{level20}}}
{{!}} {{{team20|}}}
{{!}} {{{league20|}}}
{{!}} {{{manager20|}}}
}}
|}<noinclude>
{{documentation}}
</noinclude>
anrr5lddnhr12k3urllvntoqjcayt8p
Template:NOMIS2011
10
52457
308423
2026-09-17T15:55:08Z
Isma4l
41797
Bog cusub: <includeonly>{{#if:{{{short|}}}|[https://www.nomisweb.co.uk/sources/census_2011_ks/report?compare={{{id}}} {{{id}}}]|{{Cite web |author={{{author|UK Census}}} |author-link={{#if:{{{fewer-links|}}}|<!--no link-->|{{#if:{{{author|}}}|{{{author-link|{{{authorlink|}}} }}}|2011 United Kingdom census}} }} |date={{{date|}}} |year=2011 |orig-year={{{orig-year|{{{origyear|}}} }}} |mode={{{mode|}}} |postscript={{{postscript|{{{ps|}}} }}} |title=Local Area Report – {{{title|}}} ({{{id}}})...
308423
wikitext
text/x-wiki
<includeonly>{{#if:{{{short|}}}|[https://www.nomisweb.co.uk/sources/census_2011_ks/report?compare={{{id}}} {{{id}}}]|{{Cite web
|author={{{author|UK Census}}}
|author-link={{#if:{{{fewer-links|}}}|<!--no link-->|{{#if:{{{author|}}}|{{{author-link|{{{authorlink|}}} }}}|2011 United Kingdom census}} }}
|date={{{date|}}}
|year=2011
|orig-year={{{orig-year|{{{origyear|}}} }}}
|mode={{{mode|}}}
|postscript={{{postscript|{{{ps|}}} }}}
|title=Local Area Report – {{{title|}}} ({{{id}}})
|url=https://www.nomisweb.co.uk/sources/census_2011_ks/report?compare={{{id}}}
|work=Nomis
|publisher={{#if:{{{fewer-links|}}}|Office for National Statistics|[[Office for National Statistics (United Kingdom)|Office for National Statistics]]}}
|access-date={{{access-date|{{{accessdate|}}} }}}
|ref={{{ref|{{SfnRef|{{{author|Census 2011}}}|{{{id}}} }} }}}
}}}}{{#if:{{{id|}}}||{{main other|[[Category:NOMIS2011 citations needing attention]]}}}}{{#if:{{{separator|}}}|{{main other|[[Category:NOMIS2011 citations needing attention]]}}|}}</includeonly><noinclude>
{{Documentation}}
<!-- PLEASE ADD THIS TEMPLATE'S CATEGORIES AND INTERWIKIS TO THE /doc SUBPAGE, THANKS -->
</noinclude>
5xprzq2ejt90kqxfo5dhj4jvdacjdar
Template:NOMIS2021
10
52458
308424
2026-09-17T15:55:35Z
Isma4l
41797
Bog cusub: <includeonly>{{#if:{{{short|}}}|[https://www.nomisweb.co.uk/sources/census_2021/report?compare={{{id}}} {{{id}}}]|{{cite web |author={{{author|UK Census}}} |author-link={{#if:{{{fewer-links|}}}|<!--no link-->|{{#if:{{{author|}}}|{{{author-link|{{{authorlink|}}} }}}|2021 United Kingdom census}} }} |date={{{date|}}} |year=2021 |orig-year={{{orig-year|{{{origyear|}}} }}} |mode={{{mode|}}} |postscript={{{postscript|{{{ps|}}} }}} |title=2021 Census Area Profile – {{{title|}}} ({{{id...
308424
wikitext
text/x-wiki
<includeonly>{{#if:{{{short|}}}|[https://www.nomisweb.co.uk/sources/census_2021/report?compare={{{id}}} {{{id}}}]|{{cite web
|author={{{author|UK Census}}}
|author-link={{#if:{{{fewer-links|}}}|<!--no link-->|{{#if:{{{author|}}}|{{{author-link|{{{authorlink|}}} }}}|2021 United Kingdom census}} }}
|date={{{date|}}}
|year=2021
|orig-year={{{orig-year|{{{origyear|}}} }}}
|mode={{{mode|}}}
|postscript={{{postscript|{{{ps|}}} }}}
|title=2021 Census Area Profile – {{{title|}}} ({{{id}}})
|url=https://www.nomisweb.co.uk/sources/census_2021/report?compare={{{id}}}
|work=Nomis
|publisher={{#if:{{{fewer-links|}}}|Office for National Statistics|[[Office for National Statistics (United Kingdom)|Office for National Statistics]]}}
|access-date={{{access-date|{{{accessdate|}}} }}}
|ref={{{ref|{{SfnRef|{{{author|Census 2021}}}|{{{id}}} }} }}}
}}}}{{#if:{{{id|}}}||{{main other|[[Category:NOMIS2021 citations needing attention]]}}}}{{#if:{{{separator|}}}|{{main other|[[Category:NOMIS2021 citations needing attention]]}}|}}</includeonly><noinclude>
{{Documentation}}
<!-- PLEASE ADD THIS TEMPLATE'S CATEGORIES AND INTERWIKIS TO THE /doc SUBPAGE, THANKS -->
</noinclude>
hm1dbkdy5l5008xqx1brqrjzbfv6bu2
Template:NOMIS2001
10
52459
308425
2026-09-17T15:55:59Z
Isma4l
41797
Bog cusub: <includeonly>{{#if:{{{short|}}}|[https://www.nomisweb.co.uk/sources/census_2001_ks/report?compare={{{id}}} {{{id}}}]|{{Cite web |author={{{author|UK Census}}} |author-link={{#if:{{{fewer-links|}}}|<!--no link-->|{{#if:{{{author|}}}|{{{author-link|{{{authorlink|}}} }}}|2001 United Kingdom census}} }} |date={{{date|}}} |year=2001 |orig-year={{{orig-year|{{{origyear|}}} }}} |mode={{{mode|}}} |postscript={{{postscript|{{{ps|}}} }}} |title=Local Area Report – {{{title|}}} ({{{id}}})...
308425
wikitext
text/x-wiki
<includeonly>{{#if:{{{short|}}}|[https://www.nomisweb.co.uk/sources/census_2001_ks/report?compare={{{id}}} {{{id}}}]|{{Cite web
|author={{{author|UK Census}}}
|author-link={{#if:{{{fewer-links|}}}|<!--no link-->|{{#if:{{{author|}}}|{{{author-link|{{{authorlink|}}} }}}|2001 United Kingdom census}} }}
|date={{{date|}}}
|year=2001
|orig-year={{{orig-year|{{{origyear|}}} }}}
|mode={{{mode|}}}
|postscript={{{postscript|{{{ps|}}} }}}
|title=Local Area Report – {{{title|}}} ({{{id}}})
|url=https://www.nomisweb.co.uk/sources/census_2001_ks/report?compare={{{id}}}
|work=Nomis
|publisher={{#if:{{{fewer-links|}}}|Office for National Statistics|[[Office for National Statistics]]}}
|access-date={{{access-date|{{{accessdate|}}} }}}
|ref={{{ref|{{SfnRef|{{{author|Census 2001}}}|{{{id}}} }} }}}
}}}}{{#if:{{{id|}}}||{{main other|[[Category:NOMIS2001 citations needing attention]]}}}}{{#if:{{{separator|}}}|{{main other|[[Category:NOMIS2001 citations needing attention]]}}|}}</includeonly><noinclude>
{{Documentation}}
<!-- PLEASE ADD THIS TEMPLATE'S CATEGORIES AND INTERWIKIS TO THE /doc SUBPAGE, THANKS -->
</noinclude>
11q2ru61mk6uozajy4ac683fu8waviy
Template:GSA player
10
52460
308426
2026-09-17T15:57:10Z
Isma4l
41797
Bog cusub: {{#if: {{{1<includeonly>|</includeonly>}}} {{{id|}}} {{#property:P11963}} | {{#if: {{{access-date|{{{accessdate|{{{citation|}}}}}}}}} | {{cite web |url=https://globalsportsarchive.com/{{#if: {{{1|{{{id<includeonly>|</includeonly>}}}}}} | en/soccer/athlete/{{Trim|{{{1|{{{id}}}}}}}} | people/{{First word|1={{#property:P11963}}|sep=,}}/ }} |title={{#if: {{{2|{{{name<includeonly>|</includeonly>}}}}}} | {{{2|{{{name}}}}}} | {{PAGENAMEBASE}} }} |website=Global Sports Archive |acces...
308426
wikitext
text/x-wiki
{{#if: {{{1<includeonly>|</includeonly>}}} {{{id|}}} {{#property:P11963}}
| {{#if: {{{access-date|{{{accessdate|{{{citation|}}}}}}}}}
| {{cite web |url=https://globalsportsarchive.com/{{#if: {{{1|{{{id<includeonly>|</includeonly>}}}}}} | en/soccer/athlete/{{Trim|{{{1|{{{id}}}}}}}} | people/{{First word|1={{#property:P11963}}|sep=,}}/ }} |title={{#if: {{{2|{{{name<includeonly>|</includeonly>}}}}}} | {{{2|{{{name}}}}}} | {{PAGENAMEBASE}} }} |website=Global Sports Archive |access-date={{{access-date|{{{accessdate|}}}}}} }}
| [https://globalsportsarchive.com/{{#if: {{{1|{{{id<includeonly>|</includeonly>}}}}}} | en/soccer/athlete/{{Trim|{{{1|{{{id}}}}}}}} | people/{{First word|1={{#property:P11963}}|sep=,}}/ }} {{#if: {{{2|{{{name<includeonly>|</includeonly>}}}}}} | {{{2|{{{name}}}}}} | {{PAGENAMEBASE}} }}] at Global Sports Archive<includeonly>{{EditAtWikidata|pid=P11963|{{{1|{{{id|}}}}}}}}</includeonly>
}}{{#if: {{{1|}}} {{{id|}}} || {{#ifeq:{{NAMESPACENUMBER}}|0|[[Category:GSA player template using Wikidata]]}} }}
| <span class="error">{{[[Template:GSA player|GSA player]]}} template missing ID and not present in Wikidata.</span>{{#ifeq:{{NAMESPACENUMBER}}|0|[[Category:GSA player template missing ID and not in Wikidata]]}}
}}{{#invoke:Check for unknown parameters|check|unknown={{#ifeq:{{NAMESPACENUMBER}}|0|[[Category:Pages using GSA player template with unknown parameters|_VALUE_{{PAGENAME}}]]}}|preview=Page using [[Template:GSA player]] with unknown parameter "_VALUE_"|ignoreblank=y| 1 | 2 | id | name | access-date | accessdate | citation }}<noinclude>
{{Documentation}}
<!-- Please add categories to the /doc subpage. -->
</noinclude>
ji8nd9py0cfq3ad041uwb6c60wm5hyf
Template:Performance key/styles.css
10
52461
308427
2026-09-17T16:01:14Z
Isma4l
41797
Bog cusub: /* {{pp-template}} */ .tpl-performance-key { text-align: left; } .tpl-performance-key-w { color:black; background: #00ff00; } .tpl-performance-key-f { color:black; background: #D8BFD8 ; } .tpl-performance-key-sf { color:black; background: yellow; } .tpl-performance-key-qf { color:black; background: #ffebcd ; } .tpl-performance-key-hashr { color:black; background: #afeeee; } .tpl-performance-key-rr { color:black; background...
308427
sanitized-css
text/css
/* {{pp-template}} */
.tpl-performance-key {
text-align: left;
}
.tpl-performance-key-w {
color:black;
background: #00ff00;
}
.tpl-performance-key-f {
color:black;
background: #D8BFD8 ;
}
.tpl-performance-key-sf {
color:black;
background: yellow;
}
.tpl-performance-key-qf {
color:black;
background: #ffebcd ;
}
.tpl-performance-key-hashr {
color:black;
background: #afeeee;
}
.tpl-performance-key-rr {
color:black;
background: #afeeee;
}
.tpl-performance-key-qhash {
color:black;
background: inherit ;
}
.tpl-performance-key-phash {
color:black;
background: inherit;
}
.tpl-performance-key-dnq {
color:black;
background:inherit ;
}
.tpl-performance-key-a {
color:black;
background: inherit;
}
.tpl-performance-key-zhash {
color:black;
background: #ecf2ff;
}
.tpl-performance-key-po {
color:black;
background:#ecf2ff ;
}
.tpl-performance-key-g {
color:black;
background: gold;
}
.tpl-performance-key-s {
color:black;
background: silver;
}
.tpl-performance-key-b {
color:black;
background: #e5b47d ;
}
.tpl-performance-key-nms {
color:black;
background: inherit;
}
.tpl-performance-key-nti {
color:black;
background: inherit;
}
.tpl-performance-key-p {
color:black;
background: inherit;
}
.tpl-performance-key-nh {
color:black;
background: inherit;
}
2sdn1xwwn15ci74rcgwimh5pq3gixkk
Module:Adjacent stations/Amtrak
828
52462
308428
2026-09-17T16:02:48Z
Isma4l
41797
Bog cusub: local amtrak = "%1 station (Amtrak)" local al = "%1 station (Alabama)" local ar = "%1 station (Arkansas)" local az = "%1 station (Arizona)" local ca = "%1 station (California)" local cccr = "%1 station (CCCR)" local co = "%1 station (Colorado)" local ct = "%1 station (Connecticut)" local de = "%1 station (Delaware)" local fl = "%1 station (Florida)" local ga = "%1 station (Georgia)" local go = "%1 GO Station" local ia = "%1 station (Iowa)" local ind = "%1 station (Indiana)" local...
308428
Scribunto
text/plain
local amtrak = "%1 station (Amtrak)"
local al = "%1 station (Alabama)"
local ar = "%1 station (Arkansas)"
local az = "%1 station (Arizona)"
local ca = "%1 station (California)"
local cccr = "%1 station (CCCR)"
local co = "%1 station (Colorado)"
local ct = "%1 station (Connecticut)"
local de = "%1 station (Delaware)"
local fl = "%1 station (Florida)"
local ga = "%1 station (Georgia)"
local go = "%1 GO Station"
local ia = "%1 station (Iowa)"
local ind = "%1 station (Indiana)"
local il = "%1 station (Illinois)"
local ks = "%1 station (Kansas)"
local lou = "%1 station (Louisiana)"
local ma = "%1 station (Massachusetts)"
local marc = "%1 station (MARC)"
local md = "%1 station (Maryland)"
local me = "%1 station (Maine)"
local mi = "%1 station (Michigan)"
local mn = "%1 station (Minnesota)"
local mnrr = "%1 station (Metro-North)"
local mo = "%1 station (Missouri)"
local ms = "%1 station (Mississippi)"
local mt = "%1 station (Montana)"
local nc = "%1 station (North Carolina)"
local nd = "%1 station (North Dakota)"
local ne = "%1 station (Nebraska)"
local nh = "%1 station (New Hampshire)"
local njt = "%1 station (NJ Transit)"
local ny = "%1 station (New York)"
local nm = "%1 station (New Mexico)"
local nv = "%1 station (Nevada)"
local oh = "%1 station (Ohio)"
local ok = "%1 station (Oklahoma)"
local on = "%1 station (Ontario)"
local ore = "%1 station (Oregon)"
local pa = "%1 station (Pennsylvania)"
local ri = "%1 station (Rhode Island)"
local rtd = "%1 station (RTD)"
local sc = "%1 station (South Carolina)"
local septa = "%1 station (SEPTA)"
local septarr = "%1 station (SEPTA Regional Rail)"
local tc = "%1 Transportation Center"
local tx = "%1 station (Texas)"
local union = "Union Station (%1)"
local ut = "%1 station (Utah)"
local va = "%1 station (Virginia)"
local vt = "%1 station (Vermont)"
local wa = "%1 station (Washington)"
local wi = "%1 station (Wisconsin)"
local wv = "%1 station (West Virginia)"
local wy = "%1 station (Wyoming)"
local xunion = "%1 Union Station"
local p = {
["lang"] = "en-US",
["system title"] = "[[Amtrak]]",
["system icon"] = "[[File:BSicon LOGO Amtrak2.svg|20px|link=Amtrak]]",
["system color"] = "00537E",
["name format"] = {
"font-size: 160%; font-weight: bolder; color: #FFFFFF; background-color: #00537E; padding: 0.4em 4px;",
["Amtrak old"] = "font-size: 160%; font-family:Helvetica Neue, Helvetica; font-weight: bolder; color: #ffffff; background-color: #0078B9; padding: 0.4em 4px;"
},
["header text color"] = "FFFFFF",
["header background color"] = {
"00537E",
["Amtrak old"] = "0078B9",
},
["station format"] = {
"%1 station",
["16th Street"] = "[[16th Street station (Oakland)|Oakland]]",
["30th Street"] = "[[30th Street Station|Philadelphia–30th Street]]",
["52nd Street"] = septarr,
["Aberdeen"] = md,
["Akron"] = {
["Broadway Limited"] = amtrak,
["Three Rivers"] = amtrak,
["California Zephyr"] = co,
["Desert Wind"] = co,
["Pioneer"] = co,
},
["Albany"] = {
"[[Albany–Rensselaer station|Albany–Rensselaer]]",
["Cascades"] = ore,
["Coast Starlight"] = ore,
["Willamette Valley"] = ore,
},
["Albion"] = mi,
["Albuquerque"] = "Alvarado Transportation Center",
["Aldershot"] = go,
["Alexandria"] = xunion,
["Alton"] = il,
["Altoona"] = tc,
["Amherst"] = ma,
["Amsterdam"] = ny,
["Anaheim"] = "Anaheim Regional Transportation Intermodal Center",
["Antioch"] = "[[Antioch–Pittsburg station|Antioch–Pittsburg]]",
["Ardmore"] = {
pa,
["Heartland Flyer"] = ok,
["Lone Star"] = ok,
},
["Ashland"] = {
va,
["Cardinal"] = tc,
["James Whitcomb Riley"] = tc,
["James Whitcomb Riley and George Washington"] = tc,
},
["Athens"] = oh,
["Atlanta"] = "Peachtree station",
["Atlantic City"] = "Atlantic City Rail Terminal",
["Attleboro"] = ma,
["Auburn"] = ca,
["Aurora"] = tc,
["Austin"] = tx,
["BWI Airport"] = "BWI Rail Station",
["Boston"] = {
"[[South Station|Boston South]]",
["Downeaster"] = "[[North Station|Boston North]]"
},
["Back Bay"] = "[[Back Bay station|Boston Back Bay]]",
["Bakersfield"] = amtrak,
["Baltimore Airport"] = "BWI Rail Station",
["Baltimore"] = "Baltimore Penn Station",
["Bangor"] = mi,
["Barstow"] = "Barstow Harvey House",
["Battle Creek"] = tc,
["Baton Rouge"] = "Baton Rouge, Louisiana",
["Bedford"] = va,
["Belleville"] = amtrak,
["Bellingham"] = "Fairhaven Station",
["Berkeley"] = amtrak,
["Berlin"] = ct,
["Berwyn"] = septa,
["Bill Lee"] = "[[Chipley station|Chipley]]",
["Birmingham"] = {
al,
["Wolverine"] = mi,
},
["Black Rock"] = "Black Rock Rail Yard",
["Bloomington"] = "Bloomington station (Monon Railroad)",
["Bloomington–Normal"] = {
"Uptown Station",
["Floridian (1971–1979)"] = ind,
},
["Bloomington–Normal"] = "[[Uptown Station|Bloomington–Normal]]",
["Bloomington–Normal"] = "[[Uptown Station|Bloomington–Normal]]",
["Boise"] = "Boise Union Pacific Depot",
["Boston North"] = "North Station",
["Boston South"] = "South Station",
["Bowie"] = "Bowie Railroad Buildings",
["Bowling Green"] = "Bowling Green station (Louisville and Nashville Railroad)",
["Brampton"] = go,
["Brattleboro"] = "Union Station (Brattleboro, Vermont)",
["Bridgeport"] = ct,
["Brookhaven"] = "Godbold Transportation Center",
["Brunswick"] = {
md,
["Downeaster"] = me
},
["Bryan"] = oh,
["Bryn Mawr"] = septarr,
["Buffalo"] = "Buffalo–Depew station",
["Buffalo Central Terminal"] = "[[Buffalo Central Terminal|Buffalo]]",
["Burbank Airport"] = "[[Burbank Airport–South station|Hollywood Burbank Airport]]",
["Burlington"] = {
nc,
["California Zephyr"] = ia,
["Desert Wind"] = ia,
["Ethan Allen Express"] = "Union Station (Burlington, Vermont)",
["Maple Leaf"] = "Burlington GO Station",
["Pioneer"] = ia,
},
["Burlington West"] = "Burlington GO Station#History",
["Cambridge"] = {
mn,
["Northern Lights Express"] = "Cambridge, Minnesota"
},
["Camden"] = sc,
["Canton"] = {
oh,
["City of New Orleans"] = ms,
},
["Cary"] = nc,
["Castleton"] = vt,
["Centralia"] = {
il,
["Cascades"] = wa,
["Coast Starlight"] = wa,
["Pioneer"] = wa,
},
["Champaign-Urbana"] = "[[Illinois Terminal|Champaign–Urbana]]",
["Charleston"] = {
"North Charleston station",
["Cardinal"] = wv,
["James Whitcomb Riley"] = wv,
["James Whitcomb Riley and George Washington"] = wv,
},
["Charlotte"] = amtrak,
["Charlotte Gateway"] = "[[Charlotte Gateway Station|Gateway Station]]",
["Charlottesville"] = xunion,
["Chelsea"] = mi,
["Cherry Hill"] = njt,
["Chester"] = "Chester Transit Center",
["Cheyenne"] = "Cheyenne Depot Museum",
["Chicago (Central Station)"] = "[[Central Station (Chicago terminal)|Chicago–Central]]",
["Chicago"] = xunion,
["Chillicothe"] = {
il,
["Shenandoah"] = oh,
},
["Chillicothe, IL"] = "[[Chillicothe station (Illinois)|Chillicothe]]",
["Cincinnati"] = "Cincinnati Union Terminal",
["Cincinnati River Road"] = "[[Cincinnati River Road station|Cincinnati (River Road)]]",
["Claremont"] = nh,
["Clearwater"] = amtrak,
["Cleburne"] = "Cleburne Intermodal Transportation Depot",
["Cleveland Union Terminal"] = "[[Tower City Center#Cleveland Union Terminal|Cleveland]]",
["Cleveland"] = "Cleveland Lakefront Station",
["Clinton"] = ct,
["Colonel Allensworth State Historic Park"] = "Colonel Allensworth State Historic Park#Amtrak station",
["Colonie–Schenectady"] = "Schenectady station#History",
["Columbia"] = sc,
["Columbus"] = {
"Columbus station",
["National Limited"] = "Union Station (Columbus, Ohio)",
},
["Commerce"] = ca,
["Crestview"] = {
ct,
["Sunset Limited"] = "Crestview station (Florida)",
},
["Cumberland"] = md,
["Dallas"] = xunion,
["Davis"] = ca,
["Dayton"] = "Dayton Union Station",
["DC"] = "[[Washington Union Station|Washington]]",
["Dearborn"] = "John D. Dingell Transit Center",
["Decatur"] = {
il,
["Floridian (1971–1979)"] = "Decatur station (Southern Railway)",
},
["Del Mar"] = "Solana Beach station#Former Amtrak station at Del Mar",
["Delray Beach"] = {
"%1 station",
["Floridian (1971–1979)"] = "Delray Beach station (Seaboard Air Line Railroad)",
},
["Delta"] = ut,
["Denver"] = xunion,
["Depew"] = "Buffalo–Depew station",
["Detroit (MC)"] = "[[Michigan Central Station|Detroit (Michigan Central)]]",
["Dover"] = tc,
["Dubuque"] = {
["Black Hawk"] = "Dubuque Intermodal Transportation Center",
["Black Hawk (1974–1981)"] = "Dubuque station",
},
["Duluth"] = "Duluth Depot",
["Dundas"] = "Dundas station (Dundas, Ontario)",
["Dunkirk"] = ny,
["Durand"] = xunion,
["Durham"] = {
nc,
["Downeaster"] = "[[Durham–UNH station|Durham–UNH]]",
},
["East Lansing"] = "Capital Area Multimodal Gateway",
["East Lyme"] = "Niantic station",
["East Syracuse"] = "[[William F. Walsh Regional Transportation Center#History|Syracuse]]",
["Edgewood"] = marc,
["Edmonds"] = wa,
["Edmondson"] = "West Baltimore station#Edmondson",
["El Paso"] = "Union Depot (El Paso)",
["Elgin"] = il,
["Elmhurst"] = amtrak,
["Enfield"] = ct,
["Englewood"] = "Englewood station (Chicago)",
["Erie"] = "Union Station (Erie, Pennsylvania)",
["Essex"] = mt,
["Eureka"] = amtrak,
["Eugene"] = amtrak,
["Eugene-Springfield"] = "[[Eugene station (Amtrak)|Eugene]]",
["Eugene–Springfield"] = "[[Eugene station (Amtrak)|Eugene]]",
["Evanston"] = wy,
["Everett"] = "Everett Station",
["Evergreen"] = al,
["Exeter"] = nh,
["Exton"] = pa,
["Flint"] = mi,
["Florence"] = sc,
["Forsyth"] = mt,
["Fort Madison"] = {
"Atchison, Topeka and Santa Fe Passenger and Freight Complex Historic District",
["Lone Star"] = "Fort Madison station (1968–2021)",
},
["Fort Worth"] = {
"Fort Worth Central Station",
["Inter-American"] = "Fort Worth Union Depot (1900–2002)",
["Lone Star"] = "Fort Worth Union Depot (1900–2002)",
},
["Freeport"] = {
me,
["Black Hawk"] = il,
["Black Hawk (1974–1981)"] = il,
},
["Fremont-Centerville"] = "[[Fremont station|Fremont]]",
["Fresno"] = "Santa Fe Passenger Depot (Fresno, California)",
["Fullerton"] = tc,
["Gainesville"] = {
fl,
["Crescent"] = ga,
["Piedmont"] = ga,
["Heartland Flyer"] = tx,
["Lone Star"] = tx,
},
["Galesburg (SF)"] = "[[Galesburg station (Atchison, Topeka and Santa Fe Railway)|Galesburg (SF Depot)]]",
["Garden City"] = ks,
["Gary"] = {
"Gary station (Pennsylvania Railroad)",
["Cardinal"] = "Gary station (Miller and Lake Streets)",
},
["Georgetown"] = go,
["Glasgow"] = mt,
["Glendale"] = tc,
["Grafton"] = wv,
["Grand Forks (GN)"] = "[[Great Northern Freight Warehouse and Depot|Grand Forks (GN Depot)]]",
["Grand Rapids"] = "Vernon J. Ehlers Station",
["Greenfield"] = "John W. Olver Transit Center",
["Greensboro"] = "J. Douglas Galyon Depot",
["Greenwood"] = ms,
["Green River"] = {
ut,
["City of San Francisco"] = wy,
["Pioneer"] = wy,
["San Francisco Zephyr"] = wy,
},
["Groton"] = ct,
["Guelph"] = "Guelph Central Station",
["Hamilton"] = oh,
["Hammond"] = lou,
["Hancock"] = wv,
["Harrisburg"] = tc,
["Hartford"] = xunion,
["Hastings"] = ne,
["Haverhill"] = ma,
["Hayward"] = amtrak,
["Helena"] = "Helena Railroad Depot Historic District",
["Hermann"] = mo,
["Hillsborough"] = nc,
["Hinkle"] = "Hinkle Locomotive Service and Repair Facility",
["Hinton"] = wv,
["Hobart"] = ind,
["Holland"] = mi,
["Hollywood Burbank Airport"] = "[[Burbank Airport–South station|Hollywood Burbank Airport]]",
["Hollywood"] = fl,
["Hope"] = ar,
["Houston (Union Station)"] = "[[Union Station (Houston)|Houston–Union Station]]",
["Houston"] = tx,
["Hudson"] = ny,
["Huntingdon"] = amtrak,
["Huntington"] = amtrak,
["Hyannis"] = "Hyannis Transportation Center",
["Indianapolis"] = xunion,
["Irvine"] = tc,
["Jackson"] = {
mi,
["City of New Orleans"] = "Union Station (Jackson, Mississippi)",
["Crescent"] = "Union Station (Jackson, Mississippi)",
},
["Jamestown"] = nd,
["Joliet Union Station"] = "[[Joliet Union Station|Joliet (Union Station)]]",
["Joliet"] = "Joliet Gateway Center",
["Kalamazoo"] = tc,
["Kansas City"] = xunion,
["Kelso"] = "Kelso Multimodal Transportation Center",
["Kelso–Longview"] = "Kelso Multimodal Transportation Center",
["Kensington"] = md,
["King City"] = "King City Multimodal Transportation Center",
["Kingston"] = ri,
["Kirkwood"] = mo,
["Lafayette"] = {
ind,
["Sunset Limited"] = lou,
},
["La Grande"] = "La Grande station (Union Pacific Railroad)",
["La Grange"] = "LaGrange Road station",
["Lake City"] = fl,
["Lamar"] = amtrak,
["Lambert's Point"] = "[[Lambert's Point#station|Norfolk]]",
["Lancaster"] = pa,
["Laramie"] = wy,
["Las Vegas"] = {
nm,
["Desert Wind"] = "Las Vegas Union Plaza station",
["Las Vegas Limited"] = "Las Vegas Union Plaza station",
},
["Laurel"] = ms,
["Lawrence"] = ks,
["Leavenworth"] = "Icicle Station",
["Lee Hall"] = "Lee Hall Depot",
["Levittown–Tullytown"] = "Levittown station",
["Lexington"] = nc,
["Lima"] = "Lima station (Pennsylvania Railroad)",
["Lincoln"] = {
il,
["California Zephyr"] = ne,
["Desert Wind"] = "Lincoln station (Nebraska, 1926–2012)",
["Pioneer"] = "Lincoln station (Nebraska, 1926–2012)",
},
["Lincoln, NE (CB&Q)"] = "[[Lincoln station (Nebraska, 1926–2012)|Lincoln (CB&Q Depot)]]",
["Little Rock"] = xunion,
["Livingston"] = "Livingston Depot",
["Lodi"] = "Lodi Transit Station",
["Lompoc-Surf"] = "Lompoc–Surf station",
["London"] = on,
["Lorton"] = "Lorton station (Auto Train)",
["Los Angeles"] = "Los Angeles Union Station",
["Louisville"] = union,
["Lovelock"] = "Lovelock station",
["Lynchburg"] = "Kemper Street station",
["Madera (SF)"] = "[[Storey station|Madera (SF Station)]]",
["Madera"] = amtrak,
["Madison"] = {
ct,
["Sunset Limited"] = fl,
},
["Malton"] = go,
["Malvern"] = {
ar,
["Keystone Service"] = septa,
},
["Marceline"] = "Walt Disney Hometown Museum",
["Marion"] = amtrak,
["Marshall"] = tx,
["Marysville"] = ca,
["McKeesport"] = tc,
["Memphis"] = "Memphis Central Station",
["Merced"] = amtrak,
["Merced (CAHSR)"] = "[[Merced station (California High-Speed Rail)|Merced]]",
["Meriden"] = "Meriden Transit Center",
["Meridian"] = "Union Station (Meridian, Mississippi)",
["Merion"] = septa,
["Miami"] = amtrak,
["Middletown"] = pa,
["Midway"] = "[[Midway station (Minnesota)|Saint Paul–Midway]]",
["Milford"] = "Union Pacific Railroad Depot (Milford, Utah)",
["Milwaukee Airport"] = "Milwaukee Airport Railroad Station",
["Milwaukee"] = "Milwaukee Intermodal Station",
["Mineola"] = {
tx,
["Northeast Regional"] = "Mineola station (LIRR)",
["Empire Service"] = "Mineola station (LIRR)",
},
["Minneapolis"] = "Minneapolis Great Northern Depot",
["Minneapolis Target Field"] = "Target Field station",
["Missoula"] = "Missoula station (Northern Pacific Railway)",
["Mobile"] = amtrak,
["Monroe"] = lou,
["Montgomery"] = {
"Montgomery Union Station",
["Cardinal"] = wv,
},
["Montpelier"] = vt,
["Montreal"] = "Montreal Central Station",
["Montreal old"] = "[[Windsor Station (Montreal)|Montreal]]",
["Montreal West"] = "Montréal-Ouest station",
["Morris"] = mn,
["Mount Joy"] = pa,
["Mount Pleasant"] = ia,
["Mount Vernon"] = "Skagit Station",
["Munice"] = "Cincinnati, Richmond, & Muncie Depot (Muncie, Indiana)",
["Mystic"] = ct,
["Narberth"] = septa,
["Nashville"] = union,
["Natomas/Sacramento Airport"] = "[[Natomas/Sacramento Airport station|Natomas/Sacramento Airport]]",
["Needles"] = "El Garces Intermodal Transportation Facility",
["New Buffalo (PM)"] = "[[New Buffalo station|New Buffalo (PM Depot)]]",
["New Haven"] = union,
["New London"] = xunion,
["New Orleans"] = "New Orleans Union Passenger Terminal",
["New York (Grand Central)"] = "Grand Central Terminal",
["New York"] = "New York Penn Station",
["New York City"] = "New York Penn Station",
["Newark Airport"] = "Newark Liberty International Airport Station",
["Newark, Delaware"] = "Newark station (Delaware)",
["Newark, New Jersey"] = "[[Newark Penn Station|Newark Penn]]",
["Newark, NJ"] = "[[Newark Penn Station|Newark Penn]]",
["Newark Penn"] = "[[Newark Penn Station|Newark Penn]]",
["Newbern"] = "Newbern Depot",
["Newport"] = ar,
["Newport News"] = {
tc,
["Acela Regional"] = "Newport News station",
["Colonial"] = "Newport News station",
["Twilight Shoreliner"] = "Newport News station",
["George Washington"] = "Newport News station",
["James Whitcomb Riley"] = "Newport News station",
["James Whitcomb Riley and George Washington"] = "Newport News station",
},
["Newport News old"] = "[[Newport News station|Newport News]]",
["Newton"] = ks,
["Niagara Falls (former)"] = "[[Niagara Falls station (New York, 1978–2016)|Niagara Falls, New York]]",
["Niagara Falls, New York"] = "Niagara Falls station (New York)",
["Niagara Falls, Ontario"] = "Niagara Falls station (Ontario)",
["Norfolk"] = {
amtrak,
["Mountaineer"] = "Lambert's Point#station",
},
["Normal"] = "Uptown Station",
["North Haven"] = ct,
["North Kingston"] = "Wickford Junction station",
["Northampton"] = "Union Station (Northampton, Massachusetts)",
["Oakland"] = {
"Oakland–Jack London Square station",
["Shenandoah"] = md,
["West Virginian"] = md,
},
["Oakland – Jack London Square"] = "[[Oakland–Jack London Square station|Oakland–Jack London Square]]",
["Oakland 16th Street"] = "[[16th Street station (Oakland)|Oakland-16th Street]]",
["Oakley"] = ca,
["Oakville"] = go,
["Ocala"] = xunion,
["Oceanside"] = "Oceanside Transit Center",
["Ogden"] = "Union Station (Ogden, Utah)",
["Okeechobee"] = amtrak,
["Oklahoma City"] = "Santa Fe Depot (Oklahoma City)",
["Old Town San Diego"] = "[[Old Town Transit Center|San Diego–Old Town]]",
["San Diego–Old Town"] = "[[Old Town Transit Center|San Diego–Old Town]]",
["Olympia–Lacey"] = "Centennial Station",
["Omaha (CB&Q)"] = "[[Omaha station (Chicago, Burlington and Quincy Railroad)|Omaha (CB&Q Depot)]]",
["Ontario"] = {
amtrak,
["Pioneer"] = ore,
},
["Orange"] = ca,
["Orlando"] = "Orlando Health/Amtrak station",
["Oxford"] = oh,
["Oxnard"] = "Oxnard Transit Center",
["Pajaro/Watsonville"] = "[[Pajaro/Watsonville station|Pajaro/Watsonville]]",
["Pasadena"] = "Del Mar station",
["Pasco"] = "Pasco Intermodal Train Station",
["Pensacola"] = amtrak,
["Perry"] = ok,
["Petersburg (Union Station)"] = "[[Union Station (Petersburg)|Petersburg–Union Station]]",
["Philadelphia"] = "30th Street Station",
["Philadelphia-Suburban"] = "[[Suburban Station|Philadelphia-Suburban]]",
["Philadelphia International Airport"] = "Airport Terminal stations (SEPTA)",
["Phoenix"] = "Union Station (Phoenix, Arizona)",
["Pittsburgh"] = union,
["Pittsfield"] = "Joseph Scelsi Intermodal Transportation Center",
["Plano"] = il,
["Pocatello"] = "Union Pacific Railroad Depot (Pocatello, Idaho)",
["Pomona"] = {
"[[Pomona–Downtown station|Pomona]]",
["Desert Wind"] = "Pomona–North station",
["Las Vegas Limited"] = "Pomona–North station",
["Southwest Chief"] = "Pomona–North station",
["Southwest Limited"] = "Pomona–North station",
["Super Chief"] = "Pomona–North station",
},
["Pontiac"] = {
il,
["Lake Cities"] = tc,
["Wolverine"] = tc,
["Michigan"] = tc,
},
["Portland"] = {
"Portland Union Station",
["Downeaster"] = tc,
},
["Princeton"] = il,
["Providence (Union Station)"] = "[[Union Station (Providence)|Providence–Union Station]]",
["Provo"] = amtrak,
["Pueblo"] = "Union Depot (Pueblo, Colorado)",
["Quincy"] = amtrak,
["Radnor"] = septarr,
["Raleigh"] = xunion,
["Randolph"] = vt,
["Rawlins"] = "Union Pacific Railroad Depot (Rawlins, Wyoming)",
["Redding"] = ca,
["Richmond"] = {
ca,
["Cardinal"] = "Richmond station (Chesapeake and Ohio Railway)",
["James Whitcomb Riley"] = "Richmond station (Chesapeake and Ohio Railway)",
["Mountaineer"] = "Richmond station (Chesapeake and Ohio Railway)",
["National Limited"] = "Richmond Railroad Station Historic District",
},
["Richmond Main Street"] = "[[Richmond Main Street Station|Richmond–Main Street]]",
["Richmond-Broad Street"] = "[[Broad Street Station (Richmond)|Richmond–Broad Street]]",
["Riverbank"] = "[[Gold Runner|Riverbank]]",
["Riverside"] = "[[Riverside–Downtown station|Riverside]]",
["Rochester"] = "Louise M. Slaughter Rochester Station",
["Rome"] = ny,
["Rosemont"] = septa,
["Rosenberg"] = tx,
["Roseville"] = ca,
["Royal Oak"] = mi,
["Rugby"] = nd,
["Rye"] = mnrr,
["Saco"] = tc,
["Sacramento"] = "Sacramento Valley Station",
["City College"] = "City College station (Sacramento)",
["Sacramento City College"] = "[[City College station (Sacramento)|City College]]",
["Saint Paul"] = "Saint Paul Union Depot",
["Salem"] = ore,
["Salinas"] = "Salinas Intermodal Transportation Center",
["Salisbury"] = nc,
["Salt Lake City (D&RGW)"] = "[[Denver and Rio Grande Western Depot (Salt Lake City)|Salt Lake City (D&RGW Depot)]]",
["Salt Lake City (UP)"] = "[[Salt Lake City Union Pacific Depot|Salt Lake City (UP Depot)]]",
["Salt Lake City"] = "Salt Lake City Intermodal Hub",
["San Antonio"] = tx,
["San Antonio-Sunset"] = "[[San Antonio station (Texas)#Sunset Station|San Antonio-Sunset]]",
["San Bernardino"] = "San Bernardino Santa Fe Depot",
["San Clemente"] = "[[San Clemente Pier station|San Clemente]]",
["San Diego Old Town"] = "[[Old Town Transit Center|San Diego–Old Town]]",
["San Diego Sorrento Valley"] = "[[Sorrento Valley station|San Diego–Sorrento Valley]]",
["San Diego"] = "Santa Fe Depot (San Diego)",
["San Joaquin Street"] = "[[San Joaquin Street station|Stockton–San Joaquin Street]]",
["San Jose"] = "San Jose Diridon station",
["Sandwich"] = ma,
["Sanford (ACL)"] = "[[Sanford Atlantic Coast Line Station|Sanford (ACL Depot)]]",
["Sanford"] = amtrak,
["Santa Ana"] = "Santa Ana Regional Transportation Center",
["Santa Clara"] = "[[Santa Clara Transit Center|Santa Clara–University]]",
["Santa Clarita"] = "Newhall station",
["Savannah"] = amtrak,
["Seattle"] = "King Street Station",
["Selma"] = "Selma Union Depot",
["Shreveport"] = amtrak,
["Silver Spring"] = "Silver Spring station (Baltimore and Ohio Railroad)",
["Spokane"] = "Spokane Intermodal Center",
["Springfield"] = {
"Springfield Union Station (Massachusetts)",
["Abraham Lincoln"] = il,
["Inter-American"] = il,
["Lincoln Service"] = il,
["Loop"] = il,
["Texas Eagle"] = il,
},
["St. Albans"] = vt,
["St. Louis (Union Station)"] = "[[St. Louis Union Station|St. Louis–Union Station]]",
["St. Louis"] = "Gateway Transportation Center",
["St. Marys"] = on,
["St. Paul"] = "Saint Paul Union Depot",
["St. Petersburg"] = amtrak,
["St. Thomas"] = "Canada Southern Railway Station",
["Stamford"] = tc,
["Stanley"] = nd,
["Stockton"] = "[[Robert J. Cabral Station|Stockton–Downtown]]",
["Stockton–Downtown"] = "[[Robert J. Cabral Station|Stockton–Downtown]]",
["Stockton–San Joaquin Street"] = "[[San Joaquin Street station|Stockton–San Joaquin Street]]",
["Stony Creek"] = ct,
["Stratford"] = on,
["Suburban Station"] = "[[Suburban Station|Philadelphia–Suburban]]",
["Suffolk"] = va,
["Summit"] = il,
["Superior"] = {
"[[Superior Union Station|Superior]]",
["Northern Lights Express"] = "Superior, Wisconsin",
},
["Surf"] = "[[Lompoc–Surf station|Lompoc–Surf]]",
["Syracuse"] = "William F. Walsh Regional Transportation Center",
["Tacoma (Union Station)"] = "[[Union Station (Tacoma, Washington)|Tacoma–Union Station]]",
["Tacoma Dome"] = "Tacoma Dome Station",
["Tacoma"] = "[[Tacoma station (1984)|Tacoma]]",
["Tampa"] = xunion,
["Taunton"] = amtrak,
["Tempe"] = az,
["Temple"] = tx,
["Texarkana"] = xunion,
["Thomasville"] = "Thomasville Depot (Georgia)",
["Thompson"] = "Green River station (Utah)#History",
["Toledo"] = "Martin Luther King Jr. Plaza (Toledo)",
["Toronto"] = union,
["Trenton"] = "Trenton Transit Center",
["Tri-State"] = "Catlettsburg station",
["Trinidad"] = co,
["Troy"] = "Troy Transit Center",
["Utica"] = "Union Station (Utica, New York)",
["Vancouver, British Columbia"] = "Pacific Central Station",
["Vancouver, Washington"] = "Vancouver station (Washington)",
["Victorville"] = "Victor Valley Transportation Center",
["Wallingford"] = ct,
["Wareham"] = "Wareham Village station",
["Warren"] = il,
["Warsaw"] = ind,
["Washington, DC"] = "[[Washington Union Station|Washington, D.C.]]",
["Washington, D.C."] = "[[Washington Union Station|Washington, D.C.]]",
["Washington, Missouri"] = "[[Washington station (Missouri)|Washington]]",
["Waterbury"] = vt,
["Waterloo"] = ind,
["Wells"] = "Wells Regional Transportation Center",
["Wellesley"] = "Wellesley Square station",
["Wenatchee"] = "Columbia Station (Washington)",
["Westminster"] = "Downtown Westminster station",
["Westport"] = ny,
["Westwood"] = "[[Route 128 station|Westwood Route 128]]",
["Wheeler"] = ind,
["Whiting"] = "Whiting station (Pennsylvania Railroad)",
["Wichita"] = "Union Station (Wichita, Kansas)",
["Williamsburg"] = tc,
["Wilmington"] = de,
["Wilson"] = nc,
["Windsor"] = {
ct,
["Niagara Rainbow"] = "Windsor station (Michigan Central Railroad)",
["Vermonter"] = vt,
["Wolverine"] = on,
},
["Winona"] = {
"Winona station",
["City of New Orleans"] = ms,
},
["Winslow"] = az,
["Woburn"] = "Anderson Regional Transportation Center",
["Woodbridge"] = va,
["Woodstock"] = on,
["Worcester"] = "Union Station (Worcester, Massachusetts)",
["Youngstown"] = "Youngstown station (Baltimore and Ohio Railroad)",
["Ypsilanti"] = "Michigan Executive",
["Yuma"] = az,
},
["lines"] = {
["_default"] = {
["title"] = "''[[%1]]''",
["color"] = "00537E",
},
["Abraham Lincoln"] = {
["title"] = "''[[Abraham Lincoln (train)|Abraham Lincoln]]''",
["color"] = "0078B9",
["left terminus"] = "St. Louis (Union Station)",
["right terminus"] = "Chicago",
},
["Acela"] = {
["title"] = "''[[Acela]]''",
["color"] = "00B5E2",
["left terminus"] = "Washington, D.C.",
["right terminus"] = "Boston South",
},
["Acela Commuter"] = {
["title"] = "''[[Clocker (train)|Acela Commuter]]''",
["left terminus"] = "Philadelphia",
["right terminus"] = "New York,"
},
["Acela Express"] = {
["title"] = "''[[Acela]]''",
["color"] = "00b5e2",
["left terminus"] = "Washington, D.C.",
["right terminus"] = "Boston South",
},
["Acela Regional"] = {
["title"] = "''[[Northeast Regional#History|Acela Regional]]''",
["left terminus"] = "Newport News",
["right terminus"] = "Boston South,"
},
["Adirondack"] = {
["title"] = "''[[Adirondack (train)|Adirondack]]''",
["left terminus"] = "Montreal",
["right terminus"] = "New York",
},
["Ann Rutledge"] = {
["title"] = "''[[Ann Rutledge (train)|Ann Rutledge]]''",
["left terminus"] = "Kansas City",
["right terminus"] = "St. Louis",
},
["Arrowhead"] = {
["title"] = "''[[Arrowhead (train)|Arrowhead]]''",
["color"] = "0078B9",
["left terminus"] = "Duluth",
["right terminus"] = "Minneapolis",
},
["Atlantic City Express"] = {
["title"] = "''[[Atlantic City Express (Amtrak train)|Atlantic City Express]]''",
["color"] = "0078B9",
["left terminus"] = {"Richmond Staples Mill Road", "Harrisburg", "Springfield"},
["right terminus"] = "Atlantic City",
},
["Auto Train"] = {
["left terminus"] = "Sanford",
["right terminus"] = "Lorton",
},
["Badger"] = {
["title"] = "''[[Hiawatha (Amtrak train)|Badger]]''",
["color"] = "0078B9",
},
["Bankers"] = {
["title"] = "''[[Bankers (train)|Bankers]]''",
["color"] = "0078B9",
},
["Bay State"] = {
["title"] = "''[[New Haven–Springfield Line|Bay State]]''",
["color"] = "0078B9",
["left terminus"] = "Philadelphia",
["right terminus"] = "Boston South",
},
["Beacon Hill"] = {
["title"] = "''[[Beacon Hill (train)|Beacon Hill]]''",
["color"] = "0078B9",
["left terminus"] = "New Haven",
["right terminus"] = "Boston South",
},
["Berkshire Flyer"] = {
["title"] = "''[[Berkshire Flyer]]''",
["left terminus"] = "Pittsfield",
["right terminus"] = "New York",
},
["Big Apple"] = {
["title"] = "''[[Keystone Service#Through service|Big Apple]]''",
["color"] = "0078B9",
},
["Black Hawk"] = {
["title"] = "''[[Black Hawk (Amtrak train)|Black Hawk]]''",
["left terminus"] = "Rockford",
["right terminus"] = "Chicago",
},
["Black Hawk (1974–1981)"] = {
["title"] = "''[[Black Hawk (Amtrak train)|Black Hawk]]''",
["color"] = "0078B9",
["left terminus"] = "Dubuque",
["right terminus"] = "Chicago",
["note-mid"] = "1974–1981",
},
["Blue Ridge"] = {
["title"] = "''[[Blue Ridge (train)|Blue Ridge]]''",
["color"] = "0078B9",
["left terminus"] = "Martinsburg",
["right terminus"] = "Washington, D.C.",
["note-mid"] = "1973–1986",
},
["Blue Water"] = {
["title"] = "''[[Blue Water (train)|Blue Water]]''",
["left terminus"] = "Chicago",
["right terminus"] = "Port Huron",
},
["Borealis"] = {
["title"] = "''[[Borealis (train)|Borealis]]''",
["left terminus"] = "St. Paul",
["right terminus"] = "Chicago",
},
["Broadway Limited"] = {
["color"] = "0078B9",
["left terminus"] = "Chicago",
["right terminus"] = "New York",
},
["California Zephyr"] = {
["left terminus"] = "Emeryville",
["right terminus"] = "Chicago",
},
["California Zephyr (1983–1994)"] = {
["title"] = "''[[California Zephyr]]''",
["color"] = "0078B9",
["left terminus"] = "Oakland 16th Street",
["right terminus"] = "Chicago",
},
["Calumet"] = {
["title"] = "''[[Calumet (train)|Calumet]]''",
["color"] = "0078B9",
["left terminus"] = "Chicago",
["right terminus"] = "Valparaiso",
},
["Campus"] = {
["title"] = "''[[Campus (train)|Campus]]''",
["color"] = "0078B9",
["left terminus"] = "Champaign-Urbana",
["right terminus"] = "Chicago (Central Station)",
},
["Cape Codder"] = {
["title"] = "''[[Cape Codder (train)|Cape Codder]]''",
["color"] = "0078B9",
["left terminus"] = "New York",
["right terminus"] = "Hyannis",
},
["Capitol Corridor"] = {
["color"] = "1C1B4D",
["left terminus"] = "San Jose",
["right terminus"] = "Auburn",
},
["Capitol Limited"] = {
["left terminus"] = "Chicago",
["right terminus"] = "Washington, D.C.",
},
["Capitols (1991–1998)"] = {
["title"] = "''[[Capitol Corridor|Capitols]]''",
["color"] = "FFC709",
["left terminus"] = "San Jose",
["right terminus"] = "Roseville",
},
["Cardinal"] = {
["title"] = "''[[Cardinal (train)|Cardinal]]''",
["left terminus"] = "Chicago",
["right terminus"] = "New York",
},
["Carolina Special"] = {
["title"] = "''[[Carolina Special (Amtrak train)|Carolina Special]]''",
["color"] = "0078B9",
["left terminus"] = "Jacksonville",
["right terminus"] = "New York",
},
["Carolinian"] = {
["title"] = "''[[Carolinian (train)|Carolinian]]''",
["left terminus"] = "Charlotte",
["right terminus"] = "New York",
},
["Cascades"] = {
["title"] = "[[Amtrak Cascades|Amtrak ''Cascades'']]",
["color"] = "223832",
["left terminus"] = "Eugene",
["right terminus"] = "Vancouver, British Columbia",
},
["Champion"] = {
["title"] = "''[[Champion (train)|Champion]]''",
["color"] = "0078B9",
["left terminus"] = "St. Petersburg",
["right terminus"] = "New York",
},
["Charter Oak"] = {
["title"] = "''[[Colonial (Amtrak train)|Charter Oak]]''",
["color"] = "0078B9",
},
["Chesapeake"] = {
["title"] = "''[[Chesapeake (train)|Chesapeake]]''",
["color"] = "0078B9",
["left terminus"] = "Washington, D.C.",
["right terminus"] = "Suburban Station",
},
["Chesapeake Virginia"] = {
["title"] = "''[[Colonial (Amtrak train)|Chesapeake]]''",
["color"] = "0078B9",
},
["Chief"] = {
["title"] = "''[[Chief (train)|Chief]]''",
["color"] = "0078B9",
["left terminus"] = "Los Angeles",
["right terminus"] = "Chicago",
},
["City of New Orleans"] = {
["title"] = "''[[City of New Orleans (train)|City of New Orleans]]''",
["left terminus"] = "New Orleans",
["right terminus"] = "Chicago",
},
["City of San Francisco"] = {
["title"] = "''[[City of San Francisco (train)|City of San Francisco]]''",
["color"] = "0078B9",
["left terminus"] = "Oakland 16th Street",
["right terminus"] = "Chicago",
},
["Clamdigger"] = {
["title"] = "''[[Clamdigger (train)|Clamdigger]]''",
["color"] = "0078B9",
["left terminus"] = "New Haven",
["right terminus"] = "New London",
},
["Clocker"] = {
["title"] = "''[[Clocker (train)|Clocker]]''",
["left terminus"] = "Philadelphia",
["right terminus"] = "New York,"
},
["Coast Starlight"] = {
["left terminus"] = "Los Angeles",
["right terminus"] = "Seattle",
},
["CoCo"] = {
["title"] = "[[Colorado Connector]]",
["note-mid"] = "Opening 2029",
["color"] = "F26D3D",
["left terminus"] = "Denver Union Station",
["right terminus"] = "Fort Collins",
["types"] = {
["Pueblo"] = {
["title"] = "Phase II",
["note-mid"] = "Opening 2032",
["left terminus"] = "Pueblo",
["right terminus"] = "Fort Collins",
},
},
},
["Colonial"] = {
["title"] = "''[[Colonial (Amtrak train)|Colonial]]''",
["color"] = "0078B9",
["left terminus"] = "Newport News",
["right terminus"] = "Boston South",
},
["Colonial (PRR)"] = {
["title"] = "''[[Colonial (PRR train)|Colonial]]''",
["color"] = "0078B9",
},
["Connecticut Valley Service"] = {
["title"] = "''[[Amtrak Hartford Line|Connecticut Valley Service]]''",
["color"] = "0078B9",
["left terminus"] = "New Haven",
["right terminus"] = "Springfield",
},
["Crescent"] = {
["title"] = "''[[Crescent (train)|Crescent]]''",
["left terminus"] = "New Orleans",
["right terminus"] = "New York",
},
["Desert Wind"] = {
["color"] = "0078B9",
["left terminus"] = "Los Angeles",
["right terminus"] = "Chicago",
},
["Downeaster"] = {
["title"] = "''[[Downeaster (train)|Downeaster]]''",
["left terminus"] = "Boston North",
["right terminus"] = "Brunswick",
},
["Duquesne"] = {
["title"] = "''[[Pennsylvanian (train)|Duquesne]]''",
["color"] = "0078B9",
},
["Eagle"] = {
["title"] = "''[[Texas Eagle|Eagle]]''",
["color"] = "0078B9",
},
["El Capitan"] = {
["title"] = "''[[El Capitan (train)|El Capitan]]''",
["color"] = "0078B9",
},
["Empire Builder"] = {
["left terminus"] = {"Seattle", "Portland"},
["right terminus"] = "Chicago",
},
["Empire Builder (1971-1981)"] = {
["title"] = "''[[Empire Builder]]''",
["color"] = "0078B9",
["left terminus"] = "Seattle",
["right terminus"] = "Chicago",
},
["Empire Service"] = {
["left terminus"] = "Niagara Falls, New York",
["right terminus"] = "New York",
},
["Encore"] = {
["title"] = "''[[Hiawatha Service|Encore]]''",
["color"] = "0078B9",
},
["Ethan Allen Express"] = {
["left terminus"] = "Burlington",
["right terminus"] = "New York",
},
["Executive Sleeper"] = {
["title"] = "''[[Night Owl (train)|Executive Sleeper]]''",
["color"] = "0078B9",
},
["Expo '74"] = {
["title"] = "''[[Expo '74 (train)|Expo '74]]''",
["color"] = "0078B9",
["left terminus"] = "Seattle",
["right terminus"] = "Spokane",
},
["Fast Mail"] = {
["title"] = "''[[Fast Mail (Amtrak train)|Fast Mail]]''",
["left terminus"] = "Washington, D.C.",
["right terminus"] = "Boston or Springfield",
},
["Federal"] = {
["title"] = "''[[Twilight Shoreliner|Federal]]''",
["color"] = "0078B9",
["left terminus"] = "Washington, D.C.",
["right terminus"] = "Boston South",
},
["Floridian"] = {
["title"] = "''[[Floridian (train)|Floridian]]''",
["left terminus"] = "Miami",
["right terminus"] = "Chicago",
},
["Floridian (1971–1979)"] = {
["title"] = "''[[Floridian (train, 1971–1979)|Floridian]]''",
["color"] = "0078B9",
["left terminus"] = {"St. Petersburg", "Miami"},
["right terminus"] = "Chicago",
["types"] = {
["Miami"] = {
["title"] = "",
["left terminus"] = "Miami",
["right terminus"] = "Chicago",
},
["St. Petersburg"] = {
["title"] = "",
["left terminus"] = "St. Petersburg",
["right terminus"] = "Chicago",
},
},
},
["Florida Special"] = {
["title"] = "''[[Florida Special (train)|Florida Special]]''",
["color"] = "0078B9",
},
["Fort Pitt"] = {
["title"] = "''[[Fort Pitt (train)|Fort Pitt]]''",
["color"] = "0078B9",
["left terminus"] = "Pittsburgh",
["right terminus"] = "Altoona",
},
["George Washington"] = {
["title"] = "''[[George Washington (train)|George Washington]]''",
["color"] = "0078B9",
["left terminus"] = "Chicago",
["right terminus"] = {"Washington, D.C.", "Newport News"},
},
["Gold Runner"] = {
["title"] = "''[[Gold Runner]]''",
["color"] = "0096CE",
["left terminus"] = {"Oakland", "Sacramento"},
["right terminus"] = "Bakersfield",
},
["Gotham Limited"] = {
["title"] = "''[[Colonial (Amtrak train)|Gotham Limited]]''",
["color"] = "0078B9",
},
["Gulf Breeze"] = {
["title"] = "''[[Gulf Breeze (train)|Gulf Breeze]]''",
["color"] = "0078B9",
["left terminus"] = "Mobile",
["right terminus"] = "Birmingham",
},
["Gulf Coast Limited"] = {
["title"] = "''[[Gulf Coast Limited]]''",
["color"] = "0078B9",
["left terminus"] = "New Orleans",
["right terminus"] = "Mobile",
},
["Hartford"] = {
["title"] = "[[Amtrak Hartford Line|''Hartford Line'']]",
["left terminus"] = "New Haven",
["right terminus"] = "Springfield",
},
["Heartland Flyer"] = {
["left terminus"] = "Fort Worth",
["right terminus"] = "Oklahoma City",
},
["Hiawatha (1971-1977)"] = {
["title"] = "''[[Borealis (train)#History|Hiawatha]]''",
["color"] = "0078B9",
},
["Hiawatha"] = {
["title"] = "''[[Hiawatha (Amtrak train)|Hiawatha]]''",
["left terminus"] = "Milwaukee",
["right terminus"] = "Chicago",
},
["Hilltopper"] = {
["title"] = "''[[Hilltopper (train)|Hilltopper]]''",
["color"] = "0078B9",
["left terminus"] = "Tri-State",
["right terminus"] = "Boston South",
},
["Hoosier State"] = {
["title"] = "''[[Hoosier State (train)|Hoosier State]]''",
["left terminus"] = "Chicago",
["right terminus"] = "Indianapolis",
},
["Illini and Saluki"] = {
["title"] = "[[Illini and Saluki|''Illini'' and ''Saluki'']]",
["left terminus"] = "Carbondale",
["right terminus"] = "Chicago",
},
["Illini (Central)"] = {
["title"] = "[[Illini and Saluki|''Illini'']]",
["color"] = "0078B9",
["left terminus"] = "Champaign-Urbana",
["right terminus"] = "Chicago",
},
["Illinois Zephyr and Carl Sandburg"] = {
["title"] = "[[Illinois Zephyr and Carl Sandburg|''Illinois Zephyr'' and ''Carl Sandburg'']]",
["left terminus"] = "Quincy",
["right terminus"] = "Chicago",
},
["Illinois Zephyr old"] = {
["title"] = "[[Illinois Zephyr and Carl Sandburg|''Illinois Zephyr'']]",
["left terminus"] = "Quincy",
["right terminus"] = "Chicago",
},
["Inter-American"] = {
["title"] = "''[[Inter-American (train)|Inter-American]]''",
["color"] = "0078B9",
["left terminus"] = {"Laredo", "Houston"},
["right terminus"] = "Chicago",
},
["International"] = {
["title"] = "''[[International (Amtrak train)|International]]''",
["left terminus"] = "Chicago",
["right terminus"] = "Toronto",
},
["International (1982–1990)"] = {
["title"] = "''[[International (Amtrak train)|International]]''",
["color"] = "0078B9",
["left terminus"] = "Chicago",
["right terminus"] = "Toronto",
},
["James River"] = {
["title"] = "''[[Colonial (Amtrak train)|James River]]''",
["color"] = "0078B9",
},
["James Whitcomb Riley"] = {
["title"] = "''[[James Whitcomb Riley (train)|James Whitcomb Riley]]''",
["color"] = "0078B9",
["left terminus"] = "Chicago",
["right terminus"] = {"Washington, D.C.", "Newport News"},
},
["James Whitcomb Riley and George Washington"] = {
["title"] = "''[[James Whitcomb Riley (train)|James Whitcomb Riley]] and [[George Washington (train)|George Washington]]''",
["color"] = "0078B9",
["left terminus"] = "Chicago",
["right terminus"] = {"Washington, D.C.", "Newport News"},
},
["Kentucky Cardinal"] = {
["left terminus"] = "Chicago",
["right terminus"] = "Louisville",
},
["Keystone"] = {
["title"] = "''[[Pennsylvanian (train)#History|Keystone]]''",
["color"] = "0078B9",
["left terminus"] = "Pittsburgh",
["right terminus"] = "New York",
},
["Keystone (1971-1972)"] = {
["title"] = "''[[Pennsylvanian (train)|Keystone]]''",
["color"] = "0078B9",
},
["Keystone Executive"] = {
["title"] = "''[[Keystone Service#Declining service|Keystone Executive]]''",
["color"] = "0078B9",
},
["Keystone Service"] = {
["left terminus"] = "Harrisburg",
["right terminus"] = "New York",
},
["Keystone State Express"] = {
["title"] = "''[[Keystone Service#Through service|Keystone State Express]]''",
["color"] = "0078B9",
},
["Lake Cities"] = {
["title"] = "''[[Lake Cities (Amtrak train)|Lake Cities]]''",
["left terminus"] = "Chicago",
["right terminus"] = "Pontiac",
},
["Lake Cities (1980–1995)"] = {
["title"] = "''[[Lake Cities (Amtrak train)|Lake Cities]]''",
["color"] = "0078B9",
["left terminus"] = "Chicago",
["right terminus"] = "Toledo",
},
["Lake Country Limited"] = {
["left terminus"] = "Janesville",
["right terminus"] = "Chicago",
},
["Lake Shore"] = {
["title"] = "''[[Lake Shore Limited#Lake Shore|Lake Shore]]''",
["color"] = "0078B9",
["left terminus"] = "Chicago",
["right terminus"] = "New York (Grand Central)",
},
["Lake Shore Limited"] = {
["left terminus"] = "Chicago",
["right terminus"] = {"New York", "Boston South"},
},
["LaSalle"] = {
["title"] = "''[[Hiawatha (Amtrak train)|LaSalle]]''",
["color"] = "0078B9",
},
["Las Vegas Limited"] = {
["color"] = "0078B9",
["left terminus"] = "Los Angeles",
["right terminus"] = "Las Vegas",
},
["Loop"] = {
["title"] = "''[[Loop (Amtrak train)|Loop]]''",
["color"] = "0078B9",
["left terminus"] = "Springfield",
["right terminus"] = "Chicago",
},
["Limited"] = {
["title"] = "''[[Alton Limited|Limited]]''",
["color"] = "0078B9",
},
["Lincoln Service"] = {
["left terminus"] = "St. Louis",
["right terminus"] = "Chicago",
},
["Lone Star"] = {
["title"] = "''[[Lone Star (Amtrak train)|Lone Star]]''",
["color"] = "0078B9",
["left terminus"] = {"Dallas", "Houston"},
["right terminus"] = "Chicago",
},
["Manhattan Express"] = {
["title"] = "''[[Colonial (Amtrak train)|Manhattan Express]]''",
["color"] = "0078B9",
},
["Mardi Gras Service"] = {
["title"] = "''[[Mardi Gras Service]]''",
["left terminus"] = "New Orleans",
["right terminus"] = "Mobile",
},
["Maple Leaf"] = {
["title"] = "''[[Maple Leaf (train)|Maple Leaf]]''",
["left terminus"] = "Toronto",
["right terminus"] = "New York",
},
["Marquette"] = {
["title"] = "''[[Hiawatha (Amtrak train)|Marquette]]''",
["color"] = "0078B9",
},
["Merchants"] = {
["title"] = "''[[Merchants Limited|Merchants]]''",
["color"] = "0078B9",
},
["Merchants Limited"] = {
["title"] = "''[[Merchants Limited]]''",
["color"] = "0078B9",
},
["Meteor"] = {
["title"] = "''[[Champion (train)#Amtrak|Meteor]]''",
["color"] = "0078B9",
["left terminus"] = {"St. Petersburg", "Miami"},
["right terminus"] = "Boston South",
},
["Metroliner"] = {
["title"] = "''[[Metroliner (train)|Metroliner]]''",
["left terminus"] = "Washington, D.C.",
["right terminus"] = "New York",
},
["Miamian"] = {
["title"] = "''[[Vacationer (train)|Miamian]]''",
["color"] = "0078B9",
},
["Michigan Executive"] = {
["color"] = "0078B9",
["left terminus"] = "Jackson",
["right terminus"] = "Detroit (MC)",
},
["Missouri River Runner"] = {
["left terminus"] = "Kansas City",
["right terminus"] = "St. Louis",
},
["Montrealer"] = {
["title"] = "''[[Montrealer (train)|Montrealer]]''",
["color"] = "0078B9",
["left terminus"] = "Washington, D.C.",
["right terminus"] = "Montreal",
},
["Mount Rainier"] = {
["title"] = "''[[Amtrak Cascades#History|Mount Rainier]]''",
["color"] = "0078B9",
["left terminus"] = "Eugene",
["right terminus"] = "Seattle",
},
["Mountaineer"] = {
["title"] = "''[[Mountaineer (Amtrak train)|Mountaineer]]''",
["color"] = "0078B9",
["left terminus"] = "Chicago",
["right terminus"] = "Norfolk",
},
["Mountain Rail"] = {
["title"] = "''[[Winter Park Express#Future plans|Mountain Rail]]''",
["left terminus"] = "Craig",
["right terminus"] = "Denver",
},
["National Limited"] = {
["title"] = "''[[National Limited (Amtrak train)|National Limited]]''",
["color"] = "0078B9",
["left terminus"] = "Kansas City",
["right terminus"] = {"New York", "Washington, D.C."},
},
["New England Express"] = {
["title"] = "''[[Colonial (Amtrak train)|New England Express]]''",
["color"] = "0078B9",
},
["New Orleans–Baton Rouge passenger rail"] = {
["title"] = "[[New Orleans–Baton Rouge passenger rail|New Orleans–Baton Rouge]]",
["left terminus"] = "Baton Rouge",
["right terminus"] = "New Orleans",
},
["Niagara Rainbow"] = {
["color"] = "0078B9",
["left terminus"] = "Detroit (MC)",
["right terminus"] = "New York (Grand Central)",
},
["Nicollet"] = {
["title"] = "''[[Hiawatha (Amtrak train)|Nicollet]]''",
["color"] = "0078B9",
},
["Night Owl"] = {
["title"] = "''[[Night Owl (train)|Night Owl]]''",
["color"] = "0078B9",
["left terminus"] = "Washington, D.C.",
["right terminus"] = "Boston South",
},
["North Coast Hiawatha"] = {
["color"] = "0078B9",
["left terminus"] = "Seattle",
["right terminus"] = "Chicago",
},
["Northern Lights Express"] = {
["color"] = "78BE21",
["left terminus"] = "Duluth",
["right terminus"] = "Minneapolis Target Field",
},
["North Star"] = {
["title"] = "''[[North Star (Amtrak train)|North Star]]''",
["color"] = "0078B9",
["left terminus"] = "Duluth",
["right terminus"] = {"Chicago", "Midway"},
},
["Northeast Corridor"] = {
["title"] = "[[Northeast Corridor]]",
["color"] = "0078B9",
["left terminus"] = "Washington, D.C.",
["right terminus"] = "Boston South",
},
["Northeast Regional"] = {
["left terminus"] = {"Norfolk", "Newport News", "Roanoke"},
["right terminus"] = {"Boston South", "Springfield"},
["types"] = {
["Newport News or Roanoke"] = {
["title"] = "",
["left terminus"] = {"Newport News", "Roanoke"},
["right terminus"] = {"Boston South", "Springfield"},
},
["Norfolk or Newport News"] = {
["title"] = "",
["left terminus"] = {"Norfolk", "Newport News"},
["right terminus"] = {"Boston South", "Springfield"},
},
["Norfolk or Roanoke"] = {
["title"] = "",
["left terminus"] = {"Norfolk", "Roanoke"},
["right terminus"] = {"Boston South", "Springfield"},
},
},
},
["Old Dominion"] = {
["title"] = "''[[Colonial (Amtrak train)|Old Dominion]]''",
["color"] = "0078B9",
},
["Orange County Commuter"] = {
["title"] = "''[[Orange County Line|Orange County Commuter]]''",
["color"] = "0078B9",
["left terminus"] = "Los Angeles",
["right terminus"] = "San Juan Capistrano",
},
["Pacific International"] = {
["title"] = "''[[Pacific International]]''",
["color"] = "0078B9",
["left terminus"] = "Seattle",
["right terminus"] = "Vancouver, British Columbia",
},
["Pacific Surfliner"] = {
["color"] = "003C5B",
["left terminus"] = "San Luis Obispo",
["right terminus"] = "San Diego",
},
["Palmetto"] = {
["title"] = "''[[Palmetto (train)|Palmetto]]''",
["left terminus"] = "Savannah",
["right terminus"] = "New York",
},
["Panama Limited"] = {
["title"] = "''[[Panama Limited]]''",
["color"] = "0078B9",
["left terminus"] = "New Orleans",
["right terminus"] = "Chicago (Central Station)",
},
["Pennsylvanian"] = {
["title"] = "''[[Pennsylvanian (train)|Pennsylvanian]]''",
["left terminus"] = "Pittsburgh",
["right terminus"] = "New York",
},
["Pere Marquette"] = {
["title"] = "''[[Pere Marquette (Amtrak train)|Pere Marquette]]''",
["left terminus"] = "Chicago",
["right terminus"] = "Grand Rapids",
},
["Piedmont"] = {
["title"] = "''[[Piedmont (train)|Piedmont]]''",
["left terminus"] = "Charlotte",
["right terminus"] = "Raleigh",
},
["Pioneer"] = {
["title"] = "''[[Pioneer (train)|Pioneer]]''",
["color"] = "0078B9",
["left terminus"] = "Seattle",
["right terminus"] = "Chicago",
},
["Potomac"] = {
["title"] = "''[[Colonial (Amtrak train)|Potomac]]''",
["color"] = "0078B9",
},
["Prairie Marksman"] = {
["title"] = "''[[Prairie Marksman]]''",
["left terminus"] = "East Peoria",
["right terminus"] = "Chicago",
["color"] = "0078B9",
},
["Prairie State"] = {
["title"] = "''[[Prairie State (Amtrak)|Prairie State]]''",
["color"] = "0078B9",
},
["Quad Cities"] = {
["title"] = "''[[Quad Cities (train)|Quad Cities]]''",
["left terminus"] = "Moline",
["right terminus"] = "Chicago",
["note-mid"] = "Proposed",
},
["Radisson"] = {
["title"] = "''[[Hiawatha (Amtrak train)|Radisson]]''",
["color"] = "0078B9",
},
["River Cities"] = {
["title"] = "''[[River Cities (train)|River Cities]]''",
["color"] = "0078B9",
["left terminus"] = "New Orleans",
["right terminus"] = "Kansas City",
},
["San Diegan"] = {
["title"] = "''[[San Diegan (train)|San Diegan]]''",
["color"] = "0078B9",
["left terminus"] = "Los Angeles",
["right terminus"] = "San Diego",
},
["San Francisco Zephyr"] = {
["color"] = "0078B9",
["left terminus"] = "Oakland 16th Street",
["right terminus"] = "Chicago",
},
["San Joaquin (1974–1994)"] = {
["title"] = "''[[Gold Runner#History|San Joaquins]]''",
["color"] = "0078B9",
["left terminus"] = "Oakland 16th Street",
["right terminus"] = "Bakersfield",
},
["San Joaquin (1994–1996)"] = {
["title"] = "''[[Gold Runner#History|San Joaquins]]''",
["color"] = "FFC709",
["left terminus"] = "Emeryville",
["right terminus"] = "Bakersfield",
},
["San Joaquin (1996–2002)"] = {
["title"] = "''[[Gold Runner#History|San Joaquins]]''",
["color"] = "FFC709",
["left terminus"] = "Oakland",
["right terminus"] = "Bakersfield",
},
["San Joaquins (1999–2025)"] = {
["title"] = "''[[Gold Runner#History|San Joaquins]]''",
["color"] = "1EB1D2",
["left terminus"] = {"Oakland", "Sacramento"},
["right terminus"] = "Bakersfield",
},
["Shawnee"] = {
["title"] = "''[[Shawnee (train)|Shawnee]]''",
["color"] = "0078B9",
["left terminus"] = "Carbondale",
["right terminus"] = "Chicago",
},
["Shenandoah"] = {
["title"] = "''[[Shenandoah (Amtrak train)|Shenandoah]]''",
["color"] = "0078B9",
["left terminus"] = "Cincinnati River Road",
["right terminus"] = "Washington, D.C.",
},
["Silver Meteor"] = {
["left terminus"] = "Miami",
["right terminus"] = "New York",
},
["Silver Palm (1982–1985)"] = {
["title"] = "''[[Silver Palm (train)|Silver Palm]]''",
["color"] = "0078B9",
["left terminus"] = "Miami",
["right terminus"] = "Tampa",
},
["Silver Palm (1996–2002)"] = {
["title"] = "''[[Palmetto (train)#History|Silver Palm]]''",
["left terminus"] = "Miami",
["right terminus"] = "New York",
},
["Silver Star"] = {
["title"] = "''[[Silver Star (Amtrak train)|Silver Star]]''",
["left terminus"] = "Miami",
["right terminus"] = "New York",
},
["Silverliner Service"] = {
["color"] = "0078B9",
["left terminus"] = "Harrisburg",
["right terminus"] = "Suburban Station",
},
["Southwest Chief"] = {
["left terminus"] = "Los Angeles",
["right terminus"] = "Chicago",
},
["Southwest Limited"] = {
["title"] = "''[[Southwest Chief|Southwest Limited]]''",
["color"] = "0078B9",
["left terminus"] = "Los Angeles",
["right terminus"] = "Chicago",
},
["South Wind"] = {
["title"] = "''[[South Wind (train)|South Wind]]''",
["color"] = "0078B9",
},
["Spirit of California"] = {
["color"] = "0078B9",
["left terminus"] = "Los Angeles",
["right terminus"] = "Sacramento",
},
["Spirit of St. Louis"] = {
["title"] = "''[[Spirit of St. Louis (train)|Spirit of St. Louis]]''",
["color"] = "0078B9",
},
["State House"] = {
["title"] = "''[[State House (train)|State House]]''",
["left terminus"] = "St. Louis",
["right terminus"] = "Chicago",
},
["St. Clair"] = {
["title"] = "''[[Lake Cities (Amtrak train)|St. Clair]]''",
["color"] = "0078B9",
},
["Sunset Limited"] = {
["left terminus"] = "Los Angeles",
["right terminus"] = "New Orleans",
["types"] = {
["East"] = {
["title"] = "",
["left terminus"] = "Los Angeles",
["right terminus"] = {"Orlando", "Miami"},
},
},
},
["Super Chief"] = {
["color"] = "0078B9",
["left terminus"] = "Los Angeles",
["right terminus"] = "Chicago",
},
["Super Chief/El Capitan"] = {
["title"] = "''[[Super Chief]]''/''[[El Capitan (train)|El Capitan]]''",
["color"] = "0078B9",
},
["Susquehanna"] = {
["title"] = "''[[Keystone Service#Through service|Susquehanna]]''",
["color"] = "0078B9",
},
["Texas Eagle"] = {
["left terminus"] = {"Los Angeles", "San Antonio"},
["right terminus"] = "Chicago",
},
["Three Rivers"] = {
["title"] = "''[[Three Rivers (train)|Three Rivers]]''",
["left terminus"] = "Chicago",
["right terminus"] = "New York",
},
["Tidewater"] = {
["title"] = "''[[Colonial (Amtrak train)|Tidewater]]''",
["color"] = "0078B9",
},
["Tidewater Express"] = {
["title"] = "''[[Colonial (Amtrak train)|Tidewater Express]]''",
["color"] = "0078B9",
},
["Turboliner"] = {
["title"] = "''[[Turboliner#Service|Turboliner]]''",
["color"] = "0078B9",
},
["Twilight Limited"] = {
["left terminus"] = "Chicago",
["right terminus"] = "Pontiac",
},
["Twilight Shoreliner"] = {
["title"] = "''[[Twilight Shoreliner]]''",
["color"] = "0078B9",
["left terminus"] = "Newport News",
["right terminus"] = "Boston South",
},
["Twin Cities Hiawatha"] = {
["title"] = "''[[Borealis (train)#History|Twin Cities Hiawatha]]''",
["color"] = "0078B9",
["left terminus"] = {"Minneapolis", "Midway"},
["right terminus"] = "Chicago",
},
["Vacationer"] = {
["title"] = "''[[Vacationer (train)|Vacationer]]''",
["color"] = "0078B9",
["left terminus"] = "Miami",
["right terminus"] = "New York",
},
["Valley Forge"] = {
["title"] = "''[[Keystone Service#Through service|Valley Forge]]''",
["color"] = "0078B9",
["left terminus"] = "Harrisburg",
["right terminus"] = "New York",
["types"] = {
["weekends only"] = {
["title"] = "1974-1975, weekends only",
["right terminus"] = "Boston South",
},
},
},
["Valley Flyer"] = {
["title"] = "''[[Valley Flyer]]''",
["left terminus"] = "New Haven",
["right terminus"] = "Greenfield",
},
["Vermonter"] = {
["title"] = "''[[Vermonter (train)|Vermonter]]''",
["left terminus"] = "Washington, D.C.",
["right terminus"] = "St. Albans",
},
["Virginian"] = {
["title"] = "''[[Colonial (Amtrak train)|Virginian]]''",
["color"] = "0078B9",
},
["Washington Executive"] = {
["title"] = "''[[Night Owl (train)|Washington Executive]]''",
["color"] = "0078B9",
},
["Weekender"] = {
["title"] = "''[[Lincoln Service|Weekender]]''",
["color"] = "0078B9",
},
["Weekend Metroliner"] = {
["title"] = "''[[Metroliner (train)|Weekend Metroliner]]''",
["color"] = "0078B9",
},
["West Virginian"] = {
["title"] = "''[[West Virginian (Amtrak train)|West Virginian]]''",
["color"] = "0078B9",
["left terminus"] = "Parkersburg",
["right terminus"] = "Washington, D.C.",
["note-mid"] = "1971–1973",
},
["Willamette Valley"] = {
["title"] = "''[[Willamette Valley (train)|Willamette Valley]]''",
["color"] = "0078B9",
["left terminus"] = "Eugene",
["right terminus"] = "Portland",
},
["Winter Park Express"] = {
["left terminus"] = "Fraser–Winter Park",
["right terminus"] = "Denver",
},
["Wolverine"] = {
["title"] = "''[[Wolverine (train)|Wolverine]]''",
["left terminus"] = "Chicago",
["right terminus"] = "Pontiac",
},
-- For generic system display on station layouts using rail color box
["Amtrak"] = {
["title"] = "[[Amtrak]]",
},
},
["aliases"] = {
["amtrak cascades"] = "Cascades",
["amtrak hartford line"] ="Hartford",
["carl sandburg"] = "Illinois Zephyr and Carl Sandburg",
["carl sandburg/illinois zephyr"] = "Illinois Zephyr and Carl Sandburg",
["hartford line"] ="Hartford",
["hiawatha service"] = "Hiawatha",
["hiawatha (1971-1974)"] = "Hiawatha (1971-1977)",
["illini"] = "Illini and Saluki",
["illini/saluki"] = "Illini and Saluki",
["illinois zephyr"] = "Illinois Zephyr and Carl Sandburg",
["illinois zephyr/carl sandburg"] = "Illinois Zephyr and Carl Sandburg",
["international limited"] = "International",
["international (1982-1990)"] = "International (1982–1990)",
["new haven–springfield shuttle"] = "Hartford",
["new haven-springfield shuttle"] = "Hartford",
["regional"] = "Northeast Regional",
["saluki"] = "Illini and Saluki",
["saluki/illini"] = "Illini and Saluki",
["san joaquin"] = "Gold Runner",
["san joaquins"] = "Gold Runner",
["shuttle"] = "Hartford Line",
["black hawk (1974-1981)"] = "Black Hawk (1974–1981)",
["california zephyr (1983-1994)"] = "California Zephyr (1983–1994)",
["capitols (1991-1998)"] = "Capitols (1991–1998)",
["lake cities (1980-1995)"] = "Lake Cities (1980–1995)",
["san joaquin (1974-1994)"] = "San Joaquin (1974–1994)",
["san joaquin (1994-1996)"] = "San Joaquin (1994–1996)",
["san joaquin (1996-2002)"] = "San Joaquin (1996–2002)",
["silver palm (1982-1985)"] = "Silver Palm (1982–1985)",
["silver palm (1996-2002)"] = "Silver Palm (1996–2002)",
["northern lights express"] = "Northern Lights Express",
["baton rouge"] = "New Orleans–Baton Rouge passenger rail",
["great river"] = "Borealis",
["tcmc"] = "Borealis",
},
}
return p
qec8xb0tqhp94u8nj5282zloiklk3sd
Module:Adjacent stations
828
52463
308429
2026-09-17T16:03:57Z
Isma4l
41797
Bog cusub: require('strict') local p = {} local lang = 'en-GB' -- local default language -- Below these comments: Internationalization table -- How to translate this module (for languages without variants): -- • Characters inside single and double quotation marks are called strings. -- The strings in this i18n table are used as output. -- • Strings within square brackets are keys. -- • Strings are concatenated (joined) with two dots. -- • Set the string after «local lang =» t...
308429
Scribunto
text/plain
require('strict')
local p = {}
local lang = 'en-GB' -- local default language
-- Below these comments: Internationalization table
-- How to translate this module (for languages without variants):
-- • Characters inside single and double quotation marks are called strings.
-- The strings in this i18n table are used as output.
-- • Strings within square brackets are keys.
-- • Strings are concatenated (joined) with two dots.
-- • Set the string after «local lang =» to your language's code.
-- Change the first key after "i18n" (usually "en-GB") to the same thing.
-- • For each string which is not inside a function, translate it directly.
-- • Strings with keys named "format" are Lua regular expressions.
-- «()» is a match; «.+» means all characters; «%s+» means all spaces.
-- • For each string which is concatenated to the variable «var»,
-- translate the phrase assuming that «var» will be a noun.
-- • Remove any unnecessary translations.
local i18n = require("Module:Adjacent stations/i18n")
local function getData(system, verify)
if verify then
local title = mw.title.new('Module:Adjacent stations/' .. system -- .. '/sandbox'
)
if not (title and title.exists) then return nil end
end
return require('Module:Adjacent stations/' .. system -- .. '/sandbox'
)
end
local function getLine(data, lineN)
if lineN then
if data['aliases'] then
lineN = data['aliases'][mw.ustring.lower(lineN)] or lineN
end
local default = data['lines']['_default'] or {}
local line = data['lines'][lineN] or {}
for k, v in pairs(default) do
if v then line[k] = line[k] or v end
end
line['title'] = line['title'] and mw.ustring.gsub(line['title'], '%%1', lineN)
return line, lineN
end
end
local function getColor(data, system, line, Type, frame)
if system then
if line then return frame:expandTemplate{ title = system .. ' color', args = {line, ['branch'] = Type} } end
return frame:expandTemplate{ title = system .. ' color' }
else
line = (getLine(data, line))
local default = data['lines']['_default']
if line or default then
default = default or {}
if not line then line = mw.clone(default) end
local color = line['color'] or line['background color'] or default['color'] or default['background color'] or data['system color']
local Type_value = Type and line['types'] and (line['types'][Type] and line['types'][Type]['color'])
if Type_value then color = Type_value end
return color
end
return (default and (default['color'] or default['background color']) or data['system color'] or '')
end
end
local lineN, typeN
local function somethingMissing(name, key, formats)
local formatKeys = {}
for k in pairs(formats) do
table.insert(formatKeys, k)
end
return name .. ' was "' .. key .. '" but neither an entry for it nor a default was found. Choices were: ' .. table.concat(formatKeys, ', ')
end
local function getStation(station, _Format)
if type(_Format) == 'table' then
local lineNformats = _Format
_Format = lineNformats[lineN] or lineNformats[1]
if not _Format then
error(somethingMissing('lineN', lineN, lineNformats))
elseif type(_Format) == 'table' then
local typeNformats = _Format
_Format = typeNformats[typeN] or typeNformats[1]
if not _Format then
error(somethingMissing('typeN', typeN, typeNformats))
end
end
end
if typeN then _Format = mw.ustring.gsub(_Format, '%%3', typeN) end
if lineN then _Format = mw.ustring.gsub(_Format, '%%2', lineN) end
return (mw.ustring.match(_Format, '%[%[.+%]%]')) and (mw.ustring.gsub(_Format, '%%1', station)) or table.concat({'[[', mw.ustring.gsub(_Format, '%%1', station), '|', station, ']]'})
end
local function getTerminusText(var, Format)
local function subst(var1, var2)
-- var1 is the terminus or table of termini; var2 is the key for the table of termini
return type(var1) == 'string' and getStation(var1, (Format[var1] or Format[1]))
or type(var1) == 'table' and #var1 > 0 and getStation(var1[var2], (Format[var1[var2]] or Format[1]))
or ''
end
if Format then
if type(var) == 'string' then
return subst(var)
elseif type(var) == 'table' and #var > 0 then
local t = {subst(var, 1)}
for i = 2, #var - 1 do
t[i] = i18n[lang]['comma'](subst(var, i))
end
if #var > 1 then t[#var] = i18n[lang]['or'](subst(var, #var)) end
if var['via'] then
if i18n[lang]['via-first'] then
table.insert(t, 1, i18n[lang]['via'](subst(var, 'via')))
else
table.insert(t, i18n[lang]['via'](subst(var, 'via')))
end
end
return table.concat(t)
else
return ''
end
else
return var or ''
end
end
function p._main(_args) -- Arguments are processed here instead of the main function
local yesno = require('Module:Yesno')
local trimq = require('Module:Trim quotes')._trim
local boolean = {
['oneway-left'] = true,
['oneway-right'] = true,
['reverse'] = true,
['reverse-left'] = true,
['reverse-right'] = true
}
local args = {} -- Processed arguments
local index = {} -- A list of addresses corresponding to number suffixes in the arguments
for k, v in pairs(_args) do -- Maps each raw argument to processed arguments by string matching
_args[k] = v:match('^%s*(.-)%s*$')
if _args[k] and _args[k] ~= '' then
local a = mw.ustring.match(k, '^(.*%D)%d+$') or k -- The parameter; address 1 can be omitted
local b = tonumber(mw.ustring.match(k, '^.*%D(%d+)$')) or 1 -- The address for a given argument; address 1 can be omitted
if boolean[a] then
v = yesno(v)
end
if not args[b] then
args[b] = {[a] = v}
table.insert(index, b)
elseif args[b][a] then
return error(i18n[lang]['error_duplicate'](a .. b))
else
args[b][a] = v
end
end
end
table.sort(index)
local function small(s, italic)
return italic and '<div class="isA">' .. s .. '</div>'
or '<div class="smA">' .. s .. '</div>'
end
local style = { -- Style for each cell type
['header cell'] = 'class="hcA"|',
['header midcell'] = 'colspan="3" class="hmA"|',
['body cell'] = 'class="bcA"|',
['body banner'] = 'class="bbA notheme" style="color:inherit;background-color:#',
}
local function rgb(var)
if var:len() == 3 then
return {tonumber(var:sub(1, 1), 16) * 17, tonumber(var:sub(2, 2), 16) * 17, tonumber(var:sub(2, 2), 16) * 17}
elseif var:len() == 6 then
return {tonumber(var:sub(1, 2), 16), tonumber(var:sub(3, 4), 16), tonumber(var:sub(5, 6), 16)}
end
return {}
end
local data = {} -- A table of data modules for each address
local noclearclass = (((_args.noclear or '') ~= '') and ' adjacent-stations-noclear' or '')
local wikitable = {'{| class="wikitable adjacent-stations' .. noclearclass .. '"'}
for i, v in ipairs(index) do
-- If an address has a system argument, indexes the data module
data[v] = args[v]['system'] and getData(args[v]['system'])
-- If an address has no system, the row uses data from the previous address
or data[index[i - 1]]
or (args[v]['header'] and getData(args[index[i+1]]['system']))
or error(i18n[lang]['error_unknown'](args[v]['system']))
local lang = data[v]['lang'] or lang
if args[v]['system'] and not args[v]['hide-system'] then -- Header row
local stop_noun = data[v]['header stop noun'] or i18n[lang]['stop_noun']
table.insert(wikitable, table.concat({'\n|-',
'\n! scope="col" ', style['header cell'], i18n[lang]['preceding'](stop_noun),
'\n! scope="col" ', style['header midcell'], (data[v]['system icon'] and data[v]['system icon'] .. ' ' or ''), (data[v]['system title'] or ('[['.. args[v]['system'] ..']]')),
'\n! scope="col" ', style['header cell'], i18n[lang]['following'](stop_noun)
}))
table.insert(wikitable, '')
table.insert(wikitable, '')
table.insert(wikitable, '')
end
if args[v]['header'] then -- Subheader
table.insert(wikitable, '\n|-\n!colspan="5" class="hmA"|'.. args[v]['header'])
table.insert(wikitable, '')
table.insert(wikitable, '')
table.insert(wikitable, '')
end
if args[v]['line'] or args[v]['left'] or args[v]['right'] or args[v]['nonstop'] then
if not args[v]['line'] and i > 1 and not args[v]['system'] then
args[v]['line'] = args[index[i - 1]]['line']
end
lineN = args[v]['line'] or '_default'
typeN = args[v]['type']
if data[v]['aliases'] then
lineN = data[v]['aliases'][mw.ustring.lower(lineN)] or lineN
if typeN then typeN = data[v]['aliases'][mw.ustring.lower(typeN)] or typeN end
end
-- get the line table
local line = data[v]['lines'] and (mw.clone(data[v]['lines'][lineN]) or error(i18n[lang]['error_unknown'](args[v]['line']))) or error(i18n[lang]['error_line'])
local default = data[v]['lines']['_default'] or {}
line['title'] = line['title'] or default['title'] or ''
line['title'] = mw.ustring.gsub(line['title'], '%%1', lineN)
-- cell across row for non-stop service
if args[v]['nonstop'] then
table.insert(wikitable,
table.concat({'\n|-\n|colspan="5" ',
style['body cell'],
((args[v]['nonstop'] == 'former') and i18n[lang]['nonstop_past'] or i18n[lang]['nonstop_present'])(p._box({data = data[v], line = lineN, Type = typeN, inline = 'yes'}))
})
)
table.insert(wikitable, '')
table.insert(wikitable, '')
table.insert(wikitable, '')
else
local Format = data[v]['station format'] or i18n[lang]['error_format']
local color, color_2, background_color, circular
local Type = line['types'] and line['types'][typeN] -- get the line type table
if Type then
if Type['color'] then
-- line color is used as background if there is no background color in the line type table
background_color = Type['background color'] or line['color']
color = Type['color']
color_2 = Type['color2'] or color
else
background_color = Type['background color'] or line['background color']
color = line['color'] or default['color'] or ''
color_2 = line['color2'] or color
end
if Type['circular'] then
-- Type may override the circular status of the line
circular = Type['circular']
end
else
background_color = line['background color']
color = line['color'] or default['color'] or ''
color_2 = line['color2'] or color
circular = line['circular']
end
-- Alternate termini can be specified based on type
local sideCell = {true, true}
for i, b in ipairs({'left', 'right'}) do
if not args[v][b] then -- If no station is given on one side, the station is assumed to be the terminus on that side
local _through = args[v]['through-' .. b] or args[v]['through']
local _through_data = getLine(data[v], _through)
if _through_data then _through = _through_data['title'] or _through end
sideCell[i] = _through and "''" .. i18n[lang]['through'](trimq(_through)) .. "''"
or "''" .. trimq((args[v]['reverse-' .. b]
or args[v]['reverse']) and i18n[lang]['reverse']
or i18n[lang]['terminus']) .. "''"
else
local terminusT
local terminusN = Type and Type[b .. ' terminus'] or line[b .. ' terminus']
-- If the terminus table has more than one numbered key or has the via key then the table shows only the default termini, since terminusN[2] cannot be used and terminusN[via] is reserved
if type(terminusN) == 'string' or (type(terminusN) == 'table' and (terminusN[2] or terminusN['via'])) then
if args[v]['to-' .. b] then
terminusT = args[v]['to-' .. b]
local _or = mw.ustring.match(terminusT, i18n[lang]['or-format'])
if _or then
terminusT = mw.ustring.gsub(terminusT, i18n[lang]['or-format'], '\127_OR_\127')
terminusT = mw.ustring.gsub(terminusT, i18n[lang]['comma-format'], '\127_OR_\127')
end
local _via = (mw.ustring.match(terminusT, i18n[lang]['via-format']))
if _via then
terminusT = mw.ustring.gsub(terminusT, i18n[lang]['via-format'], '')
terminusT = mw.text.split(terminusT, '\127_OR_\127')
terminusT['via'] = _via
elseif _or then
terminusT = mw.text.split(terminusT, '\127_OR_\127')
end
else
terminusT = terminusN
end
elseif type(terminusN) == 'table' then
terminusT = terminusN[args[v]['to-' .. b]] or terminusN[args[v]['to']] or terminusN[1]
end
local mainText = args[v]['note-' .. b] and getTerminusText(args[v][b], Format) .. small(args[v]['note-' .. b]) or getTerminusText(args[v][b], Format)
local subText = (args[v]['oneway-' .. b] or line['oneway-' .. b]) and i18n[lang]['oneway']
or args[v][b] == terminusT and i18n[lang]['terminus']
or circular and terminusT
or i18n[lang]['towards'](getTerminusText(terminusT, Format))
subText = small(subText, true)
sideCell[i] = mainText .. subText
end
end
table.insert(wikitable, '\n|-')
table.insert(wikitable, '\n|' .. style['body cell'] .. sideCell[1])
table.insert(wikitable, table.concat({'\n|', style['body banner'], color, '"|',
'\n|', (background_color and 'class="bcA" style="background-color:rgba(' .. table.concat(rgb(background_color), ',') .. ',.2)"|' or style['body cell']), line['title'],
-- Type; table key 'types' in subpages (datatype table, with strings as keys). If table does not exist then the input is displayed as the text
(typeN and '<div>' .. (Type and Type['title'] or typeN) .. '</div>' or ''),
-- Note-mid; table key 'note-mid' in subpages. Overridden by user input
((args[v]['note-mid'] and small(args[v]['note-mid'])) or (Type and Type['note-mid'] and small(Type['note-mid'])) or (line['note-mid'] and small(line['note-mid'])) or ''),
-- Transfer; uses system's station link table
(args[v]['transfer'] and small('transfer at ' .. getTerminusText(args[v]['transfer'], Format), true) or ''),
'\n|', style['body banner'], color_2, '"|'}))
table.insert(wikitable, '\n|' .. style['body cell'] .. sideCell[2])
end
end
if args[v]['note-row'] then -- Note
if args[v]['note-row']:match('^%s*<tr') or args[v]['note-row']:match('^%s*%|%-') then
table.insert(wikitable, '\n' .. args[v]['note-row'])
else
table.insert(wikitable, '\n|-\n|colspan="5" ' .. style['body cell'] .. args[v]['note-row'])
end
table.insert(wikitable, '')
table.insert(wikitable, '')
table.insert(wikitable, '')
end
end
local function combine(t, n)
if t[n + 4] ~= '' and t[n + 4] == t[n] then
t[n + 4] = '' -- The cell in the next row is deleted
local rowspan = 2
while t[n + rowspan * 4] == t[n] do
t[n + rowspan * 4] = ''
rowspan = rowspan + 1
end
t[n] = mw.ustring.gsub(t[n], '\n|class="', '\n|rowspan="' .. rowspan .. '" class="')
end
end
local M = #wikitable
for i = 3, M, 4 do combine(wikitable, i) end
for i = 4, M, 4 do combine(wikitable, i) end
for i = 5, M, 4 do combine(wikitable, i) end
table.insert(wikitable, '\n|}')
return table.concat(wikitable)
end
local getArgs = require('Module:Arguments').getArgs
local function makeInvokeFunction(funcName)
-- makes a function that can be returned from #invoke, using
-- [[Module:Arguments]]
return function (frame)
local args = getArgs(frame, {parentOnly = true})
return p[funcName](args, frame)
end
end
local function makeTemplateFunction(funcName)
-- makes a function that can be returned from #invoke, using
-- [[Module:Arguments]]
return function (frame)
local args = getArgs(frame, {frameOnly = true})
return p[funcName](args, frame)
end
end
p.main = makeInvokeFunction('_main')
function p._color(args, frame)
local data = args.data
if args[1] or data then
data = data or getData(args[1], true)
if not data then return getColor(nil, args[1], args[2], args[3], frame) end
return getColor(data, nil, args[2], args[3])
end
end
p.color = makeInvokeFunction('_color')
function p._box(args, frame)
local system = args[1] or args.system
lineN = args[2] or args.line
if not (system or lineN) then return '' end
local line, Type, line_data
local inline = args[3] or args.inline
typeN = args.type
local data = args.data
if system or data then
data = data or getData(system, true)
local color
if data then
local default = data['lines']['_default'] or {}
line, lineN = getLine(data, lineN)
if typeN then
typeN = data['aliases'] and data['aliases'][mw.ustring.lower(typeN)] or typeN
Type = line['types'] and line['types'][typeN] and line['types'][typeN]['title'] or typeN
end
color = getColor(data, nil, lineN, typeN)
if inline ~= 'box' then
line_data = line or error(i18n[lang]['error_unknown'](lineN))
line = line_data['title'] or default['title'] or error(i18n[lang]['error_missing']('title'))
line = mw.ustring.gsub(line, '%%1', lineN)
end
else
color = getColor(nil, system, lineN, typeN, frame)
if inline ~= 'box' then
line = frame:expandTemplate{ title = system .. ' lines', args = {lineN, ['branch'] = typeN} }
if mw.text.trim(line) == '' then return error(i18n[lang]['error_unknown'](lineN)) end
end
Type = typeN
end
local result
if Type and Type ~= '' and inline ~= 'box' then
if line == '' then
line = Type
else
result = ' – ' .. Type
end
end
if args.note then result = (result or '') .. ' ' .. args.note end
result = result or ''
if not inline then -- [[Template:Legend]]
result = '<div class="legend" style="page-break-inside:avoid;break-inside:avoid-column"><span class="legend-color" style="display:inline-block;min-width:1.25em;height:1.25em;line-height:1.25;margin:1px 0;border:1px solid black;color:inherit;background-color:#' .. color .. '"> </span> ' .. line .. result .. '</div>'
elseif inline == 'yes' then
result = '<span style="color:inherit;background-color:#' .. color .. ';border:1px solid #000"> </span> ' .. line .. result
elseif inline == 'box' then
result = '<span style="color:inherit;background-color:#' .. color .. ';border:1px solid #000"> </span>' .. result
elseif inline == 'link' then
local link = args.link or mw.ustring.match(line, '%[%[([^%[:|%]]+)[|%]]')
if link then
result = '[[' .. link .. '|<span style="color:inherit;background-color:#' .. color .. ';border:1px solid #000"> </span>]]' .. result
else
result = '<span style="color:inherit;background-color:#' .. color .. ';border:1px solid #000"> </span>' .. result
end
elseif inline == 'square' then
result = '<span style="color:#' .. color .. ';line-height:initial">■</span> ' .. line .. result
elseif inline == 'lsquare' then
local link = args.link or mw.ustring.match(line, '%[%[([^%[:|%]]+)[|%]]')
if link then
result = '[[' .. link .. '|<span style="color:#' .. color .. ';line-height:initial">■</span>]]'
else
result = '<span style="color:#' .. color .. ';line-height:initial">■</span>'
end
elseif inline == 'dot' then
result = '<span style="color:#' .. color .. ';line-height:initial">●</span> ' .. line .. result
elseif inline == 'ldot' then
local link = args.link or mw.ustring.match(line, '%[%[([^%[:|%]]+)[|%]]')
if link then
result = '[[' .. link .. '|<span style="color:#' .. color .. ';line-height:initial">●</span>]]'
else
result = '<span style="color:#' .. color .. ';line-height:initial">●</span>'
end
elseif inline == 'small' then
result = '<span style="color:inherit;background-color:#' .. color .. '"> </span>' .. ' ' .. line .. result
else
local yesno = require("Module:Yesno")
local link = args.link or mw.ustring.match(line, '%[%[([^%[:|%]]+)[|%]]')
local border_color, text_color
local color_box = data['color box format'] or data['rail box format'] or {}
if line_data then
if line_data['types'] and line_data['types'][typeN] then
local Type_data = line_data['types'][typeN]
border_color = Type_data['border color'] or line_data['border color'] or color
text_color = Type_data['text color'] or line_data['text color']
if color_box == 'title' and not args[4] then
lineN = Type_data['short name'] or line_data['short name'] or require('Module:Delink')._delink{line}
else
lineN = Type_data['short name'] or line_data['short name'] or lineN
end
else
border_color = line_data['border color'] or color
text_color = line_data['text color']
if color_box == 'title' and not args[4] then
lineN = line_data['short name'] or require('Module:Delink')._delink{line}
else
lineN = line_data['short name'] or lineN
end
end
else
border_color = color
end
text_color = text_color and '#' .. text_color or require('Module:Color contrast')._greatercontrast{color}
local bold = ';font-weight:bold'
if (yesno(args.bold) == false) then bold = '' end
if inline == 'route' then -- [[Template:RouteBox]]
if link then
result = '<span style="color:inherit;background-color:#' .. color .. ';border:.075em solid #' .. border_color .. ';padding:0 .3em">[[' .. link .. '|<span style="color:' .. text_color .. bold .. ';font-size:inherit;white-space:nowrap">' .. lineN .. '</span>]]</span>'
else
result = '<span style="background-color:#' .. color .. ';border:.075em solid #' .. border_color .. ';padding:0 .3em;color:' .. text_color .. bold .. ';font-size:inherit;white-space:nowrap">' .. lineN .. '</span>'
end
elseif inline == 'croute' then -- [[Template:Bahnlinie]]
if link then
result = '<span style="color:inherit;background-color:#' .. color .. ';border:.075em solid #' .. border_color .. ';border-radius:.5em;padding:0 .3em">[[' .. link .. '|<span style="color:' .. text_color .. bold .. ';font-size:inherit;white-space:nowrap">' .. lineN .. '</span>]]</span>'
else
result = '<span style="color:inherit;background-color:#' .. color .. ';border:.075em solid #' .. border_color .. ';border-radius:.5em;padding:0 .3em;color:' .. text_color .. bold .. ';font-size:inherit;white-space:nowrap">' .. lineN .. '</span>'
end
elseif inline == 'xroute' then -- [[Template:Bahnlinie]]
if link then
result = '<span style="border:.075em solid #' .. border_color .. ';border-radius:.5em;padding:0 .3em">[[' .. link .. '|<span style="color:#' .. color .. bold .. ';font-size:inherit;white-space:nowrap">' .. lineN .. '</span>]]</span>'
else
result = '<span style="border:.075em solid #' .. border_color .. ';border-radius:.5em;padding:0 .3em;color:#' .. color .. bold .. ';font-size:inherit;white-space:nowrap">' .. lineN .. '</span>'
end
elseif inline == 'broute' then
if link then
result = '<span style="color:inherit;background-color:#' .. color .. ';border:.075em solid #000;padding:0 .3em">[[' .. link .. '|<span style="color:' .. text_color .. bold .. ';font-size:inherit;white-space:nowrap">' .. lineN .. '</span>]]</span>'
else
result = '<span style="background-color:#' .. color .. ';border:.075em solid #000;padding:0 .3em;color:' .. text_color .. bold .. ';font-size:inherit;white-space:nowrap">' .. lineN .. '</span>'
end
else -- [[Template:Legend]] (fallback; duplication to simplify logic)
result = '<div class="legend" style="page-break-inside:avoid;break-inside:avoid-column"><span class="legend-color" style="display:inline-block;min-width:1.25em;height:1.25em;line-height:1.25;margin:1px 0;border:1px solid black;color:inherit;background-color:#' .. color .. '"> </span> ' .. line .. result .. '</div>'
end
end
result = mw.ustring.gsub(result, ':%s*#transparent', ':transparent')
return result
end
end
p.box = makeInvokeFunction('_box')
function p._icon(args, frame)
local system = args[1] or args.system
local data = args.data
if not system and not data then
return
end
data = data or getData(system)
local line, line_name = getLine(data, args[2] or args.line)
local icon
local icon_format
if line then
local line_type = args[3] or args.type
if line_type then
line_type = data.aliases and data.aliases[mw.ustring.lower(line_type)] or line_type
line_type = line.types and line.types[line_type] -- If there's no type table or entry for this type, then it can't have its own icon
icon_format = line_type['icon format'] or data['type icon format']
if line_type.icon then
icon = line_type.icon
end
end
if not icon then
icon = line.icon
end
-- Only if there is no icon use the icon_format.
if not icon and not icon_format then
icon_format = line['icon format'] or data['line icon format']
end
local default = data.lines._default or {}
if icon and string.find(icon, "%%1") and default and default.icon then
icon = mw.ustring.gsub(default.icon, '%%1', line_name)
end
end
if not icon then
icon = data['system icon']
end
if not icon_format then
icon_format = data['system icon format']
end
if icon_format then
if icon_format ~= 'image' then
icon = p._box({data = data, [2] = (args[2] or args.line), [3] = icon_format, type = (args[3] or args.type), bold = args.bold, link = args.link}, frame)
if args.name then
if line and line.title then
return icon .. " " .. line.title
end
return icon .. " " .. data["system title"]
end
end
end
local size = args.size
if size then
if mw.ustring.match(size, '%d$') then
size = '|' .. size .. 'px'
else
size = '|' .. size
end
-- Upright values are to be disabled until there is use of upright scaling in subpages; doesn't seem to work anyway as of 2018-08-10
local regex = {
'|%s*%d*x?%d+px%s*([%]|])', -- '|%s*upright=%d+%.?%d*%s*([%]|])', '|%s*upright%s*([%]|])'
}
if mw.ustring.match(icon, regex[1]) then
icon = mw.ustring.gsub(icon, regex[1], size .. '%1')
-- elseif mw.ustring.match(icon, regex[2]) then
-- icon = gsub(icon, regex[2], size .. '%1')
-- elseif mw.ustring.match(icon, regex[3]) then
-- icon = gsub(icon, regex[3], size .. '%1')
else
icon = mw.ustring.gsub(icon, '(%[%[[^%]|]+)([%]|])', '%1' .. size .. '%2')
end
end
local link = args.link
if link then
if mw.ustring.match(icon, '|%s*link=[^%]|]*[%]|]') then
icon = mw.ustring.gsub(icon, '|%s*link=[^%]|]*([%]|])', '|link=' .. link .. '%1')
else
icon = mw.ustring.gsub(icon, '(%[%[[^%]|]+)([%]|])', '%1|link=' .. link .. '%2')
end
end
local alt = args.alt or link
if alt then
if mw.ustring.match(icon, '|%s*alt=[^%]|]*[%]|]') then
icon = mw.ustring.gsub(icon, '|%s*alt=[^%]|]*([%]|])', '|alt=' .. alt .. '%1')
else
icon = mw.ustring.gsub(icon, '(%[%[[^%]|]+)([%]|])', '%1|alt=' .. alt .. '%2')
end
end
if args.name then
if line and line.title then
return icon .. " " .. line.title
end
return icon .. " " .. data["system title"]
end
return icon
end
p.icon = makeInvokeFunction('_icon')
p['rail icon'] = makeTemplateFunction('_icon')
function p._line(args, frame)
local system = args[1] or args.system
local line = args[2] or args.line
if not line then return '' end
local Type = args[3] or args.type
local data = args.data
if system or data then
data = data or getData(system, true)
if data then
line = (getLine(data, line)) or error(i18n[lang]['error_unknown'](line))
if Type then
Type = data['aliases'] and data['aliases'][mw.ustring.lower(Type)] or Type
Type = line['types'] and line['types'][Type] and line['types'][Type]['title'] or Type
end
line = line['title'] or error(i18n[lang]['error_missing']('title'))
else
line = frame:expandTemplate{ title = system .. ' lines', args = {line, ['branch'] = Type} }
if mw.text.trim(line) == '' then return error(i18n[lang]['error_unknown'](lineN)) end
end
if Type and Type ~= '' then
if line == '' then
line = Type
else
line = line .. ' – ' .. Type
end
end
return line
end
end
p.line = makeInvokeFunction('_line')
function p._shortline(args, frame)
local system = args[1] or args.system
lineN = args[2] or args.line
if not (system or lineN) then return '' end
local line, Type, line_data
typeN = args.type
local data = args.data
if system or data then
data = data or getData(system, true)
if data then
local default = data['lines']['_default'] or {}
line, lineN = getLine(data, lineN)
if typeN then
typeN = data['aliases'] and data['aliases'][mw.ustring.lower(typeN)] or typeN
Type = line['types'] and line['types'][typeN] and line['types'][typeN]['title'] or typeN
end
line_data = line or error(i18n[lang]['error_unknown'](lineN))
line = line_data['title'] or default['title'] or error(i18n[lang]['error_missing']('title'))
line = mw.ustring.gsub(line, '%%1', lineN)
else
line = frame:expandTemplate{ title = system .. ' lines', args = {lineN, ['branch'] = typeN} }
if mw.text.trim(line) == '' then return error(i18n[lang]['error_unknown'](lineN)) end
Type = typeN
end
local result
if Type and Type ~= '' then
if line == '' then
line = Type
else
result = ' – ' .. Type
end
end
if args.note then result = (result or '') .. ' ' .. args.note end
result = result or ''
local link = args.link or mw.ustring.match(line, '%[%[([^%[:|%]]+)[|%]]')
if line_data then
if line_data['types'] and line_data['types'][typeN] then
local Type_data = line_data['types'][typeN]
lineN = Type_data['short name'] or line_data['short name'] or lineN
else
lineN = line_data['short name'] or lineN
end
end
if link then
result = '[[' .. link .. '|' .. lineN .. ']]'
else
result = lineN
end
result = mw.ustring.gsub(result, ':%s*#transparent', ':transparent')
return result
end
end
p.shortline = makeInvokeFunction('_shortline')
function p._station(args, frame)
local system = args[1] or args.system
local station = args[2] or args.station
if not station then return '' end
lineN = args[3] or args.line
typeN = args[4] or args.type
local data = args.data
if system or data then
data = data or getData(system, true)
if data then
local _Format = data['station format'][station] or data['station format'][1]
if _Format then
if data['aliases'] then
if lineN then
lineN = data['aliases'][mw.ustring.lower(lineN)] or lineN
end
if typeN then
typeN = data['aliases'][mw.ustring.lower(typeN)] or typeN
end
end
station = getStation(station, _Format)
else
station = station or ''
end
else
station = frame:expandTemplate{ title = system .. ' stations', args = {['station'] = station, ['line'] = lineN, ['branch'] = typeN} }
end
return station
end
end
p.station = makeInvokeFunction('_station')
p['station link'] = makeTemplateFunction('_station')
function p._terminusTable(args, frame)
local system = args[1] or args.system
lineN = args[2] or args.line
local side = mw.ustring.sub(mw.ustring.lower(args[3] or args.side or ''), 1, 1)
typeN = args.type
local prefix = (side == 'r') and 'right' or 'left'
local data = args.data
if system or data then
data = data or getData(system, true)
end
if data then
local line = getLine(data, lineN) or error(i18n[lang]['error_unknown'](lineN))
if typeN and data and data['aliases'] then typeN = data['aliases'][mw.ustring.lower(typeN)] or typeN end
local Type = line['types'] and line['types'][typeN]
local circular
if Type then
if Type['circular'] then
-- Type may override the circular status of the line
circular = Type['circular']
end
else
circular = line['circular']
end
return Type and Type[prefix .. ' terminus'] or line[prefix .. ' terminus'], data['station format'] or i18n[lang]['error_format'], circular
else
local terminus = frame:expandTemplate{ title = 'S-line/' .. system .. ' ' .. prefix .. '/' .. lineN }
return mw.ustring.gsub(terminus, '{{{type}}}', typeN)
end
end
function p._terminus(args, frame)
local var, Format, circular = p._terminusTable(args, frame)
return circular and var or getTerminusText(var, Format)
end
p.terminus = makeInvokeFunction('_terminus')
function p._style(args, frame)
local style = args[1] or args.style
local system = args[2] or args.system
local line = args[3] or args.line
local station = args[4] or args.station
local result = {}
local data = args.data
local default = 'color:inherit;background-color:#efefef' -- Default text and background color for {{Infobox station}}
if system or data then
data = data or getData(system, true)
end
if data then
local function getValue(var)
if type(var) == 'table' then
var = var[line] or var[1]
if type(var) == 'table' then
var = var[station] or var[1]
end
end
if var ~= '' then return var end
end
if style == 'header' then
local tmp = data['name format'] and getValue(data['name format'])
if tmp then table.insert(result, tmp) end
elseif style == 'subheader' then
local tmp = data['header background color'] and getValue(data['header background color'])
if tmp then
table.insert(result, 'background-color:#' .. tmp)
local color = data['header text color'] and getValue(data['header text color'])
if color then
table.insert(result, 'color:#' .. color)
else
local greatercontrast = require('Module:Color contrast')._greatercontrast
if greatercontrast{tmp} == '#FFFFFF' then table.insert(result, 'color:#FFFFFF') end
end
else
table.insert(result, default)
local color = data['header text color'] and getValue(data['header text color'])
if color then table.insert(result, 'color:#' .. color) end
end
end
result = table.concat(result, ';')
elseif system then
local title = 'Template:' .. system .. ' style'
local titleObj = mw.title.new(title)
if titleObj and titleObj.exists then
local tmp
if style == 'header' then
tmp = frame:expandTemplate{ title = title, args = {'name_format', line, station} }
if tmp ~= '' then table.insert(result, tmp) end
elseif style == 'subheader' then
tmp = frame:expandTemplate{ title = title, args = {'thbgcolor', line, station} }
if tmp ~= '' then
table.insert(result, 'background-color:#' .. tmp)
local color = frame:expandTemplate{ title = title, args = {'thcolor', line, station} }
if color ~= '' then
table.insert(result, 'color:#' .. color)
else
local ratio = require('Module:Color contrast')._ratio
if ratio{tmp, '222222'} < 4.5 then table.insert(result, 'color:#FFFFFF') end -- 222222 is the default text color in Vector
end
else
table.insert(result, default)
tmp = frame:expandTemplate{ title = title, args = {'thcolor', line, station} }
if tmp ~= '' then
table.insert(result, 'color:#' .. tmp)
end
end
end
result = table.concat(result, ';')
else
if style == 'subheader' then
result = default
else
result = ''
end
end
else
if style == 'subheader' then
result = default
else
result = ''
end
end
return result
end
function p.style(frame)
local args = getArgs(frame, {frameOnly = true})
return p._style(args, frame)
end
function p.convert(frame)
local args = frame.args
local code = mw.text.split(mw.ustring.gsub(args[1], '^%s*{{(.*)}}%s*$', '%1'), '%s*}}%s*{{%s*')
local system
local group = tonumber(args.offset or 0) or 0
local firstgroup = group + 1
local delete = {
['s-rail'] = true,
['s-rail-next'] = true,
['s-rail-national'] = true,
['s-start'] = true,
['s-rail-start'] = true,
['start'] = true,
['s-end'] = true,
['end'] = true
}
local order = {
'line', 'left', 'right', 'to-left', 'to-right',
'oneway-left', 'oneway-right', 'through-left', 'through-right',
'reverse', 'reverse-left', 'reverse-right',
'note-left', 'note-mid', 'note-right', 'transfer'
-- circular: use module subpage
-- state: not implemented
}
local replace = {
['previous'] = 'left',
['next'] = 'right',
['type'] = 'to-left',
['type2'] = 'to-right',
['branch'] = 'type',
['note'] = 'note-left',
['notemid'] = 'note-mid',
['note2'] = 'note-right',
['oneway1'] = 'oneway-left',
['oneway2'] = 'oneway-right',
['through1'] = 'through-left',
['through2'] = 'through-right'
}
local remove_rows = {}
local data = {}
local noclear = false
for i, v in ipairs(code) do
code[i] = mw.ustring.gsub(code[i], '\n', ' ')
local template = mw.ustring.lower(mw.text.trim(mw.ustring.match(code[i], '^[^|]+')))
code[i] = mw.ustring.match(code[i], '(|.+)$')
if (mw.ustring.match(code[i] or '', 'noclear%s*=%s*[a-z]')) then
noclear = true
end
if template == 's-line' then
data[i] = {}
local this_system = mw.text.trim(mw.ustring.match(code[i], '|%s*system%s*=([^|]+)'))
code[i] = mw.text.split(code[i], '%s*|%s*')
for m, n in ipairs(code[i]) do
local tmp = mw.text.split(n, '%s*=%s*')
if tmp[3] then
tmp[2] = mw.ustring.gsub(n, '^.-%s*=', '')
end
tmp[1] = replace[tmp[1]] or tmp[1]
if tmp[2] then
-- checks for matching brackets
local curly = select(2, mw.ustring.gsub(tmp[2], "{", ""))-select(2, mw.ustring.gsub(tmp[2], "}", ""))
local square = select(2, mw.ustring.gsub(tmp[2], "%[", ""))-select(2, mw.ustring.gsub(tmp[2], "%]", ""))
if not (curly == 0 and square == 0) then
local count = mw.clone(m)+1
while not (curly == 0 and square == 0) do
tmp[2] = tmp[2]..'|'..code[i][count]
curly = curly+select(2, mw.ustring.gsub(code[i][count], "{", ""))-select(2, mw.ustring.gsub(code[i][count], "}", ""))
square = square+select(2, mw.ustring.gsub(code[i][count], "%[", ""))-select(2, mw.ustring.gsub(code[i][count], "%]", ""))
code[i][count] = ''
count = count+1
end
end
data[i][tmp[1]] = tmp[2]
end
end
if (this_system ~= system) or (not system) then
system = this_system
data[i]['system'] = system
else
data[i]['system'] = nil
end
local last = data[i-1] or data[i-2] or data[i-3]
if last then
for r, s in pairs({
['hide1'] = {'left', 'to-left', 'note-left', 'oneway-left'},
['hide2'] = {'right', 'to-right', 'note-right', 'oneway-right'},
['hidemid'] = {'type', 'note-mid'}
}) do
if data[i][r] then
for m, n in ipairs(s) do
if not data[i][n] then
data[i][n] = last[n]
end
end
end
end
end
code[i] = {}
local X = '|'
local Y = (i+group)..'='
if data[i]['system'] then
table.insert(code[i], '|system')
table.insert(code[i], Y)
table.insert(code[i], data[i]['system'])
table.insert(code[i], '\n')
end
for m, n in ipairs(order) do
if data[i][n] then
table.insert(code[i], X)
table.insert(code[i], n)
table.insert(code[i], Y)
table.insert(code[i], data[i][n])
end
end
code[i] = table.concat(code[i])
elseif template == 's-note' then
code[i] = mw.ustring.gsub(code[i], '|%s*text%s*=', '|header'..i+group..'=')
code[i] = mw.ustring.gsub(code[i], '|%s*wide%s*=[^|]*', '')
elseif template == 's-text' then
code[i] = mw.ustring.gsub(code[i], '|%s*text%s*=', '|note-row'..i+group..'=')
elseif delete[template] then
code[i] = ''
table.insert(remove_rows, 1, i) -- at the start, so that the rows are deleted in reverse order
group = group-1
end
end
for i, v in ipairs(remove_rows) do
table.remove(code, v)
end
code = table.concat(code, '\n')
local t = {'{{Adjacent stations' .. (noclear and '|noclear=y\n' or ''), '\n}}'}
system = mw.ustring.match(code, '|system(%d*)=')
code = mw.ustring.gsub(code, '\n\n+', '\n')
if tonumber(system) > firstgroup then
-- If s-line isn't the first template then the system will have to be moved to the top
system = mw.ustring.match(code, '|system%d*=([^|]*[^|\n])')
code = mw.ustring.gsub(code, '|system%d*=[^|]*', '')
code = '\n|system'..firstgroup..'='..system..code
elseif not mw.ustring.match(code, '^[^{%[]*|[^=|]+2=') then
-- If there's only one parameter group then there's no need to have line breaks
code = mw.ustring.gsub(code, '\n', '')
code = mw.ustring.gsub(code, '(|[^=|]+)1=', '%1=')
t[2] = '}}'
if not mw.ustring.match(code, '[%[{]') then
code = mw.ustring.gsub(code, '|[^=|]*=$', '')
code = mw.ustring.gsub(code, '|[^=|]*$', '')
end
end
if not mw.ustring.match(code, '[%[{]') then
code = mw.ustring.gsub(code, '|[^=|]*=|', '|')
code = mw.ustring.gsub(code, '|[^=|]*|', '|')
code = mw.ustring.gsub(code, '|[^=|]*=\n', '\n')
code = mw.ustring.gsub(code, '|[^=|]*\n', '\n')
end
return t[1]..code..t[2]
end
return p
jca1evjg28y2y92hnk1s3eak58flopp
Template:Line terminus link
10
52464
308430
2026-09-17T16:04:59Z
Isma4l
41797
Bog cusub: <includeonly>{{#invoke:Adjacent stations|terminus}}</includeonly><noinclude> {{documentation}} </noinclude>
308430
wikitext
text/x-wiki
<includeonly>{{#invoke:Adjacent stations|terminus}}</includeonly><noinclude>
{{documentation}}
</noinclude>
rond8etukbu6w1wx6cxfe7r1mbwq1jy
Template:Station icon link
10
52465
308431
2026-09-17T16:05:25Z
Isma4l
41797
Bog cusub: <includeonly>{{#invoke:adjacent stations|rail icon|{{{system|{{{1}}}}}}|{{{line|{{{3}}}}}}}}{{#if:{{{4|}}}| {{#invoke:adjacent stations|rail icon|{{{system|{{{1}}}}}}|{{{4}}}}}|}}{{#if:{{{5|}}}| {{#invoke:adjacent stations|rail icon|{{{system|{{{1}}}}}}|{{{5}}}}}|}}{{#if:{{{6|}}}| {{#invoke:adjacent stations|rail icon|{{{system|{{{1}}}}}}|{{{6}}}}}|}} {{#ifeq:{{{links}}}|no|{{{station|{{{2}}}}}}|{{#invoke:adjacent stations|station link|{{{system|{{{1}}}}}}|{{{station|{{{2}}}}}}|{...
308431
wikitext
text/x-wiki
<includeonly>{{#invoke:adjacent stations|rail icon|{{{system|{{{1}}}}}}|{{{line|{{{3}}}}}}}}{{#if:{{{4|}}}| {{#invoke:adjacent stations|rail icon|{{{system|{{{1}}}}}}|{{{4}}}}}|}}{{#if:{{{5|}}}| {{#invoke:adjacent stations|rail icon|{{{system|{{{1}}}}}}|{{{5}}}}}|}}{{#if:{{{6|}}}| {{#invoke:adjacent stations|rail icon|{{{system|{{{1}}}}}}|{{{6}}}}}|}} {{#ifeq:{{{links}}}|no|{{{station|{{{2}}}}}}|{{#invoke:adjacent stations|station link|{{{system|{{{1}}}}}}|{{{station|{{{2}}}}}}|{{{line|{{{3}}}}}}}}}}</includeonly><noinclude>{{documentation}}</noinclude>
p5fzuurb284xm6fwd4eqpsp45j9kvcd
Template:Line link
10
52466
308432
2026-09-17T16:05:50Z
Isma4l
41797
Bog cusub: <includeonly>{{#invoke:Adjacent stations|line}}</includeonly><noinclude> {{documentation}} </noinclude>
308432
wikitext
text/x-wiki
<includeonly>{{#invoke:Adjacent stations|line}}</includeonly><noinclude>
{{documentation}}
</noinclude>
kp5kspm90n7yiowkxwn0azq0oypfigm
Template:Rail color box
10
52467
308433
2026-09-17T16:06:32Z
Isma4l
41797
Bog cusub: <includeonly>{{#invoke:Adjacent stations|box}}</includeonly><noinclude> {{documentation}} </noinclude>
308433
wikitext
text/x-wiki
<includeonly>{{#invoke:Adjacent stations|box}}</includeonly><noinclude>
{{documentation}}
</noinclude>
0z5wsspuhn41s44huksyg8mmcifp924
Template:Adjacent stations
10
52468
308434
2026-09-17T16:06:56Z
Isma4l
41797
Bog cusub: <includeonly><templatestyles src="Adjacent stations/styles.css"/>{{safesubst:#invoke:Adjacent stations|main}}</includeonly><noinclude> {{documentation}} </noinclude>
308434
wikitext
text/x-wiki
<includeonly><templatestyles src="Adjacent stations/styles.css"/>{{safesubst:#invoke:Adjacent stations|main}}</includeonly><noinclude>
{{documentation}}
</noinclude>
q99wx427wztspgaso2z00zfax8t4u3l
Template:Adjacent stations/styles.css
10
52469
308435
2026-09-17T16:07:21Z
Isma4l
41797
Bog cusub: /* {{pp-template}} */ .adjacent-stations { max-width: 50em; margin: 0.5em auto; font-size: 95%; clear: both; } .infobox .adjacent-stations { font-size: 100%; } .adjacent-stations .isA { font-size: 90%; font-style: italic; } .adjacent-stations .smA { font-size: 90%; } .infobox .adjacent-stations .isA, .infobox .adjacent-stations .smA { font-size: 96.6%; } .adjacent-stations .hcA { width: 30%; vertical-align: middle; } .adjacent-stations .hmA, .adjacent-stations .hm...
308435
sanitized-css
text/css
/* {{pp-template}} */
.adjacent-stations {
max-width: 50em;
margin: 0.5em auto;
font-size: 95%;
clear: both;
}
.infobox .adjacent-stations {
font-size: 100%;
}
.adjacent-stations .isA {
font-size: 90%;
font-style: italic;
}
.adjacent-stations .smA {
font-size: 90%;
}
.infobox .adjacent-stations .isA,
.infobox .adjacent-stations .smA {
font-size: 96.6%;
}
.adjacent-stations .hcA {
width: 30%;
vertical-align: middle;
}
.adjacent-stations .hmA, .adjacent-stations .hmA > a:last-child {
vertical-align: middle;
}
.adjacent-stations .bcA {
text-align: center;
vertical-align: middle;
}
.adjacent-stations .bbA {
text-align: center;
width: 8px;
min-width: 8px;
}
.adjacent-stations-noclear {
clear: none;
}
risrhgjz6v7pgpul9mqye7kqmrkfy21
Template:Calendar/styles.css
10
52470
308436
2026-09-17T16:09:37Z
Isma4l
41797
Bog cusub: /* {{pp-template}} */ .calendar-purple { color: var(--color-base, #202122); background-color: #ccf; } .calendar-lightpurple { color: var(--color-base, #202122); background-color: #d8e0ff; } html.skin-theme-clientpref-night .calendar-purple { background-color: #2a2a5c; } html.skin-theme-clientpref-night .calendar-lightpurple { background-color: #202040; } @media screen and (prefers-color-scheme: dark){ html.skin-theme-clientpref-os .calendar-purple { background-col...
308436
sanitized-css
text/css
/* {{pp-template}} */
.calendar-purple {
color: var(--color-base, #202122);
background-color: #ccf;
}
.calendar-lightpurple {
color: var(--color-base, #202122);
background-color: #d8e0ff;
}
html.skin-theme-clientpref-night .calendar-purple {
background-color: #2a2a5c;
}
html.skin-theme-clientpref-night .calendar-lightpurple {
background-color: #202040;
}
@media screen and (prefers-color-scheme: dark){
html.skin-theme-clientpref-os .calendar-purple {
background-color: #2a2a5c;
}
html.skin-theme-clientpref-night .calendar-lightpurple {
background-color: #202040;
}
}
jrd7yfzquhnqcn1szvnw2rt01dj5nez
Template:Use shortened footnotes
10
52471
308438
2026-09-17T16:12:43Z
Isma4l
41797
Bog cusub: {{ {{{|safesubst:}}}#invoke:Unsubst||date=__DATE__|$B= {{DMCA|Use shortened footnotes|from|{{{date|}}}}} }}<noinclude>{{Documentation}}</noinclude>
308438
wikitext
text/x-wiki
{{ {{{|safesubst:}}}#invoke:Unsubst||date=__DATE__|$B=
{{DMCA|Use shortened footnotes|from|{{{date|}}}}}
}}<noinclude>{{Documentation}}</noinclude>
20rhb7nv1ahv4iombvadidqs8cr3kz0
Template:GHS exclamation mark
10
52472
308439
2026-09-17T16:14:02Z
Isma4l
41797
Bog cusub: [[File:GHS-pictogram-exclam.svg|50px|{{{1|GHS07: Exclamation mark}}}]]<!-- --><noinclude>{{documentation|1=Template:GHS exploding bomb/doc}}</noinclude>
308439
wikitext
text/x-wiki
[[File:GHS-pictogram-exclam.svg|50px|{{{1|GHS07: Exclamation mark}}}]]<!--
--><noinclude>{{documentation|1=Template:GHS exploding bomb/doc}}</noinclude>
pj5fpeqpsz924tq1d7ysyq8l2c95voh
Template:GHS exploding bomb
10
52473
308440
2026-09-17T16:14:32Z
Isma4l
41797
Bog cusub: [[File:GHS-pictogram-explos.svg|50px|{{{1|GHS01: Explosive}}}]]<!-- --><noinclude>{{documentation|1=Template:GHS exploding bomb/doc}}</noinclude>
308440
wikitext
text/x-wiki
[[File:GHS-pictogram-explos.svg|50px|{{{1|GHS01: Explosive}}}]]<!--
--><noinclude>{{documentation|1=Template:GHS exploding bomb/doc}}</noinclude>
bqrroy35u4i02y6e0b0wgcosefwv6mq
Template:GHS flame
10
52474
308441
2026-09-17T16:15:10Z
Isma4l
41797
Bog cusub: [[File:GHS-pictogram-flamme.svg|50px|{{{1|GHS02: Flammable}}}]]<!-- --><noinclude>{{documentation|1=Template:GHS exploding bomb/doc}}</noinclude>
308441
wikitext
text/x-wiki
[[File:GHS-pictogram-flamme.svg|50px|{{{1|GHS02: Flammable}}}]]<!--
--><noinclude>{{documentation|1=Template:GHS exploding bomb/doc}}</noinclude>
ab3j7d7nh12ue16srbyg5yjghaa45zt
Template:GHS flame over circle
10
52475
308442
2026-09-17T16:15:37Z
Isma4l
41797
Bog cusub: [[File:GHS-pictogram-rondflam.svg|50px|{{{1|GHS03: Oxidizing}}}]]<!-- --><noinclude>{{documentation|1=Template:GHS exploding bomb/doc}}</noinclude>
308442
wikitext
text/x-wiki
[[File:GHS-pictogram-rondflam.svg|50px|{{{1|GHS03: Oxidizing}}}]]<!--
--><noinclude>{{documentation|1=Template:GHS exploding bomb/doc}}</noinclude>
lkn4ircb92jw5vt06eqlht40en3koa2
Template:GHS gas cylinder
10
52476
308443
2026-09-17T16:16:01Z
Isma4l
41797
Bog cusub: [[File:GHS-pictogram-bottle.svg|50px|{{{1|GHS04: Compressed Gas}}}]]<!-- --><noinclude>{{documentation|1=Template:GHS exploding bomb/doc}}</noinclude>
308443
wikitext
text/x-wiki
[[File:GHS-pictogram-bottle.svg|50px|{{{1|GHS04: Compressed Gas}}}]]<!--
--><noinclude>{{documentation|1=Template:GHS exploding bomb/doc}}</noinclude>
oedsl2shc4p4dow3fw69uk7pzw02t6k
Template:GHS corrosion
10
52477
308444
2026-09-17T16:16:22Z
Isma4l
41797
Bog cusub: [[File:GHS-pictogram-acid.svg|50px|{{{1|GHS05: Corrosive}}}]]<!-- --><noinclude>{{documentation|1=Template:GHS exploding bomb/doc}}</noinclude>
308444
wikitext
text/x-wiki
[[File:GHS-pictogram-acid.svg|50px|{{{1|GHS05: Corrosive}}}]]<!--
--><noinclude>{{documentation|1=Template:GHS exploding bomb/doc}}</noinclude>
gvjpaf4fg2no8wm8mm50xi0deigmbxw
Template:GHS skull and crossbones
10
52478
308445
2026-09-17T16:17:10Z
Isma4l
41797
Bog cusub: [[File:GHS-pictogram-skull.svg|50px|{{{1|GHS06: Toxic}}}]]<!-- --><noinclude>{{documentation|1=Template:GHS exploding bomb/doc}}</noinclude>
308445
wikitext
text/x-wiki
[[File:GHS-pictogram-skull.svg|50px|{{{1|GHS06: Toxic}}}]]<!--
--><noinclude>{{documentation|1=Template:GHS exploding bomb/doc}}</noinclude>
2kgrqxrifdzs0u6uu2gglubdt95el2g
Template:GHS health hazard
10
52479
308446
2026-09-17T16:17:31Z
Isma4l
41797
Bog cusub: [[File:GHS-pictogram-silhouette.svg|50px|{{{1|GHS08: Health hazard}}}]]<!-- --><noinclude>{{documentation|1=Template:GHS exploding bomb/doc}}</noinclude>
308446
wikitext
text/x-wiki
[[File:GHS-pictogram-silhouette.svg|50px|{{{1|GHS08: Health hazard}}}]]<!--
--><noinclude>{{documentation|1=Template:GHS exploding bomb/doc}}</noinclude>
eehtp8i5yjzfnlkh1c4onaks3u2b1dj
Template:GHS environment
10
52480
308447
2026-09-17T16:17:53Z
Isma4l
41797
Bog cusub: [[File:GHS-pictogram-pollu.svg|50px|{{{1|GHS09: Environmental hazard}}}]]<!-- --><noinclude>{{documentation|1=Template:GHS exploding bomb/doc}}</noinclude>
308447
wikitext
text/x-wiki
[[File:GHS-pictogram-pollu.svg|50px|{{{1|GHS09: Environmental hazard}}}]]<!--
--><noinclude>{{documentation|1=Template:GHS exploding bomb/doc}}</noinclude>
450mbwngn1hy77go5k38asqrrwbqz0h
Template:Editcount
10
52481
308448
2026-09-17T16:19:13Z
Isma4l
41797
Bog cusub: <span class="plainlinks">[https://xtools.wmflabs.org/ec/{{CONTENTLANGUAGE}}.wikipedia/{{urlencode:{{{1}}}|PATH}} {{{2|Wax ka beddel tirada {{{1}}}}}}]</span><noinclude> {{documentation}} </noinclude>
308448
wikitext
text/x-wiki
<span class="plainlinks">[https://xtools.wmflabs.org/ec/{{CONTENTLANGUAGE}}.wikipedia/{{urlencode:{{{1}}}|PATH}} {{{2|Wax ka beddel tirada {{{1}}}}}}]</span><noinclude>
{{documentation}}
</noinclude>
kfca5rxiw6c5mey1flnh0izumn93edp
Template:Ed right
10
52482
308449
2026-09-17T16:19:48Z
Isma4l
41797
Bog cusub: <div class="editsection noprint editlink plainlinks" align="right" style="float: right; margin-left: 5px;"><small>[{{fullurl:{{transclude|{{#if:{{{namespace|}}}|{{{namespace|}}}:}}{{{1}}}}}|action=edit}} edit{{#if:{{{2|}}}| {{{2}}}}}]</small></div><noinclude> {{documentation}} </noinclude>
308449
wikitext
text/x-wiki
<div class="editsection noprint editlink plainlinks" align="right" style="float: right; margin-left: 5px;"><small>[{{fullurl:{{transclude|{{#if:{{{namespace|}}}|{{{namespace|}}}:}}{{{1}}}}}|action=edit}} edit{{#if:{{{2|}}}| {{{2}}}}}]</small></div><noinclude>
{{documentation}}
</noinclude>
1fmx0srcskfzhg7uz6c41vu3y60k16j
Template:Edit section
10
52483
308450
2026-09-17T16:20:48Z
Isma4l
41797
Bog cusub: <{{{type|div}}} class="mw-editsection plainlinks"><span class="mw-editsection-bracket">[</span><span style="color:#002bb8;">[{{fullurl:{{{page|{{FULLPAGENAME}}}}}|action=edit{{#ifeq:{{{1|{{{section}}}}}}|-1||§ion={{urlencode:{{{1|{{{section|0}}}}}}}}}}}} edit]</span><span class="mw-editsection-bracket">]</span></{{{type|div}}}><noinclude> <!--Categories and interwikis go on the /doc page.--> {{Documentation}} </noinclude>
308450
wikitext
text/x-wiki
<{{{type|div}}} class="mw-editsection plainlinks"><span class="mw-editsection-bracket">[</span><span style="color:#002bb8;">[{{fullurl:{{{page|{{FULLPAGENAME}}}}}|action=edit{{#ifeq:{{{1|{{{section}}}}}}|-1||§ion={{urlencode:{{{1|{{{section|0}}}}}}}}}}}} edit]</span><span class="mw-editsection-bracket">]</span></{{{type|div}}}><noinclude>
<!--Categories and interwikis go on the /doc page.-->
{{Documentation}}
</noinclude>
hxk71ckfgc7ieipadx5rg014o9r790v
Template:View
10
52484
308451
2026-09-17T16:21:39Z
Isma4l
41797
Bog cusub: {{#invoke:navbar|navbar|plain = 1|template = {{{template|{{{1|}}}}}}}}<noinclude> {{Documentation|Template:Navbar/doc}} </noinclude>
308451
wikitext
text/x-wiki
{{#invoke:navbar|navbar|plain = 1|template = {{{template|{{{1|}}}}}}}}<noinclude>
{{Documentation|Template:Navbar/doc}}
</noinclude>
3cdib5yx2npzm141agd4nm089qwwm12
Template:VTE
10
52485
308452
2026-09-17T16:22:06Z
Isma4l
41797
Bog cusub: {{#invoke:Navbar|navbar|mini = 1|template = {{{template|{{{1|}}}}}}}}<noinclude> {{Documentation}} </noinclude>
308452
wikitext
text/x-wiki
{{#invoke:Navbar|navbar|mini = 1|template = {{{template|{{{1|}}}}}}}}<noinclude>
{{Documentation}}
</noinclude>
frbwokefeudcd6b73e189tb5en7psk5
Template:Talk
10
52486
308453
2026-09-17T16:22:40Z
Isma4l
41797
Bog cusub: [[{{ {{{|safesubst:}}}TALKPAGENAME:{{{1|{{ {{{|safesubst:}}}FULLPAGENAME}}}}}}}{{ {{{|safesubst:}}}#if:{{{2|}}}|{{ {{{|safesubst:}}}!}}{{{2}}}}}]]<noinclude> {{documentation}} <!-- Add categories and interwikis to the /doc subpage, not here! --> </noinclude>
308453
wikitext
text/x-wiki
[[{{ {{{|safesubst:}}}TALKPAGENAME:{{{1|{{ {{{|safesubst:}}}FULLPAGENAME}}}}}}}{{ {{{|safesubst:}}}#if:{{{2|}}}|{{ {{{|safesubst:}}}!}}{{{2}}}}}]]<noinclude>
{{documentation}}
<!-- Add categories and interwikis to the /doc subpage, not here! -->
</noinclude>
fo91apztssmkvsddbf3f3uyyl9d8nve
Template:Article links
10
52487
308454
2026-09-17T16:23:22Z
Isma4l
41797
Bog cusub: {{#ifeq:{{{noanchor|no}}}|yes|<!--nothing-->|<span id="{{anchorencode:{{{1}}}}}"></span>}}<span class="plainlinks nourlexpansion lx">[[:{{encodefirst|{{ucfirst:{{{1|Article}}}}}}}]] ([[Special:EditPage/{{{1}}}|edit]] | [[Talk:{{{1}}}|talk]] | [[Special:PageHistory/{{{1}}}|history]]<span class="sysop-show"> | [[Special:ProtectPage/{{{1}}}|protect]] | [[Special:DeletePage/{{{1}}}|delete]]</span> | [{{fullurl:Special:WhatLinksHere/{{...
308454
wikitext
text/x-wiki
{{#ifeq:{{{noanchor|no}}}|yes|<!--nothing-->|<span id="{{anchorencode:{{{1}}}}}"></span>}}<span class="plainlinks nourlexpansion lx">[[:{{encodefirst|{{ucfirst:{{{1|Article}}}}}}}]] ([[Special:EditPage/{{{1}}}|edit]] | [[Talk:{{{1}}}|talk]] | [[Special:PageHistory/{{{1}}}|history]]<span class="sysop-show"> | [[Special:ProtectPage/{{{1}}}|protect]] | [[Special:DeletePage/{{{1}}}|delete]]</span> | [{{fullurl:Special:WhatLinksHere/{{{1}}}|limit=999}} links] | [{{fullurl:{{{1}}}|action=watch}} watch] | [{{fullurl:Special:Log|page={{urlencode:{{{1}}}}}}} logs] | [https://tools.wmflabs.org/pageviews?pages={{urlencode:{{encodefirst|{{{1}}}}}|WIKI}}&project=en.wikipedia.org views])</span><noinclude>
{{documentation}}
<!-- Categories go on the /doc subpage, and interwikis go on Wikidata. -->
</noinclude>
rd9w26p8xo65u4r3foruloy50jsp8ly
Template:Getalias2
10
52488
308455
2026-09-17T16:24:54Z
Isma4l
41797
Bog cusub: {{Country data {{{1|}}}|Getalias2/core|name={{{2|}}}|variant={{{variant|}}}}}<noinclude> {{Documentation}} </noinclude>
308455
wikitext
text/x-wiki
{{Country data {{{1|}}}|Getalias2/core|name={{{2|}}}|variant={{{variant|}}}}}<noinclude>
{{Documentation}}
</noinclude>
8g87ju7uka8mcb316x6x4kqww76hxqy
Template:Getalias2/core
10
52489
308456
2026-09-17T16:25:55Z
Isma4l
41797
Bog cusub: {{#if:{{{variant|}}}|{{{{{{name}}}-{{{variant}}}|{{{{{{name}}}}}}}}}|{{{{{{name}}}}}}}}<noinclude> {{Documentation|content=This template is used internally by {{tl|Getalias2}} and should not be used directly.}} [[Category:Flag template system cores]] </noinclude>
308456
wikitext
text/x-wiki
{{#if:{{{variant|}}}|{{{{{{name}}}-{{{variant}}}|{{{{{{name}}}}}}}}}|{{{{{{name}}}}}}}}<noinclude>
{{Documentation|content=This template is used internally by {{tl|Getalias2}} and should not be used directly.}}
[[Category:Flag template system cores]]
</noinclude>
ssnmytqj5xe9ej30r5f2l246byoquzc
Template:Cite NatureServe
10
52490
308457
2026-09-17T16:26:52Z
Isma4l
41797
Bog cusub: <includeonly>{{#invoke:template wrapper|wrap|_template=cite web|_exclude=id | url = https://explorer.natureserve.org/Taxon/ELEMENT_GLOBAL.{{{id|}}}/ | last1 = NatureServe | author-link1 = NatureServe | website = NatureServe Explorer | location = Arlington, Virginia | language = en }}</includeonly><noinclude> {{Documentation}} </noinclude>
308457
wikitext
text/x-wiki
<includeonly>{{#invoke:template wrapper|wrap|_template=cite web|_exclude=id
| url = https://explorer.natureserve.org/Taxon/ELEMENT_GLOBAL.{{{id|}}}/
| last1 = NatureServe
| author-link1 = NatureServe
| website = NatureServe Explorer
| location = Arlington, Virginia
| language = en
}}</includeonly><noinclude>
{{Documentation}}
</noinclude>
pqiphwa4or9qs5tgxqepk0uphars7cy
Module:Professional wrestling profiles
828
52491
308458
2026-09-17T16:27:35Z
Isma4l
41797
Bog cusub: local getArgs = require('Module:Arguments').getArgs local p = {} local profiles = { { key = "wwe", name = "WWE", person = { url = "https://www.wwe.com/superstars/%s", wikidata = "P2857" }, team = { url = "https://www.wwe.com/superstars/%s", wikidata = "P2857" }, stable = { url = "https://www.wwe.com/superstars/%s", wikidata = "P2857" } }, { key = "roh", name = "Ring of Honor", person = { url = "https://www.ringofhonor.com/active-roster/%s", wikidata = nil },...
308458
Scribunto
text/plain
local getArgs = require('Module:Arguments').getArgs
local p = {}
local profiles = {
{
key = "wwe",
name = "WWE",
person = { url = "https://www.wwe.com/superstars/%s", wikidata = "P2857" },
team = { url = "https://www.wwe.com/superstars/%s", wikidata = "P2857" },
stable = { url = "https://www.wwe.com/superstars/%s", wikidata = "P2857" }
},
{
key = "roh",
name = "Ring of Honor",
person = { url = "https://www.ringofhonor.com/active-roster/%s", wikidata = nil },
team = { url = nil, wikidata = nil },
stable = { url = nil, wikidata = nil }
},
{
key = "njpw",
name = "New Japan Pro-Wrestling",
person = { url = "https://www.njpw1972.com/profile/%s", wikidata = nil },
team = { url = nil, wikidata = nil },
stable = { url = nil, wikidata = nil }
},
{
key = "cagematch",
name = "Cagematch",
person = { url = "https://www.cagematch.net/?id=2&nr=%s", wikidata = "P2728" },
team = { url = "https://www.cagematch.net/?id=28&nr=%s", wikidata = "P2939" },
stable = { url = "https://www.cagematch.net/?id=29&nr=%s", wikidata = "P3042" }
},
{
key = "wrestlingdata",
name = "Wrestlingdata",
person = { url = "https://www.wrestlingdata.com/index.php?befehl=bios&wrestler=%s", wikidata = "P2764" },
team = { url = "https://www.wrestlingdata.com/index.php?befehl=stables&stable=%s", wikidata = nil },
stable = { url = "https://www.wrestlingdata.com/index.php?befehl=stables&stable=%s", wikidata = nil }
},
{
key = "iwd",
name = "Internet Wrestling Database",
person = { url = "http://www.profightdb.com/wrestlers/%s.html", wikidata = "P2829" },
team = { url = nil, wikidata = nil },
stable = { url = nil, wikidata = nil }
},
{
key = "wrestlingtitles",
name = "Wrestling-Titles",
person = { url = "https://www.wrestling-titles.com/personalities/%s/", wikidata = nil },
team = { url = nil, wikidata = nil },
stable = { url = nil, wikidata = nil }
}
}
local function fetch_wikidata(entity, property)
if entity and property then
local value = entity:getBestStatements(property)[1]
if value then
return value["mainsnak"]["datavalue"]["value"]
end
end
return nil
end
function p.profiles(frame)
local args = getArgs(frame)
local entity = mw.wikibase.getEntity()
local _type = "person"
local text = ""
-- Determine type
if args["type"] and (args["type"] == "person" or args["type"] == "team" or args["type"] == "stable") then
_type = args["type"]
else
local instance = fetch_wikidata(entity, "P31") -- "instance of" on Wikidata
local types = {
["Q5"] = "person", -- "human"
["Q1066670"] = "team", -- "tag team"
["Q25178247"] = "stable" -- "professional wrestling stable"
}
if instance and types[instance.id] then
_type = types[instance.id]
end
end
-- Parse profiles
for index, data in ipairs(profiles) do
local value = args[data["key"]] or fetch_wikidata(entity, data[_type]["wikidata"])
if value and data[_type]["url"] then
text = text
.. string.format("[" .. data[_type]["url"] .. " " .. data["name"] .. "]", value)
.. (args[data["key"]] and "" or frame:expandTemplate{title = 'EditAtWikidata', args = { pid = data[_type]["wikidata"] }})
.. ", "
end
end
if text == "" then
return mw.title.getCurrentTitle().namespace == 0 and "[[Category:Professional wrestling profiles template without any identifiers]]" or nil
end
return (args["name"] or frame:expandTemplate{title = 'PAGENAMEBASE'}) .. "'s profile at " .. string.sub(text, 1, -3)
end
return p
h3rlfmn2355yia23tw7t3btnf50vg8u
Template:Professional wrestling profiles
10
52492
308459
2026-09-17T16:29:01Z
Isma4l
41797
Bog cusub: <includeonly>{{#invoke:Professional wrestling profiles|profiles}}</includeonly><noinclude>{{Documentation}}</noinclude>
308459
wikitext
text/x-wiki
<includeonly>{{#invoke:Professional wrestling profiles|profiles}}</includeonly><noinclude>{{Documentation}}</noinclude>
6mkfk6eftvwjngjes14wll8gt93acps
Module:Template test case/config
828
52493
308460
2026-09-17T16:30:26Z
Isma4l
41797
Bog cusub: ------------------------------------------------------------------------------- -- Module:Template test case/config -- This module holds configuration data for [[Module:Template test case]]. ------------------------------------------------------------------------------- return { ------------------------------------------------------------------------------- -- Options ------------------------------------------------------------------------------- -- The magi...
308460
Scribunto
text/plain
-------------------------------------------------------------------------------
-- Module:Template test case/config
-- This module holds configuration data for [[Module:Template test case]].
-------------------------------------------------------------------------------
return {
-------------------------------------------------------------------------------
-- Options
-------------------------------------------------------------------------------
-- The magic word used in place of the template name when making nowiki
-- invocations.
templateNameMagicWord = '__TEMPLATENAME__',
-- The subpage that sandboxes are typically stored on. Used when loading
-- wrapper template config and when guessing the sandbox template name.
sandboxSubpage = 'sandbox',
-------------------------------------------------------------------------------
-- Messages
-------------------------------------------------------------------------------
msg = {
-- The default header for test cases rendered in columns.
['columns-header'] = 'Side by side comparison',
-- The error message to use if a template option is missing.
-- $1 - the number of the missing template option.
['missing-template-option-error'] = "one or more options ending in '$1' " ..
"were detected, but no 'template$1' option was found",
-- The error message to use if a nowiki invocation is used but the template
-- name magic word is not found.
-- $1 - the value of the template name magic word
['nowiki-magic-word-error'] = "the template invocation must include '$1' in " ..
"place of the template name",
},
-------------------------------------------------------------------------------
-- Wrapper template config.
-- The wrapper template config is a table with wrapper template names as keys,
-- and subtables containing two fields:
-- func - the function name to be used with that template. This must be a
-- function exported by the main module. This is optional: the default
-- value is "table".
-- args - a table of default arguments to be used with that template. This is
-- is optional.
-------------------------------------------------------------------------------
wrappers = {
['Template:Test case'] = {},
['Template:Testcase table'] = {
args = {_format = 'columns'}
},
['Template:Testcase rows'] = {
args = {_format = 'rows'}
},
['Template:Test case nowiki'] = {
func = 'nowiki'
},
['Template:Nowiki template demo'] = {
func = 'nowiki',
args = {showheader = false, showtemplate2 = false}
},
['Template:Collapsible test case'] = {
args = {_collapsible = true}
},
['Template:Collapsible 2 test case'] = {
args = {_collapsible = true, _wantdiff = true}
},
['Template:Inline test case'] = {
args = {_format = 'inline', _showcode = true}
},
},
-------------------------------------------------------------------------------
-- End config
-------------------------------------------------------------------------------
}
ls9rvym0pi5xrbhs2q9kgqx1nenxr3g
Module:Template test case
828
52494
308461
2026-09-17T16:31:16Z
Isma4l
41797
Bog cusub: --[[ A module for generating test case templates. This module incorporates code from the English Wikipedia's "Testcase table" module,[1] written by Frietjes [2] with contributions by Mr. Stradivarius [3] and Jackmcbarn,[4] and the English Wikipedia's "Testcase rows" module,[5] written by Mr. Stradivarius. The "Testcase table" and "Testcase rows" modules are released under the CC BY-SA 3.0 License [6] and the GFDL.[7] License: CC BY-SA 3.0 and the GFDL...
308461
Scribunto
text/plain
--[[
A module for generating test case templates.
This module incorporates code from the English Wikipedia's "Testcase table"
module,[1] written by Frietjes [2] with contributions by Mr. Stradivarius [3]
and Jackmcbarn,[4] and the English Wikipedia's "Testcase rows" module,[5]
written by Mr. Stradivarius.
The "Testcase table" and "Testcase rows" modules are released under the
CC BY-SA 3.0 License [6] and the GFDL.[7]
License: CC BY-SA 3.0 and the GFDL
Author: Mr. Stradivarius
[1] https://en.wikipedia.org/wiki/Module:Testcase_table
[2] https://en.wikipedia.org/wiki/User:Frietjes
[3] https://en.wikipedia.org/wiki/User:Mr._Stradivarius
[4] https://en.wikipedia.org/wiki/User:Jackmcbarn
[5] https://en.wikipedia.org/wiki/Module:Testcase_rows
[6] https://en.wikipedia.org/wiki/Wikipedia:Text_of_Creative_Commons_Attribution-ShareAlike_3.0_Unported_License
[7] https://en.wikipedia.org/wiki/Wikipedia:Text_of_the_GNU_Free_Documentation_License
]]
-- Load required modules
local yesno = require('Module:Yesno')
-- Set constants
local DATA_MODULE = 'Module:Template test case/data'
local SYNTAXHIGHLIGHT_IS_PRESENT = mw.getCurrentFrame():preprocess( "<syntaxhighlight lang=\"text\"></syntaxhighlight>" ) ~= "<syntaxhighlight lang=\"text\"></syntaxhighlight>"
-------------------------------------------------------------------------------
-- Shared methods
-------------------------------------------------------------------------------
local function message(self, key, ...)
-- This method is added to classes that need to deal with messages from the
-- config module.
local msg = self.cfg.msg[key]
if select(1, ...) then
return mw.message.newRawMessage(msg, ...):plain()
else
return msg
end
end
-------------------------------------------------------------------------------
-- Template class
-------------------------------------------------------------------------------
local Template = {}
Template.memoizedMethods = {
-- Names of methods to be memoized in each object. This table should only
-- hold methods with no parameters.
getFullPage = true,
getName = true,
makeHeader = true,
getOutput = true
}
function Template.new(invocationObj, options)
local obj = {}
-- Set input
for k, v in pairs(options or {}) do
if not Template[k] then
obj[k] = v
end
end
obj._invocation = invocationObj
-- Validate input
if not obj.template and not obj.title then
error('no template or title specified', 2)
end
-- Memoize expensive method calls
local memoFuncs = {}
return setmetatable(obj, {
__index = function (t, key)
if Template.memoizedMethods[key] then
local func = memoFuncs[key]
if not func then
local val = Template[key](t)
func = function () return val end
memoFuncs[key] = func
end
return func
else
return Template[key]
end
end
})
end
function Template:getFullPage()
if not self.template then
return self.title.prefixedText
elseif self.template:sub(1, 7) == '#invoke' then
return 'Module' .. self.template:sub(8):gsub('|.*', '')
else
local strippedTemplate, hasColon = self.template:gsub('^:', '', 1)
hasColon = hasColon > 0
local ns = strippedTemplate:match('^(.-):')
ns = ns and mw.site.namespaces[ns]
if ns then
return strippedTemplate
elseif hasColon then
return strippedTemplate -- Main namespace
else
return mw.site.namespaces[10].name .. ':' .. strippedTemplate
end
end
end
function Template:getName()
if self.template then
return self.template
else
return require('Module:Template invocation').name(self.title)
end
end
function Template:makeLink(display)
if display then
return string.format('[[:%s|%s]]', self:getFullPage(), display)
else
return string.format('[[:%s]]', self:getFullPage())
end
end
function Template:makeBraceLink(display)
display = display or self:getName()
local link = self:makeLink(display)
return mw.text.nowiki('{{') .. link .. mw.text.nowiki('}}')
end
function Template:makeHeader()
return self.heading or self:makeBraceLink()
end
function Template:getInvocation(format)
format = format or ''
local invocation = self._invocation:getInvocation{
template = self:getName(),
requireMagicWord = self.requireMagicWord,
}
if format == 'code' or (not SYNTAXHIGHLIGHT_IS_PRESENT and format == 'inline') then
-- if syntaxhighlight not present and inline required use code
invocation = '<code>' .. mw.text.nowiki(invocation) .. '</code>'
elseif format == 'kbd' then
invocation = '<kbd>' .. mw.text.nowiki(invocation) .. '</kbd>'
elseif format == 'plain' then
invocation = mw.text.nowiki(invocation)
elseif format == 'pre' or not SYNTAXHIGHLIGHT_IS_PRESENT then
-- if syntaxhighlight not present and block required use pre
invocation = mw.text.encode(invocation, '&')
invocation = '<pre style="white-space: pre-wrap;">' .. invocation .. '</pre>'
invocation = mw.getCurrentFrame():preprocess(invocation)
else
-- use syntaxhighlight as default if present
invocation = mw.text.encode(invocation, '&')
invocation = mw.getCurrentFrame():preprocess( '<syntaxhighlight lang="wikitext"' .. ( format == 'inline' and ' inline' or '') .. '>' .. invocation .. '</syntaxhighlight>' )
end
return invocation
end
function Template:getOutput()
local protect = require('Module:Protect')
-- calling self._invocation:getOutput{...}
return protect(self._invocation.getOutput)(self._invocation, {
template = self:getName(),
requireMagicWord = self.requireMagicWord,
})
end
-------------------------------------------------------------------------------
-- TestCase class
-------------------------------------------------------------------------------
local TestCase = {}
TestCase.__index = TestCase
TestCase.message = message -- add the message method
TestCase.renderMethods = {
-- Keys in this table are values of the "format" option, values are the
-- method for rendering that format.
columns = 'renderColumns',
rows = 'renderRows',
tablerows = 'renderRows',
inline = 'renderInline',
cells = 'renderCells',
default = 'renderDefault'
}
function TestCase.new(invocationObj, options, cfg)
local obj = setmetatable({}, TestCase)
obj.cfg = cfg
-- Separate general options from template options. Template options are
-- numbered, whereas general options are not.
local generalOptions, templateOptions = {}, {}
for k, v in pairs(options) do
local prefix, num
if type(k) == 'string' then
prefix, num = k:match('^(.-)([1-9][0-9]*)$')
end
if prefix then
num = tonumber(num)
templateOptions[num] = templateOptions[num] or {}
templateOptions[num][prefix] = v
else
generalOptions[k] = v
end
end
-- Set general options
generalOptions.showcode = yesno(generalOptions.showcode)
generalOptions.showheader = yesno(generalOptions.showheader) ~= false
generalOptions.showcaption = yesno(generalOptions.showcaption) ~= false
generalOptions.collapsible = yesno(generalOptions.collapsible)
generalOptions.notcollapsed = yesno(generalOptions.notcollapsed)
generalOptions.wantdiff = yesno(generalOptions.wantdiff)
obj.options = generalOptions
-- Preprocess template args
for num, t in pairs(templateOptions) do
if t.showtemplate ~= nil then
t.showtemplate = yesno(t.showtemplate)
end
end
-- Set up first two template options tables, so that if only the
-- "template3" is specified it isn't made the first template when the
-- the table options array is compressed.
templateOptions[1] = templateOptions[1] or {}
templateOptions[2] = templateOptions[2] or {}
-- Allow the "template" option to override the "template1" option for
-- backwards compatibility with [[Module:Testcase table]].
if generalOptions.template then
templateOptions[1].template = generalOptions.template
end
-- Add default template options
if templateOptions[1].template and not templateOptions[2].template then
templateOptions[2].template = templateOptions[1].template ..
'/' .. obj.cfg.sandboxSubpage
end
if not templateOptions[1].template then
templateOptions[1].title = mw.title.getCurrentTitle().basePageTitle
end
if not templateOptions[2].template then
templateOptions[2].title = templateOptions[1].title:subPageTitle(
obj.cfg.sandboxSubpage
)
end
-- Remove template options for any templates where the showtemplate
-- argument is false. This prevents any output for that template.
for num, t in pairs(templateOptions) do
if t.showtemplate == false then
templateOptions[num] = nil
end
end
-- Check for missing template names.
for num, t in pairs(templateOptions) do
if not t.template and not t.title then
error(obj:message(
'missing-template-option-error',
num, num
), 2)
end
end
-- Compress templateOptions table so we can iterate over it with ipairs.
templateOptions = (function (t)
local nums = {}
for num in pairs(t) do
nums[#nums + 1] = num
end
table.sort(nums)
local ret = {}
for i, num in ipairs(nums) do
ret[i] = t[num]
end
return ret
end)(templateOptions)
-- Don't require the __TEMPLATENAME__ magic word for nowiki invocations if
-- there is only one template being output.
if #templateOptions <= 1 then
templateOptions[1].requireMagicWord = false
end
mw.logObject(templateOptions)
-- Make the template objects
obj.templates = {}
for i, options in ipairs(templateOptions) do
table.insert(obj.templates, Template.new(invocationObj, options))
end
-- Add tracking categories. At the moment we are only tracking templates
-- that use any "heading" parameters or an "output" parameter.
obj.categories = {}
for k, v in pairs(options) do
if type(k) == 'string' and k:find('heading') then
obj.categories['Test cases using heading parameters'] = true
elseif k == 'output' then
obj.categories['Test cases using output parameter'] = true
end
end
return obj
end
function TestCase:getTemplateOutput(templateObj)
local output = templateObj:getOutput()
if self.options.resetRefs then
mw.getCurrentFrame():extensionTag('references')
end
return output
end
function TestCase:templateOutputIsEqual()
-- Returns a boolean showing whether all of the template outputs are equal.
-- The random parts of strip markers (see [[Help:Strip markers]]) are
-- removed before comparison. This means a strip marker can contain anything
-- and still be treated as equal, but it solves the problem of otherwise
-- identical wikitext not returning as exactly equal.
local function normaliseOutput(obj)
local out = obj:getOutput()
-- Remove the random parts from strip markers.
out = out:gsub('(\127[^\127]*UNIQ%-%-%l+%-)%x+(%-%-?QINU[^\127]*\127)', '%1%2')
return out
end
local firstOutput = normaliseOutput(self.templates[1])
for i = 2, #self.templates do
local output = normaliseOutput(self.templates[i])
if output ~= firstOutput then
return false
end
end
return true
end
function TestCase:makeCollapsible(s)
local title = self.options.title or self.templates[1]:makeHeader()
if self.options.titlecode then
title = self.templates[1]:getInvocation('kbd')
end
local isEqual = self:templateOutputIsEqual()
local root = mw.html.create('div')
root
:wikitext(mw.getCurrentFrame():extensionTag{
name = 'templatestyles',
args = { src = 'Module:Template test case/styles.css' },
})
:addClass('mw-collapsible')
:addClass('test-case-collapsible')
:addClass(self.options.notcollapsed == false and 'mw-collapsed' or nil)
if self.options.wantdiff then
root
:tag('div')
:addClass(isEqual and 'test-case-collapsible-b1' or 'test-case-collapsible-b2')
:wikitext(title)
:done()
else
if self.options.notcollapsed ~= true or false then
root
:addClass(isEqual and 'mw-collapsed' or nil)
end
root
:tag('div')
:addClass(isEqual and 'test-case-collapsible-b3' or 'test-case-collapsible-b1')
:wikitext(title)
:done()
end
root
:tag('div')
:addClass('mw-collapsible-content')
:newline()
:wikitext(s)
:newline()
return tostring(root)
end
function TestCase:renderColumns()
local root = mw.html.create()
if self.options.showcode then
root
:wikitext(self.templates[1]:getInvocation())
:newline()
end
local tableroot = root:tag('table')
if self.options.showheader then
-- Caption
if self.options.showcaption then
tableroot
:addClass(self.options.class)
:cssText(self.options.style)
:tag('caption')
:wikitext(self.options.caption or self:message('columns-header'))
end
-- Headers
local headerRow = tableroot:tag('tr')
if self.options.rowheader then
-- rowheader is correct here. We need to add another th cell if
-- rowheader is set further down, even if heading0 is missing.
headerRow:tag('th'):wikitext(self.options.heading0)
end
local width
if #self.templates > 0 then
width = tostring(math.floor(100 / #self.templates)) .. '%'
else
width = '100%'
end
for i, obj in ipairs(self.templates) do
headerRow
:tag('th')
:css('width', width)
:wikitext(obj:makeHeader())
end
end
-- Row header
local dataRow = tableroot:tag('tr'):css('vertical-align', 'top')
if self.options.rowheader then
dataRow:tag('th')
:attr('scope', 'row')
:wikitext(self.options.rowheader)
end
-- Template output
for i, obj in ipairs(self.templates) do
if self.options.output == 'nowiki+' then
dataRow:tag('td')
:newline()
:wikitext(self.options.before)
:wikitext(self:getTemplateOutput(obj))
:wikitext(self.options.after)
:wikitext('<pre style="white-space: pre-wrap;">')
:wikitext(mw.text.nowiki(self.options.before or ""))
:wikitext(mw.text.nowiki(self:getTemplateOutput(obj)))
:wikitext(mw.text.nowiki(self.options.after or ""))
:wikitext('</pre>')
elseif self.options.output == 'nowiki' then
dataRow:tag('td')
:newline()
:wikitext(mw.text.nowiki(self.options.before or ""))
:wikitext(mw.text.nowiki(self:getTemplateOutput(obj)))
:wikitext(mw.text.nowiki(self.options.after or ""))
else
dataRow:tag('td')
:newline()
:wikitext(self.options.before)
:wikitext(self:getTemplateOutput(obj))
:wikitext(self.options.after)
end
end
return tostring(root)
end
function TestCase:renderRows()
local root = mw.html.create()
if self.options.showcode then
root
:wikitext(self.templates[1]:getInvocation())
:newline()
end
local tableroot = root:tag('table')
tableroot
:addClass(self.options.class)
:cssText(self.options.style)
if self.options.caption then
tableroot
:tag('caption')
:wikitext(self.options.caption)
end
for _, obj in ipairs(self.templates) do
local dataRow = tableroot:tag('tr')
-- Header
if self.options.showheader then
if self.options.format == 'tablerows' then
dataRow:tag('th')
:attr('scope', 'row')
:css('vertical-align', 'top')
:css('text-align', 'left')
:wikitext(obj:makeHeader())
dataRow:tag('td')
:css('vertical-align', 'top')
:css('padding', '0 1em')
:wikitext('→')
else
dataRow:tag('td')
:css('text-align', 'center')
:css('font-weight', 'bold')
:wikitext(obj:makeHeader())
dataRow = tableroot:tag('tr')
end
end
-- Template output
if self.options.output == 'nowiki+' then
dataRow:tag('td')
:newline()
:wikitext(self.options.before)
:wikitext(self:getTemplateOutput(obj))
:wikitext(self.options.after)
:wikitext('<pre style="white-space: pre-wrap;">')
:wikitext(mw.text.nowiki(self.options.before or ""))
:wikitext(mw.text.nowiki(self:getTemplateOutput(obj)))
:wikitext(mw.text.nowiki(self.options.after or ""))
:wikitext('</pre>')
elseif self.options.output == 'nowiki' then
dataRow:tag('td')
:newline()
:wikitext(mw.text.nowiki(self.options.before or ""))
:wikitext(mw.text.nowiki(self:getTemplateOutput(obj)))
:wikitext(mw.text.nowiki(self.options.after or ""))
else
dataRow:tag('td')
:newline()
:wikitext(self.options.before)
:wikitext(self:getTemplateOutput(obj))
:wikitext(self.options.after)
end
end
return tostring(root)
end
function TestCase:renderInline()
local arrow = mw.language.getContentLanguage():getArrow('forwards')
local ret = {}
for i, obj in ipairs(self.templates) do
local line = {}
line[#line + 1] = self.options.prefix or '* '
if self.options.showcode then
line[#line + 1] = obj:getInvocation('inline')
line[#line + 1] = ' '
line[#line + 1] = arrow
line[#line + 1] = ' '
end
if self.options.output == 'nowiki+' then
line[#line + 1] = self.options.before or ""
line[#line + 1] = self:getTemplateOutput(obj)
line[#line + 1] = self.options.after or ""
line[#line + 1] = '<pre style="white-space: pre-wrap;">'
line[#line + 1] = mw.text.nowiki(self.options.before or "")
line[#line + 1] = mw.text.nowiki(self:getTemplateOutput(obj))
line[#line + 1] = mw.text.nowiki(self.options.after or "")
line[#line + 1] = '</pre>'
elseif self.options.output == 'nowiki' then
line[#line + 1] = mw.text.nowiki(self.options.before or "")
line[#line + 1] = mw.text.nowiki(self:getTemplateOutput(obj))
line[#line + 1] = mw.text.nowiki(self.options.after or "")
else
line[#line + 1] = self.options.before or ""
line[#line + 1] = self:getTemplateOutput(obj)
line[#line + 1] = self.options.after or ""
end
ret[#ret + 1] = table.concat(line)
end
if self.options.addline then
local line = {}
line[#line + 1] = self.options.prefix or '* '
line[#line + 1] = self.options.addline
ret[#ret + 1] = table.concat(line)
end
return table.concat(ret, '\n')
end
function TestCase:renderCells()
local root = mw.html.create()
local dataRow = root:tag('tr')
dataRow
:css('vertical-align', 'top')
:addClass(self.options.class)
:cssText(self.options.style)
-- Row header
if self.options.rowheader then
dataRow:tag('th')
:attr('scope', 'row')
:newline()
:wikitext(self.options.rowheader or self:message('row-header'))
end
-- Caption
if self.options.showcaption then
dataRow:tag('th')
:attr('scope', 'row')
:newline()
:wikitext(self.options.caption or self:message('columns-header'))
end
-- Show code
if self.options.showcode then
dataRow:tag('td')
:newline()
:wikitext(self:getInvocation('inline'))
end
-- Template output
for i, obj in ipairs(self.templates) do
if self.options.output == 'nowiki+' then
dataRow:tag('td')
:newline()
:wikitext(self.options.before)
:wikitext(self:getTemplateOutput(obj))
:wikitext(self.options.after)
:wikitext('<pre style="white-space: pre-wrap;">')
:wikitext(mw.text.nowiki(self.options.before or ""))
:wikitext(mw.text.nowiki(self:getTemplateOutput(obj)))
:wikitext(mw.text.nowiki(self.options.after or ""))
:wikitext('</pre>')
elseif self.options.output == 'nowiki' then
dataRow:tag('td')
:newline()
:wikitext(mw.text.nowiki(self.options.before or ""))
:wikitext(mw.text.nowiki(self:getTemplateOutput(obj)))
:wikitext(mw.text.nowiki(self.options.after or ""))
else
dataRow:tag('td')
:newline()
:wikitext(self.options.before)
:wikitext(self:getTemplateOutput(obj))
:wikitext(self.options.after)
end
end
return tostring(root)
end
function TestCase:renderDefault()
local ret = {}
if self.options.showcode then
ret[#ret + 1] = self.templates[1]:getInvocation()
end
for i, obj in ipairs(self.templates) do
ret[#ret + 1] = '<div style="clear: both;"></div>'
if self.options.showheader then
ret[#ret + 1] = obj:makeHeader()
end
if self.options.output == 'nowiki+' then
ret[#ret + 1] = (self.options.before or "") ..
self:getTemplateOutput(obj) ..
(self.options.after or "") ..
'<pre style="white-space: pre-wrap;">' ..
mw.text.nowiki(self.options.before or "") ..
mw.text.nowiki(self:getTemplateOutput(obj)) ..
mw.text.nowiki(self.options.after or "") .. '</pre>'
elseif self.options.output == 'nowiki' then
ret[#ret + 1] = mw.text.nowiki(self.options.before or "") ..
mw.text.nowiki(self:getTemplateOutput(obj)) ..
mw.text.nowiki(self.options.after or "")
else
ret[#ret + 1] = (self.options.before or "") ..
self:getTemplateOutput(obj) ..
(self.options.after or "")
end
end
return table.concat(ret, '\n\n')
end
function TestCase:__tostring()
local format = self.options.format
local method = format and TestCase.renderMethods[format] or 'renderDefault'
local ret = self[method](self)
if self.options.collapsible then
ret = self:makeCollapsible(ret)
end
for cat in pairs(self.categories) do
ret = ret .. string.format('[[Category:%s]]', cat)
end
return ret
end
-------------------------------------------------------------------------------
-- Nowiki invocation class
-------------------------------------------------------------------------------
local NowikiInvocation = {}
NowikiInvocation.__index = NowikiInvocation
NowikiInvocation.message = message -- Add the message method
function NowikiInvocation.new(invocation, cfg)
local obj = setmetatable({}, NowikiInvocation)
obj.cfg = cfg
invocation = mw.text.unstrip(invocation)
-- Decode HTML entities for <, >, and ". This means that HTML entities in
-- the original code must be escaped as e.g. &lt;, which is unfortunate,
-- but it is the best we can do as the distinction between <, >, " and <,
-- >, " is lost during the original nowiki operation.
invocation = invocation:gsub('<', '<')
invocation = invocation:gsub('>', '>')
invocation = invocation:gsub('"', '"')
obj.invocation = invocation
return obj
end
function NowikiInvocation:getInvocation(options)
local template = options.template:gsub('%%', '%%%%') -- Escape "%" with "%%"
local invocation, count = self.invocation:gsub(
self.cfg.templateNameMagicWordPattern,
template
)
if options.requireMagicWord ~= false and count < 1 then
error(self:message(
'nowiki-magic-word-error',
self.cfg.templateNameMagicWord
))
end
return invocation
end
function NowikiInvocation:getOutput(options)
local invocation = self:getInvocation(options)
return mw.getCurrentFrame():preprocess(invocation)
end
-------------------------------------------------------------------------------
-- Table invocation class
-------------------------------------------------------------------------------
local TableInvocation = {}
TableInvocation.__index = TableInvocation
TableInvocation.message = message -- Add the message method
function TableInvocation.new(invokeArgs, nowikiCode, cfg)
local obj = setmetatable({}, TableInvocation)
obj.cfg = cfg
obj.invokeArgs = invokeArgs
obj.code = nowikiCode
return obj
end
function TableInvocation:getInvocation(options)
if self.code then
local nowikiObj = NowikiInvocation.new(self.code, self.cfg)
return nowikiObj:getInvocation(options)
else
return require('Module:Template invocation').invocation(
options.template,
self.invokeArgs
)
end
end
function TableInvocation:getOutput(options)
if (options.template:sub(1, 7) == '#invoke') then
local moduleCall = mw.text.split(options.template, '|', true)
local args = mw.clone(self.invokeArgs)
table.insert(args, 1, moduleCall[2])
return mw.getCurrentFrame():callParserFunction(moduleCall[1], args)
end
return mw.getCurrentFrame():expandTemplate{
title = options.template,
args = self.invokeArgs
}
end
-------------------------------------------------------------------------------
-- Bridge functions
--
-- These functions translate template arguments into forms that can be accepted
-- by the different classes, and return the results.
-------------------------------------------------------------------------------
local bridge = {}
function bridge.table(args, cfg)
cfg = cfg or mw.loadData(DATA_MODULE)
local options, invokeArgs = {}, {}
for k, v in pairs(args) do
local optionKey = type(k) == 'string' and k:match('^_(.*)$')
if optionKey then
if type(v) == 'string' then
v = v:match('^%s*(.-)%s*$') -- trim whitespace
end
if v ~= '' then
options[optionKey] = v
end
else
invokeArgs[k] = v
end
end
-- Allow passing a nowiki invocation as an option. While this means users
-- have to pass in the code twice, whitespace is preserved and < etc.
-- will work as intended.
local nowikiCode = options.code
options.code = nil
local invocationObj = TableInvocation.new(invokeArgs, nowikiCode, cfg)
local testCaseObj = TestCase.new(invocationObj, options, cfg)
return tostring(testCaseObj)
end
function bridge.nowiki(args, cfg)
cfg = cfg or mw.loadData(DATA_MODULE)
-- Convert args beginning with _ for consistency with the normal bridge
local newArgs = {}
for k, v in pairs(args) do
local normalName = type(k) == "string" and string.match(k, "^_(.*)$")
if normalName then
newArgs[normalName] = v
else
newArgs[k] = v
end
end
local code = newArgs.code or newArgs[1]
local invocationObj = NowikiInvocation.new(code, cfg)
newArgs.code = nil
newArgs[1] = nil
-- Assume we want to see the code as we already passed it in.
newArgs.showcode = newArgs.showcode or true
local testCaseObj = TestCase.new(invocationObj, newArgs, cfg)
return tostring(testCaseObj)
end
-------------------------------------------------------------------------------
-- Exports
-------------------------------------------------------------------------------
local p = {}
function p.main(frame, cfg)
cfg = cfg or mw.loadData(DATA_MODULE)
-- Load the wrapper config, if any.
local wrapperConfig
if frame.getParent then
local title = frame:getParent():getTitle()
local template = title:gsub(cfg.sandboxSubpagePattern, '')
wrapperConfig = cfg.wrappers[template]
end
-- Work out the function we will call, use it to generate the config for
-- Module:Arguments, and use Module:Arguments to find the arguments passed
-- by the user.
local func = wrapperConfig and wrapperConfig.func or 'table'
local userArgs = require('Module:Arguments').getArgs(frame, {
parentOnly = wrapperConfig,
frameOnly = not wrapperConfig,
trim = func ~= 'table',
removeBlanks = func ~= 'table'
})
-- Get default args and build the args table. User-specified args overwrite
-- default args.
local defaultArgs = wrapperConfig and wrapperConfig.args or {}
local args = {}
for k, v in pairs(defaultArgs) do
args[k] = v
end
for k, v in pairs(userArgs) do
args[k] = v
end
return bridge[func](args, cfg)
end
function p._exportClasses() -- For testing
return {
Template = Template,
TestCase = TestCase,
NowikiInvocation = NowikiInvocation,
TableInvocation = TableInvocation
}
end
return p
saiu0jsc1rxo0bujmsl0mtks0pxrp9l
Module:Template test case/styles.css
828
52495
308462
2026-09-17T16:31:46Z
Isma4l
41797
Bog cusub: /* {{pp-template}} */ .test-case-collapsible { width: 100%; border: 1px solid silver; padding: 0.2em; margin: 1em 0; margin-top: -1px; clear: both; color: inherit; box-sizing: border-box; } .test-case-collapsible .mw-collapsible-content > ul { margin-left: 0; } .mw-collapsible.test-case-collapsible.mw-made-collapsible .mw-collapsible-content { padding: 0.5em 1em; } .mw-collapsible.test-case-collapsible.mw-made-collapsible.mw-collapsed { margin-bottom: 0; marg...
308462
sanitized-css
text/css
/* {{pp-template}} */
.test-case-collapsible {
width: 100%;
border: 1px solid silver;
padding: 0.2em;
margin: 1em 0;
margin-top: -1px;
clear: both;
color: inherit;
box-sizing: border-box;
}
.test-case-collapsible .mw-collapsible-content > ul {
margin-left: 0;
}
.mw-collapsible.test-case-collapsible.mw-made-collapsible .mw-collapsible-content {
padding: 0.5em 1em;
}
.mw-collapsible.test-case-collapsible.mw-made-collapsible.mw-collapsed {
margin-bottom: 0;
margin-top: -1px;
}
div.mw-collapsible-content > ul > li {
display: block;
}
.test-case-collapsible-b1 {
background-color: var(--background-color-warning-subtle, #fdf2d5);
margin: 1px;
}
.test-case-collapsible-b2 {
background-color: var(--background-color-content-added, #a3d3ff);
margin: 1px;
}
.test-case-collapsible-b3 {
background-color: var(--background-color-success-subtle, #dff2eb);
margin: 1px;
}
@media screen {
html.skin-theme-clientpref-night .test-case-collapsible-b1 {
background-color: #453217;
}
html.skin-theme-clientpref-night .test-case-collapsible-b2 {
background-color: #233566;
}
html.skin-theme-clientpref-night .test-case-collapsible-b3 {
background-color: #003500;
}
}
@media screen and ( prefers-color-scheme: dark ) {
html.skin-theme-clientpref-os .test-case-collapsible-b1 {
background-color: #453217;
}
html.skin-theme-clientpref-os .test-case-collapsible-b2 {
background-color: #233566;
}
html.skin-theme-clientpref-os .test-case-collapsible-b3 {
background-color: #003500;
}
}
r42sby19eiy8mqrh9eyydx3ttjg2v72
Module:Template test case/data
828
52496
308463
2026-09-17T16:32:40Z
Isma4l
41797
Bog cusub: -- This module processes configuration data for use in -- [[Module:Template test case]]. It is loaded from the main module with -- mw.loadData. local cfg = require('Module:Template test case/config') local function escapePattern(s) s = s:gsub('%p', '%%%0') return s end -- Escape config items that need to be used as patterns. Doing it here is more -- efficient, as mw.loadData saves them from having to be computed for every -- test case on a page. cfg.templateNameMagicWordPatt...
308463
Scribunto
text/plain
-- This module processes configuration data for use in
-- [[Module:Template test case]]. It is loaded from the main module with
-- mw.loadData.
local cfg = require('Module:Template test case/config')
local function escapePattern(s)
s = s:gsub('%p', '%%%0')
return s
end
-- Escape config items that need to be used as patterns. Doing it here is more
-- efficient, as mw.loadData saves them from having to be computed for every
-- test case on a page.
cfg.templateNameMagicWordPattern = escapePattern(cfg.templateNameMagicWord)
cfg.sandboxSubpagePattern = '/' .. escapePattern(cfg.sandboxSubpage) .. '$'
return cfg
dmdplkk88kmnriu7s6pk3hhob51o8xa
Template:Test case
10
52497
308464
2026-09-17T16:33:13Z
Isma4l
41797
Bog cusub: <includeonly>{{#invoke:Template test case|main}}</includeonly><noinclude> {{documentation}} <!-- Categories go on the /doc subpage and interwikis go on Wikidata. --> </noinclude>
308464
wikitext
text/x-wiki
<includeonly>{{#invoke:Template test case|main}}</includeonly><noinclude>
{{documentation}}
<!-- Categories go on the /doc subpage and interwikis go on Wikidata. -->
</noinclude>
tqcbtoi20hh04qz7tcyj9c81ibksvas
Template:Testcase table
10
52498
308465
2026-09-17T16:33:44Z
Isma4l
41797
Bog cusub: <includeonly>{{#invoke:Template test case|main}}</includeonly><noinclude> {{documentation}} </noinclude>
308465
wikitext
text/x-wiki
<includeonly>{{#invoke:Template test case|main}}</includeonly><noinclude>
{{documentation}}
</noinclude>
0445uyzppdfnu1j4kj9ie42pyliyrbz
Template:Testcase rows
10
52499
308466
2026-09-17T16:41:41Z
Isma4l
41797
Bog cusub: <includeonly>{{#invoke:Template test case|main}}</includeonly><noinclude> {{documentation}} <!-- Categories go on the /doc subpage, and interwikis go on Wikidata. --> </noinclude>
308466
wikitext
text/x-wiki
<includeonly>{{#invoke:Template test case|main}}</includeonly><noinclude>
{{documentation}}
<!-- Categories go on the /doc subpage, and interwikis go on Wikidata. -->
</noinclude>
irr9qc03niujceohpr6rvkn46wvotik
Template:Collapsible test case
10
52500
308467
2026-09-17T16:42:06Z
Isma4l
41797
Bog cusub: <includeonly>{{#invoke:Template test case|main}}</includeonly><noinclude> {{documentation}} <!-- Categories go on the /doc subpage and interwikis go on Wikidata. --> </noinclude>
308467
wikitext
text/x-wiki
<includeonly>{{#invoke:Template test case|main}}</includeonly><noinclude>
{{documentation}}
<!-- Categories go on the /doc subpage and interwikis go on Wikidata. -->
</noinclude>
tqcbtoi20hh04qz7tcyj9c81ibksvas
Template:Inline test case
10
52501
308468
2026-09-17T16:42:28Z
Isma4l
41797
Bog cusub: <includeonly>{{#invoke:Template test case|main}}</includeonly><noinclude> {{documentation}} <!-- Categories go on the /doc subpage and interwikis go on Wikidata. --> </noinclude>
308468
wikitext
text/x-wiki
<includeonly>{{#invoke:Template test case|main}}</includeonly><noinclude>
{{documentation}}
<!-- Categories go on the /doc subpage and interwikis go on Wikidata. -->
</noinclude>
tqcbtoi20hh04qz7tcyj9c81ibksvas
Template:Nowiki template demo
10
52502
308470
2026-09-17T16:44:56Z
Isma4l
41797
Bog cusub: <includeonly>{{#invoke:Template test case|main}}</includeonly><noinclude> {{documentation}} <!-- Categories go on the /doc subpage and interwikis go on Wikidata. --> </noinclude>
308470
wikitext
text/x-wiki
<includeonly>{{#invoke:Template test case|main}}</includeonly><noinclude>
{{documentation}}
<!-- Categories go on the /doc subpage and interwikis go on Wikidata. -->
</noinclude>
tqcbtoi20hh04qz7tcyj9c81ibksvas
Module:ScribuntoUnit
828
52503
308471
2026-09-17T16:46:11Z
Isma4l
41797
Bog cusub: ------------------------------------------------------------------------------- -- Unit tests for Scribunto. ------------------------------------------------------------------------------- require('strict') local DebugHelper = {} local ScribuntoUnit = {} ScribuntoUnit.__meta = {} -- The cfg table contains all localisable strings and configuration, to make it -- easier to port this module to another wiki. local cfg = mw.loadData('Module:ScribuntoUnit/config') ------------------...
308471
Scribunto
text/plain
-------------------------------------------------------------------------------
-- Unit tests for Scribunto.
-------------------------------------------------------------------------------
require('strict')
local DebugHelper = {}
local ScribuntoUnit = {}
ScribuntoUnit.__meta = {}
-- The cfg table contains all localisable strings and configuration, to make it
-- easier to port this module to another wiki.
local cfg = mw.loadData('Module:ScribuntoUnit/config')
-------------------------------------------------------------------------------
-- Concatenates keys and values, ideal for displaying a template or parser function argument table.
-- @param keySeparator glue between key and value (defaults to " = ")
-- @param separator glue between different key-value pairs (defaults to ", ")
-- @example concatWithKeys({a = 1, b = 2, c = 3}, ' => ', ', ') => "a => 1, b => 2, c => 3"
--
function DebugHelper.concatWithKeys(table, keySeparator, separator)
keySeparator = keySeparator or ' = '
separator = separator or ', '
local concatted = ''
local i = 1
local first = true
local unnamedArguments = true
for k, v in pairs(table) do
if first then
first = false
else
concatted = concatted .. separator
end
if k == i and unnamedArguments then
i = i + 1
concatted = concatted .. tostring(v)
else
unnamedArguments = false
concatted = concatted .. tostring(k) .. keySeparator .. tostring(v)
end
end
return concatted
end
-------------------------------------------------------------------------------
-- Compares two tables recursively (non-table values are handled correctly as well).
-- @param ignoreMetatable if false, t1.__eq is used for the comparison
--
function DebugHelper.deepCompare(t1, t2, ignoreMetatable)
local type1 = type(t1)
local type2 = type(t2)
if type1 ~= type2 then
return false
end
if type1 ~= 'table' then
return t1 == t2
end
local metatable = getmetatable(t1)
if not ignoreMetatable and metatable and metatable.__eq then
return t1 == t2
end
for k1, v1 in pairs(t1) do
local v2 = t2[k1]
if v2 == nil or not DebugHelper.deepCompare(v1, v2) then
return false
end
end
for k2, v2 in pairs(t2) do
if t1[k2] == nil then
return false
end
end
return true
end
-------------------------------------------------------------------------------
-- Raises an error with stack information
-- @param details a table with error details
-- - should have a 'text' key which is the error message to display
-- - a 'trace' key will be added with the stack data
-- - and a 'source' key with file/line number
-- - a metatable will be added for error handling
--
function DebugHelper.raise(details, level)
level = (level or 1) + 1
details.trace = debug.traceback('', level)
details.source = string.match(details.trace, '^%s*stack traceback:%s*(%S*: )')
-- setmetatable(details, {
-- __tostring: function() return details.text end
-- })
error(details, level)
end
-------------------------------------------------------------------------------
-- when used in a test, that test gets ignored, and the skipped count increases by one.
--
function ScribuntoUnit:markTestSkipped()
DebugHelper.raise({ScribuntoUnit = true, skipped = true}, 3)
end
-------------------------------------------------------------------------------
-- Unconditionally fail a test
-- @param message optional description of the test
--
function ScribuntoUnit:fail(message)
DebugHelper.raise({ScribuntoUnit = true, text = "Test failed", message = message}, 2)
end
-------------------------------------------------------------------------------
-- Checks that the input is true
-- @param message optional description of the test
-- @param level optional number to raise error stack level by
--
function ScribuntoUnit:assertTrue(actual, message, level)
if not actual then
DebugHelper.raise({ScribuntoUnit = true, text = string.format("Failed to assert that %s is true", tostring(actual)), message = message}, 2 + (level or 0))
end
end
-------------------------------------------------------------------------------
-- Checks that the input is false
-- @param message optional description of the test
-- @param level optional number to raise error stack level by
--
function ScribuntoUnit:assertFalse(actual, message, level)
if actual then
DebugHelper.raise({ScribuntoUnit = true, text = string.format("Failed to assert that %s is false", tostring(actual)), message = message}, 2 + (level or 0))
end
end
-------------------------------------------------------------------------------
-- Checks an input string contains the expected string
-- @param message optional description of the test
-- @param plain search is made with a plain string instead of a ustring pattern
-- @param level optional number to raise error stack level by
--
function ScribuntoUnit:assertStringContains(pattern, s, plain, message, level)
if type(pattern) ~= 'string' then
DebugHelper.raise({
ScribuntoUnit = true,
text = mw.ustring.format("Pattern type error (expected string, got %s)", type(pattern)),
message = message
}, 2 + (level or 0))
end
if type(s) ~= 'string' then
DebugHelper.raise({
ScribuntoUnit = true,
text = mw.ustring.format("String type error (expected string, got %s)", type(s)),
message = message
}, 2 + (level or 0))
end
if not mw.ustring.find(s, pattern, nil, plain) then
DebugHelper.raise({
ScribuntoUnit = true,
text = mw.ustring.format('Failed to find %s "%s" in string "%s"', plain and "plain string" or "pattern", pattern, s),
message = message
}, 2 + (level or 0))
end
end
-------------------------------------------------------------------------------
-- Checks an input string doesn't contain the expected string
-- @param message optional description of the test
-- @param plain search is made with a plain string instead of a ustring pattern
-- @param level optional number to raise error stack level by
--
function ScribuntoUnit:assertNotStringContains(pattern, s, plain, message, level)
if type(pattern) ~= 'string' then
DebugHelper.raise({
ScribuntoUnit = true,
text = mw.ustring.format("Pattern type error (expected string, got %s)", type(pattern)),
message = message
}, 2 + (level or 0))
end
if type(s) ~= 'string' then
DebugHelper.raise({
ScribuntoUnit = true,
text = mw.ustring.format("String type error (expected string, got %s)", type(s)),
message = message
}, 2 + (level or 0))
end
local i, j = mw.ustring.find(s, pattern, nil, plain)
if i then
local match = mw.ustring.sub(s, i, j)
DebugHelper.raise({
ScribuntoUnit = true,
text = mw.ustring.format('Found match "%s" for %s "%s"', match, plain and "plain string" or "pattern", pattern),
message = message
}, 2 + (level or 0))
end
end
-------------------------------------------------------------------------------
-- Checks that an input has the expected value.
-- @param message optional description of the test
-- @example assertEquals(4, add(2,2), "2+2 should be 4")
-- @param level optional number to raise error stack level by
--
function ScribuntoUnit:assertEquals(expected, actual, message, level)
if type(expected) == 'number' and type(actual) == 'number' then
self:assertWithinDelta(expected, actual, 1e-8, message, (level or 0) + 1)
elseif expected ~= actual then
DebugHelper.raise({
ScribuntoUnit = true,
text = string.format("Failed to assert that %s equals expected %s", tostring(actual), tostring(expected)),
actual = actual,
expected = expected,
message = message,
}, 2 + (level or 0))
end
end
-------------------------------------------------------------------------------
-- Checks that an input does not have the expected value.
-- @param message optional description of the test
-- @example assertNotEquals(5, add(2,2), "2+2 should not be 5")
-- @param level optional number to raise error stack level by
--
function ScribuntoUnit:assertNotEquals(expected, actual, message, level)
if type(expected) == 'number' and type(actual) == 'number' then
self:assertNotWithinDelta(expected, actual, 1e-8, message, (level or 0) + 1)
elseif expected == actual then
DebugHelper.raise({
ScribuntoUnit = true,
text = string.format("Failed to assert that %s does not equal expected %s", tostring(actual), tostring(expected)),
actual = actual,
expected = expected,
message = message,
}, 2 + (level or 0))
end
end
-------------------------------------------------------------------------------
-- Validates that both the expected and actual values are numbers
-- @param message optional description of the test
-- @param level number to raise error stack level by
--
local function validateNumbers(expected, actual, message, level)
if type(expected) ~= "number" then
DebugHelper.raise({
ScribuntoUnit = true,
text = string.format("Expected value %s is not a number", tostring(expected)),
actual = actual,
expected = expected,
message = message,
}, 3 + level)
end
if type(actual) ~= "number" then
DebugHelper.raise({
ScribuntoUnit = true,
text = string.format("Actual value %s is not a number", tostring(actual)),
actual = actual,
expected = expected,
message = message,
}, 3 + level)
end
end
-------------------------------------------------------------------------------
-- Checks that 'actual' is within 'delta' of 'expected'.
-- @param message optional description of the test
-- @param level optional number to raise error stack level by
-- @example assertWithinDelta(1/3, 3/9, 0.000001, "3/9 should be 1/3")
function ScribuntoUnit:assertWithinDelta(expected, actual, delta, message, level)
validateNumbers(expected, actual, message, level or 0)
local diff = expected - actual
if diff < 0 then diff = - diff end -- instead of importing math.abs
if diff > delta then
DebugHelper.raise({
ScribuntoUnit = true,
text = string.format("Failed to assert that %f is within %f of expected %f", actual, delta, expected),
actual = actual,
expected = expected,
message = message,
}, 2 + (level or 0))
end
end
-------------------------------------------------------------------------------
-- Checks that 'actual' is not within 'delta' of 'expected'.
-- @param message optional description of the test
-- @param level optional number to raise error stack level by
-- @example assertNotWithinDelta(1/3, 2/3, 0.000001, "1/3 should not be 2/3")
function ScribuntoUnit:assertNotWithinDelta(expected, actual, delta, message, level)
validateNumbers(expected, actual, message, level or 0)
local diff = expected - actual
if diff < 0 then diff = - diff end -- instead of importing math.abs
if diff <= delta then
DebugHelper.raise({
ScribuntoUnit = true,
text = string.format("Failed to assert that %f is not within %f of expected %f", actual, delta, expected),
actual = actual,
expected = expected,
message = message,
}, 2 + (level or 0))
end
end
-------------------------------------------------------------------------------
-- Checks that a table has the expected value (including sub-tables).
-- @param message optional description of the test
-- @param level optional number to raise error stack level by
-- @example assertDeepEquals({{1,3}, {2,4}}, partition(odd, {1,2,3,4}))
function ScribuntoUnit:assertDeepEquals(expected, actual, message, level)
if not DebugHelper.deepCompare(expected, actual) then
if type(expected) == 'table' then
expected = mw.dumpObject(expected)
end
if type(actual) == 'table' then
actual = mw.dumpObject(actual)
end
DebugHelper.raise({
ScribuntoUnit = true,
text = string.format("Failed to assert that %s equals expected %s", tostring(actual), tostring(expected)),
actual = actual,
expected = expected,
message = message,
}, 2 + (level or 0))
end
end
-------------------------------------------------------------------------------
-- Checks that a wikitext gives the expected result after processing.
-- @param message optional description of the test
-- @example assertResultEquals("Hello world", "{{concat|Hello|world}}")
function ScribuntoUnit:assertResultEquals(expected, text, message)
local frame = self.frame
local actual = frame:preprocess(text)
if expected ~= actual then
DebugHelper.raise({
ScribuntoUnit = true,
text = string.format("Failed to assert that %s equals expected %s after preprocessing", text, tostring(expected)),
actual = actual,
actualRaw = text,
expected = expected,
message = message,
}, 2)
end
end
-------------------------------------------------------------------------------
-- Checks that two wikitexts give the same result after processing.
-- @param message optional description of the test
-- @example assertSameResult("{{concat|Hello|world}}", "{{deleteLastChar|Hello world!}}")
function ScribuntoUnit:assertSameResult(text1, text2, message)
local frame = self.frame
local processed1 = frame:preprocess(text1)
local processed2 = frame:preprocess(text2)
if processed1 ~= processed2 then
DebugHelper.raise({
ScribuntoUnit = true,
text = string.format("Failed to assert that %s equals expected %s after preprocessing", processed1, processed2),
actual = processed1,
actualRaw = text1,
expected = processed2,
expectedRaw = text2,
message = message,
}, 2)
end
end
-------------------------------------------------------------------------------
-- Checks that a parser function gives the expected output.
-- @param message optional description of the test
-- @example assertParserFunctionEquals("Hello world", "msg:concat", {"Hello", " world"})
function ScribuntoUnit:assertParserFunctionEquals(expected, pfname, args, message)
local frame = self.frame
local actual = frame:callParserFunction{ name = pfname, args = args}
if expected ~= actual then
DebugHelper.raise({
ScribuntoUnit = true,
text = string.format("Failed to assert that %s with args %s equals expected %s after preprocessing",
DebugHelper.concatWithKeys(args), pfname, expected),
actual = actual,
actualRaw = pfname,
expected = expected,
message = message,
}, 2)
end
end
-------------------------------------------------------------------------------
-- Checks that a template gives the expected output.
-- @param message optional description of the test
-- @example assertTemplateEquals("Hello world", "concat", {"Hello", " world"})
function ScribuntoUnit:assertTemplateEquals(expected, template, args, message)
local frame = self.frame
local actual = frame:expandTemplate{ title = template, args = args}
if expected ~= actual then
DebugHelper.raise({
ScribuntoUnit = true,
text = string.format("Failed to assert that %s with args %s equals expected %s after preprocessing",
DebugHelper.concatWithKeys(args), template, expected),
actual = actual,
actualRaw = template,
expected = expected,
message = message,
}, 2)
end
end
-------------------------------------------------------------------------------
-- Checks whether a function throws an error
-- @param fn the function to test
-- @param expectedMessage optional the expected error message
-- @param message optional description of the test
-- @param varargs optional arguments to be passed to fn
function ScribuntoUnit:assertThrows(fn, expectedMessage, message, ...)
local succeeded, actualMessage = pcall(fn, ...)
if succeeded then
DebugHelper.raise({
ScribuntoUnit = true,
text = 'Expected exception but none was thrown',
message = message,
}, 2)
end
-- For strings, strip the line number added to the error message
actualMessage = type(actualMessage) == 'string'
and string.match(actualMessage, 'Module:[^:]*:[0-9]*: (.*)')
or actualMessage
local messagesMatch = DebugHelper.deepCompare(expectedMessage, actualMessage)
if expectedMessage and not messagesMatch then
DebugHelper.raise({
ScribuntoUnit = true,
expected = expectedMessage,
actual = actualMessage,
text = string.format('Expected exception with message %s, but got message %s',
tostring(expectedMessage), tostring(actualMessage)
),
message = message
}, 2)
end
end
-------------------------------------------------------------------------------
-- Checks whether a function doesn't throw an error
-- @param fn the function to test
-- @param message optional description of the test
-- @param varargs optional arguments to be passed to fn
function ScribuntoUnit:assertDoesNotThrow(fn, message, ...)
local succeeded, actualMessage = pcall(fn, ...)
if succeeded then
return
end
-- For strings, strip the line number added to the error message
actualMessage = type(actualMessage) == 'string'
and string.match(actualMessage, 'Module:[^:]*:[0-9]*: (.*)')
or actualMessage
DebugHelper.raise({
ScribuntoUnit = true,
actual = actualMessage,
text = string.format('Expected no exception, but got exception with message %s',
tostring(actualMessage)
),
message = message
}, 2)
end
-------------------------------------------------------------------------------
-- Set up metatable
ScribuntoUnit.__meta.__index = ScribuntoUnit
function ScribuntoUnit.__meta:__newindex(key, value)
if type(key) == "string" and key:find('^test') and type(value) == "function" then
-- Store test functions in the order they were defined
table.insert(self._tests, {name = key, test = value})
else
rawset(self, key, value)
end
end
-------------------------------------------------------------------------------
-- Creates a new test suite.
--
function ScribuntoUnit.new()
local self = {}
self._tests = {}
setmetatable(self, ScribuntoUnit.__meta)
self.run = function(frame) return ScribuntoUnit.run(self, frame) end
return self
end
-------------------------------------------------------------------------------
-- Resets global counters
--
function ScribuntoUnit:init(frame)
self.frame = frame or mw.getCurrentFrame()
self.successCount = 0
self.failureCount = 0
self.skipCount = 0
self.results = {}
end
-------------------------------------------------------------------------------
-- Runs a single testcase
-- @param name test nume
-- @param test function containing assertions
--
function ScribuntoUnit:runTest(name, test)
local success, details = pcall(test, self)
if success then
self.successCount = self.successCount + 1
table.insert(self.results, {name = name, success = true})
elseif type(details) ~= 'table' or not details.ScribuntoUnit then -- a real error, not a failed assertion
self.failureCount = self.failureCount + 1
table.insert(self.results, {name = name, error = true, message = 'Lua error -- ' .. tostring(details)})
elseif details.skipped then
self.skipCount = self.skipCount + 1
table.insert(self.results, {name = name, skipped = true})
else
self.failureCount = self.failureCount + 1
local message = details.source or ""
if details.message then
message = message .. details.message .. "\n"
end
message = message .. details.text
table.insert(self.results, {name = name, error = true, message = message, expected = details.expected, actual = details.actual, testname = details.message})
end
end
-------------------------------------------------------------------------------
-- Runs all tests and displays the results.
--
function ScribuntoUnit:runSuite(frame)
self:init(frame)
for i, testDetails in ipairs(self._tests) do
self:runTest(testDetails.name, testDetails.test)
end
return {
successCount = self.successCount,
failureCount = self.failureCount,
skipCount = self.skipCount,
results = self.results,
}
end
-------------------------------------------------------------------------------
-- #invoke entry point for running the tests.
-- Can be called without a frame, in which case it will use mw.log for output
-- @param displayMode see displayResults()
--
function ScribuntoUnit:run(frame)
local testData = self:runSuite(frame)
if frame and frame.args then
return self:displayResults(testData, frame.args.displayMode or 'table')
else
return self:displayResults(testData, 'log')
end
end
-------------------------------------------------------------------------------
-- Displays test results
-- @param displayMode: 'table', 'log' or 'short'
--
function ScribuntoUnit:displayResults(testData, displayMode)
if displayMode == 'table' then
return self:displayResultsAsTable(testData)
elseif displayMode == 'log' then
return self:displayResultsAsLog(testData)
elseif displayMode == 'short' then
return self:displayResultsAsShort(testData)
elseif displayMode == 'enum' then
return self:displayResultsAsEnum(testData)
else
error('unknown display mode')
end
end
function ScribuntoUnit:displayResultsAsLog(testData)
if testData.failureCount > 0 then
mw.log('FAILURES!!!')
elseif testData.skipCount > 0 then
mw.log('Some tests could not be executed without a frame and have been skipped. Invoke this test suite as a template to run all tests.')
end
mw.log(string.format('Assertions: success: %d, error: %d, skipped: %d', testData.successCount, testData.failureCount, testData.skipCount))
mw.log('-------------------------------------------------------------------------------')
for _, result in ipairs(testData.results) do
if result.error then
mw.log(string.format('%s: %s', result.name, result.message))
end
end
end
function ScribuntoUnit:displayResultsAsShort(testData)
local text = string.format(cfg.shortResultsFormat, testData.successCount, testData.failureCount, testData.skipCount)
if testData.failureCount > 0 then
text = '<span class="error">' .. text .. '</span>'
end
return text
end
function ScribuntoUnit:displayResultsAsEnum(testData)
if (testData.failureCount > 0) then
return 'fail'
elseif (testData.skipCount > 0 and testData.successCount == 0) then
return 'skipped'
else
return 'success'
end
end
function ScribuntoUnit:displayResultsAsTable(testData)
local successIcon, failIcon = self.frame:preprocess(cfg.successIndicator), self.frame:preprocess(cfg.failureIndicator)
local text = ''
if testData.failureCount > 0 then
local msg = mw.message.newRawMessage(cfg.failureSummary, testData.failureCount):plain()
msg = self.frame:preprocess(msg)
if cfg.failureCategory then
msg = cfg.failureCategory .. msg
end
text = text .. failIcon .. ' ' .. msg .. '\n'
else
text = text .. successIcon .. ' ' .. cfg.successSummary .. '\n'
end
text = text .. '{| class="wikitable scribunto-test-table"\n'
text = text .. '!\n! ' .. cfg.nameString .. '\n! ' .. cfg.expectedString .. '\n! ' .. cfg.actualString .. '\n'
for _, result in ipairs(testData.results) do
text = text .. '|-\n'
if result.error then
text = text .. '| ' .. failIcon .. '\n| '
if (result.expected and result.actual) then
local name = result.name
if result.testname then
name = name .. ' / ' .. result.testname
end
text = text .. mw.text.nowiki(name) .. '\n| ' .. mw.text.nowiki(tostring(result.expected)) .. '\n| ' .. mw.text.nowiki(tostring(result.actual)) .. '\n'
else
text = text .. mw.text.nowiki(result.name) .. '\n| ' .. ' colspan="2" | ' .. mw.text.nowiki(result.message) .. '\n'
end
else
text = text .. '| ' .. successIcon .. '\n| ' .. mw.text.nowiki(result.name) .. '\n|\n|\n'
end
end
text = text .. '|}\n'
return text
end
return ScribuntoUnit
6ndvyy4oz3v3i8fjoxts3ofs01uwk3h
Module:UnitTests
828
52504
308472
2026-09-17T16:47:45Z
Isma4l
41797
Bog cusub: -- UnitTester provides unit testing for other Lua scripts. For details see [[Wikipedia:Lua#Unit testing]]. -- For user documentation see above. local UnitTester = {} -- The cfg table contains all localisable strings and configuration, to make it -- easier to port this module to another wiki. local cfg = mw.loadData('Module:UnitTests/config') local frame, tick, cross, should_highlight local result_table = {n = 0} local result_table_mt = { insert = function (self, ...) local...
308472
Scribunto
text/plain
-- UnitTester provides unit testing for other Lua scripts. For details see [[Wikipedia:Lua#Unit testing]].
-- For user documentation see above.
local UnitTester = {}
-- The cfg table contains all localisable strings and configuration, to make it
-- easier to port this module to another wiki.
local cfg = mw.loadData('Module:UnitTests/config')
local frame, tick, cross, should_highlight
local result_table = {n = 0}
local result_table_mt = {
insert = function (self, ...)
local n = self.n
for i = 1, select('#', ...) do
local val = select(i, ...)
if val ~= nil then
n = n + 1
self[n] = val
end
end
self.n = n
end,
insert_format = function (self, ...)
self:insert(string.format(...))
end,
concat = table.concat
}
result_table_mt.__index = result_table_mt
setmetatable(result_table, result_table_mt)
local num_failures_sandbox = 0
local num_failures = 0
local num_runs = 0
local function first_difference(s1, s2)
s1, s2 = tostring(s1), tostring(s2)
if s1 == s2 then return '' end
local max = math.min(#s1, #s2)
for i = 1, max do
if s1:sub(i, i) ~= s2:sub(i, i) then return i end
end
return max + 1
end
local function add_diff_highlighting(str)
if mw.ustring.find(str, "%s") then
return '<span style="background-color: var(--wikt-palette-red-4, pink);">' ..
string.gsub(str, " ", " ") .. '</span>'
else
return '<span style="color: var(--wikt-palette-red-9, red);">' ..
str .. '</span>'
end
end
local is_combining = require("Module:Unicode data").is_combining
local function find_noncombining(str, i, incr)
while true do
local ch = mw.ustring.sub(str, i, i)
if ch == "" or not is_combining(mw.ustring.byte(ch)) then
return i
end
i = i + incr
end
end
-- Highlight character where a difference was found. Start highlight at first
-- non-combining character before the position. End it after the first non-
-- combining characters after the position.
local function highlight_difference(actual, expected, differs_at)
if type(differs_at) ~= "number" or not (actual and expected) then
return actual
end
differs_at = find_noncombining(expected, differs_at, -1)
local i = find_noncombining(actual, differs_at, -1)
local j = find_noncombining(actual, differs_at + 1, 1)
j = j - 1
return mw.ustring.sub(actual, 1, i - 1) ..
add_diff_highlighting(mw.ustring.sub(actual, i, j)) ..
mw.ustring.sub(actual, j + 1, -1)
end
local function return_varargs(...)
return ...
end
function UnitTester:calculate_output(text, expected, actual, options)
-- Set up some variables for throughout for ease
num_runs = num_runs + 1
options = options or {}
-- Fix any stripmarkers if asked to do so to prevent incorrect fails
local compared_expected = expected
local compared_actual = actual
if options.templatestyles then
local pattern = '(\127[^\127]*UNIQ%-%-templatestyles%-)(%x+)(%-QINU[^\127]*\127)'
local _, expected_stripmarker_id = compared_expected:match(pattern) -- when module rendering has templatestyles strip markers, use ID from expected to prevent false test fail
if expected_stripmarker_id then
compared_actual = compared_actual:gsub(pattern, '%1' .. expected_stripmarker_id .. '%3') -- replace actual id with expected id; ignore second capture in pattern
compared_expected = compared_expected:gsub(pattern, '%1' .. expected_stripmarker_id .. '%3') -- account for other strip markers
end
end
if options.stripmarker then
local pattern = '(\127[^\127]*UNIQ%-%-%l+%-)(%x+)(%-%-?QINU[^\127]*\127)'
local _, expected_stripmarker_id = compared_expected:match(pattern)
if expected_stripmarker_id then
compared_actual = compared_actual:gsub(pattern, '%1' .. expected_stripmarker_id .. '%3')
compared_expected = compared_expected:gsub(pattern, '%1' .. expected_stripmarker_id .. '%3')
end
end
-- Perform the comparison
local success = compared_actual == compared_expected
if options.noexpectation and compared_expected == '' then
success = true
end
if not success then
num_failures = num_failures + 1
end
-- Sort the wikitext for displaying the results
if options.combined then
-- We need 2 rows available for the expected and actual columns
-- Top one is parsed, bottom is unparsed
local diff, differs_at = 0, self.differs_at and (' \n| rowspan=2|' .. first_difference(compared_expected, compared_actual)) or ''
-- Local copies of tick/cross to allow for highlighting
local highlight = (should_highlight and not success and 'style="background: #fc0;" ') or ''
local highlight_diff = return_varargs
if self.differs_at then
diff = first_difference(compared_expected, compared_actual)
differs_at = ' \n| rowspan=2|' .. diff
if type(diff) == "number" then
highlight_diff = highlight_difference
end
end
result_table:insert( -- Start output
'| ', highlight, 'rowspan=2|', success and tick or cross, -- Tick/Cross (2 rows)
' \n| rowspan=2|', mw.text.nowiki(text), ' \n| ', -- Text used for the test (2 rows)
expected, ' \n| ', highlight_diff(actual, expected, diff), -- The parsed outputs (in the 1st row)
differs_at, ' \n|-\n| ', -- Where any relevant difference was (2 rows)
mw.text.nowiki(expected), ' \n| ', highlight_diff(mw.text.nowiki(actual), mw.text.nowiki(actual), first_difference(mw.text.nowiki(expected), mw.text.nowiki(actual))), -- The unparsed outputs (in the 2nd row)
'\n|-\n' -- End output
)
else
-- Display normally with whichever option was preferred (nowiki/parsed)
local differs_at = ''
local formatting = options.nowiki and mw.text.nowiki or return_varargs
local highlight = (should_highlight and not success and 'style="background: #fc0;" |') or ''
local formated_expected, formated_actual = formatting(expected), formatting(actual)
if self.differs_at then
local diff = first_difference(compared_expected, compared_actual)
differs_at = ' \n| ' .. diff
if type(diff) == "number" then
formated_actual = highlight_difference(formated_actual, formated_expected, first_difference(formated_actual, formated_expected))
end
end
result_table:insert( -- Start output
'| ', highlight, success and tick or cross, -- Tick/Cross
' \n| ', mw.text.nowiki(text), ' \n| ', -- Text used for the test
formated_expected, ' \n| ', formated_actual, -- The formatted outputs
differs_at, -- Where any relevant difference was
'\n|-\n' -- End output
)
end
end
function UnitTester:preprocess_equals(text, expected, options)
local actual = frame:preprocess(text)
self:calculate_output(text, expected, actual, options)
end
function UnitTester:preprocess_equals_many(prefix, suffix, cases, options)
for _, case in ipairs(cases) do
self:preprocess_equals(prefix .. case[1] .. suffix, case[2], options)
end
end
function UnitTester:preprocess_equals_preprocess(text1, text2, options)
local actual = frame:preprocess(text1)
local expected = frame:preprocess(text2)
self:calculate_output(text1, expected, actual, options)
end
function UnitTester:preprocess_equals_compare(live, sandbox, expected, options)
options = options or {}
local live_text = frame:preprocess(live)
local sandbox_text = frame:preprocess(sandbox)
local highlight_live = false
local highlight_sandbox = false
num_runs = num_runs + 1
local compared_live = live_text
local compared_sandbox = sandbox_text
local compared_expected = expected
if options.templatestyles then
local pattern = '(\127[^\127]*UNIQ%-%-templatestyles%-)(%x+)(%-QINU[^\127]*\127)'
local _, expected_stripmarker_id = compared_expected:match(pattern) -- when module rendering has templatestyles strip markers, use ID from expected to prevent false test fail
if expected_stripmarker_id then
compared_live = compared_live:gsub(pattern, '%1' .. expected_stripmarker_id .. '%3') -- replace actual id with expected id; ignore second capture in pattern
compared_sandbox = compared_sandbox:gsub(pattern, '%1' .. expected_stripmarker_id .. '%3') -- replace actual id with expected id; ignore second capture in pattern
compared_expected = compared_expected:gsub(pattern, '%1' .. expected_stripmarker_id .. '%3') -- account for other strip markers
end
end
if options.stripmarker then
local pattern = '(\127[^\127]*UNIQ%-%-%l+%-)(%x+)(%-%-?QINU[^\127]*\127)'
local _, expected_stripmarker_id = compared_expected:match(pattern)
if expected_stripmarker_id then
compared_live = compared_live:gsub(pattern, '%1' .. expected_stripmarker_id .. '%3')
compared_sandbox = compared_sandbox:gsub(pattern, '%1' .. expected_stripmarker_id .. '%3')
compared_expected = compared_expected:gsub(pattern, '%1' .. expected_stripmarker_id .. '%3')
end
end
local success = compared_live == compared_expected and compared_sandbox == compared_expected
if not success then
if compared_live ~= compared_expected then
num_failures = num_failures + 1
highlight_live = true
end
if compared_sandbox ~= compared_expected then
num_failures_sandbox = num_failures_sandbox + 1
highlight_sandbox = true
end
end
-- Sort the wikitext for displaying the results
if options.combined then
-- We need 2 rows available for the expected, live, and sandbox columns
-- Top one is parsed, bottom is unparsed
local differs_at = ''
local highlight_diff_live, highlight_diff_sandbox = return_varargs, return_varargs
local diff_live, diff_sandbox = 0,0
if self.differs_at then
diff_live = first_difference(compared_expected, compared_live)
diff_sandbox = first_difference(compared_expected, compared_sandbox)
differs_at = ' \n| rowspan=2|' .. (diff_live or diff_sandbox)
if type(diff_live) == "number" then
highlight_diff_live = highlight_difference
end
if type(diff_sandbox) == "number" then
highlight_diff_sandbox = highlight_difference
end
end
result_table:insert(
'| ', 'rowspan=2|', not highlight_live and tick or cross, not highlight_sandbox and tick or cross,
' \n| rowspan=2|', mw.text.nowiki(live),
should_highlight and highlight_live and ' \n| style="background: #fc0;" | ' or ' \n| ',
highlight_diff_live(live_text, expected, diff_live),
should_highlight and highlight_sandbox and ' \n| style="background: #fc0;" | ' or ' \n| ',
highlight_diff_sandbox(sandbox_text, expected, diff_sandbox),
' \n| ',
expected,
differs_at,
should_highlight and highlight_sandbox and ' \n|-\n| style="background: #fc0;" | ' or ' \n|-\n| ',
highlight_diff_live(mw.text.nowiki(live_text), mw.text.nowiki(expected), first_difference(mw.text.nowiki(expected), mw.text.nowiki(live_text))),
should_highlight and highlight_sandbox and ' \n| style="background: #fc0;" | ' or ' \n| ',
highlight_diff_sandbox(mw.text.nowiki(sandbox_text), mw.text.nowiki(expected), first_difference(mw.text.nowiki(expected), mw.text.nowiki(sandbox_text))),
' \n| ',
mw.text.nowiki(expected),
'\n|-\n'
)
else
-- Display normally with whichever option was preferred (nowiki/parsed)
local differs_at = ''
local formatting = options.nowiki and mw.text.nowiki or return_varargs
local formated_expected, formated_live, formated_sandbox = formatting(expected), formatting(live_text), formatting(sandbox_text)
if self.differs_at then
local diff = first_difference(compared_expected, live_text)
local diff2 = first_difference(compared_expected, sandbox_text)
differs_at = ' \n| ' .. (diff or diff2)
if type(diff) == "number" then
formated_live = highlight_difference(formated_live, formated_expected, first_difference(formated_live, formated_expected))
end
if type(diff2) == "number" then
formated_sandbox = highlight_difference(formated_sandbox, formated_expected, first_difference(formated_sandbox, formated_expected))
end
end
result_table:insert(
'| ', not highlight_live and tick or cross, not highlight_sandbox and tick or cross,
' \n| ',
mw.text.nowiki(live),
should_highlight and highlight_live and ' \n| style="background: #fc0;" | ' or ' \n| ',
formated_live,
should_highlight and highlight_sandbox and ' \n| style="background: #fc0;" | ' or ' \n| ',
formated_sandbox,
' \n| ',
formated_expected,
differs_at,
'\n|-\n'
)
end
end
function UnitTester:preprocess_equals_preprocess_many(prefix1, suffix1, prefix2, suffix2, cases, options)
for _, case in ipairs(cases) do
self:preprocess_equals_preprocess(prefix1 .. case[1] .. suffix1, prefix2 .. (case[2] and case[2] or case[1]) .. suffix2, options)
end
end
function UnitTester:preprocess_equals_sandbox_many(module, function_name, cases, options)
for _, case in ipairs(cases) do
local live = module .. '|' .. function_name .. '|' .. case[1] .. '}}'
local sandbox = module .. '/sandbox|' .. function_name .. '|' .. case[1] .. '}}'
self:preprocess_equals_compare(live, sandbox, case[2], options)
end
end
function UnitTester:equals(name, actual, expected, options)
num_runs = num_runs + 1
if actual == expected then
result_table:insert('| ', tick)
else
result_table:insert('| ', cross)
num_failures = num_failures + 1
end
local formatting = (options and options.nowiki and mw.text.nowiki) or return_varargs
local differs_at = self.differs_at and (' \n| ' .. first_difference(expected, actual)) or ''
local display = options and options.display or return_varargs
result_table:insert(' \n| ', name, ' \n| ',
formatting(tostring(display(expected))), ' \n| ',
formatting(tostring(display(actual))), differs_at, '\n|-\n')
end
local deep_compare; do
--//pulled from [[wikt:Module:table/deepEquals]]
local function is_eq(a, b, seen, include_mt)
-- If `a` and `b` have been compared before, return the memoized result. This will usually be true, since failures normally fail the whole check outright, but match failures are tolerated during the laborious check without this happening, since it compares key/value pairs until it finds a match, so it could be false.
local memo_a = seen[a]
if memo_a then
local result = memo_a[b]
if result ~= nil then
return result
end
-- To avoid recursive references causing infinite loops, assume the tables currently being compared are equivalent by memoizing the comparison as true; this will be corrected to false if there's a match failure.
memo_a[b] = true
else
memo_a = {[b] = true}
seen[a] = memo_a
end
-- Don't bother checking `memo_b` for `a`, since if `a` and `b` had been compared before then `b` would be in `memo_a`, but it isn't.
local memo_b = seen[b]
if memo_b then
memo_b[a] = true
else
memo_b = {[a] = true}
seen[b] = memo_b
end
-- If `include_mt` is set, check the metatables are equivalent.
if include_mt then
local mt_a, mt_b = getmetatable(a), getmetatable(b)
if not (mt_a == mt_b or type(mt_a) == "table" and type(mt_b) == "table" and is_eq(mt_a, mt_b, seen, true)) then
memo_a[b], memo_b[a] = false, false
return false
end
end
-- Copy all key/values pairs in `b` to `remaining_b`, and count the size: this uses `pairs`, which will also be used to iterate over `a`, ensuring that `a` and `b` are iterated over using the same iterator. This is necessary to ensure that `deepEquals(a, b)` and `deepEquals(b, a)` always give the same result. Simply iterating over `a` while accessing keys in `b` for comparison would ignore any `__pairs` metamethod that `b` has, which could cause asymmetrical outputs if `__pairs` returns more or less than the complete set of key/value pairs accessible via `__index`, so using `pairs` for both `a` and `b` prevents this.
-- TODO: handle exotic `__pairs` methods which return the same key multiple times with different values.
local remaining_b, size_b = {}, 0
for k_b, v_b in pairs(b) do
remaining_b[k_b], size_b = v_b, size_b + 1
end
-- Fast check: iterate over the keys in `a`, checking if an equivalent value exists at the same key in `remaining_b`. As matches are found, key/value pairs are removed from `remaining_b`. If any keys in `a` or `remaining_b` are tables, the fast check will only work if the exact same object exists as a key in the other table. Any others from `a` that don't match anything in `remaining_b` are added to `remaining_a`, while those in `remaining_b` that weren't found will still remain once the loop ends. `remaining_a` and `remaining_b` are then compared at the end with the laborious check.
local size_a, remaining_a = 0
for k, v_a in pairs(a) do
local v_b = remaining_b[k]
-- If `k` isn't in `remaining_b`, `a` and `b` can't be equivalent unless it's a table.
if v_b == nil then
if type(k) ~= "table" then
memo_a[b], memo_b[a] = false, false
return false
-- Otherwise, add the `k`/`v_a` pair to `remaining_a` for the laborious check.
elseif not remaining_a then
remaining_a = {}
end
remaining_a[k], size_a = v_a, size_a + 1
-- Otherwise, if `k` exists in `a` and `remaining_b`, `v_a` and `v_b` must be equivalent for there to be a match.
elseif v_a == v_b or type(v_a) == "table" and type(v_b) == "table" and is_eq(v_a, v_b, seen, include_mt) then
remaining_b[k], size_b = nil, size_b - 1
else
memo_a[b], memo_b[a] = false, false
return false
end
end
-- Must be the same number of remaining keys in each table.
if size_a ~= size_b then
memo_a[b], memo_b[a] = false, false
return false
-- If the size is 0, there's nothing left to check.
elseif size_a == 0 then
return true
end
-- Laborious check: since it's not possible to use table lookups to check if two keys are equivalent when they're tables, check each key/value pair in `remaining_a` against every key/value pair in `remaining_b` until a match is found, removing the matching key/value pair from `remaining_b` each time, to ensure one-to-one equivalence.
for k_a, v_a in next, remaining_a do
local success
for k_b, v_b in next, remaining_b do
-- Keys/value pairs must be equivalent in order to match.
if ( -- More efficient to compare the values first, as they might not be tables.
(v_a == v_b or type(v_a) == "table" and type(v_b) == "table" and is_eq(v_a, v_b, seen, include_mt)) and
(k_a == k_b or type(k_a) == "table" and type(k_b) == "table" and is_eq(k_a, k_b, seen, include_mt))
) then
-- Remove matched key from `remaining_b`, and break the inner loop.
success, remaining_b[k_b] = true, nil
break
end
end
-- Fail if `remaining_b` runs out of keys, as the `k_a`/`v_a` pair still hasn't matched.
if not success then
memo_a[b], memo_b[a] = false, false
return false
end
end
-- If every key/value pair in `remaining_a` matched with one in `remaining_b`, `a` and `b` must be equivalent. Note that `remaining_b` will now be empty, since the laborious check only starts if `remaining_a` and `remaining_b` are the same size.
return true
end
deep_compare = function(a, b, ignore_mt)
-- Do simple checks before calling is_eq to avoid generating an unnecessary memo.
-- Simple equality check and type check; if not a ~= b, a and b can only be equivalent if they're both tables.
return a == b or type(a) == "table" and type(b) == "table" and is_eq(a, b, {}, not ignore_mt)
end
end
local function val_to_str(obj)
local function table_key_to_str(k)
if type(k) == 'string' and mw.ustring.match(k, '^[_%a][_%a%d]*$') then
return k
else
return '[' .. val_to_str(k) .. ']'
end
end
if type(obj) == 'string' then
obj = mw.ustring.gsub(obj, '\n', '\\n')
if mw.ustring.match(mw.ustring.gsub(obj, '[^\'"]', ''), '^"+$') then
return "'" .. obj .. "'"
end
return '"' .. mw.ustring.gsub(obj, '"', '\\"' ) .. '"'
elseif type(obj) == 'table' then
local result, checked = {}, {}
for k, v in ipairs(obj) do
table.insert(result, val_to_str(v))
checked[k] = true
end
for k, v in pairs(obj) do
if not checked[k] then
table.insert(result, table_key_to_str(k) .. '=' .. val_to_str(v))
end
end
return '{' .. table.concat(result, ',') .. '}'
else
return tostring(obj)
end
end
local function insert_differences(keys, t1, t2)
for k, v1 in pairs(t1) do
local v2 = t2[k]
if v2 == nil or not deep_compare(v1, v2, true) then
table.insert(keys, k)
end
end
end
local function get_differing_keys(t1, t2)
local ty1 = type(t1)
if not (ty1 == type(t2) and ty1 == "table") then
return nil
end
local keys = {}
insert_differences(keys, t1, t2)
insert_differences(keys, t2, t1)
return keys
end
local function extract_keys(t, keys)
if not keys then
return t
end
local new_t = {}
for _, key in ipairs(keys) do
new_t[key] = t[key]
end
return new_t
end
function UnitTester:equals_deep(name, actual, expected, options)
num_runs = num_runs + 1
local actual_str, expected_str
local success = deep_compare(actual, expected, true)
if success then
result_table:insert('| ', tick)
if options and options.show_table_difference then
actual_str = ''
expected_str = ''
end
else
if options and options.show_table_difference then
local keys = get_differing_keys(actual, expected)
actual_str = val_to_str(extract_keys(actual, keys))
expected_str = val_to_str(extract_keys(expected, keys))
end
end
if (not options) or not options.show_table_difference then
actual_str = val_to_str(actual)
expected_str = val_to_str(expected)
end
local formatting = (options and options.nowiki and mw.text.nowiki) or return_varargs
local differs_at = self.differs_at and (' \n| ' .. first_difference(expected_str, actual_str)) or ''
result_table:insert(' \n| ', name, ' \n| ', formatting(expected_str),
' \n| ', formatting(actual_str), differs_at, '\n|-\n')
end
function UnitTester:iterate(examples, func)
require 'libraryUtil'.checkType('iterate', 1, examples, 'table')
if type(func) == 'string' then
func = self[func]
elseif type(func) ~= 'function' then
error(("bad argument #2 to 'iterate' (expected function or string, got %s)")
:format(type(func)), 2)
end
for i, example in ipairs(examples) do
if type(example) == 'table' then
func(self, unpack(example))
elseif type(example) == 'string' then
self:heading(example)
else
error(('bad example #%d (expected table, got %s)')
:format(i, type(example)), 2)
end
end
end
function UnitTester:heading(text)
result_table:insert_format(' ! colspan="%u" style="text-align: left;" | %s \n |- \n ',
self.columns, text)
end
function UnitTester:runTest(name, test)
local success, details = xpcall(function() test(self) end, function(err) return {error = err, trace = debug.traceback()} end)
if not success then
num_failures = num_failures + 1
num_runs = num_runs + 1
result_table:insert('| ', 'rowspan=2|', cross, ' \n| ', name, ' \n| ')
result_table:insert_format(' colspan="%u"| <strong class="error">Lua error during testing -- %s;traceback:<br>%s</strong>\n',
self.columns, details.error, frame:extensionTag("pre", details.trace or "(no traceback)"))
result_table:insert('\n|-\n')
end
end
function UnitTester:run(frame_arg)
frame = frame_arg or mw.getCurrentFrame()
self.frame = frame
self.differs_at = frame.args['differs_at']
self.live_sandbox = frame.args['live_sandbox']
tick = frame:preprocess(cfg.successIndicator)
cross = frame:preprocess(cfg.failureIndicator)
local table_header = '{| class="wikitable unit-tests-result"\n|+ %s\n! !! '
if self.live_sandbox then
table_header = table_header .. cfg.testString .. ' !! ' .. cfg.liveString
.. ' !! ' .. cfg.sandboxString .. ' !! ' .. cfg.expectedString
else
table_header = table_header .. cfg.testString .. ' !! ' .. cfg.expectedString .. ' !! ' .. cfg.actualString
end
if frame.args.highlight then
should_highlight = true
end
self.columns = 4
if self.differs_at then
table_header = table_header .. ' !! ' .. cfg.differsString
self.columns = self.columns + 1
end
if self._tests._last then
table.insert(self._tests, self._tests._last)
self._tests._last = nil
end
-- Add results to the results table.
for _, testDetails in ipairs(self._tests) do
result_table:insert_format('<h2>%s</h2>\n', testDetails.name)
result_table:insert_format(table_header .. '\n|-\n', testDetails.name)
self:runTest(testDetails.name, testDetails.test)
result_table:insert('|}\n')
end
local refresh_link = tostring(mw.uri.fullUrl(mw.title.getCurrentTitle().fullText, 'action=purge&forcelinkupdate=1'))
if self.live_sandbox then
local live, sandbox
if num_runs == 0 then
live = cfg.noTestsRunSummary
elseif num_failures ~= 0 then
live = mw.message.newRawMessage(cfg.liveFailureSummary, num_runs, num_failures):plain()
live = frame:preprocess(live)
else
live = mw.message.newRawMessage(cfg.liveSuccessSummary, num_runs):plain()
live = frame:preprocess(live)
end
if num_runs == 0 then
sandbox = ''
elseif num_failures_sandbox ~= 0 then
sandbox = mw.message.newRawMessage(cfg.sandboxFailureSummary, num_runs, num_failures_sandbox):plain()
sandbox = frame:preprocess(sandbox)
else
sandbox = mw.message.newRawMessage(cfg.sandboxSuccessSummary, num_runs):plain()
sandbox = frame:preprocess(sandbox)
end
local cat = (num_failures ~= 0 or num_failures_sandbox ~= 0) and
(cfg.failureCategory .. " <span class='plainlinks unit-tests-refresh'>[" .. refresh_link .. " (refresh)]</span>") or ''
return live .. ' ' .. sandbox .. cat .. '\n\n' .. frame:preprocess(result_table:concat())
else
local msg;
if num_runs == 0 then
msg = cfg.noTestsRunSummary
elseif num_failures ~= 0 then
msg = mw.message.newRawMessage(cfg.failureSummary, num_runs, num_failures):plain()
msg = frame:preprocess(msg)
msg = msg .. cfg.failureCategory
msg = msg .. " <span class='plainlinks unit-tests-refresh'>[" .. refresh_link .. " (refresh)]</span>"
else
msg = mw.message.newRawMessage(cfg.successSummary, num_runs):plain()
msg = frame:preprocess(msg)
end
return msg .. '\n\n' .. frame:preprocess(result_table:concat())
end
end
-- Set up metatable
UnitTester.__meta = {}
UnitTester.__meta.__index = UnitTester
function UnitTester.__meta:__newindex(key, value)
if type(key) == 'string' and key:find('^test') and type(value) == 'function' then
-- Store test functions in the order they were defined
if key == self.runLast or key == rawget(_G, "runLast") then
self._tests._last = {name = key, test = value}
else
table.insert(self._tests, {name = key, test = value})
end
else
rawset(self, key, value)
end
end
function UnitTester.new()
local o = {}
o.runLast = '' -- puts a test at the end of the page
o._tests = {}
setmetatable(o, UnitTester.__meta)
function o.run_tests(frame_arg) return o:run(frame_arg) end
return o
end
local p = UnitTester.new()
return p
3rqorj108acff8styw7tuar1fzojyeq
Module:Fiction-based redirects to list entries category handler/RedirectType
828
52505
308473
2026-09-17T16:49:42Z
Isma4l
41797
Bog cusub: require("strict") local libraryUtil = require("libraryUtil") local p = {} local franchiseList = { [1] = "Module:Arrowverse redirect category handler" } --[[ RedirectType class. --]] local function RedirectType(o) local RedirectType = o or {redirectType = "", defaultCategory = "", topLevelCategory = "", template = "", from = "", suffix = "", isFranchise = false} local checkSelf = libraryUtil.makeCheckSelfFunction("Fiction-based redirects to list entries category handler", "...
308473
Scribunto
text/plain
require("strict")
local libraryUtil = require("libraryUtil")
local p = {}
local franchiseList = {
[1] = "Module:Arrowverse redirect category handler"
}
--[[
RedirectType class.
--]]
local function RedirectType(o)
local RedirectType = o or {redirectType = "", defaultCategory = "", topLevelCategory = "", template = "", from = "", suffix = "", isFranchise = false}
local checkSelf = libraryUtil.makeCheckSelfFunction("Fiction-based redirects to list entries category handler", "RedirectType", RedirectType, "Fiction-based redirects to list entries category handler object")
--[[
Public function which is used to retrieve the main category for a specific type.
--]]
function RedirectType:getMainCategory(mainCategory)
return RedirectType:getCategory(mainCategory)
end
--[[
Public function which is used to retrieve the top level category (or categories) for a specific type and media format.
If no media format is passed, the function returns the default top level category.
--]]
function RedirectType:getTopLevelCategory(mediaList)
if (mediaList and #mediaList > 0) then
local categories = ""
for i = 1, #mediaList do
local category
if ((RedirectType.redirectType == "episode") and (string.lower(mediaList[i]) == "television")) then
category = RedirectType:getCategory(RedirectType.defaultCategory)
else
category = RedirectType:getCategory(RedirectType.topLevelCategory)
end
categories = categories .. category:gsub("{media}", mediaList[i])
end
return categories
else
return RedirectType.defaultCategory
end
end
--[[
Public function which is used to retrieve a category for a specific type.
--]]
function RedirectType:getCategory(category)
return category:gsub("{type}", RedirectType.redirectType)
end
--[[
Public function which is used to check if the category belongs to a special franchise, such as the Arrowverse.
If the category is part of that franchise, returns the series name, else returns nil.
--]]
function RedirectType:isCategorySpecialFranchise(series)
local seriesParameter
if (RedirectType.redirectType == "character" or RedirectType.redirectType == "element" or RedirectType.redirectType == "location") then
for i, v in pairs(franchiseList) do
local seriesModule = require(v)
local seriesList = seriesModule.getSeriesList()
for i, v in pairs(seriesList) do
local currentTVSeries = seriesList[i]
if (series == currentTVSeries.seriesName) then
seriesParameter = currentTVSeries.argName
break
end
end
local franchise = seriesModule.getFranchiseName()
if (series == franchise) then
seriesParameter = franchise
RedirectType.isFranchise = true
end
if (seriesParameter) then
if (i == 1) then
RedirectType:setTemplateAsArrowverse()
end
break
end
end
end
if (seriesParameter) then
return seriesParameter
else
return nil
end
end
--[[
Public function which is used to change the type of template to the Arrowverse specific version.
--]]
function RedirectType:setTemplateAsArrowverse()
RedirectType.template = "Arrowverse " .. RedirectType.redirectType .. " redirect"
end
return RedirectType
end
--[[
Public function which is used to retrieve the list of redirect types.
--]]
function p.getRedirectTypes()
return {
RedirectType{
redirectType = "character",
defaultCategory = "[[Category:Redirects from fictional characters]]",
topLevelCategory = "[[Category:{media} character redirects]]",
template = "Fictional character redirect",
from = "fictional characters",
suffix = "redirects"
},
RedirectType{
redirectType = "element",
defaultCategory = "[[Category:Fictional element redirects]]",
topLevelCategory = "[[Category:{media} element redirects to lists]]",
template = "Fictional element redirect",
from = "fictional elements",
suffix = "redirects to lists"
},
RedirectType{
redirectType = "episode",
defaultCategory = "[[Category:Episode redirects to lists]]",
topLevelCategory = "[[Category:{media} episode redirects to lists]]",
template = "Television episode redirect handler",
from = "episodes",
suffix = "redirects to lists"
},
RedirectType{
redirectType = "location",
defaultCategory = "[[Category:Redirects from fictional locations]]",
topLevelCategory = "[[Category:{media} location redirects]]",
template = "Fictional location redirect",
from = "fictional locations or settings",
suffix = "redirects"
}
}
end
--[[
Public function which is used to retrieve a default redirect type.
--]]
function p.getDefaultType(typeList)
return typeList[3]
end
return p
0zkqfk6y8durx9rrrw0twob6eul69el
Module:Arrowverse redirect category handler
828
52506
308474
2026-09-17T16:50:29Z
Isma4l
41797
Bog cusub: require("strict") local getArgs = require("Module:Arguments").getArgs local p = {} local tvSeriesNameList = { {argName = "arrow", seriesName = "Arrow (TV series)"}, {argName = "flash", seriesName = "The Flash (2014 TV series)"}, {argName = "constantine", seriesName = "Constantine (TV series)"}, {argName = "legends", seriesName = "Legends of Tomorrow"}, {argName = "supergirl", seriesName = "Supergirl (TV series)"}, {argName = "vixen", seriesName = "Vixen (web series)"},...
308474
Scribunto
text/plain
require("strict")
local getArgs = require("Module:Arguments").getArgs
local p = {}
local tvSeriesNameList = {
{argName = "arrow", seriesName = "Arrow (TV series)"},
{argName = "flash", seriesName = "The Flash (2014 TV series)"},
{argName = "constantine", seriesName = "Constantine (TV series)"},
{argName = "legends", seriesName = "Legends of Tomorrow"},
{argName = "supergirl", seriesName = "Supergirl (TV series)"},
{argName = "vixen", seriesName = "Vixen (web series)"},
{argName = "ray", seriesName = "Freedom Fighters: The Ray"},
{argName = "batwoman", seriesName = "Batwoman (TV series)"},
{argName = "black_lightning", seriesName = "Black Lightning (TV series)"},
{argName = "superman", seriesName = "Superman & Lois"},
}
local FRANCHISE = "Arrowverse"
--[[
Local function which handles the main operation.
--]]
local function main(args, objectType)
local franchiseHandlerModule = require("Module:Fiction redirect category handler/Franchise")
return franchiseHandlerModule.main(args, objectType, FRANCHISE, tvSeriesNameList)
end
--[[
Public function which is used to create a Redirect category shell
with relevant redirects for Arrowverse-related character redirects.
Parameters:
-- |arrow= — optional; Any value will tag the redirect as belonging to Arrow.
-- |flash= — optional; Any value will tag the redirect as belonging to The Flash.
-- |constantine= — optional; Any value will tag the redirect as belonging to Constantine.
-- |legends= — optional; Any value will tag the redirect as belonging to Legends of Tomorrow.
-- |supergirl= — optional; Any value will tag the redirect as belonging to Supergirl.
-- |vixen= — optional; Any value will tag the redirect as belonging to Vixen.
-- |ray= — optional; Any value will tag the redirect as belonging to Freedom Fighters: The Ray.
-- |batwoman= — optional; Any value will tag the redirect as belonging to Batwoman.
-- |black_lightning= — optional; Any value will tag the redirect as belonging to Black Lightning.
Notes:
-- A: The redirect will automatically be tagged with "R from fictional character", "R from fictional element" or "R from fictional location",
depending on the function used, and be placed in the category "Arrowverse (object) redirects to lists".
-- B: Using any of the series parameters will place the redirect in a series-specific category: "(series) (object) redirects to lists".
-- F: If the redirect does not use one of the following correct disambiguation —
"Arrowverse", "Arrowverse character", "Arrowverse element" or "Arrowverse character" —
the redirect will be tagged with "R from incorrect disambiguation" and "R unprintworthy".
--]]
function p.character(frame)
local args = getArgs(frame)
return main(args, "character")
end
--[[
Public function which is used to create a Redirect category shell
with relevant redirects for Arrowverse-related element redirects.
Parameters: See character() for documentation.
--]]
function p.element(frame)
local args = getArgs(frame)
return main(args, "element")
end
--[[
Public function which is used to create a Redirect category shell
with relevant redirects for Arrowverse-related location redirects.
Parameters: See character() for documentation.
--]]
function p.location(frame)
local args = getArgs(frame)
return main(args, "location")
end
--[[
Public function which is used to return a list of Arrowverse shows.
--]]
function p.getSeriesList()
return tvSeriesNameList
end
--[[
Public function which is used to return a franchise name.
--]]
function p.getFranchiseName()
return FRANCHISE
end
--[[
Public function which is used for the testcases.
--]]
function p.testSeriesName(frame)
local args = getArgs(frame)
local franchiseHandlerModule = require("Module:Fiction redirect category handler/Franchise")
return franchiseHandlerModule.testSeriesName(args, FRANCHISE, tvSeriesNameList)
end
return p
bbiyp8n4vogplntslfp5qkzdx87zuji
Module:Fiction redirect category handler/Franchise
828
52507
308475
2026-09-17T16:51:16Z
Isma4l
41797
Bog cusub: require("strict") local p = {} --[[ Local function which adds the names relevant TV series to the args table. Franchise templates, such as the Arrowverse-specific one, have short parameters that editors can use instead of the full TV series name. This functions checks if the user-input parameters match the ones on the list, and if they do, adds them to the list. Franchise templates can also use a "franchise" default parameter so all members will automatically be tagged in the...
308475
Scribunto
text/plain
require("strict")
local p = {}
--[[
Local function which adds the names relevant TV series to the args table.
Franchise templates, such as the Arrowverse-specific one, have short parameters that editors can use
instead of the full TV series name.
This functions checks if the user-input parameters match the ones on the list,
and if they do, adds them to the list.
Franchise templates can also use a "franchise" default parameter
so all members will automatically be tagged in the franchise category,
as well as the specific TV series category.
--]]
local function getListOfSeriesTags(templateArgs, franchise, tvSeriesNameList, validArgs)
local seriesArgs = {}
for i, v in ipairs(tvSeriesNameList) do
local tvSeries = tvSeriesNameList[i]
-- Check if the user-input parameter matches one on the list;
-- If it matches, add the series name to the list.
if (templateArgs[tvSeries.argName]) then
table.insert(seriesArgs, tvSeries.seriesName)
table.insert(validArgs, tvSeries.argName)
end
end
if (#seriesArgs > 0) then
table.insert(seriesArgs, franchise)
-- This parameter is used by the relevant "R to fictional x" templates
-- to enable multi-series categories.
seriesArgs["multi"] = "yes"
templateArgs["multi_series_name_table"] = seriesArgs
else
templateArgs["series_name"] = franchise
end
return templateArgs, validArgs
end
--[[
Public function which handles the main operation.
--]]
function p.main(args, objectType, franchise, tvSeriesNameList)
local validArgs = {"correct_disambiguation", "multi", "multi_series_name_table"}
args, validArgs = getListOfSeriesTags(args, franchise, tvSeriesNameList, validArgs)
-- Franchise articles, such as the Arrowverse and the Marvel Cinematic Universe,
-- use the franchise name as disambiguation for articles, and not a TV series or film name.
args["correct_disambiguation"] = franchise
local fictionRedirectCategoryHandler = require("Module:Fiction redirect category handler")
return fictionRedirectCategoryHandler["_" .. objectType](args, validArgs)
end
--[[
Public function which is used for the /testcases to verify correct series name output.
--]]
function p.testSeriesName(args, franchise, tvSeriesNameList)
args = getListOfSeriesTags(args, franchise, tvSeriesNameList, {})
if (args.series_name) then
return args.series_name
else
return args.multi_series_name_table[1]
end
end
return p
2hpj0m1jgjh64l4ukw75beidqayzph4
Module:Fiction-based redirects to list entries category handler
828
52508
308476
2026-09-17T16:51:54Z
Isma4l
41797
Bog cusub: require("strict") local p = {} local mainCategory = {name = "Category:{series}", link = "[[Category:{series}|{type}]]"} local secondaryCategoryList = { {name = "Category:{series} {type}s", link = "[[Category:{series} {type}s|*]]"}, {name = "Category:{series} redirects", link = "[[Category:{series} redirects|{type}]]"} } local TRACKING_CATEGORY = "[[Category:Fiction redirect categories with non-existent parent categories]]" local ERROR_MESSAGE = "Valid titles are in the styl...
308476
Scribunto
text/plain
require("strict")
local p = {}
local mainCategory = {name = "Category:{series}", link = "[[Category:{series}|{type}]]"}
local secondaryCategoryList = {
{name = "Category:{series} {type}s", link = "[[Category:{series} {type}s|*]]"},
{name = "Category:{series} redirects", link = "[[Category:{series} redirects|{type}]]"}
}
local TRACKING_CATEGORY = "[[Category:Fiction redirect categories with non-existent parent categories]]"
local ERROR_MESSAGE = "Valid titles are in the style of \"Category:series-name content-type redirects to lists\""
--[[
Local function which checks if the category exists.
--]]
local function doesCategoryExist(category)
return mw.title.new(category).exists
end
--[[
Local function which "Module:Sort title" to retrieve a sortkey and set it as the default sortkey.
--]]
local function getDefaultSortKey(frame)
local sortkeyModule = require("Module:Sort title")
local sortkey = sortkeyModule._getSortKey()
return frame:preprocess{text = "{{DEFAULTSORT:" .. sortkey .. "}}"}
end
--[[
Local helper function which handles the gsub of the series name into the category name.
--]]
local function gsubSeriesName(category, articleTitle)
return category:gsub("{series}", articleTitle)
end
--[[
Local helper function which sets the top level category.
--]]
local function getTopLevelCategory(categoryType, args)
local mediaList = {}
table.insert(mediaList, args.media)
for i = 2, 10 do
if (args["media" .. i]) then
table.insert(mediaList, args["media" .. i])
else
break
end
end
return categoryType:getTopLevelCategory(mediaList)
end
--[[
Local helper function which sets the main category.
--]]
local function getMainCategory(categoryType, articleTitle)
local categoryLink = gsubSeriesName(mainCategory.link, articleTitle)
local categoryName = gsubSeriesName(mainCategory.name, articleTitle)
if (not doesCategoryExist(categoryName)) then
return TRACKING_CATEGORY
end
return categoryType:getMainCategory(categoryLink)
end
--[[
Local helper function which sets the secondary categories.
--]]
local function getSecondaryCategories(categoryType, articleTitle)
local categoryList = ""
for i = 1, #secondaryCategoryList do
local secondaryCategory = secondaryCategoryList[i]
local category = gsubSeriesName(secondaryCategory.name, articleTitle)
category = categoryType:getCategory(category)
if (doesCategoryExist(category)) then
category = gsubSeriesName(secondaryCategory.link, articleTitle)
category = categoryType:getCategory(category)
categoryList = categoryList .. category
end
end
return categoryList
end
--[[
Local function which handles the categorization of the category.
--]]
local function getCategories(categoryType, articleTitle, args)
if (args.main) then
articleTitle = args.main
end
local categoryList = getSecondaryCategories(categoryType, articleTitle)
-- Only if there are no secondary categories, add to main category.
if (categoryList == "") then
categoryList = getMainCategory(categoryType, articleTitle)
end
local topLevelCategory = getTopLevelCategory(categoryType, args)
return categoryList .. topLevelCategory
end
--[[
Local function which handles the Redirect category code.
--]]
local function getRedirectCategoryTemplate(frame, categoryType, articleTitle, seriesNameModified, seriesParameter)
local redirectArgs = {
from = string.format("[[%s|%s]] %s", articleTitle, seriesNameModified, categoryType.from),
template = categoryType.template,
no_info = "yes",
not_maintenance = "yes",
fiction = "yes"
}
if (categoryType.isFranchise) then
redirectArgs.parameters = -1
else
redirectArgs.parameters = "series_name=" .. seriesParameter
end
return frame:expandTemplate{title = "Redirect category", args = redirectArgs}
end
--[[
Local function which handles the italicization of the category title.
--]]
local function getItalicTitle(frame, seriesName, noItalic, test)
local seriesNameModified = "''" .. seriesName .. "''"
if (test) then
if (noItalic) then
return seriesName, seriesName
else
return seriesNameModified, seriesNameModified
end
else
if (noItalic) then
return "", seriesName
else
local italicTitleModule = require("Module:Italic title")._main
local italicTitleArg = {string = seriesName}
local italicText = italicTitleModule(italicTitleArg)
return frame:preprocess{text = italicText}, seriesNameModified
end
end
end
--[[
Local function which extracts the series article name
and the category type from the category name.
--]]
local function getCategoryTitleParts(currentTitle, typeList)
for _, categoryType in ipairs(typeList) do
local _, _, articleTitle = string.find(currentTitle, "^(.*) " .. categoryType.redirectType .. " " .. categoryType.suffix)
if (articleTitle) then
return articleTitle, categoryType
end
end
return nil, -1
end
--[[
Local function which is used to handle the actual main process.
--]]
local function _main(frame, args, title, namespace)
local redirectType = require("Module:Fiction-based redirects to list entries category handler/RedirectType")
local typeList = redirectType.getRedirectTypes()
local articleTitle, categoryType = getCategoryTitleParts(title, typeList)
-- A call from a documentation page; Show only the Redirect category header.
if ((namespace ~= "Category") and (not args.test)) then
categoryType = redirectType.getDefaultType(typeList)
local redirectCategoryTemplate = getRedirectCategoryTemplate(frame, categoryType, "Series name", "Series name", "Series name")
return redirectCategoryTemplate
end
if (articleTitle) then
local seriesParameter = articleTitle
local franchiseSeriesParameter = categoryType:isCategorySpecialFranchise(articleTitle)
if (franchiseSeriesParameter) then
seriesParameter = franchiseSeriesParameter
end
local seriesName = mw.ustring.gsub(articleTitle, "%s+%b()$", "")
local italicTitle, seriesNameModified = getItalicTitle(frame, seriesName, args.no_italic, args.test)
local redirectCategoryTemplate = getRedirectCategoryTemplate(frame, categoryType, articleTitle, seriesNameModified, seriesParameter)
local categoryToc = frame:expandTemplate{title = "Automatic category TOC"}
local categories = getCategories(categoryType, articleTitle, args)
local defaultSortKey = getDefaultSortKey(frame)
if (args.test) then
return italicTitle, articleTitle, categoryType.template, categories
else
return italicTitle .. "\n" .. redirectCategoryTemplate .. "\n" .. categoryToc .. "\n\n" .. defaultSortKey .. "\n" .. categories
end
else
return error(ERROR_MESSAGE, 0)
end
end
--[[
Public function which is used to handle the logic for fiction-based redirects to lists categories.
Parameters:
-- |media= — optional and suggested; The type of media the fiction belongs to.
Types include, but not limited to: Film, Television and Video game. If unsure, check the high level category,
such as "Category:Fictional character redirects", and see what sub-categories that category has.
-- |media2...4= — optional; Additional types of media the fiction belongs to.
-- |main= — optional; Use when the main series category is not written or disambiguated the same as the series article.
Value will be used for the series category title.
-- |no_italic= — optional; Disables the italicizing of the series title.
--]]
function p.main(frame)
local getArgs = require("Module:Arguments").getArgs
local args = getArgs(frame)
local currentTitle = mw.title.getCurrentTitle()
return _main(frame, args, currentTitle.text, currentTitle.nsText)
end
--[[
Public function which is used for the testcases.
Parameters:
-- |test= — required; The series article name.
--]]
function p.test(frame)
local getArgs = require("Module:Arguments").getArgs
local args = getArgs(frame)
local seriesName, articleTitle, template, categories = _main(frame, args, args.test, "Module")
local testString = "Series name: %s\n\nArticle title: %s\n\nTemplate: %s\n\nCategories: <nowiki>%s</nowiki>"
testString = string.format(testString, seriesName, articleTitle, template, categories)
return testString
end
return p
g9b1buxm1c5rs8ytah92nfbu8j1icq4
Template:Fiction-based redirects to list entries category handler
10
52509
308477
2026-09-17T16:52:34Z
Isma4l
41797
Bog cusub: <includeonly><!-- -->{{#invoke:Fiction-based redirects to list entries category handler|main}}<!-- --></includeonly><!-- --><noinclude>{{Documentation}}</noinclude>
308477
wikitext
text/x-wiki
<includeonly><!--
-->{{#invoke:Fiction-based redirects to list entries category handler|main}}<!--
--></includeonly><!--
--><noinclude>{{Documentation}}</noinclude>
tpmx31s38f1hb57rg7h6z1i3q0uzpoq
Template:Television episode redirect handler
10
52510
308478
2026-09-17T16:53:06Z
Isma4l
41797
Bog cusub: <includeonly><!-- -->{{#invoke:Television episode redirect handler|main}}<!-- --></includeonly><!-- --><noinclude>{{Documentation}}</noinclude>
308478
wikitext
text/x-wiki
<includeonly><!--
-->{{#invoke:Television episode redirect handler|main}}<!--
--></includeonly><!--
--><noinclude>{{Documentation}}</noinclude>
40w5th1w2ex9x9fs1owjt0clxg3t1ey
Template:Fictional character redirect
10
52511
308479
2026-09-17T16:53:35Z
Isma4l
41797
Bog cusub: <includeonly><!-- -->{{#invoke:Fiction redirect category handler|character}}<!-- --></includeonly><!-- --><noinclude>{{Documentation}}</noinclude>
308479
wikitext
text/x-wiki
<includeonly><!--
-->{{#invoke:Fiction redirect category handler|character}}<!--
--></includeonly><!--
--><noinclude>{{Documentation}}</noinclude>
jyhz9nip93zqvjzgyb63eztga1atjn2
Axmed Gacayte
0
52512
308480
2026-09-17T17:04:51Z
Mohamed Abdiwali Yusuf
46970
Samee turjumidda bogga "[[:en:Special:Redirect/revision/1364495395|Ahmed Gacayte]]"
308480
wikitext
text/x-wiki
{{Infobox musical artist|Name=Ahmed Gacayte|birth_place=[[Hargeisa]], [[British Somaliland]]|image=|image_size=|caption=|Birth_name=Ahmed Mohamed Yusuf|Alias=|birth_date={{birth date text|1948}}|native_name=Axmed Gacayte|native_name_lang=so|death_place=[[Hargeisa]], [[Somali Democratic Republic|Somalia]]|death_date={{death year and age|1988|1948}}|Origin=|instruments=Singing|Genre=[[Music of Somalia|Somali music]]|Occupation=Musician, artist|Years_active=1965–1988|Label=|website=}}'''Axmed Maxamed Yuusuf,''' oo inta badan loo yaqaan Axmed Gacayte, wuxuu ahaa fannaan, hal-abuur, laxamiiste iyo qoraa heeso Soomaaliyeed oo caan ah.<ref name=":1">Woolner, Christina J. (2023-11-24). ''Love Songs in Motion: Voicing Intimacy in Somaliland''. University of Chicago Press. ISBN <bdi>978-0-226-82738-4</bdi>.</ref><ref>Diiriye, Anwar Maxamed (2006). ''Literature of Somali Onomastics & Proverbs with Comparison of Foreign Sayings''. Gobaad Communications & Press. ISBN <bdi>978-0-9726615-1-5</bdi>.</ref><ref>Ahmedyasin, Ismail (2019-10-19). "Taariikhda Axmed Gacayte (WQ: Cumar seerbiya)". ''Bandhige- Wararka Somaliland iyo faallooyinkooda''. Retrieved 2021-01-22.</ref>
== Taariikh ==
'''Axmed Gacayte''' wuxuu ku dhashay sannadkii '''1948''', xaafadda '''Xidigta''', oo ku dhow togga magaalada '''Hargeysa'''. Wuxuu ahaa curadka qoys ka kooban '''10 wiil iyo 3 gabdhood'''.
Magaca '''“Gacayte”''' wuxuu ka dhaxlay aabbihii, '''Maxamed Yuusuf “Gacayte”''', oo uu naanaystiisa u qaatay.
Sannadkii '''1964''', wariyeyaal ka socday '''Raadiyo Hargeysa''' ayaa yimid dugsigii uu dhiganayay Axmed Gacayte, iyagoo raadinayay arday leh karti iyo hibbo dhanka '''heesaha iyo codka''' ah. Gacayte ayaa lagu arkay hibadiisa, waxaana ugu dambayn loo '''xushay inuu ku biiro Raadiyo Hargeysa''', taasoo noqotay bilow muhiim ah oo uu ka sameeyo mihnaddiisa fanka.
Sannadkii '''1965''', Axmed Gacayte wuxuu duubay heestiisii ugu horreysay oo la oran jiray '''“Ahlan wa Sahlan Daahir”''', taas oo laga sii daayay '''Raadiyo Hargeysa'''.<ref>"Taariikhdii Axmed Gacayte Yuusuf | Somalisan.com". Retrieved 2021-01-22.</ref>
Heestu waxay noqotay tallaabo muhiim ah oo uu ku bilaabay safarkiisa faneed. Hase yeeshee, aabbihii arrintaas kuma uusan qanacsanayn, waxaana la sheegay inuu '''ka diiday wiilnimadiisa isla markaana guriga ka saaray''', taas oo ku timid doorashadii uu Gacayte ku doortay inuu fanka sii wato.
Kadib, '''Axmed Gacayte''' wuxuu sii waday hal-abuurkiisa, isagoo curiyay isla markaana qoray heeso iyo riwaayado dhowr ah, oo ay ka mid yihiin '''“Bood Xirsi”''' iyo '''“Siyar”''', kuwaas oo uu la sameeyay '''Aamina Cabdullaahi'''.<ref>admin (2016-04-25). "Sahra-yartii Miyiga : Waxa Qoray Cumar Seerbiya". ''Sagal News''. Retrieved 2021-01-22.</ref><ref>"Aamina Cabdilaahi Xirsi: Fankii Jabuuti, Hargeysa Iyo Muqdisho U Kala Dabqaaday – Qalinka: Cumar Seerbiya | Somalidiasporanews.com". Retrieved 2021-01-22.</ref>
Sidoo kale, wuxuu laxameeyay heeso ay qaadday fanaanadda '''Khadra Daahir Cige'''. Hibadiisa curinta, qoraalka iyo laxanka ayaa si dhakhso ah uga dhigtay fannaan caan ah oo laga wada yaqaan '''dunida Soomaalida''', gaar ahaan dhulka maanta loo yaqaan '''Somaliland'''.
== Nolosha shaqsiyeed ==
Axmed Gacayte '''waligiis ma uusan guursan''', balse wuxuu lahaa '''hal wiil'''. Wiilkiisa ayaa ku geeriyooday '''Hargeysa sannadkii 1988''', isagoo jiray '''40 sano'''. <ref>"Somalilandhorta". Archived from the original on July 1, 2007. Retrieved 2021-01-22.</ref>
== Diwaan-gelin ==
* Inaan Weli Ku Jecelahay <ref name=":1" />
* Ilaahay Baa Deeq Baxshee
* Umaley Jacayl
* Orod orod
* Sabaalo
* Dulmiga
* Siyar (oo ay la socoto Amina Cabdullaahi)
* Bood Xirsi (with Amina Abdullahi)
* Ahlan wa sahlaan Daahir
== Tixraacyada ==
<references />
{{Reflist}}
[[Category:Articles with hCards]]
[[Category:Somalia]]
[[Category:Heeso]]
[[Category:Fanka iyo Suugaanta Soomaalida]]
[[Category:1988]]
[[Category:Radio Hargeysa]]
3vcdf850ws8u0zynz3716tarsbzuqep
308481
308480
2026-09-17T17:05:21Z
Quinlan83
28506
Fix
308481
wikitext
text/x-wiki
{{Infobox musical artist|Name=Ahmed Gacayte|birth_place=[[Hargeisa]], [[British Somaliland]]|image=|image_size=|caption=|Birth_name=Ahmed Mohamed Yusuf|Alias=|birth_date={{birth date text|1948}}|native_name=Axmed Gacayte|native_name_lang=so|death_place=[[Hargeisa]], [[Somali Democratic Republic|Somalia]]|death_date={{death year and age|1988|1948}}|Origin=|instruments=Singing|Genre=[[Music of Somalia|Somali music]]|Occupation=Musician, artist|Years_active=1965–1988|Label=|website=}}'''Axmed Maxamed Yuusuf,''' oo inta badan loo yaqaan Axmed Gacayte, wuxuu ahaa fannaan, hal-abuur, laxamiiste iyo qoraa heeso Soomaaliyeed oo caan ah.<ref name=":1">Woolner, Christina J. (2023-11-24). ''Love Songs in Motion: Voicing Intimacy in Somaliland''. University of Chicago Press. ISBN <bdi>978-0-226-82738-4</bdi>.</ref><ref>Diiriye, Anwar Maxamed (2006). ''Literature of Somali Onomastics & Proverbs with Comparison of Foreign Sayings''. Gobaad Communications & Press. ISBN <bdi>978-0-9726615-1-5</bdi>.</ref><ref>Ahmedyasin, Ismail (2019-10-19). "Taariikhda Axmed Gacayte (WQ: Cumar seerbiya)". ''Bandhige- Wararka Somaliland iyo faallooyinkooda''. Retrieved 2021-01-22.</ref>
== Taariikh ==
'''Axmed Gacayte''' wuxuu ku dhashay sannadkii '''1948''', xaafadda '''Xidigta''', oo ku dhow togga magaalada '''Hargeysa'''. Wuxuu ahaa curadka qoys ka kooban '''10 wiil iyo 3 gabdhood'''.
Magaca '''“Gacayte”''' wuxuu ka dhaxlay aabbihii, '''Maxamed Yuusuf “Gacayte”''', oo uu naanaystiisa u qaatay.
Sannadkii '''1964''', wariyeyaal ka socday '''Raadiyo Hargeysa''' ayaa yimid dugsigii uu dhiganayay Axmed Gacayte, iyagoo raadinayay arday leh karti iyo hibbo dhanka '''heesaha iyo codka''' ah. Gacayte ayaa lagu arkay hibadiisa, waxaana ugu dambayn loo '''xushay inuu ku biiro Raadiyo Hargeysa''', taasoo noqotay bilow muhiim ah oo uu ka sameeyo mihnaddiisa fanka.
Sannadkii '''1965''', Axmed Gacayte wuxuu duubay heestiisii ugu horreysay oo la oran jiray '''“Ahlan wa Sahlan Daahir”''', taas oo laga sii daayay '''Raadiyo Hargeysa'''.<ref>"Taariikhdii Axmed Gacayte Yuusuf | Somalisan.com". Retrieved 2021-01-22.</ref>
Heestu waxay noqotay tallaabo muhiim ah oo uu ku bilaabay safarkiisa faneed. Hase yeeshee, aabbihii arrintaas kuma uusan qanacsanayn, waxaana la sheegay inuu '''ka diiday wiilnimadiisa isla markaana guriga ka saaray''', taas oo ku timid doorashadii uu Gacayte ku doortay inuu fanka sii wato.
Kadib, '''Axmed Gacayte''' wuxuu sii waday hal-abuurkiisa, isagoo curiyay isla markaana qoray heeso iyo riwaayado dhowr ah, oo ay ka mid yihiin '''“Bood Xirsi”''' iyo '''“Siyar”''', kuwaas oo uu la sameeyay '''Aamina Cabdullaahi'''.<ref>admin (2016-04-25). "Sahra-yartii Miyiga : Waxa Qoray Cumar Seerbiya". ''Sagal News''. Retrieved 2021-01-22.</ref><ref>"Aamina Cabdilaahi Xirsi: Fankii Jabuuti, Hargeysa Iyo Muqdisho U Kala Dabqaaday – Qalinka: Cumar Seerbiya | Somalidiasporanews.com". Retrieved 2021-01-22.</ref>
Sidoo kale, wuxuu laxameeyay heeso ay qaadday fanaanadda '''Khadra Daahir Cige'''. Hibadiisa curinta, qoraalka iyo laxanka ayaa si dhakhso ah uga dhigtay fannaan caan ah oo laga wada yaqaan '''dunida Soomaalida''', gaar ahaan dhulka maanta loo yaqaan '''Somaliland'''.
== Nolosha shaqsiyeed ==
Axmed Gacayte '''waligiis ma uusan guursan''', balse wuxuu lahaa '''hal wiil'''. Wiilkiisa ayaa ku geeriyooday '''Hargeysa sannadkii 1988''', isagoo jiray '''40 sano'''. <ref>"Somalilandhorta". Archived from the original on July 1, 2007. Retrieved 2021-01-22.</ref>
== Diwaan-gelin ==
* Inaan Weli Ku Jecelahay <ref name=":1" />
* Ilaahay Baa Deeq Baxshee
* Umaley Jacayl
* Orod orod
* Sabaalo
* Dulmiga
* Siyar (oo ay la socoto Amina Cabdullaahi)
* Bood Xirsi (with Amina Abdullahi)
* Ahlan wa sahlaan Daahir
== Tixraacyada ==
<references />
{{Reflist}}
[[Category:Articles with hCards]]
[[Category:Somalia]]
[[Category:Heeso]]
[[Category:Fanka iyo Suugaanta Soomaalida]]
[[Category:1988]]
[[Category:Radio Hargeysa]]
gevc9qu08cy87yp01hl2ciwn5us9t0v
Template:Quote frame
10
52513
308483
2026-09-17T22:06:27Z
Isma4l
41797
Bog cusub: <templatestyles src="Quote frame/styles.css"/><blockquote class="quote-frame pullquote {{#switch:{{{align|}}}|left=quote-frame-left|right=quote-frame-right|center=quote-frame-center|#default=}} {{#if:{{{width|}}}|quote-frame-with-width}}" {{#if:{{{width|}}} |style="width:{{{width}}};"}}><div><!-- left this now-unused div in because I don't want to fight the parser right now -->{{{text|{{{content|{{{quotetext|{{{quote|{{{1|<includeonly>{{error|Error: No text given for quotation (o...
308483
wikitext
text/x-wiki
<templatestyles src="Quote frame/styles.css"/><blockquote class="quote-frame pullquote {{#switch:{{{align|}}}|left=quote-frame-left|right=quote-frame-right|center=quote-frame-center|#default=}} {{#if:{{{width|}}}|quote-frame-with-width}}" {{#if:{{{width|}}} |style="width:{{{width}}};"}}><div><!-- left this now-unused div in because I don't want to fight the parser right now -->{{{text|{{{content|{{{quotetext|{{{quote|{{{1|<includeonly>{{error|Error: No text given for quotation (or equals sign used in the actual argument to an unnamed parameter)}}</includeonly><noinclude>{{lorem ipsum}}</noinclude>}}}}}}}}}}}}}}}<!--
-->{{#if:{{{author|}}}{{{2|}}}{{{title|}}}{{{3|}}}{{{source|}}}{{{4|}}}
|<cite class="quote-frame-source"> — {{trim|1={{{author|{{{2|}}}}}}{{#if:{{{title|}}}{{{3|}}}
|{{#if:{{{author|}}}{{{2|}}}|, }}''{{{title|{{{3}}}}}}''
}}{{#if:{{{source|}}}{{{4|}}}
|{{#if:{{{author|}}}{{{2|}}}{{{title|}}}{{{3|}}}|, }}{{{source|{{{4}}}}}}
}}}}</cite>}}</div></blockquote><noinclude>
{{Documentation}}
<!-- PLEASE ADD CATEGORIES TO THE /doc SUBPAGE, THANKS -->
</noinclude>
tg03374i2hyx0vx01azk7g6ppma1hh7
Template:Quote frame/styles.css
10
52514
308484
2026-09-17T22:07:07Z
Isma4l
41797
Bog cusub: .quote-frame { font-size: 95%; background-color: var( --background-color-neutral-subtle, #f8f9fa ); border: 1px solid #aaa; box-sizing: border-box; } .quote-frame-source { display: block; text-align: right; } @media (max-width: 639px) { .quote-frame-with-width { width: auto !important; } } @media (min-width: 640px) { .quote-frame { width: fit-content; padding: 1em 3em; } .quote-frame-left { float: left; } .quote-frame-right { float: right; } .qu...
308484
sanitized-css
text/css
.quote-frame {
font-size: 95%;
background-color: var( --background-color-neutral-subtle, #f8f9fa );
border: 1px solid #aaa;
box-sizing: border-box;
}
.quote-frame-source {
display: block;
text-align: right;
}
@media (max-width: 639px) {
.quote-frame-with-width {
width: auto !important;
}
}
@media (min-width: 640px) {
.quote-frame {
width: fit-content;
padding: 1em 3em;
}
.quote-frame-left {
float: left;
}
.quote-frame-right {
float: right;
}
.quote-frame-center {
margin-left: auto;
margin-right: auto;
}
}
q4bpepimgz7vmchi5khyl60hbp08fk5
Template:Block indent
10
52515
308485
2026-09-17T22:07:31Z
Isma4l
41797
Bog cusub: <templatestyles src="Block indent/styles.css"/><div class="block-indent {{{class|}}}" {{#if:{{{left|}}}{{{em|}}}{{{right|}}}{{{style|}}}|style="{{#if:{{{left|{{{em|}}}}}}|padding-left: {{{left|{{{em}}}}}}em;}}{{#if:{{{right|}}}|padding-right: {{{right}}}em;}}{{#if:{{{style|}}}|{{{style}}}}}"}}>{{{1|{{{text|{{{content|{{{quote|<noinclude>{{lorem ipsum}}</noinclude><includeonly>{{error|Error: No content given to indent (or equals sign used in the actual argument to an unnamed param...
308485
wikitext
text/x-wiki
<templatestyles src="Block indent/styles.css"/><div class="block-indent {{{class|}}}" {{#if:{{{left|}}}{{{em|}}}{{{right|}}}{{{style|}}}|style="{{#if:{{{left|{{{em|}}}}}}|padding-left: {{{left|{{{em}}}}}}em;}}{{#if:{{{right|}}}|padding-right: {{{right}}}em;}}{{#if:{{{style|}}}|{{{style}}}}}"}}>{{{1|{{{text|{{{content|{{{quote|<noinclude>{{lorem ipsum}}</noinclude><includeonly>{{error|Error: No content given to indent (or equals sign used in the actual argument to an unnamed parameter)}}</includeonly>}}}}}}}}}}}}</div><noinclude>
{{documentation}}
</noinclude>
s97n0kekohfw61aczb4rdypuzqrqlog
Template:Indent 5
10
52516
308486
2026-09-17T22:07:59Z
Isma4l
41797
Bog cusub: <includeonly>{{{{{|safesubst:}}}#invoke:in5|in5|1={{{1|}}}}}</includeonly><noinclude> {{Documentation}} <!--[[Category:Smart formatting templates|In5]]--> </noinclude>
308486
wikitext
text/x-wiki
<includeonly>{{{{{|safesubst:}}}#invoke:in5|in5|1={{{1|}}}}}</includeonly><noinclude>
{{Documentation}}
<!--[[Category:Smart formatting templates|In5]]-->
</noinclude>
8vq8wpy1id7garukyg2rx2pi2ojk3nv
Module:In5
828
52517
308487
2026-09-17T22:08:25Z
Isma4l
41797
Bog cusub: -- This module implements {{in5}}. local p = {} function p.in5(frame) local indent = frame.args[1] -- Trim whitespace and convert to number. Default to 5 if not present, -- as per the template title. indent = tonumber( mw.text.trim(indent) ) or 5 -- Round down to nearest integer. Decimal values produce funky results -- from the original template, but there's no need for us to replicate that. indent = math.floor( indent ) -- Don't output anything...
308487
Scribunto
text/plain
-- This module implements {{in5}}.
local p = {}
function p.in5(frame)
local indent = frame.args[1]
-- Trim whitespace and convert to number. Default to 5 if not present,
-- as per the template title.
indent = tonumber( mw.text.trim(indent) ) or 5
-- Round down to nearest integer. Decimal values produce funky results
-- from the original template, but there's no need for us to replicate that.
indent = math.floor( indent )
-- Don't output anything for zero or less. Again, there was some funky output
-- here for negatives, but now we're in Lua we should use sane defaults.
if indent <= 0 then
return
end
local base = ' '
local modulo = ' '
--[[
Indent values and the corresponding values for base and modulo:
indent base modulo
1 0 1
2 0 2
3 1 1
4 1 2
5 2 1
6 2 2
7 3 1
8 3 2
9 4 1
10 4 2
]]
local baseNum = math.floor( (indent - 1) / 2 )
local modNum = math.fmod( indent - 1 , 2 ) + 1
return mw.ustring.rep( base, baseNum) .. mw.ustring.rep( modulo, modNum )
end
return p
d2jdhmzl1ariwd7uypwfkhex9llkyg6
Template:Numbered verses
10
52518
308488
2026-09-17T22:09:09Z
Isma4l
41797
Bog cusub: <includeonly>{{#if:{{{1|}}}|<templatestyles src="Template:Numbered verses/styles.css" /><div class="numbered-verses"{{#if:{{{first|}}}|{{#iferror:{{#expr:{{{first}}}*0}}||<nowiki /> style="counter-reset: versus {{#expr:({{{first}}}) - 1}};"}}|<nowiki /> style="counter-reset: versus 0;"}}>{{#invoke:string|replace|{{#invoke:string|replace|{{#invoke:string|replace|{{#invoke:string|replace|~#!@@/// <div>{{#if:1|{{{1}}}}}</div>| +|</div><div class{{=}}"intervallum-carminis"><br /> |p...
308488
wikitext
text/x-wiki
<includeonly>{{#if:{{{1|}}}|<templatestyles src="Template:Numbered verses/styles.css" /><div class="numbered-verses"{{#if:{{{first|}}}|{{#iferror:{{#expr:{{{first}}}*0}}||<nowiki /> style="counter-reset: versus {{#expr:({{{first}}}) - 1}};"}}|<nowiki /> style="counter-reset: versus 0;"}}>{{#invoke:string|replace|{{#invoke:string|replace|{{#invoke:string|replace|{{#invoke:string|replace|~#!@@///
<div>{{#if:1|{{{1}}}}}</div>|
+|</div><div class{{=}}"intervallum-carminis"><br />
|plain=false}}|([^
]+
[^
]+
[^
]+
[^
]+
[^
]+)
|%1</div><div class{{=}}"quintina-carminis">|plain=false}}|^~#!@@///
||count=1|plain=false}}|
|</div><div>|plain=true}}{{#if:{{{2|}}}|<div class="auctor-carminis">{{#if:1|{{{2}}}}}</div>}}</div><div style="clear: both;"></div>|{{#invoke:Error|error|Error: No verses were given.}}
}}</includeonly><noinclude>{{Documentation}}</noinclude>
pmzjlp3985fhdut6fvehpu8yc41h54z
Template:Numbered verses/styles.css
10
52519
308489
2026-09-17T22:09:43Z
Isma4l
41797
Bog cusub: div.numbered-verses { float: left; margin: 1em auto 1em 3%; } div.numbered-verses > div { margin-left: 3em; text-indent: -3em; counter-increment: versus; margin-right: 5em; } div.numbered-verses > div.titulus-carminis { text-indent: 0; margin: 0 0 1em 0; font-weight: bold; counter-increment: none; } div.numbered-verses > div.intervallum-carminis { margin-left: 0; text-indent: 0; counter-increment: none; } div.numbered-verses > div.quintina-carminis { position: r...
308489
sanitized-css
text/css
div.numbered-verses {
float: left;
margin: 1em auto 1em 3%;
}
div.numbered-verses > div {
margin-left: 3em;
text-indent: -3em;
counter-increment: versus;
margin-right: 5em;
}
div.numbered-verses > div.titulus-carminis {
text-indent: 0;
margin: 0 0 1em 0;
font-weight: bold;
counter-increment: none;
}
div.numbered-verses > div.intervallum-carminis {
margin-left: 0;
text-indent: 0;
counter-increment: none;
}
div.numbered-verses > div.quintina-carminis {
position: relative;
}
div.numbered-verses > div.quintina-carminis::after {
display: block;
position: absolute;
right: -5em;
bottom: 0;
content: counter(versus);
}
div.auctor-carminis {
margin: 0 auto .5em 8%;
position: relative;
top: -.5em;
left: 0;
}
div.auctor-carminis::before {
content: "\2015";
margin-right: .25em;
}
o0eqr5gnl2k4kh495wpriem6xvcwz3r
Template:Poem
10
52520
308490
2026-09-17T22:10:20Z
Isma4l
41797
Bog cusub: <includeonly><<noinclude></noinclude>poem>{{{1|}}}<<noinclude></noinclude>/poem></includeonly><noinclude>{{documentation}}<!-- Add categories and interwikis to the /doc subpage, not here! --></noinclude>
308490
wikitext
text/x-wiki
<includeonly><<noinclude></noinclude>poem>{{{1|}}}<<noinclude></noinclude>/poem></includeonly><noinclude>{{documentation}}<!-- Add categories and interwikis to the /doc subpage, not here! --></noinclude>
lxh06q36jeurkf3ihs391f1fgg0zold
Template:Poetically break lines
10
52521
308491
2026-09-17T22:10:55Z
Isma4l
41797
Bog cusub: <includeonly><templatestyles src="Template:Poetically break lines/styles.css" />{{#if:{{{1|}}}|<div class="pbl" style="margin:{{#if:{{{margin|}}}|{{{margin|}}}|1em auto 1em 5%}};"><div>{{#invoke:String|replace|{{#invoke:String|replace|{{trim|{{{1}}}}}| |</div><div>|plain=true}}|<div></div>|<div><br /></div>|plain=true}}</div></div>|{{#invoke:Error|error|Error: Missing argument.}}}}</includeonly><noinclude>{{Documentation}}</noinclude>
308491
wikitext
text/x-wiki
<includeonly><templatestyles src="Template:Poetically break lines/styles.css" />{{#if:{{{1|}}}|<div class="pbl" style="margin:{{#if:{{{margin|}}}|{{{margin|}}}|1em auto 1em 5%}};"><div>{{#invoke:String|replace|{{#invoke:String|replace|{{trim|{{{1}}}}}|
|</div><div>|plain=true}}|<div></div>|<div><br /></div>|plain=true}}</div></div>|{{#invoke:Error|error|Error: Missing argument.}}}}</includeonly><noinclude>{{Documentation}}</noinclude>
6nvbha92kwi9g9jh91k6q0ebtjyueg3
Template:Poetically break lines/styles.css
10
52522
308492
2026-09-17T22:11:16Z
Isma4l
41797
Bog cusub: div.pbl > div { margin-left: 3em; text-indent: -3em; }
308492
sanitized-css
text/css
div.pbl > div {
margin-left: 3em;
text-indent: -3em;
}
b7qkcr465hjxfo470uir6el3v6bghc7
Template:Translated blockquote
10
52523
308493
2026-09-17T22:11:50Z
Isma4l
41797
Bog cusub: <includeonly>{{#invoke:Template wrapper|{{#if:{{{_debug|}}}|list|wrap}} |_template=blockquote |_exclude=_debug,language,lang,translation,quote,italic,rtl,show-language,link-language,nocat,size,brackets,text-style,text-class |multiline=yes |text={{#if:{{{text-style|}}}{{{text-class|}}}|<div class="{{{text-class|}}}" style="{{{text-style|}}}">}}{{if both|{{yesno|{{{show-language|}}}}}|{{yesno|{{{link-language|}}}|yes=|no=true|def=true}}|{{lang|fn=name_from_tag|{{{language|{{{lang|}...
308493
wikitext
text/x-wiki
<includeonly>{{#invoke:Template wrapper|{{#if:{{{_debug|}}}|list|wrap}}
|_template=blockquote
|_exclude=_debug,language,lang,translation,quote,italic,rtl,show-language,link-language,nocat,size,brackets,text-style,text-class
|multiline=yes
|text={{#if:{{{text-style|}}}{{{text-class|}}}|<div class="{{{text-class|}}}" style="{{{text-style|}}}">}}{{if both|{{yesno|{{{show-language|}}}}}|{{yesno|{{{link-language|}}}|yes=|no=true|def=true}}|{{lang|fn=name_from_tag|{{{language|{{{lang|}}}}}}}}: }}{{Lang/with italics|italic={{{italic|}}}|nocat={{{nocat|}}}|rtl={{{rtl|}}}|size={{{size|}}}|fn={{if both|{{yesno|{{{show-language|}}}}}|{{yesno|{{{link-language|}}}}}|lang_xx_inherit|lang}}|code={{{language|{{{lang|}}}}}}|text={{{1|{{{quote|}}}}}}}}
{{#if:{{{3|}}}{{{4|}}}{{{5|}}}|{{error|Too many unnamed parameters given to {{FULLPAGENAME}}. A maximum of 2 unnamed parameters are allowed.}}
|}}{{yesno|{{{brackets|}}}|yes=[|no=|blank=[|def=[}}{{trim|{{{2|{{{translation|}}}}}}}}{{yesno|{{{brackets|yes}}}|yes=]|no=|blank=]|def=]{{error|Unexpected value {{para|brackets|{{{brackets}}}}}}}}}{{if either|1={{{text-style|}}}|2={{{text-class|}}}|3=</div>|4=}}
}}</includeonly><noinclude>{{documentation}}</noinclude>
big63259rkzxj4ijtmixqbcn43ku1i7
Template:Text and translation
10
52524
308494
2026-09-17T22:12:27Z
Isma4l
41797
Bog cusub: <div class="text-and-translation" style="padding:1em 3em 1em 3em"><!-- --><div style="display:flex;flex-flow:row wrap; gap:1em"><!-- --><div style="flex: 1 1 300px;">{{#if:{{{language|}}}|{{lang|{{{language}}}|{{{1}}}|italic=unset}}|{{trim|{{{1}}}}}}}</div><!-- --><div style="flex: 1 1 300px;">{{trim|{{{2}}}}}</div><!-- --></div><!-- -->{{#if:{{{3|<noinclude>TRUE</noinclude>}}}|<p style="clear:left;margin:1em 0 1em 6em;align-self:flex-end">—{{hair space}...
308494
wikitext
text/x-wiki
<div class="text-and-translation" style="padding:1em 3em 1em 3em"><!--
--><div style="display:flex;flex-flow:row wrap; gap:1em"><!--
--><div style="flex: 1 1 300px;">{{#if:{{{language|}}}|{{lang|{{{language}}}|{{{1}}}|italic=unset}}|{{trim|{{{1}}}}}}}</div><!--
--><div style="flex: 1 1 300px;">{{trim|{{{2}}}}}</div><!--
--></div><!--
-->{{#if:{{{3|<noinclude>TRUE</noinclude>}}}|<p style="clear:left;margin:1em 0 1em 6em;align-self:flex-end">—{{hair space}}{{{3}}}</p>}}<!--
--></div><noinclude>
{{Documentation}}
<!-- PLEASE ADD THIS TEMPLATE'S CATEGORIES AND INTERWIKIS TO THE /doc SUBPAGE, THANKS -->
</noinclude>
iuzmeijjj02y0bsy8x6x66q4xmmow15
Template:Verse transliteration-translation
10
52525
308495
2026-09-17T22:12:57Z
Isma4l
41797
Bog cusub: <templatestyles src="Verse transliteration-translation/styles.css" /> {| class="Verse_transliteration-translation" {{#if:{{{originalHeading|}}}||style="margin-left:2em !important;"}} |- style="vertical-align: top;" | style="padding-right:1em" | {{#if:{{{originalHeading|}}}|<strong>{{{originalHeading}}}</strong>|}}{{#if:{{{originalHeading|{{{transliteration heading|{{{translationHeading|}}}}}}}}}|<br />}}{{#if:{{{lang|}}}|<div style={{#if:{{{rtl|}}}|"direction:rtl;"|""}}>{{lang...
308495
wikitext
text/x-wiki
<templatestyles src="Verse transliteration-translation/styles.css" />
{| class="Verse_transliteration-translation" {{#if:{{{originalHeading|}}}||style="margin-left:2em !important;"}}
|- style="vertical-align: top;"
| style="padding-right:1em" |
{{#if:{{{originalHeading|}}}|<strong>{{{originalHeading}}}</strong>|}}{{#if:{{{originalHeading|{{{transliteration heading|{{{translationHeading|}}}}}}}}}|<br />}}{{#if:{{{lang|}}}|<div style={{#if:{{{rtl|}}}|"direction:rtl;"|""}}>{{lang|{{{lang}}}|{{#tag:poem|{{{1|{{error|missing input}}}}}}}|rtl={{{rtl|}}}}}</div>|{{#tag:poem|{{{1|{{error|missing input}}}}}|style={{#if:{{{originalHeading|}}}|"margin-left:1em;"}}}}}}
| style="padding-right:1em" |
{{#if:{{{transliterationHeading|}}}|<strong>{{{transliterationHeading}}}</strong>}} {{#if:{{{originalHeading|{{{transliterationHeading|{{{translationHeading|}}}}}}}}}|<br />}} {{#if:{{{lang|}}}|{{Transliteration|{{{lang}}}|{{#tag:poem|{{{2|{{error|missing input}}}}}|style={{#if:{{{transliterationHeading|}}}|"margin-left:1em;"}}}}}}|{{#tag:poem|{{{2|{{error|missing input}}}}}|style={{#if:{{{transliterationHeading|}}}|"margin-left:1em;"}}}}}}
| {{#if:{{{translationHeading|}}}|<strong>{{{translationHeading}}}</strong>}} {{#if:{{{originalHeading|{{{transliterationHeading|{{{translationHeading|}}}}}}}}}|<br />}} {{#tag:poem|{{{3|{{error|missing input}}}}}
|style={{#if:{{{translationHeading|}}}|"margin-left:1em;"}}}}
|}<noinclude>
{{documentation}}
</noinclude>
79uv36zqsbogfpp0u3qgwm2pwf9uzxc
308497
308495
2026-09-17T22:15:21Z
Isma4l
41797
308497
wikitext
text/x-wiki
<templatestyles src="Verse transliteration-translation/styles.css" />
{| class="Verse_transliteration-translation" {{#if:{{{originalHeading|}}}||style="margin-left:2em !important;"}}
|- style="vertical-align: top;"
| style="padding-right:1em" |
{{#if:{{{originalHeading|}}}|<strong>{{{originalHeading}}}</strong>|}}{{#if:{{{originalHeading|{{{transliteration heading|{{{translationHeading|}}}}}}}}}|<br />}}{{#if:{{{lang|}}}|<div style={{#if:{{{rtl|}}}|"direction:rtl;"|""}}>{{lang|{{{lang}}}|{{#tag:poem|{{{1|{{error|missing input}}}}}}}|rtl={{{rtl|}}}}}</div>|{{#tag:poem|{{{1|{{error|missing input}}}}}|style={{#if:{{{originalHeading|}}}|"margin-left:1em;"}}}}}}
| style="padding-right:1em" |
{{#if:{{{transliterationHeading|}}}|<strong>{{{transliterationHeading}}}</strong>}} {{#if:{{{originalHeading|{{{transliterationHeading|{{{translationHeading|}}}}}}}}}|<br />}} {{#if:{{{lang|}}}|{{Transliteration|{{{lang}}}|{{#tag:poem|{{{2|{{error|missing input}}}}}|style={{#if:{{{transliterationHeading|}}}|"margin-left:1em;"}}}}}}|{{#tag:poem|{{{2|{{error|missing input}}}}}|style={{#if:{{{transliterationHeading|}}}|"margin-left:1em;"}}}}}}
| {{#if:{{{translationHeading|}}}|<strong>{{{translationHeading}}}</strong>}} {{#if:{{{originalHeading|{{{transliterationHeading|{{{translationHeading|}}}}}}}}}|<br />}} {{#tag:poem|{{{3|{{error|Wax gelinta maqan}}}}}
|style={{#if:{{{translationHeading|}}}|"margin-left:1em;"}}}}
|}<noinclude>
{{documentation}}
</noinclude>
hebsnz2yv9b63f4zsv3c6emgtytlw44
308498
308497
2026-09-17T22:16:46Z
Isma4l
41797
308498
wikitext
text/x-wiki
<templatestyles src="Verse transliteration-translation/styles.css" />
{| class="Verse_transliteration-translation" {{#if:{{{originalHeading|}}}||style="margin-left:2em !important;"}}
|- style="vertical-align: top;"
| style="padding-right:1em" |
{{#if:{{{originalHeading|}}}|<strong>{{{originalHeading}}}</strong>|}}{{#if:{{{originalHeading|{{{transliteration heading|{{{translationHeading|}}}}}}}}}|<br />}}{{#if:{{{lang|}}}|<div style={{#if:{{{rtl|}}}|"direction:rtl;"|""}}>{{lang|{{{lang}}}|{{#tag:poem|{{{1|{{error|Wax gelinta maqan}}}}}}}|rtl={{{rtl|}}}}}</div>|{{#tag:poem|{{{1|{{error|Wax gelinta maqan}}}}}|style={{#if:{{{originalHeading|}}}|"margin-left:1em;"}}}}}}
| style="padding-right:1em" |
{{#if:{{{transliterationHeading|}}}|<strong>{{{transliterationHeading}}}</strong>}} {{#if:{{{originalHeading|{{{transliterationHeading|{{{translationHeading|}}}}}}}}}|<br />}} {{#if:{{{lang|}}}|{{Transliteration|{{{lang}}}|{{#tag:poem|{{{2|{{error|Wax gelinta maqan}}}}}|style={{#if:{{{transliterationHeading|}}}|"margin-left:1em;"}}}}}}|{{#tag:poem|{{{2|{{error|Wax gelinta maqan}}}}}|style={{#if:{{{transliterationHeading|}}}|"margin-left:1em;"}}}}}}
| {{#if:{{{translationHeading|}}}|<strong>{{{translationHeading}}}</strong>}} {{#if:{{{originalHeading|{{{transliterationHeading|{{{translationHeading|}}}}}}}}}|<br />}} {{#tag:poem|{{{3|{{error|Wax gelinta maqan}}}}}
|style={{#if:{{{translationHeading|}}}|"margin-left:1em;"}}}}
|}<noinclude>
{{documentation}}
</noinclude>
dnkfjqoiqkzxwact3gntema6na339ds
Template:Verse transliteration-translation/styles.css
10
52526
308496
2026-09-17T22:13:45Z
Isma4l
41797
Bog cusub: .Verse_transliteration-translation tr > td > .poem > p > span > i, .Verse_transliteration-translation tr > td > .poem > p > span > span { line-height: 1em; } .Verse_transliteration-translation td { display: inline-block; } /*wrap if below 900px*/ @media only screen and (max-width: 900px) { .Verse_transliteration-translation td { display: block; } }
308496
sanitized-css
text/css
.Verse_transliteration-translation tr > td > .poem > p > span > i,
.Verse_transliteration-translation tr > td > .poem > p > span > span {
line-height: 1em;
}
.Verse_transliteration-translation td {
display: inline-block;
}
/*wrap if below 900px*/
@media only screen and (max-width: 900px) {
.Verse_transliteration-translation td {
display: block;
}
}
hmlj25mh8v43ggyqhvvq4crxwp25btl
Template:Reduced quote
10
52527
308499
2026-09-17T22:17:41Z
Isma4l
41797
Bog cusub: <noinclude>The template appears as follows in article space: {{Blockquote|class=rquote|text={{lorem ipsum}}|style=width:33%}} and as follows in all other namespaces: </noinclude><templatestyles src="Reduced quote/styles.css"/>{{Main other |demospace={{{demospace|}}} |1=<!-- result if in mainspace --><div class="rquote" style="float: {{{1|{{{align}}}}}}; width: {{{width|39%}}}; {{{style|}}}">{{Blockquote | class = | text = {{Trim quotes|{{{text|{{{content|{{{quotetext|{{...
308499
wikitext
text/x-wiki
<noinclude>The template appears as follows in article space:
{{Blockquote|class=rquote|text={{lorem ipsum}}|style=width:33%}}
and as follows in all other namespaces:
</noinclude><templatestyles src="Reduced quote/styles.css"/>{{Main other
|demospace={{{demospace|}}}
|1=<!-- result if in mainspace --><div class="rquote" style="float: {{{1|{{{align}}}}}}; width: {{{width|39%}}}; {{{style|}}}">{{Blockquote
| class =
| text = {{Trim quotes|{{{text|{{{content|{{{quotetext|{{{quote|{{{2|<includeonly>{{Error|Error: No text given for quotation (or equals sign used in the actual argument to an unnamed parameter)}}</includeonly><noinclude>{{lorem ipsum}}</noinclude>}}}}}}}}}}}}}}}}}
| author = {{{3|{{{author|<noinclude>person quoted</noinclude>}}}}}}
| source = {{#if:{{{4|{{{source|}}}}}}|{{{4|{{{source<noinclude>|cited source</noinclude>}}}}}}}}
}}</div>
|2=<!-- result if elsewhere -->
{{{!}} class="rquote pullquote float{{{1|{{{align}}}}}}" role="presentation" style="display:table; border-collapse:collapse; border-style:none; float:{{{1|{{{align}}}}}}; margin:0.5em 0.75em; width:{{{width|33%}}}; {{{style|}}}"
{{!}}- style="text-align:left; vertical-align:top;"
{{!}} style="color:#b2b7f2; font-size:3.3em; font-family:'Times New Roman',serif; font-weight:bold; padding:4px 2px 2px; width:0.5em; line-height: 1em;"{{!}} “
{{!}} style="padding:0 10px;"{{!}} {{trim quotes|{{{text|{{{content|{{{quotetext|{{{quote|{{{2|<includeonly>{{Error|Error: No text given for quotation (or equals sign used in the actual argument to an unnamed parameter)}}</includeonly><noinclude>{{Lorem ipsum}}</noinclude>}}}}}}}}}}}}}}}}}
{{!}} style="color:#b2b7f2; font-size:3.3em; font-family:'Times New Roman',serif; font-weight:bold; padding:4px 2px 2px; text-align:right; vertical-align:bottom; width:0.5em; line-height: 1em;"{{!}} ”
{{!}}-
{{!}} class="rquotecite" colspan="3" style="padding-top:10px; font-size:smaller; line-height:normal; text-align:right;"{{!}} {{#if:{{{3|{{{author|{{{4|{{{source|}}}}}}}}}}}}|<cite>— <!--hairspace-->{{trim|1={{{3|{{{author|<noinclude>person quoted</noinclude>}}}}}}{{#if:{{{4|{{{source|}}}}}}|{{#if:{{{3|{{{author|}}}}}}|,}} {{{4|{{{source<noinclude>|cited source</noinclude>}}}}}}}}}}</cite>}}
{{!}}}
}}<!--Markup inserted from Template:Rquote--><noinclude>
{{Documentation}}
</noinclude>
laqdc7tm4zfshl5bolq7226fctvwc9r
Template:Reduced quote/styles.css
10
52528
308500
2026-09-17T22:19:14Z
Isma4l
41797
Bog cusub: /* {{pp-template}} */ @media all and (max-width:720px) { .rquote { width:auto !important; float:none !important; } }
308500
sanitized-css
text/css
/* {{pp-template}} */
@media all and (max-width:720px) {
.rquote {
width:auto !important;
float:none !important;
}
}
oone4wbwswbh8wrhecdprbqwo2932mh
Template:Talk quote block minimalist
10
52529
308501
2026-09-17T22:20:59Z
Isma4l
41797
Bog cusub: <templatestyles src="Talk quote block minimalist/styles.css" /><blockquote class="tqb talkquote-minimal"><!-- -->{{{text|{{{1|<noinclude>{{lorem ipsum}}</noinclude>}}}}}}<!-- --></blockquote><noinclude> {{Documentation}} <!-- PLEASE ADD THIS TEMPLATE'S CATEGORIES AND INTERWIKIS TO THE /doc SUBPAGE, THANKS --> </noinclude>
308501
wikitext
text/x-wiki
<templatestyles src="Talk quote block minimalist/styles.css" /><blockquote class="tqb talkquote-minimal"><!--
-->{{{text|{{{1|<noinclude>{{lorem ipsum}}</noinclude>}}}}}}<!--
--></blockquote><noinclude>
{{Documentation}}
<!-- PLEASE ADD THIS TEMPLATE'S CATEGORIES AND INTERWIKIS TO THE /doc SUBPAGE, THANKS -->
</noinclude>
qrp6ffi0hkm8o3831w6wflvfm0u7fo7
Template:Talk quote block minimalist/styles.css
10
52530
308502
2026-09-17T22:21:24Z
Isma4l
41797
Bog cusub: /* {{pp-template}} */ .talkquote-minimal { color: var(--color-subtle, #54595d); border-left: .25em solid var(--border-color-muted, #dadde3); padding: 0 1em; margin: 0.3em 0 0 0; }
308502
sanitized-css
text/css
/* {{pp-template}} */
.talkquote-minimal {
color: var(--color-subtle, #54595d);
border-left: .25em solid var(--border-color-muted, #dadde3);
padding: 0 1em;
margin: 0.3em 0 0 0;
}
t4jbl1ixlvxkpqqz1fedzald35ax4r0
User:Mjcwm
2
52531
308503
2026-09-18T01:34:32Z
Mjcwm
47428
/* */
308503
wikitext
text/x-wiki
Maxamed xaaji jaamac cabdilaahi Awal
olg647vmfhss698iyxk07ca93d15ogu
User talk:SHB2000
3
52532
308505
2026-09-18T03:43:33Z
Max
35277
Max la wareejiyay bogga [[User talk:SHB2000]] ilaa [[User talk:SHB]]: Bogga si otomaatig ah ayaa loo wareejiyay intii lagu jiray magaca beddelka isticmaalaha "[[Special:CentralAuth/SHB2000|SHB2000]]" loona beddelay "[[Special:CentralAuth/SHB|SHB]]"
308505
wikitext
text/x-wiki
#REDIRECT [[User talk:SHB]]
dgionzejbwpmne0gol3e840676zou8k