Permanently protected module
From Wikipedia, the free encyclopedia


require('strict')

local p = {}

local political_party = require('Module:Political party')



function p.main(frame)

	local args = require('Module:Arguments').getArgs(frame)

	local index, headings, showtotal = {}, {}, {}

	local cols, rounds = 0, 1

	local winner, winner_votes = {0, 0, 0}, {0, 0, 0}

	local valid = {0, 0, 0}

	local invalid = {tonumber(args.invalid) or 0, tonumber(args.invalid2) or 0, tonumber(args.invalid3) or 0}

	local blank = {tonumber(args.blank) or 0, tonumber(args.blank2) or 0, tonumber(args.blank3) or 0}

	local majority = {tonumber(args.majority)}

	local majority2 = {tonumber(args.majority2)}

	local majoritypct = {tonumber(args.majoritypct)}

	local majoritypct2 = {tonumber(args.majoritypct2)}

	local totalvotes = {tonumber(args.totalvotes), tonumber(args.totalvotes2), tonumber(args.totalvotes3)}

	local electorate = {tonumber(args.electorate), tonumber(args.electorate2), tonumber(args.electorate3)}

	local turnout = {tonumber(args.turnout), tonumber(args.turnout2), tonumber(args.turnout3)}

	local seats = 0

	local seats_2 = 0

	local seats_3 = 0

	local st1t = 0

	local st2t = 0

	local st3t = 0

	local st4t = 0

	local st5t = 0

	local totseats = 0

	local row, secondrow

	local tracking = ''

	local max_rows = 0



	-- helper functions

	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 tonumdash(s)

		if s then

			s = mw.ustring.gsub(s, '&[MmNn][Dd][Aa][Ss][Hh];', '-')

			s = mw.ustring.gsub(s, '&[Mm][Ii][Nn][Uu][Ss];', '-')

			s = mw.ustring.gsub(s, '[—–−]', '-')

			return tonumber(s) or 0

		end

	end

	local function unlink(s)

		if s then

			s = s:match("^[^%[]-%[%[([^%]]-)|[^%]]-%]%].*$") or s

			s = s:match("^[^%[]-%[%[([^%]]-)%]%].*$") or s

		end

		return s

	end

	local function get_color(color, party)

		if color == nil then

			local party = unlink(party) or ''

			if party ~= '' then

				color = political_party._fetch({party, 'color'})

			end

		end



		if color ~= nil then

			color = mw.ustring.gsub(color, '&(#)35;', '%1')

		end

		return color

	end



	-- preprocess the input

	local stop_flag = false

	local i = 0

	local has_votes = args'invalid' or args'totalvotes' or args'electorate' or args'turnout'

	local has_votes2 = args'invalid2' or args'totalvotes2' or args'electorate2' or args'turnout2'

	local has_votes3 = args'votes' .. i .. '_3' or args'ivotes' .. i .. '_3'

	local has_seats2 = args'seats' .. i .. '_2' or args'iseats' .. i .. '_2'

	local has_seats3 = args'seats' .. i .. '_3'

	local has_sw2 = args'sw' .. i .. '_2'

	local seats_only = has_seats2 and not has_votes

	local has_cand = args'cand' .. i

	local has_alliance = args'alliance' .. i

	local has_party = args'party' .. i

	local has_rspan = args'vspan' .. i or args'v2span' .. i

	local has_sspan = args'sspan' .. i or args'tsspan' .. i

	while stop_flag == false do

		stop_flag = true

		for kk = 1, 20 do

			i = i + 1

			for k, key in ipairs({'alliance', 'atotal', 'cand', 'vp', 'party', 'ivotes', 'ipct', 'iseats', 'sc', 'st1t', 'st2t', 'st3t', 'st4t', 'st5t', 'sw', 'seats', 'totalvotes', 'totseats', 'acolor', 'rcolor'}) do

				if argskey .. i then

					headingskey = true

					stop_flag = false

					max_rows = i > max_rows and i or max_rows

				end

			end

			if args'row' .. i then

				stop_flag = false

				max_rows = i > max_rows and i or max_rows

			end



			if args'row' .. i or args'cand' .. i or args'party' .. i or args'alliance' .. i or args'atotal' .. i or args'atotalnv' .. i or args'header' .. i then

				table.insert(index, i)

				if args'votes' .. i then

					has_votes = true

					if tonumber(args'votes' .. i]) then showtotal.votes = 1 end

					local votesi = tonumber(args'votes' .. i]) or 0

					args'votes' .. i = votesi

					if votesi > winner_votes1 then

						winner1 = i

						winner_votes1 = votesi

					end

					valid1 = valid1 + votesi

				end

				if args'votes' .. i .. '_2' or args'ivotes' .. i .. '_2' or args'avotes' .. i .. '_2' or args'ipct' .. i .. '_2' or args'apct' .. i .. '_2' then

					has_votes2 = true

				end

				if args'votes' .. i .. '_3' or args'ivotes' .. i .. '_3' or args'ipct' .. i .. '_3' then

					has_votes3 = true

				end

				if args'alliance' .. i then

					has_alliance = true

				end

				if args'party' .. i then

					has_party = true

				end

				if args'cand' .. i then

					has_cand = true

				end

				if args'ivotes' .. i then

					has_votes = true

				end

				if args'ipct' .. i then

					has_votes = true

				end

				if args'sw' .. i .. '_2' then

					has_sw2 = true

					rounds = (rounds < 2) and 2 or rounds

				end

				if args'valid2' or args'invalid2' or args'totalvotes2' or args'electorate2' or args'turnout2' then

 					rounds = (rounds < 2) and 2 or rounds

				end

				if args'vspan' .. i or args'v2span' .. i then

					has_rspan = true

				end

				if args'sspan' .. i or args'tsspan' .. i then

					has_sspan = true

				end

				if args'ipct' .. i .. '_2' then

					rounds = (rounds < 2) and 2 or rounds

				end

				if args'votes' .. i .. '_2' then

					has_votes = true

					rounds = (rounds < 2) and 2 or rounds

					if tonumber(args'votes' .. i .. '_2']) then showtotal.votes_2 = 1 end

					local votesi = tonumber(args'votes' .. i .. '_2']) or 0

					args'votes' .. i .. '_2' = votesi

					if votesi > winner_votes2 then

						winner2 = i

						winner_votes2 = votesi

					end

					valid2 = valid2 + votesi

				end

				if args'votes' .. i .. '_3' then

					has_votes = true

					rounds = (rounds < 3) and 3 or rounds

					if tonumber(args'votes' .. i .. '_3']) then showtotal.votes_3 = 1 end

					local votesi = tonumber(args'votes' .. i .. '_3']) or 0

					args'votes' .. i .. '_3' = votesi

					if votesi > winner_votes3 then

						winner3 = i

						winner_votes3 = votesi

					end

					valid3 = valid3 + votesi

				end

				if args'seats' .. i then

					if tonumber(args'seats' .. i]) then showtotal.seats = 1 end

					seats = seats + (tonumber(args'seats' .. i]) or 0)

				end

				if args'seats' .. i .. '_2' or args'iseats' .. i .. '_2' then

					has_seats2 = true

					rounds = (rounds < 2) and 2 or rounds

					if tonumber(args'seats' .. i ..'_2']) then showtotal.seats_2 = 1 end

					seats_2 = seats_2 + (tonumber(args'seats' .. i .. '_2']) or 0)

				end

				if args'seats' .. i .. '_3' then

					has_seats3 = true

					rounds = (rounds < 3) and 3 or rounds

					if tonumber(args'seats' .. i ..'_3']) then showtotal.seats_3 = 1 end

					seats_3 = seats_3 + (tonumber(args'seats' .. i .. '_3']) or 0)

				end

				if args'st1t' .. i then

					if tonumber(args'st1t' .. i]) then showtotal.st1t = 1 end

					st1t = st1t + (tonumber(args'st1t' .. i]) or 0)

				end

				if args'st2t' .. i then

					if tonumber(args'st2t' .. i]) then showtotal.st2t = 1 end

					st2t = st2t + (tonumber(args'st2t' .. i]) or 0)

				end

				if args'st3t' .. i then

					if tonumber(args'st3t' .. i]) then showtotal.st3t = 1 end

					st3t = st3t + (tonumber(args'st3t' .. i]) or 0)

				end

				if args'st4t' .. i then

					if tonumber(args'st4t' .. i]) then showtotal.st4t = 1 end

					st4t = st4t + (tonumber(args'st4t' .. i]) or 0)

				end

				if args'st5t' .. i then

					if tonumber(args'st5t' .. i]) then showtotal.st5t = 1 end

					st5t = st5t + (tonumber(args'st5t' .. i]) or 0)

				end

				if args'totseats' .. i then

					if tonumber(args'totseats' .. i]) then showtotal.totseats = 1 end

					totseats = totseats + (tonumber(args'totseats' .. i]) or 0)

				end

				if has_seats2 and not has_votes or has_seats3 and not has_votes then

					seats_only = true

				end

			end

		end

	end



	local ovalid = {valid1], valid2], valid3]}

	seats = ((args'total_seats' or '') == 'TOTAL' and seats) or args'total_seats' or seats

	totseats = ((args'total_totseats' or '') == 'TOTAL' and totseats) or args'total_totseats' or totseats

	st1t = ((args'total_st1t' or '') == 'TOTAL' and st1t) or args'total_st1t' or st1t

	st2t = ((args'total_st2t' or '') == 'TOTAL' and st2t) or args'total_st2t' or st2t

	st3t = ((args'total_st3t' or '') == 'TOTAL' and st3t) or args'total_st3t' or st3t

	st4t = ((args'total_st4t' or '') == 'TOTAL' and st4t) or args'total_st4t' or st4t

	st5t = ((args'total_st5t' or '') == 'TOTAL' and st5t) or args'total_st5t' or st5t

	if seats or totseats or st1t or st2t or st3t or st4t or st5t or args'total_sc' or args'total_st1t' or args'total_st2t' or args'total_st3t' or args'total_st4t' or args'total_st5t' or args'valid' or ((rounds > 1) and args'valid2']) or ((rounds > 1) and args'valid3']) then

		max_rows = max_rows + 1

		local i = max_rows

		table.insert(index, i)

		args'votes' .. i = showtotal.votes and valid1 or nil

		args'votes' .. i .. '_2' = showtotal.votes_2 and valid2 or nil

		args'votes' .. i .. '_3' = showtotal.votes_3 and valid3 or nil

		args'colour' .. i = 'inherit'

		args'color' .. i = 'inherit'

		args'row' .. i = 'Total'

		args'sw' .. i = '–'

		args'sw' .. i .. '_2' = '–'

		args'seats' .. i = showtotal.seats and seats or nil

		args'seats' .. i .. '_2' = showtotal.seats_2 and seats_2 or nil

		args'seats' .. i .. '_3' = showtotal.seats_3 and seats_3 or nil

		args'st1t' .. i = showtotal.st1t and st1t or args.total_st1t

		args'st2t' .. i = showtotal.st2t and st2t or args.total_st2t

		args'st3t' .. i = showtotal.st3t and st3t or args.total_st3t

		args'st4t' .. i = showtotal.st4t and st4t or args.total_st4t

		args'st5t' .. i = showtotal.st5t and st5t or args.total_st5t

		args'sc' .. i = args'total_sc'

		args'totseats' .. i = showtotal.totseats and totseats or nil

		args'font-weight' .. i = 'bold'

		args'class' .. i = 'sortbottom'

		ovalid1 = tonumber(args'valid']) or valid1

		ovalid2 = tonumber(args'valid2']) or valid2

		ovalid3 = tonumber(args'valid3']) or valid3

	end



	-- build the table

	local root = mw.html.create(args'embed' and '' or 'table')

	if args'embed' == nil then

		root

			:addClass('wikitable sortable')

			:tag('caption')

				:wikitext(args.caption)

				:done()

	end



	local topcell = nil

	if args'image' then

		topcell = root

			:tag('th')

				:css('text-align', 'center')

				:css('background', '#F8F9FA')

				:wikitext(args'image'])

	end

	if args'reporting' then

		if (topcell == nil) then

			topcell = root

				:tag('td')

					:css('text-align', 'center')

					:css('background', '#F8F9FA')

		end

		topcell:tag('div')

				:addClass('center')

				:wikitext(frame:expandTemplate{

					title = 'percentage bar',

					args = {args.reporting, 

						args.reporting .. '% reporting',

						'width' = '200px',

						'hex' = '1BCE0E'

						}})

	end



	local rowspan = (rounds > 1) and 2 or headings'st1t' and 2 or nil

	row = args'embed' and mw.html.create('') or root:tag('tr')

	if args'dsv' and has_alliance and has_party then

		row

			:tag('th')

				:wikitext(args.partytitle or 'Party or alliance')

				:attr('scope', 'col')

				:attr('colspan', 4)

				:attr('rowspan', rowspan)

				:done()

		cols = cols + 4

		row

			:tag('th')

			:wikitext(args.candtitle or 'Candidate')

			:attr('scope', 'col')

			:attr('rowspan', rowspan)

			:done()

		cols = cols + 1

	elseif args'dsv' then

		row

			:tag('th')

				:wikitext(args.partytitle or 'Party')

				:attr('scope', 'col')

				:attr('colspan', 2)

				:attr('rowspan', rowspan)

				:done()

		cols = cols + 2

		row

			:tag('th')

			:wikitext(args.candtitle or 'Candidate')

			:attr('scope', 'col')

			:attr('rowspan', rowspan)

			:done()

		cols = cols + 1

	elseif has_cand then

	if has_cand and has_party and has_alliance then

			row

				:tag('th')

				:wikitext('Candidate')

				:attr('rowspan', rowspan)

				:attr('colspan', 2)

			row

				:tag('th')

				:wikitext(args.partytitle or 'Party or alliance')

				:attr('scope', 'col')

				:attr('rowspan', rowspan)

				:attr('colspan', 3)

				:done()

			cols = cols + 5

	elseif has_cand and has_party then

		row

			:tag('th')

				:wikitext('Candidate')

				:attr('scope', 'col')

				:attr('colspan', 2)

				:attr('rowspan', rowspan)

				:done()

		cols = cols + 2

	end

	if has_cand and not has_party then

		row

			:tag('th')

				:wikitext('Candidate')

				:attr('scope', 'col')

				:attr('rowspan', rowspan)

				:done()

		cols = cols + 1

	end

		if headings'vp' then

			row

				:tag('th')

						:wikitext('Running mate')

						:attr('scope', 'col')

						:attr('rowspan', rowspan)

						:done()

			cols = cols + 1

		end

		if has_party and not has_alliance then

			row

				:tag('th')

				:wikitext(args.partytitle or 'Party')

				:attr('scope', 'col')

				:attr('rowspan', rowspan)

				:done()

			cols = cols + 1

		end

	elseif has_party and has_alliance then

			row

				:tag('th')

				:wikitext(args.partytitle or 'Party or alliance')

				:attr('scope', 'col')

				:attr('rowspan', rowspan)

				:attr('colspan', 4)

				:done()

			cols = cols + 4

	else 

			row

			:tag('th')

				:wikitext(args.partytitle or 'Party')

				:attr('scope', 'col')

				:attr('colspan', 2)

				:attr('rowspan', rowspan)

				:done()

		cols = cols + 2

	end

	if rounds > 1 then

		if has_seats2 and headings'sw' and not has_seats3 then

			row

				:tag('th')

					:wikitext(args.firstround or 'First round')

					:attr('scope', 'col')

					:attr('colspan', 4)

					:done()

				:tag('th')

					:wikitext(args.secondround or 'Second round')

					:attr('scope', 'col')

					:attr('colspan', 4)

					:done()

		elseif has_seats2 and not has_seats3 then

			row

				:tag('th')

					:wikitext(args.firstround or 'First round')

					:attr('scope', 'col')

					:attr('colspan', 3)

					:done()

				:tag('th')

					:wikitext(args.secondround or 'Second round')

					:attr('scope', 'col')

					:attr('colspan', 3)

					:done()

		elseif has_seats3 then

			row

				:tag('th')

					:wikitext(args.firstround or 'First round')

					:attr('scope', 'col')

					:attr('colspan', 3)

					:done()

				:tag('th')

					:wikitext(args.secondround or 'Second round')

					:attr('scope', 'col')

					:attr('colspan', 3)

					:done()

				:tag('th')

					:wikitext(args.thirdround or 'Third round')

					:attr('scope', 'col')

					:attr('colspan', 3)

					:done()

		elseif has_votes3 then

			row

				:tag('th')

					:wikitext(args.firstround or 'First round')

					:attr('scope', 'col')

					:attr('colspan', 2)

					:done()

				:tag('th')

					:wikitext(args.secondround or 'Second round')

					:attr('scope', 'col')

					:attr('colspan', 2)

					:done()

				:tag('th')

					:wikitext(args.thirdround or 'Third round')

					:attr('scope', 'col')

					:attr('colspan', 2)

					:done()

		elseif has_votes then

			row

				:tag('th')

					:wikitext(args.firstround or 'First round')

					:attr('scope', 'col')

					:attr('colspan', 2)

					:done()

				:tag('th')

					:wikitext(args.secondround or 'Second round')

					:attr('scope', 'col')

					:attr('colspan', 2)

					:done()

		end

		secondrow = args'embed' and mw.html.create('') or root:tag('tr')

	else

		secondrow = row

	end

	rowspan = (rounds > 1) and 1 or (rounds < 2 and headings'st1t']) and 2 or nil

	if has_seats2 and not has_seats3 and headings'sw' then

		for k=1, rounds do

			secondrow

				:tag('th')

					:wikitext(args.votestitle or 'Votes')

					:attr('scope', 'col')

					:attr('rowspan', rowspan)

					:done()

				:tag('th')

					:wikitext('%')

					:attr('scope', 'col')

					:attr('rowspan', rowspan)

					:done()

				:tag('th')

					:wikitext('+/–')

					:attr('scope', 'col')

					:attr('rowspan', rowspan)

					:done()

				:tag('th')

					:wikitext(args.seatstitle or 'Seats')

					:attr('scope', 'col')

					:attr('rowspan', rowspan)

					:done()

			cols = cols + 4

		end

	end

	if has_seats2 and not headings'sw' or has_seats3 and not headings'sw' then

		for k=1, rounds do

			secondrow

				:tag('th')

					:wikitext(args.votestitle or 'Votes')

					:attr('scope', 'col')

					:attr('rowspan', rowspan)

					:done()

				:tag('th')

					:wikitext('%')

					:attr('scope', 'col')

					:attr('rowspan', rowspan)

					:done()

				:tag('th')

					:wikitext(args.seatstitle or 'Seats')

					:attr('scope', 'col')

					:attr('rowspan', rowspan)

					:done()

			cols = cols + 3

		end

	end

	if has_votes and not has_seats2 then

		for k=1, rounds do

			secondrow

				:tag('th')

					:wikitext(args.votestitle or 'Votes')

					:attr('scope', 'col')

					:attr('rowspan', rowspan)

					:done()

				:tag('th')

					:wikitext('%')

					:attr('scope', 'col')

					:attr('rowspan', rowspan)

					:done()

			cols = cols + 2

		end

	end

	if headings'sw' and not has_seats2 then

		row

			:tag('th')

				:wikitext('+/–')

				:attr('scope', 'col')

				:attr('rowspan', rowspan)

				:done()

		cols = cols + 1

	end

	rowspan = (rounds > 1) and 2 or headings'sc' and headings'st1t' and 2 or headings'seats' and headings'st1t' and 2 or nil

	if headings'seats' and not has_seats2 then

		row

			:tag('th')

				:wikitext(args.seatstitle or 'Seats')

				:attr('scope', 'col')

				:attr('rowspan', rowspan)

				:done()

		cols = cols + 1

	end

	if headings'st1t' then

		row

			:tag('th')

				:wikitext('Seats')

				:attr('colspan', 5)

				:attr('scope', 'col')

				:done()

	if rounds < 2 then secondrow = root:tag('tr')

	end

		secondrow

			:tag('th')

				:wikitext(args.seattype1)

				:attr('scope', 'col')

				:done()

		cols = cols + 1

	if headings'st2t' then

		secondrow

			:tag('th')

				:wikitext(args.seattype2)

				:attr('scope', 'col')

				:done()

		cols = cols + 1

	end

	if headings'st3t' then

		secondrow

			:tag('th')

				:wikitext(args.seattype3)

				:attr('scope', 'col')

				:done()

		cols = cols + 1

	end

	if headings'st4t' then

		secondrow

			:tag('th')

				:wikitext(args.seattype4)

				:attr('scope', 'col')

				:done()

		cols = cols + 1

	end

	if headings'st5t' then

		secondrow

			:tag('th')

				:wikitext(args.seattype5)

				:attr('scope', 'col')

				:done()

		cols = cols + 1

	end

	end

	if headings'totseats' then

		row

			:tag('th')

				:wikitext(headings'totseats' and 'Total<br>seats' or 'Totseats&pm;')

				:attr('scope', 'col')

				:attr('rowspan', rowspan)

				:done()

		cols = cols + 1

	end

	if headings'sc' then

		row

			:tag('th')

				:wikitext(args.sctitle or '+/–')

				:attr('scope', 'col')

				:attr('rowspan', rowspan)

				:done()

		cols = cols + 1

	end

	if topcell then

		topcell:attr('colspan', cols)

	end



	local cs = cols - 2*rounds

			- (headings'sw' and 1 or 0)

			- (headings'totseats' and 1 or 0)

			- (headings'seats' and 1 or 0)

			- (headings'sc' and 1 or 0)

			- (headings'st1t' and 1 or 0)

			- (headings'st2t' and 1 or 0)

			- (headings'st3t' and 1 or 0)

			- (headings'st4t' and 1 or 0)

			- (headings'st5t' and 1 or 0)

			- (has_seats2 and 1 or 0)

			- (has_seats3 and 1 or 0)

			- (has_sw2 and 1 or 0)

			+ (has_votes and 0 or 2)

			- (seats_only and 2 or 0)

	local rsuff = (rounds > 1) and {'', '_2'} or (rounds > 2) and {'', '_3'} or {''}

	for i, v in ipairs(index) do

		local has_votesrow = args'votes' .. v or args'ivotes' .. v or args'avotes' .. v or args'ipct' .. v or args'apct' .. v or args'atotal' .. v

		local has_seatsrow = args'seats' .. v or args'iseats' .. v or args'aseats' .. v

		local has_votesrow2 = args'votes' .. v .. '_2' or args'ivotes' .. v .. '_2' or args'avotes' .. v .. '_2' or args'ipct' .. v .. '_2' or args'apct' .. v .. '_2' or args'atotal' .. v .. '_2'

		local has_seatsrow2 = args'seats' .. v .. '_2' or args'iseats' .. v .. '_2' or args'aseats' .. v .. '_2'

		local has_votesrow3 = args'votes' .. v .. '_3' or args'ivotes' .. v .. '_3' or args'avotes' .. v .. '_3' or args'ipct' .. v .. '_3' or args'apct' .. v .. '_3' or args'atotal' .. v .. '_3'

		local has_seatsrow3 = args'seats' .. v .. '_3' or args'iseats' .. v .. '_3' or args'aseats' .. v .. '_3'

					row = root:tag('tr')

			:addClass(args'class' .. v])

			:css('font-weight', args'font-weight' .. v])







		-- determine the colors

		local color = get_color(args'colour' .. v or args'color' .. v or nil, args'party' .. v])

		local acolor = get_color(args'acolour' .. v or args'acolor' .. v or nil, args'alliance' .. v])

		local rcolor = get_color(args'rcolour' .. v or args'rcolor' .. v or nil)



		-- headers

		if args'header' .. v then

			row

			:tag('th')

				:wikitext(args'header' .. v])

				:attr('colspan', cols)

		else

		if args'alliance' .. v then

			row

				:tag('td')

					:attr('rowspan', args'aspan' .. v])

					:css('width', '0px')

					:css('background-color', acolor)

		elseif args'party' .. v and not has_alliance or args'cand' .. v and has_party and not has_alliance then

			row

				:tag('td')

					:css('width', '0px')

					:css('background-color', color)

		end

		if args'cand' .. v and not args.dsv then

			row

					:css('background-color', rcolor)

				:tag('td')

					:attr('rowspan', args'candspan' .. v or args'aspan' .. v])

					:wikitext(args'cand' .. v])

		end

		if args'vp' .. v then

			row

				:tag('td')

					:wikitext(args'vp' .. v])

		end

		if args'alliance' .. v and not has_party and args.dsv then

			row

				:tag('td')

					:attr('rowspan', args'aspan' .. v])

					:wikitext(args'alliance' .. v])

		end

		if args'alliance' .. v and not args'party' .. v and not args.dsv then

			row

				:tag('td')

					:attr('rowspan', args'aspan' .. v])

					:attr('colspan', 3)

					:wikitext(args'alliance' .. v])

		end

		if args'alliance' .. v and not args'party' .. v and has_party and args.dsv then

			row

				:tag('td')

					:attr('rowspan', args'aspan' .. v])

					:attr('colspan', 3)

					:wikitext(args'alliance' .. v])

		end

		if args'alliance' .. v and args'party' .. v then

			row

				:tag('td')

					:attr('rowspan', args'aspan' .. v])

					:wikitext(args'alliance' .. v])

		end

		if args'party' .. v and not has_alliance or args'cand' .. v and has_party and not has_alliance then

			row

				:tag('td')

					:wikitext(args'party' .. v])

		end

		if args'row' .. v then

			row

					:css('background-color', rcolor)

				:tag('td')

					:attr('colspan', cs)

					:wikitext(args'row' .. v])

		end

		if has_alliance and args'party' .. v then

			row

				:tag('td')

					:css('background-color', color)

				:tag('td')

					:wikitext(args'party' .. v])

		end

		if args'cand' .. v and args.dsv then

			row

				:tag('td')

					:attr('rowspan', args'candspan' .. v])

					:wikitext(args'cand' .. v])

		end

		if args'atotal' .. v and has_party and not args.dsv or args'atotalnv' .. v and has_party and not args.dsv then

			row

					:css('font-style', 'italic')

				:tag('td')

					:attr('colspan', 2)

					:wikitext('Total')

		end

		if args'atotal' .. v and not has_party or args'atotalnv' .. v and not has_party then

			row

					:css('font-style', 'italic')

				:tag('td')

					:wikitext('Total')

		end

		if args'atotal' .. v and has_cand and has_party and args.dsv or args'atotalnv' .. v and has_party and args.dsv then

			row

					:css('font-style', 'italic')

				:tag('td')

					:attr('colspan', 3)

					:wikitext('Total')

		end

		if args'votes' .. v and args'divisor' then

				row:tag('td')

					:attr('rowspan', args'vspan' .. v])

					:css('text-align', 'right')

					:wikitext(fmt(args'votes' .. v]))

				row:tag('td')

					:attr('rowspan', args'vspan' .. v])

					:css('text-align', 'right')

					:wikitext(pct(args'votes' .. v], (args'row' .. v == 'Total') and args'votes' .. v or args'divisor']))

		elseif args'votes' .. v then

				row:tag('td')

					:attr('rowspan', args'vspan' .. v])

					:css('text-align', 'right')

					:wikitext(fmt(args'votes' .. v]))

				row:tag('td')

					:attr('rowspan', args'vspan' .. v])

					:css('text-align', 'right')

					:wikitext(pct(args'votes' .. v], valid1]))

		elseif args'avotes' .. v then

				row:tag('td')

					:attr('rowspan', args'vspan' .. v])

					:css('text-align', 'right')

					:css('font-style', 'italic')

					:wikitext(fmt(args'avotes' .. v]))

				row:tag('td')

					:attr('rowspan', args'vspan' .. v])

					:css('text-align', 'right')

					:css('font-style', 'italic')

					:wikitext(pct(args'avotes' .. v], valid1]))

		elseif args'ivotes' .. v or args 'ipct' .. v or args'atotal' .. v then

				row:tag('td')

					:attr('rowspan', args'vspan' .. v])

					:css('text-align', 'right')

					:css('font-style', 'italic')

					:wikitext(fmt(args'ivotes' .. v]) or fmt(args'atotal' .. v]))

			if args'ipct' .. v or args'apct' .. v or args'atotal' .. v then

				row:tag('td')

					:attr('rowspan', args'vspan' .. v])

					:css('text-align', 'right')

					:css('font-style', 'italic')

					:wikitext(args'ipct' .. v or args'apct' .. v or pct(args'atotal' .. v], valid1]))

			else

				row:tag('td')

					:attr('rowspan', args'vspan' .. v])

					:wikitext()

			end

		elseif has_votes and headings'seats' and headings'sw' and not has_votesrow and not has_seatsrow and not args'sw' .. v and not has_rspan then

				row:tag('td')

					:attr('colspan', 4)

		elseif has_votes and headings'seats' and not has_votesrow and not has_seatsrow and not has_rspan or has_votes and headings'sw' and not has_votesrow and not args'sw' .. v and not has_rspan or has_seats2 and not has_votesrow and not has_seatsrow and not has_rspan then

				row:tag('td')

					:attr('colspan', 3)

		elseif has_votes and not has_votesrow and not has_rspan or has_votes and args'row' .. v and has_seatsrow and not has_votesrow or has_seats2 and not has_votesrow and not has_rspan then

				row:tag('td')

					:attr('colspan', 2)

		elseif args'r1blockc' .. v then

				row:tag('td')

					:attr('rowspan', args'r1blockr' .. v])

					:attr('colspan', args'r1blockc' .. v])

					:wikitext()

		end

		if headings'sw' and has_votesrow then

			row

				:tag('td')

					:css('text-align', 'right')

					:wikitext(args'sw' .. v])

		end

		if headings'seats' and not args'dsv' and not has_seats2 and rounds < 2 or has_seats2 and args'seats' .. v or has_seats2 and args'votes' .. v or has_seats2 and args'iseats' .. v or has_seats2 and args'aseats' .. v then

		if args'iseats' .. v or args'aseats' .. v then

			row

				:tag('td')

					:css('font-style', 'italic')

					:css('text-align', 'right')

					:wikitext(args'iseats' .. v or args'aseats' .. v])

		elseif args'seats' .. v or headings'seats' and not has_sspan then

			row

				:tag('td')

					:attr('rowspan', args'sspan' .. v])

					:css('text-align', 'right')

					:wikitext(fmt(args'seats' .. v]) or '–')

		end

		end

		if args'votes' .. v .. '_2' and args'divisor2' then

				row:tag('td')

					:attr('rowspan', args'v2span' .. v])

					:css('text-align', 'right')

					:wikitext(fmt(args'votes' .. v .. '_2']))

				row:tag('td')

					:attr('rowspan', args'v2span' .. v])

					:css('text-align', 'right')

					:wikitext(pct(args'votes' .. v .. '_2'], (args'row' .. v == 'Total') and args'votes' .. v .. '_2' or args'divisor2']))

		elseif args'votes' .. v .. '_2' then

				row:tag('td')

					:attr('rowspan', args'v2span' .. v])

					:css('text-align', 'right')

					:wikitext(fmt(args'votes' .. v .. '_2']))

				row:tag('td')

					:attr('rowspan', args'v2span' .. v])

					:css('text-align', 'right')

					:wikitext(pct(args'votes' .. v .. '_2'], valid2]))

		elseif args'ivotes' .. v .. '_2' or args 'ipct' .. v.. '_2' or args'avotes' .. v .. '_2' then

				row:tag('td')

					:attr('rowspan', args'v2span' .. v])

					:css('text-align', 'right')

					:css('font-style', 'italic')

					:wikitext(fmt(args'ivotes' .. v .. '_2']) or fmt(args'avotes' .. v .. '_2']))

				row:tag('td')

					:attr('rowspan', args'v2span' .. v])

					:css('text-align', 'right')

					:css('font-style', 'italic')

					:wikitext(args'ipct' .. v .. '_2' or args'apct' .. v .. '_2' or pct(args'avotes' .. v .. '_2'], valid2]))

		elseif has_votes2 and has_seats2 and has_sw2 and not has_votesrow2 and not has_seatsrow2 and not args'sw' .. v .. '_2' and not has_rspan then

				row:tag('td')

					:attr('colspan', 4)

		elseif has_votes2 and has_seats2 and not has_votesrow2 and not has_seatsrow2 and not has_rspan or has_votes2 and has_sw2 and not has_votesrow2 and not args'sw' .. v .. '_2' and not has_rspan or has_seats2 and not has_votesrow2 and not has_seatsrow2 and not has_rspan then

				row:tag('td')

					:attr('colspan', 3)

		elseif has_votes2 and not has_votesrow2 and not has_rspan or has_votes2 and args'row' .. v and has_seatsrow2 and not has_votesrow2 or has_seats2 and not has_votesrow2 and not has_rspan then

				row:tag('td')

					:attr('colspan', 2)

		elseif args'r2blockc' .. v then

				row:tag('td')

					:attr('rowspan', args'r2blockr' .. v])

					:attr('colspan', args'r2blockc' .. v])

					:wikitext()

		end

		if headings'seats' and args'dsv' and not has_sspan or headings'seats' and rounds > 1 and not has_seats2 and not has_sspan or args'seats' .. v and has_sspan and rounds > 1 and not has_seats2 then

			row

				:tag('td')

					:attr('rowspan', args'sspan' .. v])

					:css('text-align', 'right')

					:wikitext(fmt(args'seats' .. v]) or fmt(args'aseats' .. v]) or '–')

		end

		if has_sw2 and args'votes' .. v .. '_2' then

			row

				:tag('td')

					:css('text-align', 'right')

					:wikitext(args'sw' .. v .. '_2'])

		end

		if args'seats' .. v .. '_2' or has_seats2 and args'votes' .. v .. '_2' then

			row

				:tag('td')

					:css('text-align', 'right')

					:wikitext(fmt(args'seats' .. v .. '_2']) or '–')

		end

		if args'iseats' .. v .. '_2' or has_seats2 and args'ivotes' .. v .. '_2' and not args'seats' .. v .. '_2' or args'aseats' .. v .. '_2' then

			row

				:tag('td')

					:css('text-align', 'right')

					:wikitext(fmt(args'iseats' .. v .. '_2']) or fmt(args'aseats' .. v .. '_2']))

		end

		if has_seats3 or has_votes3 then

		if args'votes' .. v .. '_3' then

				row:tag('td')

					:attr('rowspan', args'v3span' .. v])

					:css('text-align', 'right')

					:wikitext(fmt(args'votes' .. v .. '_3']))

				row:tag('td')

					:attr('rowspan', args'v3span' .. v])

					:css('text-align', 'right')

					:wikitext(pct(args'votes' .. v .. '_3'], valid3]))

		elseif args'ivotes' .. v .. '_3' or args 'ipct' .. v.. '_3' or args'avotes' .. v .. '_3' then

				row:tag('td')

					:attr('rowspan', args'v3span' .. v])

					:css('text-align', 'right')

					:css('font-style', 'italic')

					:wikitext(fmt(args'ivotes' .. v .. '_3']) or fmt(args'avotes' .. v .. '_3']))

				row:tag('td')

					:attr('rowspan', args'v3span' .. v])

					:css('text-align', 'right')

					:css('font-style', 'italic')

					:wikitext(args'ipct' .. v .. '_3' or args'apct' .. v .. '_3' or pct(args'avotes' .. v .. '_3'], valid3]))

		elseif has_seats3 and not has_votesrow3 and not has_seatsrow3 and not has_rspan then

				row:tag('td')

					:attr('colspan', 3)

		elseif has_seats3 and not has_votesrow3 and not has_rspan or has_seats3 and args'row' .. v and has_seatsrow3 and not has_votesrow3 or has_votes3 and not has_votesrow3 and not has_rspan then

				row:tag('td')

					:attr('colspan', 2)

		elseif args'r3blockc' .. v then

				row:tag('td')

					:attr('rowspan', args'r3blockr' .. v])

					:attr('colspan', args'r3blockc' .. v])

					:wikitext()

		end

		if has_sw2 and args'votes' .. v .. '_3' then

			row

				:tag('td')

					:css('text-align', 'right')

					:wikitext(args'sw' .. v .. '_3'])

		end

		if args'seats' .. v .. '_3' or has_seats3 and args'votes' .. v .. '_3' then

			row

				:tag('td')

					:css('text-align', 'right')

					:wikitext(fmt(args'seats' .. v .. '_3']) or '–')

		end

		if args'iseats' .. v .. '_3' or has_seats3 and args'ivotes' .. v .. '_3' and not args'seats' .. v .. '_3' or args'aseats' .. v .. '_3' then

			row

				:tag('td')

					:css('text-align', 'right')

					:wikitext(fmt(args'iseats' .. v .. '_3']) or fmt(args'aseats' .. v .. '_3']))

		end

		end

		if args'st1t' .. v and has_sspan or headings'st1t' and not has_sspan then

			row

				:tag('td')

					:attr('rowspan', args'sspan' .. v])

					:css('text-align', 'right')

					:wikitext(args'st1t' .. v or '–')

		end

		if args'st2t' .. v and has_sspan or headings'st2t' and not has_sspan then

			row

				:tag('td')

					:attr('rowspan', args'sspan' .. v])

					:css('text-align', 'right')

					:wikitext(args'st2t' .. v or '–')

		end

		if args'st3t' .. v and has_sspan or headings'st3t' and not has_sspan then

			row

				:tag('td')

					:attr('rowspan', args'sspan' .. v])

					:css('text-align', 'right')

					:wikitext(args'st3t' .. v or '–')

		end

		if args'st4t' .. v and has_sspan or headings'st4t' and not has_sspan then

			row

				:tag('td')

					:attr('rowspan', args'sspan' .. v])

					:css('text-align', 'right')

					:wikitext(args'st4t' .. v or '–')

		end

		if args'st5t' .. v and has_sspan or headings'st5t' and not has_sspan then

			row

				:tag('td')

					:attr('rowspan', args'sspan' .. v])

					:css('text-align', 'right')

					:wikitext(args'st5t' .. v or '–')

		end

		if args'totseats' .. v and has_sspan or args'atotseats' .. v and has_sspan then

			row

				:tag('td')

					:attr('rowspan', args'tsspan' .. v])

					:css('text-align', 'right')

					:wikitext(args'totseats' .. v or args'atotseats' .. v or '–')

		end

		if headings'totseats' and not args'itotseats' .. v and not args'atotseats' .. v and not has_sspan then

			row

				:tag('td')

					:css('text-align', 'right')

					:wikitext(fmt(args'totseats' .. v]) or '–')

		elseif headings'totseats' and not has_sspan then

			row

				:tag('td')

					:css('text-align', 'right')

					:css('font-style', 'italic')

					:wikitext(args'itotseats' .. v or args'atotseats' .. v])

		end

		if headings'sc' and args.sctitle then

			row

				:tag('td')

					:wikitext(args'sc' .. v])

		elseif headings'sc' then

			row

				:tag('td')



					:css('text-align', 'right')

					:wikitext(args'sc' .. v or '–')

		end

	end

	end

	-- separating line

	if args'valid' or args'valid2' or args'valid3' or args'invalid' or args'invalid2' or args'invalid3' or args'totalvotes' or args'totalvotes2' or args'totalvotes3' or args'electorate' or args'electorate2' or args'electorate3' or args'turnout' or args'turnout2' or args'turnout3' or args'source' then

	row = root

		:tag('tr')

			:addClass('sortbottom')

	row

		:tag('td')

			:css('background', '#eaecf0')

			:attr('colspan', cols)

	end

	-- valid votes

	if args'invalid' or args'invalid2'  or args'invalid3' then

	row = root

		:tag('tr')

			:addClass('sortbottom')

			:css('text-align', 'right')

	row

		:tag('th')

			:wikitext('Valid votes')

			:attr('scope', 'row')

			:attr('colspan', cs)

			:css('text-align', 'left')

			:css('font-weight', 'normal')

			:css('background', 'inherit')

	if args'invalid' then

	row

		:tag('td')

			:wikitext(fmt(ovalid1]))

		:tag('td')

				:wikitext(pct(ovalid1], ovalid1 + invalid1 + blank1]))

	elseif not args'invalid' then

	row

		:tag('td')

			:wikitext()

		:tag('td')

				:wikitext()

	end

	if has_seats2 and not headings'sw' then

	row

		:tag('td')

			:wikitext()

	end

	if has_seats2 and headings'sw' and args'validsw' then

	row

		:tag('td')

			:wikitext(args'validsw'])

		:tag('td')

			:wikitext()

	end

	if has_seats2 and headings'sw' and not args'validsw' then

	row

		:tag('td')

			:attr('colspan', 2)

			:wikitext()

	end

	if rounds > 1 and args'invalid2' then

	row

		:tag('td')

			:wikitext(fmt(ovalid2]))

		:tag('td')

				:wikitext(pct(ovalid2], ovalid2 + invalid2 + blank2]))

	elseif rounds > 1 and not args'invalid2' then

	row

		:tag('td')

			:wikitext()

		:tag('td')

			:wikitext()

	end

	if has_seats2 and not headings'sw' then

	row

		:tag('td')

			:wikitext()

	end

	if has_seats2 and headings'sw' and args'validsw2' then

	row

		:tag('td')

			:wikitext(args'validsw2'])

		:tag('td')

			:wikitext()

	end

	if has_seats2 and headings'sw' and not args'validsw2' then

	row

		:tag('td')

			:attr('colspan', 2)

			:wikitext()

	end

	if args'invalid3' then

	row

		:tag('td')

			:wikitext(fmt(ovalid3]))

		:tag('td')

				:wikitext(pct(ovalid3], ovalid3 + invalid3 + blank3]))

	elseif has_seats3 and not args'invalid3' then

	row

		:tag('td')

			:wikitext()

		:tag('td')

			:wikitext()

	end

	if args'invalidsw' and not has_sw2 then

		row:tag('td')

			:wikitext(args'validsw'])

		local cspan = (headings'seats' and 1 or 0) + (headings'sc' and 1 or 0) + (headings'st1t' and 1 or 0) + (headings'st2t' and 1 or 0) + (headings'st3t' and 1 or 0) + (headings'st4t' and 1 or 0) + (headings'st5t' and 1 or 0) + (has_seats3 and 1 or 0)

	if headings'seats' or headings'sc' then

		local cspan = (headings'seats' and 1 or 0) + (headings'sc' and 1 or 0) + (headings'st1t' and 1 or 0) + (headings'st2t' and 1 or 0) + (headings'st3t' and 1 or 0) + (headings'st4t' and 1 or 0) + (headings'st5t' and 1 or 0) + (has_seats3 and 1 or 0)

		row

			:tag('td')

				:attr('colspan', cspan > 1 and cspan or nil)

	end

	elseif headings'sw' or headings'seats' or headings'sc' or headings'st1t' or headings'st2t' or headings'st3t' or headings'st4t' or headings'st5t' then

		local cspan = (headings'sw' and 1 or 0) + (headings'seats' and 1 or 0) + (headings'sc' and 1 or 0) + (headings'st1t' and 1 or 0) + (headings'st2t' and 1 or 0) + (headings'st3t' and 1 or 0) + (headings'st4t' and 1 or 0) + (headings'st5t' and 1 or 0) + (has_seats3 and 1 or 0)

		row

			:tag('td')

				:attr('colspan', cspan > 1 and cspan or nil)

	end

	-- invalid votes

	row = root:tag('tr')

			:addClass('sortbottom')

			:css('text-align', 'right')

		if args'invalidonly' or args'blank' then

	row

		:tag('th')

			:wikitext('Invalid votes')

			:attr('scope', 'row')

			:attr('colspan', cs)

			:css('text-align', 'left')

			:css('font-weight', 'normal')

			:css('background', 'inherit')

	else

	row

		:tag('th')

			:wikitext('Invalid/blank votes')

			:wikitext(args.invalidnote)

			:attr('scope', 'row')

			:attr('colspan', cs)

			:css('text-align', 'left')

			:css('font-weight', 'normal')

			:css('background', 'inherit')

	end

	if args'invalid' then

	row

		:tag('td')

			:wikitext(fmt(invalid1]))

		:tag('td')

				:wikitext(pct(invalid1], ovalid1 + invalid1 + blank1]))

	elseif not args'invalid' then

	row

		:tag('td')

			:wikitext()

		:tag('td')

				:wikitext()

	end

	if has_seats2 and not headings'sw' then

	row

		:tag('td')

			:wikitext()

	end

	if has_seats2 and headings'sw' and args'invalidsw' then

	row

		:tag('td')

			:wikitext(args'invalidsw'])

		:tag('td')

			:wikitext()

	end

	if has_seats2 and headings'sw' and not args'invalidsw' then

	row

		:tag('td')

			:attr('colspan', 2)

			:wikitext()

	end

	if rounds > 1 and args'invalid2' then

	row

		:tag('td')

			:wikitext(fmt(invalid2]))

		:tag('td')

				:wikitext(pct(invalid2], ovalid2 + invalid2 + blank2]))

	elseif rounds > 1 and not args'invalid2' then

	row

		:tag('td')

			:wikitext()

		:tag('td')

				:wikitext()

	end

	if has_seats2 and not headings'sw' then

	row

		:tag('td')

			:wikitext()

	end

	if has_seats2 and headings'sw' and args'invalidsw2' then

	row

		:tag('td')

			:wikitext(args'invalidsw2'])

		:tag('td')

			:wikitext()

	end

	if has_seats2 and headings'sw' and not args'invalidsw2' then

	row

		:tag('td')

			:attr('colspan', 2)

			:wikitext()

	end

	if has_seats3 and args'invalid3' or has_votes3 and args'invalid3' then

	row

		:tag('td')

			:wikitext(fmt(invalid3]))

		:tag('td')

				:wikitext(pct(invalid3], ovalid3 + invalid3 + blank3]))

	elseif has_seats3 and not args'invalid3' then

	row

		:tag('td')

			:wikitext()

		:tag('td')

			:wikitext()

	end

	if args'invalidsw' and not has_sw2 then

		row:tag('td')

			:wikitext(args'invalidsw'])

	if headings'seats' or headings'sc' or headings'st1t' or headings'st2t' or headings'st3t' or headings'st4t' or headings'st5t' then

		local cspan = (headings'seats' and 1 or 0) + (headings'sc' and 1 or 0) + (has_seats3 and 1 or 0)

		row

			:tag('td')

				:attr('colspan', cspan > 1 and cspan or nil)

	end

	elseif headings'sw' or headings'seats' or headings'sc' or headings'st1t' or headings'st2t' or headings'st3t' or headings'st4t' or headings'st5t' then

		local cspan = (headings'sw' and 1 or 0) + (headings'seats' and 1 or 0) + (headings'sc' and 1 or 0) + (headings'st1t' and 1 or 0) + (headings'st2t' and 1 or 0) + (headings'st3t' and 1 or 0) + (headings'st4t' and 1 or 0) + (headings'st5t' and 1 or 0) + (has_seats3 and 1 or 0)

		row

			:tag('td')

				:attr('colspan', cspan > 1 and cspan or nil)

	end

	end

	-- blank votes

	if args'blank' then

	row = root:tag('tr')

			:addClass('sortbottom')

			:css('text-align', 'right')

	row

		:tag('th')

			:wikitext('Blank votes')

			:attr('scope', 'row')

			:attr('colspan', cs)

			:css('text-align', 'left')

			:css('font-weight', 'normal')

			:css('background', 'inherit')

	row

		:tag('td')

			:wikitext(fmt(blank1]))

		:tag('td')

				:wikitext(pct(blank1], ovalid1 + invalid1 + blank1]))

	if has_seats2 and not headings'sw' then

	row

		:tag('td')

			:wikitext()

	end

	if has_seats2 and headings'sw' and args'blanksw' then

	row

		:tag('td')

			:wikitext(args'blanksw'])

		:tag('td')

			:wikitext()

	end

	if has_seats2 and headings'sw' and not args'blanksw' then

	row

		:tag('td')

			:attr('colspan', 2)

			:wikitext()

	end

	if rounds > 1 and args'blank2' then

	row

		:tag('td')

			:wikitext(fmt(blank2]))

		:tag('td')

				:wikitext(pct(blank2], ovalid2 + invalid2 + blank2]))

	elseif rounds > 1 and not args'blank2' then

	row

		:tag('td')

			:wikitext()

		:tag('td')

				:wikitext()

	end

	if has_seats2 and not headings'sw' then

	row

		:tag('td')

			:wikitext()

	end

	if has_seats2 and headings'sw' and args'blanksw2' then

	row

		:tag('td')

			:wikitext(args'blanksw2'])

		:tag('td')

			:wikitext()

	end

	if has_seats2 and headings'sw' and not args'blanksw2' then

	row

		:tag('td')

			:attr('colspan', 2)

			:wikitext()

	end

	if has_seats3 and args'blank3' or has_votes3 and args'blank3' then

	row

		:tag('td')

			:wikitext(fmt(blank3]))

		:tag('td')

				:wikitext(pct(blank3], ovalid3 + invalid3 + blank3]))

	elseif has_seats3 and args'blank3' or has_votes3 and args'blank3' then

	row

		:tag('td')

			:wikitext()

		:tag('td')

			:wikitext()

	end

	if args'blanksw' and not has_sw2 then

		row:tag('td')

			:wikitext(args'blanksw'])

	if headings'seats' or headings'sc' or headings'st1t' or headings'st2t' or headings'st3t' or headings'st4t' or headings'st5t' then

		local cspan = (headings'seats' and 1 or 0) + (headings'sc' and 1 or 0) + (has_seats3 and 1 or 0)

		row

			:tag('td')

				:attr('colspan', cspan > 1 and cspan or nil)

	end

	elseif headings'sw' or headings'seats' or headings'sc' or headings'st1t' or headings'st2t' or headings'st3t' or headings'st4t' or headings'st5t' then

		local cspan = (headings'sw' and 1 or 0) + (headings'seats' and 1 or 0) + (headings'sc' and 1 or 0) + (headings'st1t' and 1 or 0) + (headings'st2t' and 1 or 0) + (headings'st3t' and 1 or 0) + (headings'st4t' and 1 or 0) + (headings'st5t' and 1 or 0) + (has_seats3 and 1 or 0)

		row

			:tag('td')

				:attr('colspan', cspan > 1 and cspan or nil)

	end

	end

	-- total

	if args'invalid' or args'totalvotes' or args'invalid2' or args'totalvotes2' then

	row = root:tag('tr')

			:addClass('sortbottom')

			:css('font-weight', 'bold')

			:css('text-align', 'right')

	row

		:tag('th')

			:wikitext(args.tvtitle or 'Total votes')

			:attr('scope', 'row')

			:attr('colspan', cs)

			:css('text-align', 'left')

			:css('background', 'inherit')

			:css('color', 'inherit')

	if not args'totalvotes' and args'invalid' then

	row

		:tag('td')

			:wikitext(fmt(ovalid1 + invalid1 + blank1]))

		:tag('td')

			:wikitext(pct(1, 1))

	elseif args'totalvotes' then

	row

		:tag('td')

			:wikitext(fmt(args.totalvotes))

		:tag('td')

			:wikitext('–')

	elseif not args'invalid' and not args'totalvotes' then

	row

		:tag('td')

			:wikitext()

		:tag('td')

			:wikitext()

	end

	if has_seats2 and not headings'sw' then

	row

		:tag('td')

			:wikitext()

	end

	if has_seats2 and headings'sw' and args'invalidsw' then

	row

		:tag('td')

			:wikitext('–')

		:tag('td')

			:wikitext()

	end

	if has_seats2 and headings'sw' and not args'invalidsw' then

	row

		:tag('td')

			:attr('colspan', 2)

			:wikitext()

	end

	if rounds > 1 and args'invalid2' and not args'totalvotes2' then

	row

		:tag('td')

			:wikitext(fmt(ovalid2 + invalid2 + blank2]))

		:tag('td')

			:wikitext(pct(1, 1))

	elseif rounds > 1 and args'totalvotes2' then

	row

		:tag('td')

			:wikitext(fmt(args.totalvotes2))

		:tag('td')

			:wikitext('–')

	elseif rounds > 1 and not args'invalid2' or rounds > 1 and not args'totalvotes2' then

	row

		:tag('td')

			:wikitext()

		:tag('td')

				:wikitext()

	end

	if has_seats2 and not headings'sw' then

	row

		:tag('td')

			:wikitext()

	end

	if has_seats2 and headings'sw' and args'invalidsw2' then

	row

		:tag('td')

			:wikitext('–')

		:tag('td')

			:wikitext()

	end

	if has_seats2 and headings'sw' and not args'invalidsw2' then

	row

		:tag('td')

			:attr('colspan', 2)

			:wikitext()

	end

	if has_seats3 and not args'totalvotes3' and args'invalid3' or has_votes3 and not args'totalvotes3' and args'invalid3' then

	row

		:tag('td')

			:wikitext(fmt(ovalid3 + invalid3 + blank3]))

		:tag('td')

			:wikitext(pct(1, 1))

	elseif has_seats3 and args'totalvotes3' or has_votes3 and args'totalvotes3' then

	row

		:tag('td')

			:wikitext(fmt(args.totalvotes3))

		:tag('td')

			:wikitext('–')

	elseif has_seats3 and not args'invalid3' or has_votes3 and not args'invalid3' then

	row

		:tag('td')

			:wikitext()

		:tag('td')

				:wikitext()

	end

	if args'invalidsw' and not has_sw2 then

		row:tag('td')

			:wikitext('–')

	if headings'seats' or headings'sc' or headings'st1t' or headings'st2t' or headings'st3t' or headings'st4t' or headings'st5t' then

		local cspan = (headings'seats' and 1 or 0) + (headings'sc' and 1 or 0) + (headings'st1t' and 1 or 0) + (headings'st2t' and 1 or 0) + (headings'st3t' and 1 or 0) + (headings'st4t' and 1 or 0) + (headings'st5t' and 1 or 0) + (has_seats3 and 1 or 0)

		row

			:tag('td')

				:attr('colspan', cspan > 1 and cspan or nil)

	end

	elseif headings'sw' or headings'seats' or headings'sc' or headings'st1t' or headings'st2t' or headings'st3t' or headings'st4t' or headings'st5t' then

		local cspan = (headings'sw' and 1 or 0) + (headings'seats' and 1 or 0) + (headings'sc' and 1 or 0) + (headings'st1t' and 1 or 0) + (headings'st2t' and 1 or 0) + (headings'st3t' and 1 or 0) + (headings'st4t' and 1 or 0) + (headings'st5t' and 1 or 0) + (has_seats3 and 1 or 0)

		row

			:tag('td')

				:attr('colspan', cspan > 1 and cspan or nil)

	end

	end

	-- registered

	if args'electorate' or args'electorate2' or args'turnout' or args'turnout2' then

	row = root:tag('tr')

			:addClass('sortbottom')

			:css('text-align', 'right')

	row

		:tag('th')

			:wikitext('Registered voters/turnout')

			:attr('scope', 'row')

			:attr('colspan', cs)

			:css('text-align', 'left')

			:css('font-weight', 'normal')

			:css('color', 'inherit')

			:css('background', 'inherit')

	row

			:tag('td')

				:wikitext(fmt(electorate1]))

	if args'invalid' and args'electorate' and not args'totalvotes' then

		row

			:tag('td')

				:wikitext(args.turnout or pct(ovalid1 + invalid1 + blank1], electorate1]))

	elseif args'totalvotes' and args'electorate' then

		row

			:tag('td')

				:wikitext(args.turnout or pct(totalvotes1], electorate1]))

	elseif args'electorate' then

		row

			:tag('td')

				:wikitext(args.turnout or '–')

	else

		row

			:tag('td')

				:wikitext(args.turnout)

	end

	if has_seats2 and not headings'sw' then

		row

			:tag('td')

				:wikitext()

	end

	if has_seats2 and headings'sw' and args'turnoutsw' then

	row

		:tag('td')

			:wikitext(args'turnoutsw'])

		:tag('td')

			:wikitext()

	end

	if has_seats2 and headings'sw' and not args'turnoutsw' then

	row

		:tag('td')

			:attr('colspan', 2)

			:wikitext()

	end

	if rounds > 1 then

		row

			:tag('td')

				:wikitext(fmt(electorate2]))

	if args'invalid2' and args'electorate2' then

		row

			:tag('td')

				:wikitext(args.turnout2 or pct(ovalid2 + invalid2 + blank2], electorate2]))

	elseif args'totalvotes2' and args'electorate2' then

		row

			:tag('td')

				:wikitext(args.turnout2 or pct(totalvotes2], electorate2]))

	elseif args'electorate2' then

		row

			:tag('td')

				:wikitext(args.turnout2 or '–')

	else

		row

			:tag('td')

				:wikitext(args.turnout2)

	end

	if has_seats2 and not headings'sw' then

		row

			:tag('td')

				:wikitext()

	end

	if has_seats2 and headings'sw' and args'turnoutsw2' then

	row

		:tag('td')

			:wikitext(args'turnoutsw2'])

		:tag('td')

			:wikitext()

	end

	if has_seats2 and headings'sw' and not args'turnoutsw2' then

	row

		:tag('td')

			:attr('colspan', 2)

			:wikitext()

	end

	end

	if has_seats3 or has_votes3 then

		row

			:tag('td')

				:wikitext(fmt(electorate3]))

	if args'invalid3' and args'electorate3' then

		row

			:tag('td')

				:wikitext(args.turnout3 or pct(ovalid3 + invalid3 + blank3], electorate3]))

	elseif args'totalvotes3' and args'electorate3' then

		row

			:tag('td')

				:wikitext(args.turnout3 or pct(totalvotes3], electorate3]))

	elseif args'electorate3' then

		row

			:tag('td')

				:wikitext(args.turnout3 or '–')

	else

		row

			:tag('td')

				:wikitext(args.turnout3)

	end

	end

	if args'turnoutsw' and not has_sw2 then

		row:tag('td')

			:wikitext(args'turnoutsw'])

	if headings'seats' or headings'sc' or headings'st1t' or headings'st2t' or headings'st3t' or headings'st4t' or headings'st5t' then

		local cspan = (headings'seats' and 1 or 0) + (headings'sc' and 1 or 0) + (headings'st1t' and 1 or 0) + (headings'st2t' and 1 or 0) + (headings'st3t' and 1 or 0) + (headings'st4t' and 1 or 0) + (headings'st5t' and 1 or 0) + (has_seats3 and 1 or 0)

		row

			:tag('td')

				:attr('colspan', cspan > 1 and cspan or nil)

	end

	elseif headings'sw' or headings'seats' or headings'sc' or headings'st1t' or headings'st2t' or headings'st3t' or headings'st4t' or headings'st5t' then

		local cspan = (headings'sw' and 1 or 0) + (headings'seats' and 1 or 0) + (headings'sc' and 1 or 0) + (headings'st1t' and 1 or 0) + (headings'st2t' and 1 or 0) + (headings'st3t' and 1 or 0) + (headings'st4t' and 1 or 0) + (headings'st5t' and 1 or 0) + (has_seats3 and 1 or 0)

		row

			:tag('td')

				:attr('colspan', cspan > 1 and cspan or nil)

	end

	end

	if args'majority' then

	if args'invalid' or args'electorate' then

	row = root

		:tag('tr')

			:addClass('sortbottom')

	row

		:tag('td')

			:css('background', '#eaecf0')

			:attr('colspan', cols)

	end

	row = root

		:tag('tr')

			:addClass('sortbottom')

			:css('text-align', 'right')

	row

		:tag('th')

			:wikitext('Majority')

			:attr('scope', 'row')

			:attr('colspan', cs)

			:css('text-align', 'left')

			:css('font-weight', 'normal')

			:css('background', 'inherit')

	for k=1, rounds do

	row

		:tag('td')

			:wikitext(fmt(majorityk]))

		:tag('td')

			:wikitext(fmt(majoritypctk]))

	end

	if args'majoritysw' then

	row

		:tag('td')

			:wikitext(args'majoritysw'])

	end

	end

	if args'result' then

		row = root:tag('tr')

			:addClass('sortbottom')

		-- determine the color

		local color = get_color(args'resultcolour' or nil, args'result'])

		if args'resultsw' then

			row

				:tag('td')

					:css('background-color', color)

			row

				:tag('td')

					:attr('colspan', 2)

					:wikitext(args'result'])

			row

				:tag('td')

					:attr('colspan', 2)

					:css('text-align', 'right')

					:wikitext('Swing')

			row

				:tag('td')

					:css('text-align', 'right')

					:wikitext(args'resultsw'])

		else

			row

				:tag('td')

					:css('background-color', color)

			row

				:tag('td')

					:attr('colspan', cols - 1)

					:wikitext(args'result'])

		end

	end

	if args'majority2' then

	row = root

		:tag('tr')

			:addClass('sortbottom')

			:css('text-align', 'right')

	row

		:tag('th')

			:wikitext('Majority')

			:attr('scope', 'row')

			:attr('colspan', cs)

			:css('text-align', 'left')

			:css('font-weight', 'normal')

			:css('background', 'inherit')

	for k=1, rounds do

	row

		:tag('td')

			:wikitext(fmt(majority2k]))

		:tag('td')

			:wikitext(fmt(majoritypct2k]))

	end

	if args'majoritysw2' then

	row

		:tag('td')

			:wikitext(args'majoritysw2'])

	end

	end

	if args'result2' then

		row = root:tag('tr')

			:addClass('sortbottom')

		-- determine the color

		local color = get_color(args'resultcolour' or nil, args'result2'])

		if args'resultsw2' then

			row

				:tag('td')

					:css('background-color', color)

			row

				:tag('td')

					:attr('colspan', 2)

					:wikitext(args'result2'])

			row

				:tag('td')

					:attr('colspan', 2)

					:css('text-align', 'right')

					:wikitext('Swing')

			row

				:tag('td')

					:css('text-align', 'right')

					:wikitext(args'resultsw2'])

		else

			row

				:tag('td')

					:css('background-color', color)

			row

				:tag('td')

					:attr('colspan', cols - 1)

					:wikitext(args'result2'])

		end

	end

	if args'source' then

	row = root:tag('tr')

			:addClass('sortbottom')

			:css('text-align', 'right')

	row:tag('td')

		:wikitext('Source: ', args.source)

		:attr('colspan', cols)

		:css('text-align', 'left')

	end

	if args'embedded' then

		root:wikitext(args'embedded'])

	end

	return tostring(root) .. tracking

end



return p