Module:Mayor

local loader = require('Module:Loader') local getArgs = require('Module:Arguments').getArgs

local string, table, yesno, slotutils = loader.require('String', 'Table', 'Yesno', 'Inventory slot/Utils') local mayorData, colorData, uitextData = loader.loadData('Mayor/Data', 'Color/Data', 'UIText/Data')

local p = {}

local candidateColors = { 'c', 'a', 'b', 'e', 'd' }

function p.getMayorLink(mayor) return (''):format(mayorData.mayors[mayor] and mayorData.mayors[mayor].link or mayor, mayor) end

-- For Template:Current Mayor function p.getCurrentMayor(frame) local args = getArgs(frame) local m = mayorData.currentMayor if args[1] == 'r' then return m end local d = mayorData.mayors[m] return mw.getCurrentFrame:preprocess(('%s'):format( d and d.link or m, m	)) end

-- For Template:MayorList function p.mayorList(frame) local args = getArgs(frame) return mw.getCurrentFrame:preprocess(p._mayorList(args[1])) end

function p._mayorList(_type) local function insertperks(t, perksTb, frontdent) for _, info in ipairs(perksTb) do			table.push(t, ('%s %s : %s'):format( frontdent, mayorData.linkedPerkNames[info[1]] or info[1], type(info[2]) == 'table' and '' or info[2] ))			if type(info[2]) == 'table' then for _, item in ipairs(info[2]) do					table.push(t, ('%s* %s'):format(frontdent, item)) end end end end local mayors = table.deepCopy(mayorData.mayors, true) if _type then mayors = table.filterNamed(mayors, function(k, v)			return v.type == string.lower(_type)		end) end local paragraphs = {} for k, v in table.sortedPairs(mayors) do		local lines_ = {} local frontdent = v.perks_listed and '**#' or '*#' if v.perks_listed then table.push(lines_, '**\'\'\'Listed Perks\'\'\':') insertperks(lines_, v.perks_listed, frontdent) table.push(lines_, ('**\'\'\'Actual Perks\'\'\': \'\'(hidden until %s is elected)\'\''):format(k)) end insertperks(lines_, v.perks, frontdent) table.push(paragraphs, table.concat({ ('*\'\'\'%s\'\'\' %s'):format(				p.getMayorLink(k), v.aka or ''			), unpack(lines_) }, '\n')) end return table.concat(paragraphs, '\n\n') end

-- For Template:ElectionTable function p.electionTable(frame) return mw.getCurrentFrame:preprocess(p._electionTable) end

function p.generatePerks(col, mayor, num) local function each(t, i, title, text) text = type(text) == 'table' and table.map(table.deepCopy(text, true), function(d)			return '— ' .. d		end) or { text } table.push(t, string.wrapHtml{			i,			' ', {				class = 'minetip gemstone-slot',				style = { ['color'] = colorData.hexColors[col] or 'Orange' },				['data-minetip-title'] = '&' .. (uitextData.conversions[col] or 'd') .. title,				['data-minetip-text'] = table.concat(table.map(text, function(tx)					return string.gsubAll(tx, '{', '&#123;', '}', '&#125;', '.*', '')				end), '/'),			}		}) end local allperks, t = mayorData.mayors[mayor].perks, {} if num:match('%*') then for i = 1, table.xlength(allperks, false) do			if not allperks[i] then error(('Perk %s of "%s" not found.'):format(i, mayor)) end if not allperks[i] then break end each(t, i, allperks[i][1], allperks[i][3] ~= '' and allperks[i][3] or allperks[i][2]) end else for _, v in ipairs(string.split(num, '')) do			v = tonumber(v) each(t, v, allperks[v][1], allperks[v][3] ~= '' and allperks[v][3] or allperks[v][2]) end end return table.concat(t, ' ') end

