Module:Sandbox/Julio974fr
Appearance
local p = {};
local political_party = require('Module:Political party')
local lang = 'en'
--[[ Properties shorthands ]]
local P_MEMBER_OF_PARTY = 'P102'
local P_FOLLOWS = 'P155'
local P_FOLLOWED_BY = 'P156'
local P_HAS_PARTS = 'P527'
local P_PART_OF = 'P361'
local P_COLOR = 'P465'
local P_POINT_IN_TIME = 'P585'
local P_CANDIDATE = 'P726'
local P_SUCCESSFUL_CANDIDATE = 'P991'
local P_VOTES_RECEIVED = 'P1111'
local P_REPLACED_BY = 'P1366'
local P_SEATS = 'P1410'
local P_TOTAL_VALID_VOTES = 'P1697'
local P_SHORT_NAME = 'P1813'
local P_ELIGIBLE_VOTERS = 'P1867'
local P_BALLOTS_CAST = 'P1868'
local P_NAME = 'P2561'
local P_SPOILT_VOTES = 'P5044'
local P_BLANK_VOTES = 'P5045'
--[[ Get a best ranking statement value from "item" with the property "property".
The value is returned through the function "typefunc". ]] -- Function copied from elsewhere
local function getStatementValue(item, property, typefunc)
local statements = mw.wikibase.getBestStatements(item, property)
if statements[1] and statements[1].mainsnak.snaktype == 'value' then
return typefunc(statements[1].mainsnak.datavalue.value)
end
end
--[[ The "typefunc"s - A series of functions that extract the wanted information
from a statement value depending on the value type. ]]
local function getAmount(value) return tonumber(value.amount) end
local function getString(value) return value end
local function getItem(value) return value.id end
local function getTimestamp(value) return value.time end
-- Finds the text value of a given property in the given language
local function getValueFromLanguage(qid, property, lang)
local statement = mw.wikibase.getBestStatements(qid, property)
for i, v in ipairs(statement) do
if v.mainsnak.datavalue.value.language == lang then
return v.mainsnak.datavalue.value.text
end
end
for i, v in ipairs(statement) do
if v.mainsnak.datavalue.value.language == 'mul' then
return v.mainsnak.datavalue.value.text
end
end
end
function p.getAllPartiesData(electionQid, previousQid, partyNameOverrides, doGroupByParty)
local partiesData = p.getPartiesDataFromElection(electionQid, previousQid, doGroupByParty)
for partyIndex, partyData in ipairs(partiesData) do
local fetchedPartyData = p.fetchPartyData(partyData.qid)
partyData.name = fetchedPartyData.name
partyData.color = fetchedPartyData.color
partyData.articleTitle = fetchedPartyData.articleTitle
if partyNameOverrides['name_override_'..(partyData.qid)] then -- If name override specified
partyData.name = partyNameOverrides['name_override_'..(fetchedPartyData.qid)]
end
partiesData[partyIndex] = partyData
end
return partiesData
end
function p.getAllCandidatesData(firstRoundQid, secondRoundQid, partyNameOverrides)
local candidatesData = p.getCandidatesDataFromElection(firstRoundQid, secondRoundQid)
for candidateIndex, candidateData in ipairs(candidatesData) do
local fetchedCandidateData = p.fetchCandidateData(candidateData.qid)
candidateData.name = fetchedCandidateData.name
candidateData.color = fetchedCandidateData.color
candidateData.articleTitle = fetchedCandidateData.articleTitle
candidateData.partyWikitext = fetchedCandidateData.partyWikitext
-- @todo Name overrides etc
candidatesData[candidateIndex] = candidateData
end
return candidatesData
end
local function sortParties(listParties)
local function comparePartyByVotes(partyA, partyB)
if partyB.qid == 'Q86630688' then -- Q86630688 is 'Others'
return true
elseif partyA.qid == 'Q86630688' then
return false
elseif (partyA.votes or 0) > (partyB.votes or 0) then
return true
elseif (partyA.votes or 0) < (partyB.votes or 0) then
return false
else
return ((partyA.seats or 0) > (partyB.seats or 0))
end
end
table.sort(listParties, comparePartyByVotes)
end
local function findPartyIndex(listParties, partyQid)
local finalPartyIndex = nil
for curPartyindex, curParty in ipairs(listParties) do
if curParty.qid == partyQid then
finalPartyIndex = curPartyindex
break
end
end
return finalPartyIndex
end
local function initPartyIndex(listParties, partyQid)
local partyIndex = findPartyIndex(listParties, partyQid)
if not partyIndex then
table.insert(listParties, {qid=partyQid, votes = 0, seats = 0})
partyIndex = #listParties
end
return partyIndex
end
local function initCandidateIndex(listCandidates, candidateQid)
local candidateIndex = findPartyIndex(listCandidates, candidateQid)
if not candidateIndex then
table.insert(listCandidates, {qid=candidateQid, votes = 0})
candidateIndex = #listCandidates
end
return candidateIndex
end
local function addPartyDataFromStatement(partyData, statement)
if statement.qualifiers[P_VOTES_RECEIVED] then
if not partyData.votes then partyData.votes = 0 end
partyData.votes = partyData.votes + getAmount(statement.qualifiers[P_VOTES_RECEIVED][1].datavalue.value)
end
if statement.qualifiers[P_SEATS] then
if not partyData.seats then partyData.seats = 0 end
partyData.seats = partyData.seats + getAmount(statement.qualifiers[P_SEATS][1].datavalue.value)
end
if statement.qualifiers[P_FOLLOWS] then
if not partyData.predecessors then partyData.predecessors = {} end
for _, predecessorStatement in ipairs(statement.qualifiers[P_FOLLOWS]) do
table.insert(partyData.predecessors, getItem(predecessorStatement.datavalue.value))
end
end
return partyData
end
local function addCandidateDataFromStatement(candidateData, statement, round)
votesKey = 'votes'..(round==2 and '2' or '')
if statement.qualifiers[P_VOTES_RECEIVED] then
if not candidateData[votesKey] then candidateData[votesKey] = 0 end
candidateData[votesKey] = candidateData[votesKey] + getAmount(statement.qualifiers[P_VOTES_RECEIVED][1].datavalue.value)
end
return candidateData
end
local function addPrevPartyDataFromStatement(partyData, statement)
if not partyData.prevVotes then partyData.prevVotes = 0 end
if statement.qualifiers[P_VOTES_RECEIVED] then
partyData.prevVotes = partyData.prevVotes + getAmount(statement.qualifiers[P_VOTES_RECEIVED][1].datavalue.value)
end
if not partyData.prevSeats then partyData.prevSeats = 0 end
if statement.qualifiers[P_SEATS] then
partyData.prevSeats = partyData.prevSeats + getAmount(statement.qualifiers[P_SEATS][1].datavalue.value)
end
return partyData
end
function findPartyPredecessorOverride(listParties, partyQid, partyIndex)
for tempIndex, tempParty in ipairs(listParties) do
if tempParty.predecessors then
for _, tempPredecessor in ipairs(tempParty.predecessors) do
if tempPredecessor == partyQid then
return tempIndex
end
end
end
end
return partyIndex
end
function addPartyPredecessorsByComponents(listParties)
for partyIndex, partyData in ipairs(listParties) do
local allParts = mw.wikibase.getAllStatements(partyData.qid, P_HAS_PARTS)
for _, predecessorStatement in ipairs(allParts) do
if not partyData.predecessors then partyData.predecessors = {} end
table.insert(partyData.predecessors, getItem(predecessorStatement.mainsnak.datavalue.value))
end
listParties[partyIndex] = partyData
end
return listParties
end
-- Returns the party Qid from a candidacy statement
local function getPartyQidFromStatement(partyStatement, doGroupByParty)
if not doGroupByParty or not partyStatement.qualifiers[P_MEMBER_OF_PARTY] then
return partyStatement.mainsnak.datavalue.value.id
end
return partyStatement.qualifiers[P_MEMBER_OF_PARTY][1].datavalue.value.id
end
local function getCandidateQidFromStatement(candidateStatement)
return candidateStatement.mainsnak.datavalue.value.id
end
-- Insert a party of the current election in the list of candidates
local function insertPartyInList(listParties, partyStatement, doGroupByParty)
partyQid = getPartyQidFromStatement(partyStatement, doGroupByParty)
local partyIndex = initPartyIndex(listParties, partyQid)
listParties[partyIndex] = addPartyDataFromStatement(listParties[partyIndex], partyStatement)
return listParties
end
-- Inserts a party of the previous election in the list of candidates
local function insertPreviousPartyInList(listParties, partyStatement, doGroupByParty)
local partyQid = getPartyQidFromStatement(partyStatement, doGroupByParty)
local partyIndex = findPartyIndex(listParties, partyQid)
partyIndex = findPartyPredecessorOverride(listParties, partyQid, partyIndex)
if not partyIndex then
partyIndex = findPartyIndex(listParties, getStatementValue(partyQid, P_REPLACED_BY, getItem))
end
if partyIndex then
listParties[partyIndex] = addPrevPartyDataFromStatement(listParties[partyIndex], partyStatement)
end
return listParties
end
local function insertCandidateInList(listCandidates, candidateStatement, round)
-- @todo - merge with the parties version, rework the entire code to make it understandable
local candidateQid = getCandidateQidFromStatement(candidateStatement)
local candidateIndex = initCandidateIndex(listCandidates, candidateQid)
listCandidates[candidateIndex] = addCandidateDataFromStatement(listCandidates[candidateIndex], candidateStatement, round)
return listCandidates
end
local function insertWinningCandidateInList(listCandidates, winningStatement, round)
-- @todo - Rework the entire code to make it understandable
local candidateQid = getCandidateQidFromStatement(winningStatement)
local candidateIndex = initCandidateIndex(listCandidates, candidateQid)
listCandidates[candidateIndex].winning = round
return listCandidates
end
-- Retrieves the list of parties and sorts it by votes/seats
function p.getPartiesDataFromElection(electionQid, previousQid, doGroupByParty)
local listParties = {}
-- For each party in the election
local allStatementsInElection = mw.wikibase.getAllStatements(electionQid, P_CANDIDATE)
for _, partyStatement in ipairs(allStatementsInElection) do
insertPartyInList(listParties, partyStatement, doGroupByParty)
end
listParties = addPartyPredecessorsByComponents(listParties)
-- For each party in the previous election
if previousQid then
local allStatementsPrevElection = mw.wikibase.getAllStatements(previousQid, P_CANDIDATE)
for _, partyStatement in ipairs(allStatementsPrevElection) do
insertPreviousPartyInList(listParties, partyStatement, doGroupByParty)
end
end
sortParties(listParties)
return listParties
end
function p.getCandidatesDataFromElection(firstRoundQid, secondRoundQid)
local listCandidates = {}
-- For each candidate in the first round
local allStatementsInElection = mw.wikibase.getAllStatements(firstRoundQid, P_CANDIDATE)
for _, candidateStatement in ipairs(allStatementsInElection) do
insertCandidateInList(listCandidates, candidateStatement, 1)
end
local allWinningStatementsInElection = mw.wikibase.getAllStatements(firstRoundQid, P_SUCCESSFUL_CANDIDATE)
for _, winningStatement in ipairs(allWinningStatementsInElection) do
insertWinningCandidateInList(listCandidates, winningStatement, 1)
end
-- For each candidate in the second round
if secondRoundQid then
local allStatementsInElection = mw.wikibase.getAllStatements(secondRoundQid, P_CANDIDATE)
for _, candidateStatement in ipairs(allStatementsInElection) do
insertCandidateInList(listCandidates, candidateStatement, 2)
end
local allWinningStatementsInElection = mw.wikibase.getAllStatements(secondRoundQid, P_SUCCESSFUL_CANDIDATE)
for _, winningStatement in ipairs(allWinningStatementsInElection) do
insertWinningCandidateInList(listCandidates, winningStatement, 2)
end
end
sortParties(listCandidates)
return listCandidates
end
local function getPartyColor(qid, articleTitle)
local color = getStatementValue(qid, P_COLOR, getString)
if color then
return '#'..color
end
if articleTitle == nil then
return '#ffffff'
end
color = political_party._fetch({articleTitle, 'color', error='#ffffff'})
color = mw.ustring.gsub(color, '&(#)35;', '%1')
return color
end
-- Formats wikilinks with an article, a display text, and a fallback qid
local function formatWikilink(mainlink, displaytext, fallback)
if mainlink and ((mainlink == displaytext) or not displaytext) then
return '[['..mainlink..']]'
elseif mainlink then
return '[['..mainlink..'|'..(displaytext or mainlink)..']]'
elseif displaytext then
return displaytext
else
return '[[wikidata:'..fallback..']]'
end
end
-- For a given candidate, gets their name, article link, party shortlink, and color
function p.fetchCandidateData(qid)
-- Get person article name
local articleTitle, personLabel
articleTitle = mw.wikibase.getSitelink(qid)
if not articleTitle then
personLabel = mw.wikibase.getLabel(qid)
end
local nameWikitext = formatWikilink(articleTitle, nil, qid)
-- Get party
local partyQid = getStatementValue(qid, P_MEMBER_OF_PARTY, getItem)
local partyArticle = mw.wikibase.getSitelink(partyQid)
local partyAbbrev = getValueFromLanguage(partyQid, P_SHORT_NAME, lang)
-- Make party abbrev/link wikitext
local partyWikitext = formatWikilink(partyArticle, (partyAbbrev), partyQid)
-- Get party color
local color = getPartyColor(partyQid, partyArticle)
return {
qid=qid,
partyQid=partyQid,
name=nameWikitext,
partyWikitext=partyWikitext,
partyAbbrev=partyAbbrev,
color=color,
articleTitle=articleTitle,
}
end
-- For a given party, gets its name, article, and color
function p.fetchPartyData(qid)
-- Get party article name
local articleTitle, partyLabel
articleTitle = mw.wikibase.getSitelink(qid)
if not articleTitle then
partyLabel = mw.wikibase.getLabel(qid)
end
-- Get party name
local partyName = getValueFromLanguage(qid, P_NAME, lang)
-- Make party name/link wikitext
local nameWikitext = formatWikilink(articleTitle, (partyName or partyLabel), qid)
-- Get party color
local color = getPartyColor(qid, articleTitle)
return {
qid=qid,
name=nameWikitext,
color=color,
articleTitle=articleTitle
}
end
local function getElectionSitelink(qid)
local articleTitle
local supersetElectionQid = getStatementValue(qid, P_PART_OF, getItem)
while (not articleTitle) and supersetElectionQid do
qid = supersetElectionQid
supersetElectionQid = getStatementValue(qid, P_PART_OF, getItem)
articleTitle = mw.wikibase.getSitelink(qid)
end
return articleTitle
end
local function filterArgs(args, filter)
local matched = {}
for k, v in pairs(args) do
if string.match(k, filter) then
matched[k] = v
end
end
return matched
end
local function getYear(timestamp)
return tonumber(string.match(timestamp, '%+(%d%d%d%d)%-%d%d%-%d%dT%d%d:%d%d:%d%d'))
end
function p.getReferences(electionQid)
local allReferences = {}
local function getReferenceIndex(allReferences, reference)
local url = reference.snaks.P854[1].datavalue.value
for i, curRef in ipairs(allReferences) do
if curRef.url == url then
return i
end
end
table.insert(allReferences, {url=url})
return #allReferences
end
local function addReference(allReferences, reference)
refIndex = getReferenceIndex(allReferences, reference)
-- TODO: Add other reference attributes
-- allReferences[refIndex].url = uwu
end
for _, property in ipairs({P_CANDIDATE, P_ELIGIBLE_VOTERS, P_BALLOTS_CAST, P_SPOILT_VOTES, P_TOTAL_VALID_VOTES, P_BLANK_VOTES}) do
for _, statement in ipairs(mw.wikibase.getBestStatements(electionQid, property)) do
if statement.references then
for _, reference in ipairs(statement.references) do
addReference(allReferences, reference)
end
end
end
end
return allReferences
end
local function getRounds(electionQid)
local rounds = {}
for _,partStatement in ipairs(mw.wikibase.getAllStatements(electionQid, P_HAS_PARTS)) do
roundQid = partStatement.mainsnak.datavalue.value.id
roundNumber = partStatement.qualifiers.P1545[1].datavalue.value
rounds[tonumber(roundNumber)] = roundQid
end
return rounds
end
-- Formatting functions (copied from Module:Election_results)
local lang = mw.getContentLanguage()
local function fmt(n)
return n and tonumber(n) and lang:formatNum(tonumber(n)) or nil
end
local function pct(n, d)
n, d = tonumber(n), tonumber(d)
if n and d and d > 0 then
return string.format('%.2f', n / d * 100)
end
return '–'
end
local function diff(n, prevN)
if not n then
return '–'
elseif not prevN then
return "''New''"
end
n, prevN = tonumber(n), tonumber(prevN)
if n > prevN then
return '+'..tostring(n-prevN)
elseif prevN > n then
return '−'..tostring(prevN-n)
else
return '±0'
end
end
local function diffPct(n, d, prevN, prevD)
if not n or not d then
return '–'
elseif not prevN then
return "''New''"
end
n = tonumber(n) / tonumber(d)
prevN = tonumber(prevN) / tonumber(prevD)
if n > prevN then
return '+'..string.format('%.2f', (n - prevN) * 100)
elseif prevN > n then
return '−'..string.format('%.2f', (prevN - n) * 100)
else
return '±0.00'
end
end
--[[ Table-generating functions ]]
local function beginTable(classes, electionQid)
local root = mw.html.create('span')
root:attr('id', electionQid..'_resultsTable')
tab = root:tag('table')
tab:addClass(classes)
local tableCaption = tab:tag('caption')
local caption = 'Results of the ' .. mw.wikibase.getLabel(electionQid)
local previousElectionQid = getStatementValue(electionQid, P_FOLLOWS, getItem)
local nextElectionQid = getStatementValue(electionQid, P_FOLLOWED_BY, getItem)
if previousElectionQid then
caption = '[['..getElectionSitelink(previousElectionQid)..'#'..previousElectionQid..'_resultsTable|←]] ' .. caption
end
if nextElectionQid then
caption = caption .. ' [['.. getElectionSitelink(nextElectionQid)..'#'..nextElectionQid..'_resultsTable|→]]'
end
tableCaption:wikitext(caption)
tableCaption:done()
tab:done()
return root, tab
end
local function addHeaderCell(row, wikitext, colspan, rowspan)
local cell = row:tag('th')
cell:wikitext(wikitext)
cell:attr('scope', 'col')
if colspan then cell:attr('colspan', tostring(colspan)) end
if rowspan then cell:attr('rowspan', tostring(rowspan)) end
cell:done()
end
local function addCell(row, wikitext, align, colspan, isBold)
local cell = row:tag('td')
if align then cell:css('text-align', align) end
if colspan then cell:attr('colspan', tostring(colspan)) end
if isBold then cell:css('font-weight', 'bold') end
cell:wikitext(wikitext)
cell:done()
end
local function addColorCell(row, color)
local cell = row:tag('td')
cell:css('width', '0px')
cell:css('background-color', color)
cell:done()
end
local function fillTopCell(topCell, wikitext, colspan)
topCell:wikitext(wikitext)
topCell:css('text-align', 'center')
topCell:css('background', '#F8F9FA')
topCell:attr('colspan', colspan)
topCell:done()
end
local function addReference(refsCell, ref)
local r = refsCell:wikitext(
mw.getCurrentFrame():extensionTag({
name = 'ref',
content = ref.url
})
)
return r
end
local function formatReferencesRow(root, references, electionQid, cols)
-- References and wikidata link row
local row = root:tag('tr')
row:css('font-size', '90%')
local refsCell = row:tag('td')
refsCell:wikitext('[[:wikidata:'..electionQid..'|See on Wikidata]]')
refsCell:attr('colspan', cols)
if references then
refsCell:wikitext(' - Sources')
for _, ref in ipairs(references) do
addReference(refsCell, ref)
end
end
end
--[[ Main functions ]]
function p._ch_proportional(args)
local electionQid = args.qid or args.election or args[1]
local previousElectionQid = getStatementValue(electionQid, P_FOLLOWS, getItem)
local doGroupByParty = args.groupByParty or false
local cols = 0
local year = getYear(getStatementValue(electionQid, P_POINT_IN_TIME, getTimestamp))
local totalVotes = getStatementValue(electionQid, P_TOTAL_VALID_VOTES, getAmount)
local prevTotalVotes
if previousElectionQid then prevTotalVotes = getStatementValue(previousElectionQid, P_TOTAL_VALID_VOTES, getAmount) end
local references = p.getReferences(electionQid)
local rootSpan, root = beginTable('wikitable sortable', electionQid)
-- topCell (for the parliament diagram)
local topCell = nil
topCell = root:tag('th')
-- Table header
local headerRow = root:tag('tr')
addHeaderCell(headerRow, (args.partytitle or 'Party'), 2)
addHeaderCell(headerRow, 'Votes')
addHeaderCell(headerRow, '%')
if previousElectionQid then addHeaderCell(headerRow, '+/−') end
addHeaderCell(headerRow, 'Seats')
if previousElectionQid then addHeaderCell(headerRow, '+/−') end
cols = cols + 5
if previousElectionQid then cols = cols + 2 end
-- Fetch parties data
partyNameOverrides = filterArgs(args, 'name_override_Q%d+')
local partiesData = p.getAllPartiesData(electionQid, previousElectionQid, partyNameOverrides, doGroupByParty)
if topCell then
fillTopCell(
topCell,
(args['image'] or require('Module:Sandbox/Julio974fr/parliament_diagram').makeParliamentDiagram(partiesData, year)),
cols
)
end
-- Get parties list and make the rows
for _, party in ipairs(partiesData) do
local row = root:tag('tr')
if party.qid == 'Q86630688' then --Others
addCell(row, 'Others', 'left', 2)
else
addColorCell(row, party.color)
addCell(row, party.name)
end
addCell(row, fmt(party.votes), 'right')
addCell(row, pct(party.votes, totalVotes), 'right')
if previousElectionQid then addCell(row, diffPct(party.votes, totalVotes, party.prevVotes, prevTotalVotes), 'right') end
addCell(row, party.seats, 'right')
if previousElectionQid then addCell(row, diff(party.seats, party.prevSeats), 'right') end
end
-- Footer separator
local row = root:tag('tr')
addHeaderCell(row, '', cols)
formatReferencesRow(root, references, electionQid, cols)
return rootSpan
end
function p._ch_majoritarian(args)
local electionQid = args.qid or args.election or args[1]
local cols = 0
local year = getYear(getStatementValue(electionQid, P_POINT_IN_TIME, getTimestamp))
local references = p.getReferences(electionQid)
local roundsQid = getRounds(electionQid)
local firstRoundQid = roundsQid[1]
local secondRoundQid = roundsQid[2]
local roundsCount = secondRoundQid and 2 or 1
local totalVotes = (
getStatementValue(electionQid, P_TOTAL_VALID_VOTES, getAmount)
or getStatementValue(firstRoundQid, P_TOTAL_VALID_VOTES, getAmount)
) -- @todo Calculate percentage based on a property of the number of votes per voter or of the overall majority
local totalVotes2 = secondRoundQid and getStatementValue(secondRoundQid, P_TOTAL_VALID_VOTES, getAmount) or nil
local rootSpan, root = beginTable('wikitable sortable', electionQid)
-- Table header
local headerRow = root:tag('tr')
if roundsCount == 1 then
addHeaderCell(headerRow, 'Candidate', 2)
addHeaderCell(headerRow, (args.partytitle or 'Party'))
addHeaderCell(headerRow, 'Votes')
addHeaderCell(headerRow, '%')
cols = cols+5
elseif roundsCount == 2 then
local secondHeaderRow = root:tag('tr')
addHeaderCell(headerRow, 'Candidate', 2, 2)
addHeaderCell(headerRow, (args.partytitle or 'Party'), 1, 2)
addHeaderCell(headerRow, 'First round', 2)
addHeaderCell(headerRow, 'Second round', 2)
addHeaderCell(secondHeaderRow, 'Votes')
addHeaderCell(secondHeaderRow, '%')
addHeaderCell(secondHeaderRow, 'Votes')
addHeaderCell(secondHeaderRow, '%')
cols = cols+7
end
-- Fetch parties data
partyNameOverrides = filterArgs(args, 'name_override_Q%d+')
local candidatesData = p.getAllCandidatesData(firstRoundQid, secondRoundQid, partyNameOverrides)
mw.logObject(candidatesData)
-- Get parties list and make the rows
for _, candidate in ipairs(candidatesData) do
local row = root:tag('tr')
if candidate.qid == 'Q86630688' then --Others
addCell(row, 'Others', 'left', 2)
else
addColorCell(row, candidate.color)
addCell(row, candidate.name)
end
addCell(row, candidate.partyWikitext, 'left')
addCell(row, fmt(candidate.votes), 'right', 1, (candidate.winning==1))
addCell(row, pct(candidate.votes, totalVotes), 'right', 1, (candidate.winning==1))
if candidate.votes2 then
addCell(row, fmt(candidate.votes2), 'right', 1, (candidate.winning==2))
addCell(row, pct(candidate.votes2, totalVotes2), 'right', 1, (candidate.winning==2))
end
end
-- Footer separator
local row = root:tag('tr')
addHeaderCell(row, '', cols)
formatReferencesRow(root, references, electionQid, cols)
return rootSpan
end
--[[ Wrappers ]]
function p.ch_proportional(frame)
-- Initialise and populate variables
local getArgs = require("Module:Arguments").getArgs
local args = getArgs(frame)
return p._ch_proportional(args)
end
function p.ch_majoritarian(frame)
-- Initialize and populate variables
local getArgs = require("Module:Arguments").getArgs
local args = getArgs(frame)
return p._ch_majoritarian(args)
end
return p