Module:ChampionDataWR

From League of Legends Wiki, LoL Wiki
Jump to navigation Jump to search
-- <pre>
local p = {}
 
local lib       = require('Module:Feature')
local json      = require('Module:JSON')
local userError = require('Module:User error')
local FN        = require('Module:Filename')

-- wrapper template: CWRcd
function p.get(frame)
    local args = lib.frameArguments(frame)
    
    local get         = require ('Module:ChampionDataWR/getter')
    args['champname'] = args['champname'] or args[1]
    args['datatype']  = args['datatype']  or args[2]
    args['output']    = args['output']    or args[3] or nil
    
    args['champname'] = lib.validateName(args['champname']) --corrects for acceptable misspellings (e.g. Nunu -> Nunu & Willump)
    
    local resultGet = get[args['datatype']]
    local result
    if resultGet then
    	result = resultGet(args['champname'])
    end
    
    if args['output'] ~= nil and type(result) == "table" then
        if args['output'] == "csv" then
            return lib.tbl_concat{result}
        elseif args['output'] == "custom" then 
            return frame:preprocess(lib.tbl_concat{result, prepend = args['prepend'], append = args['append'], separator = args['separator'], index = args["index"]})
        elseif args['output'] == "template" then 
            return frame:preprocess(lib.tbl_concat{result, prepend = "{{" .. args['t_name'] .. "|", append = "}}", separator = args['separator'], index = args["index"]})
        elseif args['output'] == "category" then 
            return frame:preprocess(lib.tbl_concat{result, prepend = "[[Category:" .. (args['prepend'] or ""), append = (args['append'] or "") .. "]]", separator = args['separator'] or " "})
        end
    elseif result == nil then
        return ""
    else
        return result
    end
end

-- wrapper template Template:Champion_roster, Template:Champions
function p.getRoster()
    local wrData  = mw.loadData('Module:ChampionDataWR/data')
    local wrTable = {}
    --local lorTable = {}
    local s        = ""
    
    for champname in pairs(wrData) do
        if  
            wrData[champname]["date"] == ("Upcoming" or "N/A" or "Cancelled" or "")
            then
            --ignore champion
        else
            table.insert(wrTable, champname)
        end
            
    end
    table.sort(wrTable)
    
    --lorTable = lorData.getRosters{}
    
    for _, champion in pairs(wrTable) do
        
        --custom searches
        local search = champion
        
        if wrData[champion]["title"]    then search = search .. "," .. wrData[champion]["title"]    end
        if wrData[champion]["fullname"] then search = search .. "," .. wrData[champion]["fullname"] end
        if wrData[champion]["nickname"] then search = search .. "," .. wrData[champion]["nickname"] end
        
        --champion roles
        local role = p.get{champion, "herotype", "csv"}
        
        -- EDIT NECESSARY TO ADJUST TO WR ICON!
        local rangetype = wrData[champion]["rangetype"]
        s = s .. '<li><span class="grid-icon champion-icon" data-champion="' .. champion .. '" data-search="' .. search .. '" data-game="' .. 'wr' .. '" data-role="' .. role .. '" data-type="' .. rangetype .. '">[[File:' .. FN.WRchampionsquare{champion} .. '|46px|alt=' .. champion .. '|link=WR:' .. champion .. '|border]]</span></li>'
    end
    
    return s
end

function p.getChampionCount(frame)
	local wrData = mw.loadData('Module:ChampionDataWR/data')
	local i = 0
	local skip = {
		["Upcoming"] = true, ["N/A"] = true, ["Cancelled"] = true, [""] = true,
	}
    for k, v in pairs(wrData) do
        if not skip[k] and not skip[v["date"] or "Upcoming"] then
        	i = i + 1
        end
    end
    return i
end

