Toggle menu
Toggle preferences menu
Toggle personal menu
Not logged in
Your IP address will be publicly visible if you make any edits.

Documentation for this module may be created at Module:Standings/doc

local p = {}
local html = mw.html
local cargo = mw.ext.cargo

local function sqlEscape(s)
    if not s then return "" end
    s = s:gsub("\\", "\\\\")
    s = s:gsub("'", "\\'")
    return s
end

local function getTrophyIcon()
return '🏆'
end

local function buildLogo(teamName, tData, mData)
local lightFile = "Shield_team.png"
local darkFile = "Shield_team_dark.png"

if tData and tData.image and tData.image ~= "" then
lightFile = tData.image
darkFile = (tData.image_dark and tData.image_dark ~= "") and tData.image_dark or lightFile
elseif mData then
if mData.image and mData.image ~= "" then lightFile = mData.image else lightFile = teamName .. ".png" end
if mData.image_dark and mData.image_dark ~= "" then darkFile = mData.image_dark else darkFile = lightFile end
end

local container = html.create('span'):addClass('team-logo-wrapper')
container:tag('span'):addClass('logo-lightmode'):wikitext('[[File:' .. lightFile .. '|30px|link=|class=team-logo]]')
container:tag('span'):addClass('logo-darkmode'):wikitext('[[File:' .. darkFile .. '|30px|link=|class=team-logo]]')
return tostring(container)
end

function p.main(frame)
local args = frame:getParent().args

local tournament = args.tournament or mw.title.getCurrentTitle().text
local stage = args.stage
local group = args.group
local showgroup = (args.showgroup == 'true')

local matchlistStr = args.matchlist
local matchNumbers = {}
if matchlistStr and matchlistStr ~= "" then
local parts = mw.text.split(matchlistStr, ",")
for _, v in ipairs(parts) do
table.insert(matchNumbers, tonumber(mw.text.trim(v)))
end
else
local numMatches = tonumber(args.matches) or 6
local startMatch = tonumber(args.startmatch) or 1
local endMatch = startMatch + numMatches - 1
for i = startMatch, endMatch do
table.insert(matchNumbers, i)
end
end

local qtext = args.qtext
local q2text = args.q2text
local q3text = args.q3text
local etext = args.etext
local dtext = args.dtext
local ntext = args.ntext

local whereParts = {}
table.insert(whereParts, "tournament='" .. sqlEscape(tournament) .. "'")
if stage and stage ~= "" then table.insert(whereParts, "stage='" .. sqlEscape(stage) .. "'") end
if group and group ~= "" then table.insert(whereParts, "groupname='" .. sqlEscape(group) .. "'") end

local rCols = ""
for i=1,30 do rCols = rCols .. ", r" .. i end

local results = cargo.query("StageStandings", 
"team, teamshort, groupname, totalpts, matchesplayed, wwcd, placepts, elimpts, result" .. rCols, 
{
where = table.concat(whereParts, " AND "),
orderBy = "totalpts DESC, wwcd DESC, placepts DESC, elimpts DESC, lastmatchrank ASC",
limit = 100
})

if not results or #results == 0 then return html.create('div'):wikitext('No data found.'):css('color', 'red') end

local teamListQuoted = {}
for _, row in ipairs(results) do table.insert(teamListQuoted, "'" .. sqlEscape(row.team) .. "'") end
local teamSql = table.concat(teamListQuoted, ",")

local teamInfo = {}
if cargo and cargo.query then
local tResults = cargo.query("Tournament_Teams", "team, display_name, image, image_dark", { where = "tournament='" .. sqlEscape(tournament) .. "'", limit = 100 })
for _, row in ipairs(tResults) do teamInfo[row.team:lower()] = row end
end

local masterInfo = {}
if #teamListQuoted > 0 and cargo and cargo.query then
local mResults = cargo.query("Teams", "name, image, image_dark", { where = "name IN (" .. teamSql .. ")", limit = 100 })
for _, row in ipairs(mResults) do masterInfo[row.name:lower()] = row end
end

local container = html.create('div')

local legend = container:tag('div'):addClass('standings-legend')
local function addLegendItem(colorCode, text, className)
if text and text ~= "" then
local item = legend:tag('div'):addClass('legend-item')
item:tag('span'):addClass('legend-color ' .. className)
item:tag('span'):addClass('legend-text'):wikitext(text)
end
end
addLegendItem('#28a745', qtext, 'qual-q'); addLegendItem('#007bff', q2text, 'qual-q2'); addLegendItem('#6f42c1', q3text, 'qual-q3')
addLegendItem('#dc3545', etext, 'qual-e'); addLegendItem('#343a40', dtext, 'qual-d'); addLegendItem('#adb5bd', ntext, 'qual-n')

local wrapper = container:tag('div'):addClass('standings-wrapper')
local tbl = wrapper:tag('table'):addClass('standings-card-table')

