<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://wiki.tachyony.co.uk/w/index.php?action=history&amp;feed=atom&amp;title=Module%3AArbcom_election_banner</id>
	<title>Module:Arbcom election banner - Revision history</title>
	<link rel="self" type="application/atom+xml" href="https://wiki.tachyony.co.uk/w/index.php?action=history&amp;feed=atom&amp;title=Module%3AArbcom_election_banner"/>
	<link rel="alternate" type="text/html" href="https://wiki.tachyony.co.uk/w/index.php?title=Module:Arbcom_election_banner&amp;action=history"/>
	<updated>2026-05-15T09:05:45Z</updated>
	<subtitle>Revision history for this page on the wiki</subtitle>
	<generator>MediaWiki 1.35.5</generator>
	<entry>
		<id>https://wiki.tachyony.co.uk/w/index.php?title=Module:Arbcom_election_banner&amp;diff=5754&amp;oldid=prev</id>
		<title>Tachyony: Created page with &quot;local messageBox = require(&#039;Module:Message box&#039;) local navbarModule = require(&#039;Module:Navbar&#039;)  local p = {}  -- Get constants. local lang = mw.language.getContentLanguage() local currentUnixDate = lang:formatDate(&#039;U&#039;) currentUnixDate = tonumber(currentUnixDate)  local function err(msg) 	return mw.ustring.format(&#039;&lt;b class=&quot;error&quot;&gt;%s&lt;/b&gt;&#039;, msg) end  local function getUnixDate(date) 	local success, unixDate = pcall(lang.formatDate, lang, &#039;U&#039;, date) 	if success then 		retur...&quot;</title>
		<link rel="alternate" type="text/html" href="https://wiki.tachyony.co.uk/w/index.php?title=Module:Arbcom_election_banner&amp;diff=5754&amp;oldid=prev"/>
		<updated>2022-01-15T01:10:44Z</updated>

		<summary type="html">&lt;p&gt;Created page with &amp;quot;local messageBox = require(&amp;#039;Module:Message box&amp;#039;) local navbarModule = require(&amp;#039;Module:Navbar&amp;#039;)  local p = {}  -- Get constants. local lang = mw.language.getContentLanguage() local currentUnixDate = lang:formatDate(&amp;#039;U&amp;#039;) currentUnixDate = tonumber(currentUnixDate)  local function err(msg) 	return mw.ustring.format(&amp;#039;&amp;lt;b class=&amp;quot;error&amp;quot;&amp;gt;%s&amp;lt;/b&amp;gt;&amp;#039;, msg) end  local function getUnixDate(date) 	local success, unixDate = pcall(lang.formatDate, lang, &amp;#039;U&amp;#039;, date) 	if success then 		retur...&amp;quot;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;local messageBox = require(&amp;#039;Module:Message box&amp;#039;)&lt;br /&gt;
local navbarModule = require(&amp;#039;Module:Navbar&amp;#039;)&lt;br /&gt;
&lt;br /&gt;
local p = {}&lt;br /&gt;
&lt;br /&gt;
-- Get constants.&lt;br /&gt;
local lang = mw.language.getContentLanguage()&lt;br /&gt;
local currentUnixDate = lang:formatDate(&amp;#039;U&amp;#039;)&lt;br /&gt;
currentUnixDate = tonumber(currentUnixDate)&lt;br /&gt;
&lt;br /&gt;
local function err(msg)&lt;br /&gt;
	return mw.ustring.format(&amp;#039;&amp;lt;b class=&amp;quot;error&amp;quot;&amp;gt;%s&amp;lt;/b&amp;gt;&amp;#039;, msg)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function getUnixDate(date)&lt;br /&gt;
	local success, unixDate = pcall(lang.formatDate, lang, &amp;#039;U&amp;#039;, date)&lt;br /&gt;
	if success then&lt;br /&gt;
		return tonumber(unixDate)&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function unixDateError(date)&lt;br /&gt;
	return err(tostring(date) .. &amp;#039; is not a valid date.&amp;#039;)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function makeOmbox(oargs)&lt;br /&gt;
	return messageBox.main(&amp;#039;ombox&amp;#039;, oargs)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function makeNavbar(name)&lt;br /&gt;
	return navbarModule.navbar{name, mini = &amp;#039;1&amp;#039;}&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function randomizeArray(t)&lt;br /&gt;
	-- Iterate through the array backwards, each time swapping the entry &amp;quot;i&amp;quot; with a random entry.&lt;br /&gt;
	-- Courtesy of Xinhuan at http://forums.wowace.com/showthread.php?p=279756&lt;br /&gt;
	math.randomseed(mw.site.stats.edits)&lt;br /&gt;
	for i = #t, 2, -1 do&lt;br /&gt;
		local r = math.random(i)&lt;br /&gt;
		t[i], t[r] = t[r], t[i]&lt;br /&gt;
	end&lt;br /&gt;
	return t&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function getArgNums(args, prefix)&lt;br /&gt;
	-- Returns a table containing the numbers of the arguments that exist for the specified prefix. For example, if the prefix&lt;br /&gt;
	-- was &amp;#039;data&amp;#039;, and &amp;#039;data1&amp;#039;, &amp;#039;data2&amp;#039;, and &amp;#039;data5&amp;#039; exist, it would return {1, 2, 5}.&lt;br /&gt;
	local nums = {}&lt;br /&gt;
	for k, v in pairs(args) do&lt;br /&gt;
		k = tostring(k)&lt;br /&gt;
		local num = mw.ustring.match(k, &amp;#039;^&amp;#039; .. prefix .. &amp;#039;([1-9]%d*)$&amp;#039;)&lt;br /&gt;
		if num then&lt;br /&gt;
			table.insert(nums, tonumber(num))&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	table.sort(nums)&lt;br /&gt;
	return nums&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function showBeforeDate(datePairs)&lt;br /&gt;
	-- Shows a value if it is before a given date.&lt;br /&gt;
	for i, datePair in ipairs(datePairs) do&lt;br /&gt;
		local date = datePair.date&lt;br /&gt;
		local val = datePair.val&lt;br /&gt;
		if not date then -- No date specified, so assume we have no more dates to process.&lt;br /&gt;
			return val&lt;br /&gt;
		end&lt;br /&gt;
		local unixDate = getUnixDate(date)&lt;br /&gt;
		if not unixDate then return unixDateError(date) end&lt;br /&gt;
		if currentUnixDate &amp;lt; unixDate then -- The specified date is in the future.&lt;br /&gt;
			return val&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function countdown(date, event)&lt;br /&gt;
	if type(event) ~= &amp;#039;string&amp;#039; then return err(&amp;#039;No event name provided.&amp;#039;) end&lt;br /&gt;
	-- Get the current date unix timestamp.&lt;br /&gt;
	local unixDate = getUnixDate(date)&lt;br /&gt;
	if not unixDate then return unixDateError(date) end&lt;br /&gt;
	unixDate = tonumber(unixDate)&lt;br /&gt;
	-- Subtract the timestamp from the current unix timestamp to find the time left, and output that in a readable way.&lt;br /&gt;
	local secondsLeft = unixDate - currentUnixDate&lt;br /&gt;
	if secondsLeft &amp;lt;= 0 then return end&lt;br /&gt;
	local timeLeft = lang:formatDuration(secondsLeft, {&amp;#039;weeks&amp;#039;, &amp;#039;days&amp;#039;, &amp;#039;hours&amp;#039;})&lt;br /&gt;
	-- Find whether we are plural or not.&lt;br /&gt;
	local isOrAre&lt;br /&gt;
	if mw.ustring.match(timeLeft, &amp;#039;^%d+&amp;#039;) == &amp;#039;1&amp;#039; then&lt;br /&gt;
		isOrAre = &amp;#039;is&amp;#039;&lt;br /&gt;
	else&lt;br /&gt;
		isOrAre = &amp;#039;are&amp;#039;&lt;br /&gt;
	end&lt;br /&gt;
	-- Make the numbers red and bold, because that&amp;#039;s what {{countdown}} does and it makes them look important.&lt;br /&gt;
	local timeLeft = mw.ustring.gsub(timeLeft, &amp;#039;(%d+)&amp;#039;, &amp;#039;&amp;lt;span style=&amp;quot;color: #F00; font-weight: bold;&amp;quot;&amp;gt;%1&amp;lt;/span&amp;gt;&amp;#039;)&lt;br /&gt;
	-- Make the refresh link, and join it all together.&lt;br /&gt;
	local refreshLink = mw.title.getCurrentTitle():fullUrl{action = &amp;#039;purge&amp;#039;}&lt;br /&gt;
	refreshLink = mw.ustring.format(&amp;#039;&amp;lt;small&amp;gt;&amp;lt;span class=&amp;quot;plainlinks&amp;quot;&amp;gt;([%s refresh])&amp;lt;/span&amp;gt;&amp;lt;/small&amp;gt;&amp;#039;, refreshLink)&lt;br /&gt;
	return mw.ustring.format(&amp;#039;There %s %s until %s. %s&amp;#039;, isOrAre, timeLeft, event, refreshLink)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function collapse(s, heading, bg)&lt;br /&gt;
	local ret = [=[&lt;br /&gt;
&amp;lt;div style=&amp;quot;margin-left: 0px;&amp;quot;&amp;gt;&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed&amp;quot; style=&amp;quot;width:100%%; background: transparent; text-align: left; border: 1px solid silver; margin-top: 0.2em;&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;background-color: %s; text-align: center;&amp;quot; | %s&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;border: solid 1px silver; padding: 8px; background-color: white;&amp;quot; | %s&lt;br /&gt;
|}&amp;lt;/div&amp;gt;]=]&lt;br /&gt;
	return mw.ustring.format(ret, bg or &amp;#039;#e0f8e2&amp;#039;, heading, s)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p._main(args)&lt;br /&gt;
	-- Get data for the box, plus the box title.&lt;br /&gt;
	local year = lang:formatDate(&amp;#039;Y&amp;#039;)&lt;br /&gt;
	local name = args.name or &amp;#039;ACE&amp;#039; .. year&lt;br /&gt;
	local navbar = makeNavbar(name)&lt;br /&gt;
	local electionpage = args.electionpage or mw.ustring.format(&lt;br /&gt;
		&amp;#039;[[Wikipedia:Arbitration Committee Elections December %s|%s Arbitration Committee Elections]]&amp;#039;,&lt;br /&gt;
		year, year&lt;br /&gt;
	)&lt;br /&gt;
	-- Get nomination or voting link, depending on the date.&lt;br /&gt;
	local beforenomlink = args.beforenomlink or mw.ustring.format(&amp;#039;[[Wikipedia:Requests for comment/Arbitration Committee Elections December %s/Electoral Commission|Electoral Commission RFC]]&amp;#039;, year)&lt;br /&gt;
	local nomstart = args.nomstart or error(&amp;#039;No nomstart date supplied&amp;#039;)&lt;br /&gt;
	local nomlink = args.nomlink or mw.ustring.format(&amp;#039;[[Wikipedia:Arbitration Committee Elections December %s/Candidates|Nominate]]&amp;#039;, year)&lt;br /&gt;
	local nomend = args.nomend or error(&amp;#039;No nomend date supplied&amp;#039;)&lt;br /&gt;
	local votestart = args.votestart or error(&amp;#039;No votestart date supplied&amp;#039;)&lt;br /&gt;
	local votepage = args.votepage or &amp;#039;[[Special:SecurePoll|Cast your vote]]&amp;#039;&lt;br /&gt;
	local votelog = args.votelog or mw.ustring.format(&amp;#039;[[Wikipedia:Arbitration Committee Elections December %s/Log|Voter log]]&amp;#039;, year)&lt;br /&gt;
	local votelink = args.votelink or mw.ustring.format(&amp;quot;&amp;#039;&amp;#039;&amp;#039;%s&amp;#039;&amp;#039;&amp;#039;\n* %s&amp;quot;, votepage, votelog)&lt;br /&gt;
	local voteend = args.voteend or error(&amp;#039;No voteend date supplied&amp;#039;)&lt;br /&gt;
	local voteendlink = args.voteendlink or votelog&lt;br /&gt;
	local scheduleText = showBeforeDate{&lt;br /&gt;
		{val = beforenomlink, date = nomstart},&lt;br /&gt;
		{val = nomlink, date = nomend},&lt;br /&gt;
		{val = countdown(votestart, &amp;#039;voting begins&amp;#039;), date = votestart},&lt;br /&gt;
		{val = votelink, date = voteend},&lt;br /&gt;
		{val = voteendlink}&lt;br /&gt;
	}&lt;br /&gt;
	-- Get other links.&lt;br /&gt;
	local contact = args.contact or mw.ustring.format(&amp;#039;[[WT:COORD%s|Contact the coordinators]]&amp;#039;, mw.ustring.sub(year, 3, 4))&lt;br /&gt;
	local discuss = args.discuss or mw.ustring.format(&amp;#039;[[WT:ACE%s|Discuss the elections]]&amp;#039;, year)&lt;br /&gt;
	local cguide = args.cguide or mw.ustring.format(&amp;#039;[[Wikipedia:Arbitration Committee Elections December %s/Candidates/Guide|Candidate guide]]&amp;#039;, year)&lt;br /&gt;
	local cstatements = args.cstatements or mw.ustring.format(&amp;#039;[[Wikipedia:Arbitration Committee Elections December %s/Candidates|Candidate statements]]&amp;#039;, year)&lt;br /&gt;
	local cquestions = args.cquestions or mw.ustring.format(&amp;#039;[[Wikipedia:Arbitration Committee Elections December %s/Questions|Questions for the candidates]]&amp;#039;, year)&lt;br /&gt;
	local cdiscuss = args.cdiscuss or mw.ustring.format(&amp;#039;[[Wikipedia:Arbitration Committee Elections December %s/Candidates/Discussion|Discuss the candidates]]&amp;#039;, year)&lt;br /&gt;
	-- Get voter guides&lt;br /&gt;
	local guideNums = getArgNums(args, &amp;#039;guide&amp;#039;)&lt;br /&gt;
	local guides = {}&lt;br /&gt;
	for _, num in ipairs(guideNums) do&lt;br /&gt;
		table.insert(guides, &amp;#039;\n* &amp;#039; .. args[&amp;#039;guide&amp;#039; .. tostring(num)])&lt;br /&gt;
	end&lt;br /&gt;
	guides = randomizeArray(guides)&lt;br /&gt;
	guides = table.concat(guides)&lt;br /&gt;
	guides = &amp;#039;&amp;lt;div class=&amp;quot;hlist&amp;quot;&amp;gt;\nThese [[:Category:Wikipedia Arbitration Committee Elections 2021 voter guides|guides]] represent the thoughts of their authors. All individually written voter guides are eligible for inclusion. Guides to other guides are ineligible.\n&amp;#039; .. guides .. &amp;#039;&amp;lt;/div&amp;gt;&amp;#039;&lt;br /&gt;
	guides = collapse(guides, &amp;#039;Voter guides&amp;#039;, &amp;#039;#e0f8e2&amp;#039;)&lt;br /&gt;
	-- Get the text field of ombox.&lt;br /&gt;
	local text = [=[&lt;br /&gt;
&amp;lt;div style=&amp;quot;float: right&amp;quot;&amp;gt;%s&amp;lt;/div&amp;gt;&amp;lt;div class=&amp;quot;hlist&amp;quot;&amp;gt;&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;%s&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
* %s&lt;br /&gt;
* %s&lt;br /&gt;
* %s&lt;br /&gt;
* [[Wikipedia:5-minute guide to ArbCom elections|Quick guide]]&amp;lt;/div&amp;gt;&lt;br /&gt;
----&lt;br /&gt;
&amp;lt;div class=&amp;quot;hlist&amp;quot;&amp;gt;&lt;br /&gt;
; Candidates&lt;br /&gt;
: %s&lt;br /&gt;
: %s&lt;br /&gt;
: %s&lt;br /&gt;
: %s&amp;lt;/div&amp;gt;&lt;br /&gt;
%s]=]&lt;br /&gt;
	text = mw.ustring.format(&lt;br /&gt;
		text,&lt;br /&gt;
		navbar,&lt;br /&gt;
		electionpage,&lt;br /&gt;
		scheduleText,&lt;br /&gt;
		contact,&lt;br /&gt;
		discuss,&lt;br /&gt;
		cguide,&lt;br /&gt;
		cstatements,&lt;br /&gt;
		cquestions,&lt;br /&gt;
		cdiscuss,&lt;br /&gt;
		guides&lt;br /&gt;
	)&lt;br /&gt;
	-- Build the ombox args&lt;br /&gt;
	local oargs = {}&lt;br /&gt;
	oargs.image = args.image or &amp;#039;[[File:Judges cupola.svg|50px|ArbCom|link=]]&amp;#039;&lt;br /&gt;
	oargs.style = args.style or &amp;#039;background-color: #e0f8e2&amp;#039;&lt;br /&gt;
	oargs.text = text&lt;br /&gt;
	return makeOmbox(oargs)		&lt;br /&gt;
end&lt;br /&gt;
 &lt;br /&gt;
function p.main(frame)&lt;br /&gt;
        -- If called via #invoke, use the args passed into the invoking template, or the args passed to #invoke if any exist.&lt;br /&gt;
        -- Otherwise assume args are being passed directly in from the debug console or from another Lua module.&lt;br /&gt;
        local origArgs&lt;br /&gt;
        if frame == mw.getCurrentFrame() then&lt;br /&gt;
                origArgs = frame:getParent().args&lt;br /&gt;
                for k, v in pairs(frame.args) do&lt;br /&gt;
                        origArgs = frame.args&lt;br /&gt;
                        break&lt;br /&gt;
                end&lt;br /&gt;
        else&lt;br /&gt;
                origArgs = frame&lt;br /&gt;
        end&lt;br /&gt;
        -- Trim whitespace and remove blank arguments.&lt;br /&gt;
        local args = {}&lt;br /&gt;
        for k, v in pairs(origArgs) do&lt;br /&gt;
                if type(v) == &amp;#039;string&amp;#039; then&lt;br /&gt;
                        v = mw.text.trim(v)&lt;br /&gt;
                end&lt;br /&gt;
                if v ~= &amp;#039;&amp;#039; then&lt;br /&gt;
                        args[k] = v&lt;br /&gt;
                end&lt;br /&gt;
        end&lt;br /&gt;
        return p._main(args)&lt;br /&gt;
end&lt;br /&gt;
 &lt;br /&gt;
return p&lt;/div&gt;</summary>
		<author><name>Tachyony</name></author>
	</entry>
</feed>