function p.statTable(frame)
    local args = lib.frameArguments(frame)
    
    args['datatype'] = args['datatype'] or args[1]

    local IL         = require('Module:ImageLink')
    local builder    = require("Module:SimpleHTMLBuilder")
    local wrData     = mw.loadData('Module:ChampionDataWR/data')
    local wrTable    = {}
    local tablenode  = builder.create('table')
    
    local convert   = {
        ["Health"]          = "hp",
        ["Health regen"]    = "hp5",
        ["Mana"]            = "mp",
        ["Mana regen"]      = "mp5",
        ["Armor"]           = "arm",
        ["Magic resist"]    = "mr",
        ["Attack damage"]   = "dam",
        ["Move speed"]      = "ms",
        ["Attack speed"]    = "as"
    }
    if args['datatype'] == "Base" then
        tablenode
            :addClass('sortable wikitable sticky-header')
            :css('width', '100%')
            :css('text-align', 'right')
            :css('white-space', 'nowrap')
            :newline()
    elseif args['datatype'] == "Base 18" then
        tablenode
            :addClass('sortable wikitable sticky-header')
            :css('width', '100%')
            :css('text-align', 'center')
            :css('white-space', 'nowrap')
            :tag('caption')
                :wikitext('Champion statistics at level 18 (without skill bonuses)')
            :done()
            :newline()
    elseif args['datatype'] == "Manaless" then
        tablenode
            :addClass('sortable wikitable')
            :css('width', '90%')
            :css('text-align', 'center')
            :css('white-space', 'nowrap')
            :css('margin-left', '5%')
            :newline()
    elseif args['datatype'] == "Ratings" then
        tablenode
            :addClass('sortable article-table sticky-header')
            :css('width', '100%')
            :css('text-align', 'center')
            :css('white-space', 'nowrap')
            :newline()
    else
    tablenode
        :addClass('sortable article-table sticky-header')
        :css('width', '100%')
        :css('text-align', 'center')
        :newline()
    end
    if args['datatype'] == "Attack speed" then
        tablenode
            :tag('tr')
                :tag('th')
                    :wikitext('Champion')
                    :css('width', '180px')
                :done()
                :tag('th')
                    :wikitext('Base')
                :done()
                :tag('th')
                    :wikitext('AS Ratio')
                :done()
                :tag('th')
                    :wikitext('Bonus AS at level 1')
                :done()
                :tag('th')
                    :wikitext('Bonus growth coefficient')
                :done()
                :tag('th')
                    :wikitext('Bonus at level 18')
                :done()
                :tag('th')
                    :wikitext('Value at level 18')
                :done()
                :tag('th')
                    :wikitext('Additional AS needed to cap at level 18')
                :done()
            :done()
            :newline()
    elseif args['datatype'] == "Basic attack" then
        tablenode
            :tag('tr')
                :tag('th')
                    :wikitext('Champion')
                    :css('width', '180px')
                :done()
                :tag('th')
                    :wikitext('Attack range')
                :done()
                :tag('th')
                    :wikitext('Range type')
                :done()
                :tag('th')
                    :wikitext('Missile speed')
                :done()
                :tag('th')
                    :wikitext('Windup')
                :done()
                :tag('th')
                    :wikitext('Windup modifier')
                :done()
            :done()
            :newline()
    elseif args['datatype'] == "Hitbox" then
        tablenode
            :tag('tr')
                :tag('th')
                    :wikitext('Champion')
                    :css('width', '180px')
                :done()
                :tag('th')
                    :wikitext('Gameplay radius')
                :done()
                :tag('th')
                    :wikitext('Selection radius')
                :done()
                :tag('th')
                    :wikitext('Pathing radius')
                :done()
                :tag('th')
                    :wikitext('Acquisition radius')
                :done()
            :done()
            :newline()
    elseif args['datatype'] == "Base" then
        tablenode
            :tag('tr')
                :tag('th')
                    :wikitext('[[Champion]]s')
                :done()
                :tag('th')
                    :wikitext('[[Health|HP]]')
                    :css('width', '4em')
                :done()
                :tag('th')
                    :wikitext('HP+')
                    :css('width', '4em')
                :done()
                :tag('th')
                    :wikitext('[[Health regeneration|HP5]]')
                    :css('width', '4em')
                :done()
                :tag('th')
                    :wikitext('HP5+')
                    :css('width', '4em')
                :done()
                :tag('th')
                    :wikitext('[[Mana|MP]]')
                    :css('width', '4em')
                :done()
                :tag('th')
                    :wikitext('MP+')
                    :css('width', '4em')
                :done()
                :tag('th')
                    :wikitext('[[Mana regeneration|MP5]]')
                    :css('width', '4em')
                :done()
                :tag('th')
                    :wikitext('MP5+')
                    :css('width', '4em')
                :done()
                :tag('th')
                    :wikitext('[[Attack damage|AD]]')
                    :css('width', '4em')
                :done()
                :tag('th')
                    :wikitext('AD+')
                    :css('width', '4em')
                :done()
                :tag('th')
                    :wikitext('[[Attack speed|AS]]')
                    :css('width', '4em')
                :done()
                :tag('th')
                    :wikitext('AS+')
                    :css('width', '4em')
                :done()
                :tag('th')
                    :wikitext('[[Armor|AR]]')
                    :css('width', '4em')
                :done()
                :tag('th')
                    :wikitext('AR+')
                    :css('width', '4em')
                :done()
                :tag('th')
                    :wikitext('[[Magic resistance|MR]]')
                    :css('width', '4em')
                :done()
                :tag('th')
                    :wikitext('MR+')
                    :css('width', '4em')
                :done()
                :tag('th')
                    :wikitext('[[Movement speed|MS]]')
                    :css('width', '4em')
                :done()
                :tag('th')
                    :wikitext('[[Range]]')
                    :css('width', '4em')
                :done()
            :done()
            :newline()
    elseif args['datatype'] == "Base 18" then
        tablenode
            :tag('tr')
                :tag('th')
                    :wikitext('Champion')
                    :css('color', 'black')
                    :css('background-color', 'white')
                :done()
                :tag('th')
                    :attr('data-sort-type', 'number')
                    :wikitext('HP')
                    :css('color', 'black')
                    :css('background-color', 'lightgreen')
                :done()
                :tag('th')
                    :attr('data-sort-type', 'number')
                    :wikitext('HP5')
                    :css('color', 'black')
                    :css('background-color', 'lightgreen')
                :done()
                :tag('th')
                    :attr('data-sort-type', 'number')
                    :wikitext('MP')
                    :css('color', 'black')
                    :css('background-color', 'lightblue')
                :done()
                :tag('th')
                    :attr('data-sort-type', 'number')
                    :wikitext('MP5')
                    :css('color', 'black')
                    :css('background-color', 'lightblue')
                :done()
                :tag('th')
                    :attr('data-sort-type', 'number')
                    :wikitext('AD')
                    :css('color', 'black')
                    :css('background-color', '#ffaaaa')
                :done()
                :tag('th')
                    :attr('data-sort-type', 'number')
                    :wikitext('AS')
                    :css('color', 'black')
                    :css('background-color', '#ffaaaa')
                :done()
                :tag('th')
                    :attr('data-sort-type', 'number')
                    :wikitext('AR')
                    :css('color', 'black')
                    :css('background-color', '#ffffaa')
                :done()
                :tag('th')
                    :attr('data-sort-type', 'number')
                    :wikitext('MR')
                    :css('color', 'black')
                    :css('background-color', '#ffffaa')
                :done()
                :tag('th')
                    :attr('data-sort-type', 'number')
                    :wikitext('Range')
                :done()
                :tag('th')
                    :attr('data-sort-type', 'number')
                    :wikitext('MS')
                :done()
            :done()
            :newline()
    elseif args['datatype'] == "Manaless" then
        tablenode
            :tag('tr')
                :tag('th')
                    :wikitext('Champion')
                :done()
                :tag('th')
                    :wikitext('Secondary Resource')
                :done()
            :done()
            :newline()
    elseif args['datatype'] == "Ratings" then
        tablenode
            :tag('tr')
                :tag('th')
                    :wikitext('Champion')
                :done()
                :tag('th')
                    :wikitext('Primary')
                :done()
                :tag('th')
                    :wikitext('Secondary')
                :done()
                :tag('th')
                    :wikitext('[[File:Damage rating.png|15px|link=]]')
                :done()
                :tag('th')
                    :wikitext('[[File:Toughness rating.png|15px|link=]]')
                :done()
                :tag('th')
                    :wikitext('[[File:Utility rating.png|15px|link=]]')
                :done()
                :tag('th')
                    :wikitext(frame:expandTemplate{title='sti', args={'Adaptive Damage',icononly='true'}})
                :done()
                :tag('th')
                    :wikitext('Difficulty')
                :done()
            :done()
            :newline()
    else
        tablenode
            :tag('tr')
                :tag('th')
                    :wikitext('Champion')
                    :css('width', '180px')
                :done()
                :tag('th')
                    :wikitext('Base')
                :done()
                :tag('th')
                    :wikitext('Growth coefficient')
                :done()
                :tag('th')
                    :wikitext('Value at 18')
                :done()
            :done()
            :newline()
    end
    
    for champname in pairs(wrData) do
        if wrData[champname]["date"] == "Upcoming"
            or wrData[champname]["date"] == "N/A"
            or wrData[champname]["date"] == "Cancelled"
            or wrData[champname]["date"] == ""
            or 
            champname == ("Rhaast" or "Shadow Assassin")
            or
            ((args['datatype'] == "Mana" or args['datatype'] == "Mana regen") and string.lower(wrData[champname]["resource"]) ~= "mana")
            then
            --ignore champion
        else
            table.insert(wrTable, champname)
        end
    end
    table.sort(wrTable)
    
    for _, champion in pairs(wrTable) do
        local t         = wrData[champion]["stats"]
        local tablerow  = builder.create('tr')
        
        if args['datatype'] == "Attack speed" then
            local as_base   = t["as_base"]
            local as_ratio  = t["as_ratio"]
            local bonus_lvl = t["as_lvl"]
            local bonus_18  = 0 + bonus_lvl * (18 - 1) * (0.7025 + 0.0175 * (18 - 1))
            local variation = string.format("%.f", as_base / as_ratio * 100 - 100, 3)
                
            if variation == "-0" then
                variation = "0"
            end
            
            local disp_name = champion
            if champion == "Mega Gnar" then disp_name = "Gnar (Mega)" end
            
            if champion == "Jhin" then
                tablerow
                    :tag('td')
                        :attr('data-sort-value', disp_name)
                        :css('text-align', 'left')
                        :node(IL.champion{["champion"] = champion, ["circle"] = "true"})
                        :wikitext("<span title='Jhin&#39;s growth increases his base attack speed. He does not gain &#39;bonus attack speed&#39;.'><sup>note</sup></span>")
                    :done()
                    :tag('td')
                        :wikitext(string.format("%0.3f", as_base, 3))
                    :done()
                    :tag('td')
                        :wikitext(string.format("%0.3f", as_ratio, 3))
                    :done()
                    :tag('td')
                        :wikitext("N/A")
                    :done()
                    :tag('td')
                        :wikitext(bonus_lvl .. "%")
                    :done()
                    :tag('td')
                        :wikitext(bonus_18 .. "%")
                    :done()
                    :tag('td')
                        :wikitext(string.format("%0.3f", as_base + as_base * (bonus_18 / 100), 3))
                    :done()
                    :tag('td')
                        :attr('data-sort-value', "9999%")
                        :wikitext(string.format("%0.0f", (2.5 / as_ratio - 1) * 100 - bonus_18, 3) .. "%")
                    :done()
                :done()
            else
                tablerow
                    :tag('td')
                        :attr('data-sort-value', disp_name)
                        :css('text-align', 'left')
                        :node(IL.champion{["champion"] = champion, ["circle"] = "true"})
                    :done()
                    :tag('td')
                        :wikitext(string.format("%0.3f", as_base, 3))
                    :done()
                    :tag('td')
                        :wikitext(string.format("%0.3f", as_ratio, 3))
                    :done()
                    :tag('td')
                        :wikitext(variation .. "%")
                    :done()
                    :tag('td')
                        :wikitext(bonus_lvl .. "%")
                    :done()
                    :tag('td')
                        :wikitext(bonus_18 .. "%")
                    :done()
                    :tag('td')
                        :wikitext(string.format("%0.3f", as_base + as_ratio * (bonus_18 / 100), 3))
                    :done()
                    :tag('td')
                        :wikitext(string.format("%0.0f", (2.5 / as_ratio - 1) * 100 - bonus_18 - (as_base / as_ratio - 1) * 100, 3) .. "%")
                    :done()
                :done()
            end
        elseif args['datatype'] == "Basic attack" then
            local windup
            if (t["attack_cast_time"] and t["attack_total_time"]) then
                windup = t["attack_cast_time"] / t["attack_total_time"]
            else
                windup = 0.3 + (t["attack_delay_offset"] or 0)
            end
            
            local windup_mod
            if t["windup_modifier"] == nil then
                windup_mod = "N/A"
            else
                windup_mod = math.floor(t["windup_modifier"] * 1000 + 0.5) / 1000
            end
            
            tablerow
                :tag('td')
                    :attr('data-sort-value', champion)
                    :css('text-align', 'left')
                    :node(IL.champion{["champion"] = champion, ["circle"] = "true"})
                :done()
                :tag('td')
                    :wikitext(t["range"])
                :done()
                :tag('td')
                    :wikitext(wrData[champion]["rangetype"])
                :done()
                :tag('td')
                    :wikitext(t["missile_speed"] or "N/A")
                :done()
                :tag('td')
                    :wikitext((math.floor(math.floor(windup*100*1000+0.5)/1000*100+0.5)/100) .. "%")
                :done()
                :tag('td')
                    :wikitext(windup_mod)
                :done()
            :done()
        elseif args['datatype'] == "Hitbox" then
            tablerow
                :tag('td')
                    :attr('data-sort-value', champion)
                    :css('text-align', 'left')
                    :node(IL.champion{["champion"] = champion, ["circle"] = "true"})
                :done()
                :tag('td')
                    :wikitext(math.floor(t["gameplay_radius"] or 65 + 0.5))
                :done()
                :tag('td')
                    :wikitext(math.floor(t["selection_radius"] or 0 + 0.5))
                :done()
                :tag('td')
                    :wikitext(math.floor(t["pathing_radius"] or 0 + 0.5))
                :done()
                :tag('td')
                    :wikitext(math.floor(t["acquisition_radius"] or 750 + 0.5))
                :done()
            :done()
        elseif args['datatype'] == "Base" then
            local FD        = require('Module:Fd')
            
            local hp_base = FD.get{tostring(t["hp_base"])}
            local hp_lvl  = FD.get{tostring(t["hp_lvl"])}
            local hp5_base = FD.get{tostring(t["hp5_base"])}
            local hp5_lvl  = FD.get{tostring(t["hp5_lvl"])}
            local mp_base = FD.get{tostring(t["mp_base"])}
            local mp_lvl  = FD.get{tostring(t["mp_lvl"])}
            local mp5_base = FD.get{tostring(t["mp5_base"])}
            local mp5_lvl  = FD.get{tostring(t["mp5_lvl"])}
            local dam_base = FD.get{tostring(t["dam_base"])}
            local dam_lvl  = FD.get{tostring(t["dam_lvl"])}
            local as_base = FD.get{tostring(t["as_base"])}
            local as_lvl  = FD.get{tostring(t["as_lvl"])}
            local arm_base = FD.get{tostring(t["arm_base"])}
            local arm_lvl  = FD.get{tostring(t["arm_lvl"])}
            local mr_base = FD.get{tostring(t["mr_base"])}
            local mr_lvl  = FD.get{tostring(t["mr_lvl"])}
            local ms  = FD.get{tostring(t["ms"])}
            local range = FD.get{tostring(t["range"])}
            
            tablerow
                :tag('td')
                    :attr('data-sort-value', champion)
                    :css('text-align', 'left')
                    :node(IL.champion{["champion"] = champion, ["circle"] = "true"})
                :done()
                :tag('td')
                    :wikitext(hp_base)
                :done()
                :tag('td')
                    :wikitext('+' .. hp_lvl)
                :done()
                :tag('td')
                    :wikitext(hp5_base)
                :done()
                :tag('td')
                    :wikitext('+' .. hp5_lvl)
                :done()
                :tag('td')
                    :wikitext(mp_base)
                :done()
                :tag('td')
                    :wikitext('+' .. mp_lvl)
                :done()
                :tag('td')
                    :wikitext(mp5_base)
                :done()
                :tag('td')
                    :wikitext('+' .. mp5_lvl)
                :done()
                :tag('td')
                    :wikitext(dam_base)
                :done()
                :tag('td')
                    :wikitext('+' .. dam_lvl)
                :done()
                :tag('td')
                    :wikitext(as_base)
                :done()
                :tag('td')
                    :wikitext('+' .. as_lvl .. '%')
                :done()
                :tag('td')
                    :wikitext(arm_base)
                :done()
                :tag('td')
                    :wikitext('+' .. arm_lvl)
                :done()
                :tag('td')
                    :wikitext(mr_base)
                :done()
                :tag('td')
                    :wikitext('+' .. mr_lvl)
                :done()
                :tag('td')
                    :wikitext(ms)
                :done()
                :tag('td')
                    :wikitext(range)
                :done()
            :done()
        elseif args['datatype'] == "Base 18" then
            local FD        = require('Module:Fd')
            
            local hp_base = tonumber(t["hp_base"])
            local hp_lvl  = tonumber(t["hp_lvl"])
            local hp_18 = FD.get{tostring(hp_base + hp_lvl * (18 - 1) * (0.7025 + 0.0175 * (18 - 1)))}
            local hp5_base = tonumber(t["hp5_base"])
            local hp5_lvl  = tonumber(t["hp5_lvl"])
			local hp5_18 = FD.get{tostring(hp5_base + hp5_lvl * (18 - 1) * (0.7025 + 0.0175 * (18 - 1)))}
            local mp_base = tonumber(t["mp_base"])
            local mp_lvl  = tonumber(t["mp_lvl"])
			local mp_18 = FD.get{tostring(mp_base + mp_lvl * (18 - 1) * (0.7025 + 0.0175 * (18 - 1)))}
            local mp5_base = tonumber(t["mp5_base"])
            local mp5_lvl  = tonumber(t["mp5_lvl"])
			local mp5_18 = FD.get{tostring(mp5_base + mp5_lvl * (18 - 1) * (0.7025 + 0.0175 * (18 - 1)))}
            local dam_base = tonumber(t["dam_base"])
            local dam_lvl  = tonumber(t["dam_lvl"])
			local dam_18 = FD.get{tostring(dam_base + dam_lvl * (18 - 1) * (0.7025 + 0.0175 * (18 - 1)))}
            local as_base = tonumber(t["as_base"])
            local as_ratio  = tonumber(t["as_ratio"])
            local as_lvl  = tonumber(t["as_lvl"])
            local bonus_as_18  = 0 + as_lvl * (18 - 1) * (0.7025 + 0.0175 * (18 - 1))
            local as_18 = string.format("%0.3f", as_base + as_ratio * (bonus_as_18 / 100), 3)
            if champion == "Jhin" then as_18 = string.format("%0.3f", as_base + as_base * (bonus_as_18 / 100), 3) end
            as_18 = FD.get{as_18}
            
            local arm_base = tonumber(t["arm_base"])
            local arm_lvl  = tonumber(t["arm_lvl"])
			local arm_18 = FD.get{tostring(arm_base + arm_lvl * (18 - 1) * (0.7025 + 0.0175 * (18 - 1)))}
            local mr_base = tonumber(t["mr_base"])
            local mr_lvl  = tonumber(t["mr_lvl"])
			local mr_18 = FD.get{tostring(mr_base + mr_lvl * (18 - 1) * (0.7025 + 0.0175 * (18 - 1)))}
            local range = FD.get{tostring(t["range"])}
            local ms  = FD.get{tostring(t["ms"])}
            
            
            
            local resource = wrData[champion]["resource"]
            if resource == "Rage"
            or resource == "Heat"
            or resource == "Grit"
            or resource == "Fury"
            or resource == "Shield"
            or resource == "Bloodthirst"
            or resource == "Courage"
            or resource == "Health"
            or resource == "Flow"
            or resource == "Soul Unbound"
            or resource == "Ferocity"
            or resource == "Energy"
            or resource == "None" then
                mp_18 = '-'
                mp5_18 = '-'
            end
                
            tablerow
                :tag('td')
                    :attr('data-sort-value', champion)
                    :css('text-align', 'left')
                    :node(IL.champion{["champion"] = champion, ["circle"] = "true"})
                :done()
                :tag('td')
                    :wikitext(hp_18)
                    :css('color', 'lightgreen')
                :done()
                :tag('td')
                    :wikitext(hp5_18)
                    :css('color', 'lightgreen')
                :done()
                :tag('td')
                    :wikitext(mp_18)
                    :css('color', 'lightblue')
                :done()
                :tag('td')
                    :wikitext(mp5_18)
                    :css('color', 'lightblue')
                :done()
                :tag('td')
                    :wikitext(dam_18)
                    :css('color', '#ffaaaa')
                :done()
                :tag('td')
                    :wikitext(as_18)
                    :css('color', '#ffaaaa')
                :done()
                :tag('td')
                    :wikitext(arm_18)
                    :css('color', '#ffffaa')
                :done()
                :tag('td')
                    :wikitext(mr_18)
                    :css('color', '#ffffaa')
                :done()
                :tag('td')
                    :wikitext(range)
                    :css('color', '#ffffff')
                :done()
                :tag('td')
                    :wikitext(ms)
                    :css('color', '#ffffff')
                :done()
            :done()
        elseif args['datatype'] == "Manaless" then -- Rage, Heat, Grit, Fury, Mana, Shield, Bloodthirst, Courage, Health, Flow, Soul Unbound,Ferocity, Energy, None -- as of 8/20/2020
            local resource = wrData[champion]["resource"]
            if resource ~= "Mana" then
                local resource_msg
                if resource == nil then resource = "None" end
                if resource == "Flow" 
                or resource == "Soul Unbound"
                or resource == "None" then
                    resource_msg = "''[[Manaless]] champion (uses '''no secondary resource''')''"
                elseif resource == "Bloodthirst" then
                    resource_msg = "''[[Manaless]] champion (uses '''[[Manaless#Health|health]]''', '''[[Manaless#Fury|" .. mw.ustring.lower(resource) .. "]]''')''"
                elseif resource == "Grit" then
                    resource_msg = "''[[Manaless]] champion (uses '''[[Manaless#Fury|" .. mw.ustring.lower(resource) .. "]]''')''"
                elseif resource == "Energy" then
                    resource_msg = "''[[Manaless]] champion (uses '''[[" .. mw.ustring.lower(resource) .. "]]''')''"
                elseif resource == "Shield"then
                    resource_msg = "''[[Manaless]] champion (uses '''[[Manaless#Flow|" .. mw.ustring.lower(resource) .. "]]''')''"
                else
                    resource_msg = "''[[Manaless]] champion (uses '''[[Manaless#" .. resource .. "|" .. mw.ustring.lower(resource) .. "]]''')''"
                end
                tablerow
                    :tag('td')
                        :attr('data-sort-value', champion)
                        :css('text-align', 'left')
                        :node(IL.champion{["champion"] = champion, ["circle"] = "true"})
                    :done()
                    :tag('td')
                        :wikitext(resource_msg)
                    :done()
            else
                tablerow = nil
            end
        elseif args['datatype'] == "Ratings" then
            local type = wrData[champion]['type']
            local primary = type[1]
            local secondary = type[2]
            local damage = wrData[champion]['damage']
            local toughness = wrData[champion]['toughness']
            local utility = wrData[champion]['utility']
            local adaptivetype = mw.ustring.lower(wrData[champion]['adaptivetype'])
            local difficulty = wrData[champion]['difficulty']
            
            local primary_msg = ''
            if primary ~= nil then
               primary_msg = frame:expandTemplate{title="tip", args={primary}}
            else 
                primary = ''
            end
            local secondary_msg = ''
            if secondary ~= nil then
                secondary_msg = frame:expandTemplate{title="tip", args={secondary}}
            else
                secondary = ''
            end
            local damage_msg = damage
            local toughness_msg = toughness
            local utility_msg = utility
            local adaptivetype_msg;
            if adaptivetype == "magic" then
                adaptivetype_msg = "Magic"
            elseif adaptivetype == "physical" then
                adaptivetype_msg = "Physical"
            else
                -- adaptivetype_msg = frame:expandTemplate{title="pending for test"} .. " " .. frame:expandTemplate{title="edit", args={"Module:ChampionDataWR/data"}}
                adaptivetype_msg = "Physical" -- default physical
            end
            local difficulty_msg = difficulty

            
            tablerow
                :tag('td')
                    :attr('data-sort-value', champion)
                    :css('text-align', 'left')
                    :css('padding', '1px')
                    :node(IL.champion{["champion"] = champion, ["circle"] = "true"})
                :done()
                :tag('td')
                    :wikitext(primary_msg)
                    :attr('data-sort-value', primary)
                    :css('text-align', 'left')
                    :css('padding', '1px')
                :done()
                :tag('td')
                    :wikitext(secondary_msg)
                    :attr('data-sort-value', secondary)
                    :css('text-align', 'left')
                    :css('padding', '1px')
                :done()
                :tag('td')
                    :wikitext(damage_msg)
                    :attr('bgcolor', '#420300')
                    :css('padding', '1px')
                :done()
                :tag('td')
                    :wikitext(toughness_msg)
                    :attr('bgcolor', '#102E00')
                    :css('padding', '1px')
                :done()
                :tag('td')
                    :wikitext(utility_msg)
                    :attr('bgcolor', '#5d4407')
                    :css('padding', '1px')
                :done()
                :tag('td')
                    :wikitext(adaptivetype_msg)
                    :attr('data-sort-value', adaptivetype)
                    :css('padding', '1px')
                :done()
                :tag('td')
                    :wikitext(difficulty_msg)
                    :css('padding', '1px')
                :done()
        else
            local _base = tonumber(t[convert[args['datatype']] .. "_base"])
            local _lvl  = tonumber(t[convert[args['datatype']] .. "_lvl"])
            
            tablerow
                :tag('td')
                    :attr('data-sort-value', champion)
                    :css('text-align', 'left')
                    :node(IL.champion{["champion"] = champion, ["circle"] = "true"})
                :done()
                :tag('td')
                    :wikitext(_base)
                :done()
                :tag('td')
                    :wikitext(_lvl)
                :done()
                :tag('td')
                    :wikitext((_base or 0) + (_lvl or 0) * (18 - 1) * (0.7025 + 0.0175 * (18 - 1)))
                :done()
            :done()
        end
        
        -- Add row to table
        if tablerow ~= nil then
            tablenode
                :node(tablerow)
                :newline()
        end
    end
    
    tablenode:allDone()
    
    return tostring(tablenode)