function p._electionTable local dt, rows = mayorData.elections, {} local _date, _year = {}, {} for i = table.length(dt), 1, -1 do		local item = dt[i] local c = item.control or '' -- if c:match('in-progress') then table.push(_date, item.date) table.push(_year, i)		if not c:match('collapsedown') then local y2, y1 = _year[1], _year[#_year] local y = y2 == y1 and y2 or ('%s-%s'):format(y1, y2) local button = item.ui and (' &#91;UI&#93; '):format(y1) or '' local tot, _other, _mayor, _votes, mayorName if item.result then tot, _other = 0, {} for _, v in pairs(item.result) do					tot = tot + v				end for k, v in table.sortedPairsByValue(item.result, function(a, b)					return a > b				end) do					if not _mayor then mayorName = k						_mayor = p.getMayorLink(mayorName) _votes = ('%s %s'):format(							():format(v / tot * 100),							():format(v)						) else table.push(_other, (' %s: %s %s '):format( p.getMayorLink(k), (''):format(v / tot * 100), (''):format(v) ))					end end _other = table.concat(_other, ' ') else mayorName = item.mayor _mayor = mayorData.mayors[mayorName] _mayor = item.mayor and p.getMayorLink(mayorName) or nil _votes = (item.percent and item.votes) and ('%s %s'):format(					():format(item.percent),					():format(item.votes)				) or nil end local _perks = item.perks if _perks then local num, caption = _perks:match('([%d%*%?]+)(%(.-%))') if not num then num = _perks end if num:match('%?') then _perks = '' elseif mayorName then _perks = p.generatePerks(mayorData.mayors[mayorName].color, mayorName, num) else _perks = 'Perk ' .. table.concat(string.split(num, ''), ', ') end _perks = caption and ('%s %s '):format(_perks, caption) or _perks end table.push(rows, {				date = table.concat(_date, ' '),				year = y .. button,				mayor = _mayor,				votes = _votes,				perks = _perks,				other = _other,				control = c,			}) _date, _year = {}, {} end end local wikitable = mw.html.create('table'):addClass('article-table wikitable') wikitable:tag('tr'):tag('th'):wikitext('SkyBlock Year'):done :tag('th'):wikitext('Date*'):done :tag('th'):wikitext('Mayor'):done :tag('th'):wikitext('Votes'):done :tag('th'):wikitext('Perks'):done :tag('th'):wikitext('Other Candidates'):done local function g(val, control) return val or (control:match('novote') and  or ) end for _, v in ipairs(rows) do		wikitable:tag('tr'):tag('th'):wikitext(v.year):done :tag('td'):wikitext(v.date):done :tag('td'):wikitext(g(v.mayor, v.control)):done :tag('td'):wikitext(g(v.votes, v.control)):done :tag('td'):wikitext(g(v.perks, v.control)):done :tag('td'):wikitext(g(v.other, v.control)):done end return tostring(wikitable) end

local function mayorTooltip(name, mode, nums, col) col = col or 'd'	local m = mayorData.mayors[name] local info = {} local perksref = table.deepCopy(mode == 'candidate' and m.perks_listed or m.perks, true) for _, perk in ipairs(nums and table.map(string.split(nums, ''), function(i) return perksref[tonumber(i)] end) or perksref) do		local desc = perk[3] ~= '' and perk[3] or perk[2] desc = type(desc) == 'table' and table.map(desc, function(d)			return '— ' .. d		end) or { desc } desc = string.gsubAll(table.concat(desc, '/'), '{', '&#123;', '}', '&#125;', '.*', '') table.push(info, ('&%s%s/&r%s'):format( col, perk[1], desc ))	end return { name, col, m.link or name, table.concat(info, '//'), title = perksref.title, text = perksref.text } end

local function templateTemplate(id, mode) local ret = {} for name, _ in pairs(mayorData.mayors) do		table.push(ret, mayorTooltip(name, mode)) end ret.id = id	return ret end

function p.getMayorsTemplate return templateTemplate('Mayor {o}', 'mayor') end

function p.getMayorCandidatesTemplate return templateTemplate(nil, 'candidate') end

function p.mayorElectionUI( frame ) local args = getArgs(frame) return mw.getCurrentFrame:preprocess(p._mayorElectionUI(args.year or args[1])) end

function p._mayorElectionUI(year) local function slotview(tb) local slot = slotutils._useTemplate(			{ table.merge({ id = 'THIS' }, tb) }, 'T:Mayor Candidate'		) local params = '' slot['THIS']['image'] = nil for k, v in pairs(slot['THIS']) do			params = ('%s|%s = %s'):format(params, k, v)		end return params end local function uiview(tb) local params = '' for k, v in pairs(tb) do			params = ('%s|%s = %s'):format(params, k, v)		end return (''):format(params) end local data = mayorData.elections[year].data if type(data) ~= 'table' then error(('Data of Year %s is not a table'):format(year)) end local t = {} -- [1]: candidate name; [2]: perks string; [3]: slot template string for stained glass; [4]: slot template string for mayor for candidate, candidateData in table.sortedPairsByValue(data, function(a, b)		return a.order < b.order	end) do		table.push(t, { candidate, candidateData.perks }) end for i, v in ipairs(t) do		local tt = mayorTooltip(v[1], 'candidate', v[2], candidateColors[i]) local pp = slotview(tt) v[3] = (''):format(v[1], pp) v[4] = (''):format(v[1], v[1], pp) end return uiview { ('Election, Year %s'):format(year), ['col 1'] = ('%s; 1, 5'):format(t[1][3]), ['col 3'] = ('%s; 1, 5'):format(t[2][3]), ['col 5'] = ('%s; 1, 5'):format(t[3][3]), ['col 7'] = ('%s; 1, 5'):format(t[4][3]), ['col 9'] = ('%s; 1, 5'):format(t[5][3]), ['6, 1'] = t[1][4], ['6, 3'] = t[2][4], ['6, 5'] = t[3][4], ['6, 7'] = t[4][4], ['6, 9'] = t[5][4], arrow = 'none', close = 'none', } end

return p