if showgroup then tbl:addClass('has-group-col') end

local header = tbl:tag('tr')
header:tag('th'):wikitext('#'):addClass('sticky-col sticky-1')
header:tag('th'):wikitext('TEAM'):addClass('sticky-col sticky-2')

if showgroup then header:tag('th'):wikitext('GRP'):addClass('grp-sticky') end

header:tag('th'):wikitext('M'):addClass('pc-only pc-sticky-1')
header:tag('th'):wikitext('WWCD'):addClass('pc-only pc-sticky-2')
header:tag('th'):wikitext('PLACE'):addClass('pc-only pc-sticky-3')
header:tag('th'):wikitext('ELIMS'):addClass('pc-only pc-sticky-4')

header:tag('th'):wikitext('M'):addClass('mobile-only')
header:tag('th'):wikitext('W'):addClass('mobile-only')
header:tag('th'):wikitext('P'):addClass('mobile-only') 
header:tag('th'):wikitext('E'):addClass('mobile-only')

header:tag('th'):wikitext('PTS'):addClass('sticky-col sticky-3')

for _, mNum in ipairs(matchNumbers) do header:tag('th'):wikitext('M' .. mNum):addClass('match-col') end

if #matchNumbers == 0 then header:tag('th'):addClass('match-col') end

for i, row in ipairs(results) do

local tr = tbl:tag('tr'):addClass('standings-row')

local res = (row.result or ''):lower()
local statusClass = 'qual-default'
local tooltip = '' 
if res == 'q' then statusClass = 'qual-q'; tooltip = qtext or 'Qualified'
elseif res == 'q2' then statusClass = 'qual-q2'; tooltip = q2text or 'Qualified'
elseif res == 'q3' then statusClass = 'qual-q3'; tooltip = q3text or 'Qualified'
elseif res == 'e' then statusClass = 'qual-e'; tooltip = etext or 'Eliminated'
elseif res == 'd' then statusClass = 'qual-d'; tooltip = dtext or 'Disqualified'
elseif res == 'n' then statusClass = 'qual-n'; tooltip = ntext or 'Inactive' end

tr:tag('td'):wikitext(i .. '.'):addClass('sticky-col sticky-1 ' .. statusClass):attr('title', tooltip)

local tData = teamInfo[row.team:lower()]
local mData = masterInfo[row.team:lower()]
local displayName = row.team
if tData and tData.display_name and tData.display_name ~= "" then displayName = tData.display_name end

local teamCell = tr:tag('td'):addClass('sticky-col sticky-2 team-name-cell')
teamCell:wikitext(buildLogo(row.team, tData, mData))
teamCell:tag('span'):addClass('pc-only'):wikitext('[[' .. row.team .. '|' .. displayName .. ']]')
teamCell:tag('span'):addClass('mobile-only'):wikitext('[[' .. row.team .. '|' .. (row.teamshort or displayName) .. ']]')

if showgroup then tr:tag('td'):wikitext(row.groupname or '-'):addClass('text-center font-weight-bold grp-sticky') end

tr:tag('td'):wikitext(row.matchesplayed):addClass('pc-only pc-sticky-1')
tr:tag('td'):wikitext(row.wwcd):addClass('pc-only pc-sticky-2')
tr:tag('td'):wikitext(row.placepts):addClass('pc-only pc-sticky-3')
tr:tag('td'):wikitext(row.elimpts):addClass('pc-only pc-sticky-4')

tr:tag('td'):wikitext(row.matchesplayed):addClass('mobile-only text-center')
tr:tag('td'):wikitext(row.wwcd):addClass('mobile-only text-center')
tr:tag('td'):wikitext(row.placepts):addClass('mobile-only text-center')
tr:tag('td'):wikitext(row.elimpts):addClass('mobile-only text-center')

tr:tag('td'):wikitext(row.totalpts):addClass('sticky-col sticky-3 total-points-cell')

for _, m in ipairs(matchNumbers) do
local raw = row['r' .. m]
local cell = tr:tag('td'):addClass('match-cell')

if raw and raw ~= "" then
local mRank, mPts
if raw:find(";") then local parts = mw.text.split(raw, ";"); mRank = tonumber(parts[1]); mPts = tonumber(parts[2]) else mPts = tonumber(raw) end

if mRank == 0 then cell:wikitext('-'):addClass('dim-text')
elseif mRank == 1 then cell:wikitext(getTrophyIcon() .. ' <b>' .. (mPts or '') .. '</b>'):addClass('match-win')
else cell:wikitext(mPts); if mRank then cell:tag('sub'):wikitext(mRank):addClass('pc-only') end end

if mPts and mPts >= 15 and mRank ~= 0 then cell:addClass('high-score') end
else cell:wikitext('-'):addClass('dim-text') end
end

if #matchNumbers == 0 then tr:tag('td'):addClass('match-cell') end

end
return tostring(container)
end

return p