end

-- wrapper template Template:Grouped_stat_table
function p.groupedStatTable(frame)
    local args = lib.mergeArguments(frame)
    
    args['datatype'] = args['datatype'] or args[1]
    args['label']    = args['label']    or args[2]
    args['filter']   = args['filter']   or args[3]
    local wrData    = mw.loadData('Module:ChampionDataWR/data')
    local get        = require('Module:ChampionDataWR/getter')
    local IL         = require('Module:ImageLink')
    local builder    = require("Module:SimpleHTMLBuilder")
    
    local threshold3col = tonumber(args['3col']) or 12
    local threshold2col = tonumber(args['2col']) or 8
    
    local statTable = {}
    -- standard entries with note
    for champion in pairs(wrData) do
        -- filter
        local releasedate = get["date"](champion)
        if  releasedate== "Upcoming" or 
            releasedate == "N/A" or
            releasedate == "Cancelled" or
            releasedate == "" then
            --ignore champion
        elseif args['datatype'] == 'range' and get['rangetype'](champion) ~= args['filter'] then -- do nothing
        elseif args[champion .. '_o'] then -- do nothing 
        else
            local v = get[args['datatype']](champion)
            if v == nil then
            else
                if statTable[v] == nil then statTable[v] = {} end
                local displaystring = {tostring(IL.champion{
                    ["champion"] = champion,
                    -- ["circle"] = "true",
                })}
                if args[champion .. '_m'] then
                    displaystring[#displaystring + 1] = ' '
                    displaystring[#displaystring + 1] = args[champion .. '_m']
                end
                if args[champion .. '_n'] then
                    displaystring[#displaystring + 1] = ' <span title="'
                    displaystring[#displaystring + 1] = args[champion .. '_n']
                    displaystring[#displaystring + 1] = '"><sup>note</sup></span>'
                end
                statTable[v][champion] = table.concat(displaystring)
            end
        end
    end
    -- custom/manual entries
    local function customparams_iter(t)
        local i = 0
        local n = 0
        for i, _ in pairs(t) do
            n = n + 1
        end
        return function ()
            i = i + 1
            if i <= n and (t['c' .. i .. 'c'] or t['c' .. i .. 'm']) and t['c' .. i .. 'v'] then
                return t['c' .. i .. 'c'] or '', t['c' .. i .. 'm'] or '', t['c' .. i ..'n'] or '', t['c' .. i .. 'v']
            else
                return nil
            end
        end
    end
    for champion, modifier, note, value in customparams_iter(args) do
        local v = tonumber(value)
        local displaystring = {}
        if champion ~= '' then
            displaystring[#displaystring + 1] = tostring(IL.champion{
                ["champion"] = champion,
                -- ["circle"] = "true",
            })
        end
        if modifier ~= '' then
            if champion ~= '' then
            	displaystring[#displaystring + 1] = ' '
            end
            displaystring[#displaystring + 1] = modifier
        end
        if note ~= '' then
            displaystring[#displaystring + 1] = '  <span title="'
            displaystring[#displaystring + 1] = note
            displaystring[#displaystring + 1] = '"><sup>note</sup></span>'
        end
        if statTable[v] == nil then statTable[v] = {} end
        if champion ~= '' then 
            statTable[v][champion] = table.concat(displaystring)
        else
            statTable[v][modifier] = table.concat(displaystring)
        end
    end
    
    -- table header row
    local tablenode = builder.create('table')
    tablenode
        :addClass('wikitable')
        :css('width', '100%')
        :newline()
    tablenode
        :tag('tr')
            :tag('th')
                :wikitext(args['label'] or args['datatype'])
            :done()
            :tag('th')
                :wikitext('Champion')
            :done()
            -- :tag('th')
            --     :wikitext('Notes')
            -- :done()
        :done()
        :newline()
    
    -- sorting and table rows
    local optionTable = {}
    for option in pairs(statTable) do
        table.insert(optionTable, option)
    end
    table.sort(optionTable, function(a,b) return a > b end)
    for _, option in ipairs(optionTable) do
        local tablerow = builder.create('tr')
        local champcell = tablerow
            :tag('td')
                :css('text-align', 'center')
        if option == tonumber('inf') then
            champcell:wikitext('∞')
        else
            champcell:wikitext(option)
        end
        champcell = champcell
            :done()
            :newline()
            :tag('td')
                :tag('div')
                    :addClass('columntemplate')
                    :css('margin','0.4em 0 0.4em 0')
        local championTable = {}
        for champion in pairs(statTable[option]) do
            table.insert(championTable, champion)
        end
        table.sort(championTable)
        if #championTable >= threshold3col then
            champcell
                :css('column-count', 3)
                :css('-webkit-column-count', 3)
                :css('-moz-column-count', 3)
        elseif #championTable >= threshold2col then
            champcell
                :css('column-count', 2)
                :css('-webkit-column-count', 2)
                :css('-moz-column-count', 2)
        end
        champcell = champcell
                    :tag('ul')
        for _, champion in ipairs(championTable) do
            champcell
                :tag('li')
                    :wikitext(statTable[option][champion])
                    :newline()
        end
        tablenode
            :node(tablerow)
            :newline()
    end
    return tostring(tablenode)
end

-- wrapper template Template:List_of_champion_abilities
function p.abilitiesList(frame)
    local args = lib.mergeArguments(frame)
    local wrData   = mw.loadData('Module:ChampionDataWR/data')
    local IL        = require('Module:ImageLink')
    local builder    = require("Module:SimpleHTMLBuilder")
 
    local param = args[1] or args['parameter'] or nil
    local value = args[2] or args['value'] or ''
    local compare = args['compare'] or nil
    local ignorecase = args['noignorecase'] ~= 'true'
    if value and ignorecase then value = string.lower(value) end
    local outformat = args['format'] or args['output'] or nil
    local paramDisplayName = args['label'] or nil
    local edit = args['edit'] == 'true'
    
    local ret = ""
    if outformat == 'bullet' or outformat == 'combinedbullet' then
    	ret = builder.create('ul')
    elseif outformat == 'table' then
        ret = builder.create('table')
        ret
            :addClass('sortable wikitable sticky-header')
            :css('width', '100%')
            --:css('text-align', 'right')
            :css('white-space', 'nowrap')
            :newline()
        local temp = ret
            :tag('tr')
                :tag('th')
                    :wikitext('Champion')
                    --:css('width', '180px')
                    --:attr('class', 'unsortable')
                :done()
                :tag('th')
                    :wikitext('Ability')
                    --:attr('class', 'unsortable')
                :done()
        if param then
        	temp
	    		:tag('th')
	                :wikitext(paramDisplayName or param)
	            :done()
        end
        temp
            :done()
            :newline()
    end
    local sortedChamps = {}
    for champname in pairs(wrData) do
        local release = wrData[champname]["date"]
        if release == "Upcoming"
        or release == "N/A"
        or release == "Cancelled"
        or release == ""
        then
            --ignore champion
            --skip
        else
            table.insert(sortedChamps, champname)
        end
    end
    table.sort(sortedChamps)
    for _, champname in ipairs(sortedChamps) do
        local abilities = wrData[champname]["skills"]
        local count = 0
        local matched = {}
        local dataprobes = {}
        if param then
            for _, ability in ipairs(abilities) do
                local probe = mw.text.trim(frame:expandTemplate{title = "Data_" .. champname .. "/" .. ability, args = {"pst2", param}})
                dataprobes[ability] = probe
                if ignorecase then probe = string.lower(probe) end
                if (not compare or compare == "equals" and probe == value)
                or compare == "not equals" and probe ~= value
                or compare == "exists" and probe ~= "{{{" .. param .. "}}}"
                or compare == "exists and not empty" and (probe ~= "{{{" .. param .. "}}}" and probe ~= "")
                or compare == "exists and not equals" and (probe ~= "{{{" .. param .. "}}}" and probe ~= value)
                or compare == "exists and not empty and not equals" and (probe ~= "{{{" .. param .. "}}}" and probe ~= "" and probe ~= value)
                or compare == "exists and not empty and not contains" and (probe ~= "{{{" .. param .. "}}}" and probe ~= "" and not string.find(probe, value))
                or compare == "contains" and string.find(probe, value)
                then
                    count = count + 1
                    table.insert(matched, ability)
                end
            end
        else
            matched = abilities
            for _, ability in ipairs(abilities) do
                count = count + 1
            end
        end
        -- output
        if outformat == 'bullet' then
            for _, ability in ipairs(matched) do
            	local item = ret:tag('li')
                if edit then
                    item
                    	:node(IL.champion{['champion'] = champname, ['possessive'] = 'true'})
                    	:wikitext(" ")
                    	:node(IL.ability{['champion'] = champname, ['ability'] = ability, ['edit'] = 'true'})
                    :done()
                    :newline()
                else
                    item
                    	:node(IL.champion{['champion'] = champname, ['possessive'] = 'true'})
                    	:wikitext(" ")
                    	:node(IL.ability{['champion'] = champname, ['ability'] = ability})
                    :done()
                    :newline()
                end
            end
        elseif outformat == 'combinedbullet' then
            if count > 0 then
            	local item = ret:tag('li')
                item
                	:node(IL.champion{['champion'] = champname, ['possessive'] = 'true'})
                	:wikitext(" ")
                if count == 1 then
                    for i, ability in ipairs(matched) do
                        if edit then
                            item:node(IL.ability{['champion'] = champname, ['ability'] = ability, ['edit'] = 'true'})
                        else
                            item:node(IL.ability{['champion'] = champname, ['ability'] = ability})
                        end
                    end
                elseif count == 2 then
                    for i, ability in ipairs(matched) do
                        if edit then
                            item:node(IL.ability{['champion'] = champname, ['ability'] = ability, ['edit'] = 'true'})
                        else
                            item:node(IL.ability{['champion'] = champname, ['ability'] = ability})
                        end
                        if i == count - 1 then
                            item:wikitext(" and ")
                        end
                    end
                else
                    for i, ability in ipairs(matched) do
                        if edit then
                            item:node(IL.ability{['champion'] = champname, ['ability'] = ability, ['edit'] = 'true'})
                        else
                            item:node(IL.ability{['champion'] = champname, ['ability'] = ability})
                        end
                        if i < count then
                            item:wikitext(", ")
                        end
                        if i == count - 1 then
                            item:wikitext("and ")
                        end
                    end
                end
                ret
                	:newline()
            end
        elseif outformat == 'table' then
            for i, ability in ipairs(matched) do
                local tablerow = builder.create('tr')
                if i == 1 then
                    tablerow
                        :tag('td')
                            :node(IL.champion{['champion'] = champname})
                            :attr('data-sort-value', champname)
                            :attr('rowspan', count)
                        :done()
                end
                
                if edit then
                    tablerow
                        :tag('td')
                            :node(IL.ability{['champion'] = champname, ['ability'] = ability, ['edit'] = 'true'})
                            :attr('data-sort-value', i)
                        :done()
                else
                    tablerow
                        :tag('td')
                            :node(IL.ability{['champion'] = champname, ['ability'] = ability})
                            :attr('data-sort-value', i)
                        :done()
                end
                if param then
	                local probe = dataprobes[ability]
	                tablerow
	                    :tag('td')
	                        :wikitext(probe)
	                        :attr('data-sort-value', probe)
	                    :done()
	                :done()
	            end
                ret
                    :node(tablerow)
                    :newline()
            end
        else
            for _, ability in ipairs(matched) do
                ret = ret .. "* " .. champname .. " " .. ability .. "\n"
            end
        end
    end
    return tostring(ret)
end


function p.abilityverify(frame)
	local args = lib.frameArguments(frame)
	local cd = mw.loadData('Module:ChampionDataWR/data')
    local search_ability = args[1] or args['ability'] or ''
    local search_champion = args[2] or args['champion'] or ''
    
    search_champion = lib.validateName(search_champion)
    

	local v = cd[search_champion]
	local spells = {}
	
	for i,j in pairs(v.skill_i) do spells[#spells+1] = j end
	for i,j in pairs(v.skill_1) do spells[#spells+1] = j end
	for i,j in pairs(v.skill_2) do spells[#spells+1] = j end
	for i,j in pairs(v.skill_3) do spells[#spells+1] = j end
	for i,j in pairs(v.skill_4) do spells[#spells+1] = j end
	for i,j in pairs(v.skills) do spells[#spells+1] = j end

	for a,b in pairs(spells) do
		if search_ability:find(b, 1, true) then -- Necessary for enumerated abilites (e.g. Fiddlesticks A Harmless Scarecrow 2) to work | find(string, 1, true) is scuffed, but necessary cuz it otherwise struggles with hyphens (-)
			return true
		end
	end
	return false
end

function p.filenametochampion(frame)
	local args = lib.frameArguments(frame)
	local cd_load = mw.loadData('Module:ChampionDataWR/data')
    local searchstr = args[1] or ''
    local cd = {"Ao Shin", "Avasha", "Averdrian", "CeeCee", "Cyborg Cowboy", "Eagle Rider", "Gavid", "Iron Engineer", "Ivan", "Omen", "Priscilla", "Rob Blackblade", "Seth", "Tabu", "Tiki", "Well"}--removed champs
    for champ,_ in pairs(cd_load) do cd[#cd+1] = champ end

	for _, champ_in_data in ipairs(cd) do --k is championname
		if champ_in_data == "Nunu & Willump" then
			champ_in_data = "Nunu"
		end

		if searchstr:find(champ_in_data.." ") then
			return champ_in_data
		end
	end
	return "Error: No champion found!"
end


-- JSON to Lua function for data from
-- http://ddragon.leagueoflegends.com/cdn/<patchversion>/data/en_US/champion.json

return p
-- </pre>
-- [[Category:Lua]]