Module:SkinData

-- local p = {}

local skinData = mw.loadData('Module:SkinData/data') local lib      = require('Module:Feature') local color    = require('Module:Color') local FN       = require('Module:Filename') local IL       = require('Module:ImageLink') local userError = require('Dev:User error')

function p.skinscount local s          = "" local resulttable = {} local prices     = {} local limited    = 0 local rare       = 0 local total      = 0 local cost       = 0

for championname in pairs(skinData) do       local t = skinData[championname]["skins"] for skinname in pairs(t) do           if skinname ~= "Original" and t[skinname]["id"] ~= nil and t[skinname]["release"] ~= "N/A" then if t[skinname]["availability"] == "Limited" then limited = limited + 1 total  = total   + 1 else local price = t[skinname]["cost"] if price == 10 or price == 100 or price == "special" then price = 2450 end if                        (t[skinname]["availability"] == "Rare" and price ~= 2450) or                       (skinname == "Neo PAX" and championname == "Sivir") or                       (skinname == "Dark Star" and championname == "Cho'Gath") then rare = rare  + 1 total = total + 1 else if resulttable[price] == nil then resulttable[price] = 0 table.insert(prices, price) end resulttable[price] = resulttable[price] + 1 total = total + 1 cost = cost + price end end end end end table.sort(prices) s = ' ' s = s .. 'Total: ' .. total ..' skins (Total: ' .. cost .. ' RP)' return s end

function p.splashartistpage local searchstring = mw.title.getCurrentTitle.text

local championtable = {} for championname in pairs(skinData) do       table.insert(championtable, championname) end table.sort(championtable)

local resulttable = {} for _, championname in pairs(championtable) do       local skintable  = {} for championname in pairs(skinData[championname]["skins"]) do           table.insert(skintable, championname) end table.sort(skintable)

for _, skinname in pairs(skintable) do           local t = skinData[championname]["skins"][skinname] if t.splashartist ~= nil then for _, splashartistname in pairs(t.splashartist) do                   if splashartistname == searchstring then table.insert(resulttable, {championname, skinname, t.formatname, t.splashartist}) end end end end end if #resulttable == 0 then return userError("No results for " .. searchstring, "LuaError") end -- Three random images of work examples math.randomseed(os.time) local hash = {} local rnd = 0 local s1  = "" for i = 1, 3 do       rnd = math.random(#resulttable) if hash[rnd] ~= true then s1 = s1 .. ""       end hash[rnd] = true end -- Splash Art list local s2 = "Splash Art" local tempval = "" for i, val in pairs(resulttable) do       local championname = val[1] local skinname    = val[2] local formatname  = val[3] local splashartist = val[4] if tempval == championname then s2 = s2 .. ", "       else if i ~= 1 then s2 = s2 .. "" end tempval = championname end s2 = s2 .. tostring(IL.skin{           ["champion"] = championname,            ["skin"] = skinname,            ["link"] = championname .. "/Skins",            ["text"] = lib.ternary(formatname, formatname, skinname .. " " .. championname),           ["circle"] = "true"        }) count = 0 for i, val in pairs (splashartist) do           if val ~= searchstring then if count == 0 then s2 = s2 .. " (Collaboration with "               else                    s2 = s2 .. ", "                end                s2 = s2 .. splashartist[i]                count = count + 1            end        end        if count ~= 0 then            s2 = s2 .. ") " end end s2 = s2 .. "" return s1 .. s2 end

function p.chromapartner(frame) local s = '' s = s .. ' '   s = s .. 'Partner Program Chromas' s = s .. '  '    local championtable = {} for x in pairs(skinData) do       table.insert(championtable, x)    end table.sort(championtable) local resulttable = {} for _, championname in pairs(championtable) do       local skintable  = {} for championname in pairs(skinData[championname]["skins"]) do           table.insert(skintable, championname) end table.sort(skintable) for _, skinname in pairs(skintable) do           local chromatable = {} local t          = skinData[championname]["skins"][skinname] local formatname = t.formatname if t.chromas ~= nil then t = t.chromas for chromaname in pairs(t) do                   if t[chromaname].distribution == "Partner Program" then s = s .. '   ' .. lib.ternary(formatname, formatname, skinname .. ' ' .. championname) .. '  ' end end end end end s = s .. ' '   return s end

function p.chromagallery(frame) local args; if frame.args == nil then args = lib.arguments(frame) else args = lib.arguments(frame.args) end local t = skinData[args[1]].skins[args[2] or "Original"] if t == nil or t.chromas == nil then return userError("No chromas specified for skin " .. args[2] .. " in Module:SkinData/data", "LuaError") end t = t.chromas local header = "Chromas" local frame = mw.getCurrentFrame if skinData[args[1]].skins[args[2] or "Original"].forms ~= nil then header = "forms" end local chromatable = {} local chromastring = args['chromas'] or "true" if chromastring == "true" then for chromaname in pairs(t) do           table.insert(chromatable, chromaname) end else chromatable = mw.text.split(chromastring, ",") end table.sort(chromatable) local champname = args[1] local skinname  = args[2] or "Original" local formatname = skinData[champname].skins[skinname].formatname local key       = args["key"] or "true" local imagewidth = "100px" local s = '' s = s .. '  .. lib.ternary(formatname, formatname, skinname .. " " .. champname) .. " " .. header .. "'''"   if key == "true" then s = s .. " " end if #chromatable > 8 then imagewidth = "80px" s = s .. ' '   else s = s .. ' '   end s = s .. ' '    for i, chromaname in pairs(chromatable) do        if skinData[champname].skins[skinname].chromas[chromaname] == nil then return userError("Chroma " .. chromaname .. " not specified in Module:SkinData/data for " .. lib.ternary(formatname, formatname, skinname .. " " .. champname), "LuaError") end local availability = skinData[champname].skins[skinname].chromas[chromaname].availability or "Available" if availability ~= "Canceled" then s = s .. "  " .. chromaname .. " "        end end s = s .. ' '   return frame:preprocess(s) end

function p.skinpage(frame) local args; if frame.args == nil then args = lib.arguments(frame) else args = lib.arguments(frame.args) end local champname = args[1] or mw.title.getCurrentTitle.rootText if skinData[champname] == nil then return userError("Champion " .. champname .. " does not exist in Module:SkinData/data", "LuaError") end local t = skinData[champname]["skins"] local availabletable = {} local legacytable   = {} local limitedtable  = {} local upcomingtable = {} local canceledtable = {}

for skinname in pairs(t) do       if t[skinname].availability == "Available" then table.insert(availabletable, {skinname, t[skinname]}) end if t[skinname].availability == "Legacy" then table.insert(legacytable,   {skinname, t[skinname]}) end if t[skinname].availability == "Limited" or t[skinname].availability == "Rare" then table.insert(limitedtable,  {skinname, t[skinname]}) end if t[skinname].availability == "Upcoming" then table.insert(upcomingtable, {skinname, t[skinname]}) end if t[skinname].availability == "Canceled" then table.insert(canceledtable, {skinname, t[skinname]}) end end

function skinitem(data) local lang = mw.language.new("en") local skinname    = data[1] local formatname  = data[2].formatname or skinname .. ' ' .. champname local champid     = skinData[champname]["id"] local skinid      = data[2].id        local cost         = data[2].cost local release     = data[2].release local distribution = data[2].distribution if release ~= "N/A" then release = lang:formatDate("d-M-Y", data[2].release) end

local s = "" s = s .. '   ' .. formatname if skinid ~= nil then standardizedname = string.lower(champname:gsub("[' ]", "")) if standardizedname == "wukong" then standardizedname = "monkeyking" end teemogg_skinid = standardizedname .. '-' .. skinid s = s .. ' [https://teemo.gg/model-viewer?model-type=champions&skinid=' .. teemogg_skinid .. ' View in 3D ] ' end s = s .. ' '       if cost == 'N/A' then -- skip elseif cost == 150000 then s = s .. tostring(IL.basic{["link"] = "Blue Essence", ["text"] = cost, ["alttext"] = cost .. " Blue Essence", ["image"] = "BE icon.png", ["border"] = "false", ["labellink"] = "false"}) .. ' / '        elseif cost == 100 then s = s .. tostring(IL.basic{["link"] = "Prestige point", ["text"] = cost, ["alttext"] = cost .. " Prestige Points", ["image"] = "Hextech Crafting Prestige token.png", ["border"] = "false", ["labellink"] = "false"}) .. ' / '        elseif cost == 10 then s = s .. tostring(IL.basic{["link"] = "Gemstone", ["text"] = cost, ["alttext"] = cost .. " Rare Gems", ["image"] = "Rare Gem.png", ["border"] = "false", ["labellink"] = "false"}) .. ' / '        elseif cost == "special" then s = s .. "Special pricing" .. ' / '        else s = s .. tostring(IL.basic{["link"] = "Riot Points", ["text"] = cost, ["alttext"] = cost .. " RP", ["image"] = "RP icon.png", ["border"] = "false", ["labellink"] = "false"}) .. ' / '        end s = s .. lib.ternary(release == 'N/A', 'N/A', release) .. '   '

return s   end

function chroma(chromatable) s = "" if #chromatable > 0 then for i in ipairs(chromatable) do               s = s .. ' ' .. p.chromagallery{champname, chromatable[i]} end end return s   end function comp(a, b)       local a = a[2].id or -1 local b = b[2].id or -1 if a < b then return true end end local skintable = { {availabletable, text = 'Available'}, {legacytable,   text = 'Legacy Vault'}, {limitedtable,  text = 'Rare & Limited'}, {upcomingtable, text = 'Upcoming'}, {canceledtable, text = 'Canceled'} }   local s = '' for i, value in ipairs(skintable) do       table.sort(skintable[i][1], comp) local chromatable = {} if #value[1] > 0 then s = s .. (' \n==' .. value.text .. '==\n ') for i in pairs(value[1]) do               s = s .. skinitem(value[1][i]) if value[1][i][2].chromas then table.insert(chromatable, value[1][i][1]) end end s = s .. ' '           table.sort(chromatable) s = s .. chroma(chromatable) end end s = s .. ' '   return s end

function p.getAllchampionskins(frame) local args; if frame.args == nil then args = lib.arguments(frame) else args = lib.arguments(frame.args) end

return skinData[args[1]] end

function p.getChampionskin(frame) local args; if frame.args == nil then args = lib.arguments(frame) else args = lib.arguments(frame.args) end

return skinData[args[1]].skins[args[2] or "Original"] end

function p.getFormatname(frame) local args; if frame.args == nil then args = lib.arguments(frame) else args = lib.arguments(frame.args) end

return skinData[args[1]].skins[args[2] or "Original"].formatname end

function p.getAvailability(frame) local args; if frame.args == nil then args = lib.arguments(frame) else args = lib.arguments(frame.args) end

return skinData[args[1]].skins[args[2] or "Original"].availability end

function p.getDistribution(frame) local args; if frame.args == nil then args = lib.arguments(frame) else args = lib.arguments(frame.args) end

return skinData[args[1]].skins[args[2] or "Original"].distribution end

function p.getCost(frame) local args; if frame.args == nil then args = lib.arguments(frame) else args = lib.arguments(frame.args) end

return skinData[args[1]].skins[args[2] or "Original"].cost end

function p.getRelease(frame) local args; if frame.args == nil then args = lib.arguments(frame) else args = lib.arguments(frame.args) end

return skinData[args[1]].skins[args[2] or "Original"].release end

function p.getRetired(frame) local args; if frame.args == nil then args = lib.arguments(frame) else args = lib.arguments(frame.args) end

return skinData[args[1]].skins[args[2] or "Original"].retired end

function p.getEarlysale(frame) local args; if frame.args == nil then args = lib.arguments(frame) else args = lib.arguments(frame.args) end

return skinData[args[1]].skins[args[2] or "Original"].earlysale end

function p.getSet(frame) local args; if frame.args == nil then args = lib.arguments(frame) else args = lib.arguments(frame.args) end

local t = skinData[args[1]].skins[args[2] or "Original"].set if t == nil then return nil end for i, setname in ipairs(t) do       if i ~= 1 then s = s .. ", " .. setname:gsub("% ", " ") else s = setname end end

return s end

function p.getSetlist(frame) local championtable = {} local sets = {} local hash = {} local setList = mw.html.create('ul') setList:newline for x in pairs(skinData) do       table.insert(championtable, x)    end table.sort(championtable)

for _, championname in pairs(championtable) do       local skintable  = {} for championname in pairs(skinData[championname]["skins"]) do           table.insert(skintable, championname) end table.sort(skintable)

for _, skinname in pairs(skintable) do           local t = skinData[championname]["skins"][skinname] if t.set ~= nil then for _, value in pairs(t.set) do                   if (not hash[value]) then table.insert(sets, value) hash[value] = true end end end end end table.sort(sets) for _, setname in pairs(sets) do       setList :tag('li') :wikitext( .. setname .. ) :done :done :newline end return setList end

function p.getSetskins(frame) local args; if frame.args == nil then args = lib.arguments(frame) else args = lib.arguments(frame.args) end local skinList = mw.html.create('ul') local championtable = {} local result = false skinList:newline for x in pairs(skinData) do       table.insert(championtable, x)    end table.sort(championtable) for _, championname in pairs(championtable) do       local skintable  = {} for championname in pairs(skinData[championname]["skins"]) do           table.insert(skintable, championname) end table.sort(skintable) for _, skinname in pairs(skintable) do           local hit = false local t = skinData[championname]["skins"][skinname] if t.set ~= nil then for _, subset in pairs(t.set) do                   if subset == args[1] then hit = true result = true end end end if hit == true then skinList :tag('li') :tag('div') :addClass('skin-icon') :attr('data-champion', championname) :attr('data-skin', skinname) :wikitext(' ' .. lib.ternary(t["formatname"] ~= nil, t["formatname"], skinname .. " " .. championname) .. '') :done :done :newline end end end

if result == false then skinList :tag('li') :wikitext('No match found for ' .. args[1] .. '.') :done :newline end return skinList end

function p.getNeweffects(frame) local args; if frame.args == nil then args = lib.arguments(frame) else args = lib.arguments(frame.args) end

return skinData[args[1]].skins[args[2] or "Original"].neweffects end

function p.getNewrecall(frame) local args; if frame.args == nil then args = lib.arguments(frame) else args = lib.arguments(frame.args) end

return skinData[args[1]].skins[args[2] or "Original"].newrecall end

function p.getNewanimations(frame) local args; if frame.args == nil then args = lib.arguments(frame) else args = lib.arguments(frame.args) end

return skinData[args[1]].skins[args[2] or "Original"].newanimations end

function p.getTransforming(frame) local args; if frame.args == nil then args = lib.arguments(frame) else args = lib.arguments(frame.args) end

return skinData[args[1]].skins[args[2] or "Original"].transforming end

function p.getFilter(frame) local args; if frame.args == nil then args = lib.arguments(frame) else args = lib.arguments(frame.args) end

return skinData[args[1]].skins[args[2] or "Original"].filter end

function p.getNewquotes(frame) local args; if frame.args == nil then args = lib.arguments(frame) else args = lib.arguments(frame.args) end

return skinData[args[1]].skins[args[2] or "Original"].newquotes end

function p.getNewvoice(frame) local args; if frame.args == nil then args = lib.arguments(frame) else args = lib.arguments(frame.args) end

return skinData[args[1]].skins[args[2] or "Original"].newvoice end

function p.getExtras(frame) local args; if frame.args == nil then args = lib.arguments(frame) else args = lib.arguments(frame.args) end

return skinData[args[1]].skins[args[2] or "Original"].extras end

function p.getLore(frame) local args; if frame.args == nil then args = lib.arguments(frame) else args = lib.arguments(frame.args) end

return skinData[args[1]].skins[args[2] or "Original"].lore end

function p.getLootEligible(frame) local args; if frame.args == nil then args = lib.arguments(frame) else args = lib.arguments(frame.args) end

return skinData[args[1]].skins[args[2] or "Original"].looteligible end

function p.getChromas(frame) local args; if frame.args == nil then args = lib.arguments(frame) else args = lib.arguments(frame.args) end

return skinData[args[1]].skins[args[2] or "Original"].chromas end

function p.getChromacount(frame) local args; if frame.args == nil then args = lib.arguments(frame) else args = lib.arguments(frame.args) end local t = skinData[args[1]].skins[args[2] or "Original"].chromas local s = "" local chromatable = {} for chromaname in pairs(t) do       table.insert(chromatable, chromaname) end return #chromatable or "N/A" end

function p.getChromanames(frame) local args; if frame.args == nil then args = lib.arguments(frame) else args = lib.arguments(frame.args) end local t = skinData[args[1]].skins[args[2] or "Original"] if t == nil or t.chromas == nil then return "" end t = t.chromas local chromatable = {} for chromaname in pairs(t) do       table.insert(chromatable, chromaname) end table.sort(chromatable)

local s = "" for i, chromaname in pairs(chromatable) do       if i ~= 1 then s = s .. ", " .. chromaname else s = s .. chromaname end end return s end

function p.getForms(frame) local args; if frame.args == nil then args = lib.arguments(frame) else args = lib.arguments(frame.args) end

return skinData[args[1]].skins[args[2] or "Original"].forms end

function p.getFormnames(frame) local args; if frame.args == nil then args = lib.arguments(frame) else args = lib.arguments(frame.args) end local t = skinData[args[1]].skins[args[2] or "Original"].forms local s = "" local formtable = {} for formname in pairs(t) do       table.insert(formtable, formname) end table.sort(formtable)

for i, formname in pairs(formtable) do       if i ~= 1 then s = s .. ", " .. formname else s = s .. formname end end return s end

function p.getFormicon(frame) local args; if frame.args == nil then args = lib.arguments(frame) else args = lib.arguments(frame.args) end

return skinData[args[1]].skins[args[2] or "Original"].formicon end

function p.getVu(frame) local args; if frame.args == nil then args = lib.arguments(frame) else args = lib.arguments(frame.args) end

return skinData[args[1]].skins[args[2] or "Original"].vu end

function p.getSplashartist(frame) local args; if frame.args == nil then args = lib.arguments(frame) else args = lib.arguments(frame.args) end local t = skinData[args[1]].skins[args[2] or "Original"].splashartist local s = "" if t == nil then return "Unknown artist" end for i, splashartistname in ipairs(t) do       if i ~= 1 then s = s .. ", " .. splashartistname:gsub("% ", " ") else s = splashartistname end end return s end

function p.getArtistlist(frame) local championtable = {} local artists = {} local hash = {} local artistList = mw.html.create('ul') artistList:newline for x in pairs(skinData) do       table.insert(championtable, x)    end table.sort(championtable)

for _, championname in pairs(championtable) do       local skintable  = {} for championname in pairs(skinData[championname]["skins"]) do           table.insert(skintable, championname) end table.sort(skintable)

for _, skinname in pairs(skintable) do           local t = skinData[championname]["skins"][skinname] if t.splashartist ~= nil then for _, value in pairs(t.splashartist) do                   if (not hash[value]) then table.insert(artists, value) hash[value] = true end end end end end table.sort(artists) for _, artist in pairs(artists) do       artistList :tag('li') :wikitext( .. artist .. ) :done :done :newline end return artistList end

function p.getVariant(frame) local args; if frame.args == nil then args = lib.arguments(frame) else args = lib.arguments(frame.args) end local searchid = skinData[args[1]].skins[args[2] or "Original"].variant local skintable = {} if searchid == nil then return nil end for skinname, data in pairs(skinData[args[1]]["skins"]) do       if data.id == searchid then return skinname end end

return nil end

function p.getVoiceactor(frame) local args; if frame.args == nil then args = lib.arguments(frame) else args = lib.arguments(frame.args) end local t = skinData[args[1]].skins[args[2] or "Original"].voiceactor local s = "" if t == nil then return "Unknown voice actor" end for i, voiceactorname in ipairs(t) do       if i ~= 1 then s = s .. ", " .. voiceactorname:gsub("% ", " ") else s = voiceactorname end end

return s end

function p.skinlist(frame) local lang = mw.language.new( "en" ) local sdtable = mw.html.create('table') sdtable :addClass('sortable article-table nopadding sticky-header') :css('width','100%') :css('text-align','center') :newline :tag('tr') :tag('th') :css('width','26px') :done :newline :tag('th') :wikitext('Skin') :done :newline :tag('th') :tag('span') :attr('title','Availability') :wikitext('') :done :done :newline :tag('th') :tag('span') :attr('title','Release') :wikitext('') :done :done :newline :tag('th') :tag('span') :attr('title','Cost') :wikitext('') :done :done :newline :tag('th') :css('width','40px') :tag('span') :attr('title','Voice filter') :wikitext('') :done :done :newline :tag('th') :css('width','40px') :tag('span') :attr('title','Additional/unique quotes') :wikitext('') :done :done :newline :tag('th') :css('width','40px') :tag('span') :attr('title','New voiceover') :wikitext('') :done :done :newline :tag('th') :css('width','40px') :tag('span') :attr('title','New visual and/or sound effects') :wikitext('') :done :done :newline :tag('th') :css('width','40px') :tag('span') :attr('title','New animations and/or new recall animation') :wikitext('') :done :done :newline :tag('th') :css('width','40px') :tag('span') :attr('title','Appearance can be toggled in-game [e.g. Ctrl + 5], or the skin "evolves" over the course of the game that is not part of the champion&#39;s base mechanics.') :wikitext('') :done :done :newline :tag('th') :css('width','40px') :tag('span') :attr('title','Part of a Collection') :wikitext('') :done :done :newline :tag('th') :css('width','40px') :tag('span') :attr('title','Features lore') :wikitext('') :done :done :newline :tag('th') :css('width','40px') :tag('div') :attr('title','Chromas') :css('width','30px') :css('height','30px') :css('padding','5px') :wikitext('') :done :done :done :newline -- START local championtable = {} for x in pairs(skinData) do           table.insert(championtable, x)        end table.sort(championtable) local availablenode = mw.html.create('span') availablenode :css('color', 'green') :css('font-size', 'x-large') :css('vertical-align', 'text-top') :wikitext("✔") local legacynode = mw.html.create('span') legacynode :css('color', 'yellow') :css('font-size', 'x-large') :css('font-weight', '600') :css('vertical-align', 'text-top') :wikitext("‒") local limitednode = mw.html.create('span') limitednode :css('color', 'red') :css('font-size', 'x-large') :css('vertical-align', 'text-top') :wikitext("✘") local rarenode = mw.html.create('span') rarenode :css('color', 'orange') :css('font-size', 'x-large') :css('vertical-align', 'text-top') :wikitext("⭐") for _, championname in pairs(championtable) do           local skintable  = {} for championname in pairs(skinData[championname]["skins"]) do               table.insert(skintable, championname) end table.sort(skintable) for _, skinname in pairs(skintable) do               if (                    championname == "Akali"      and skinname == "Crimson"                     or                     championname == "Amumu"      and skinname == "Sewn Chaos"                    or                    championname == "Blitzcrank" and skinname == "Sewn Chaos"                    or                    championname == "Ryze"       and skinname == "Human"                ) then -- skip else local t = skinData[championname]["skins"][skinname] local sdnode = mw.html.create('tr') local temp = "" -- Skincircle if (skinname == "Original") then temp = "!" .. t["release"] else temp = t["release"] end sdnode :tag('td') :addClass('champion-icon') :attr('data-sort-value', championname .. temp) :attr('data-champion', championname) :attr('data-skin', skinname) :wikitext('') :done -- Skinname sdnode :tag('td') :addClass('skin-icon') :attr('data-champion', championname) :attr('data-skin', skinname) :css('text-align', 'left') :wikitext(lib.ternary(t["formatname"] ~= nil, t["formatname"], skinname .. " " .. championname)) :done -- Availability astring = ' ⭘ ' if (t["availability"] == "Available") then astring = tostring(availablenode) end if (t["availability"] == "Legacy") then astring = tostring(legacynode) end if (t["availability"] == "Limited") then astring = tostring(limitednode) end if (t["availability"] == "Rare") then astring = tostring(rarenode) end sdnode :tag('td') :tag('span') :attr('title', t["availability"] or 'Upcoming') :wikitext(astring) :done -- Release local y, m, d = t["release"]:match("(%d+)-(%d+)-(%d+)") if y == nil or m == nil or d == nil then sdnode :tag('td') :attr('data-sort-value', t["release"]) :wikitext(t["release"]) :done else sdnode :tag('td') :attr('data-sort-value', t["release"]) :wikitext(lang:formatDate('d-M-Y', t["release"])) :done end -- Cost local image = "" if (tostring(t["cost"]) == "150000") then image = "" end if (tostring(t["cost"]) == "100") then image = "" end if (tostring(t["cost"]) == "10") then image = "" end sdnode :tag('td') :attr('data-sort-value', lib.ternary(tostring(t["cost"]) == "10" or tostring(t["cost"]) == "100", "2450", t["cost"])) :tag('span') :css('color', color.skin({t["cost"] .. ""}))                               :wikitext(image .. t["cost"]) :done :done -- Filter sdnode :tag('td') :attr('data-sort-value', lib.ternary(type(t["filter"]) ~= "nil", 1, 0)) :wikitext(lib.ternary(type(t["filter"]) ~= "nil", tostring(availablenode), "")) :done -- Newquotes sdnode :tag('td') :attr('data-sort-value', lib.ternary(type(t["newquotes"]) ~= "nil", 1, 0)) :wikitext(lib.ternary(type(t["newquotes"]) ~= "nil", tostring(availablenode), "")) :done -- Newvoice sdnode :tag('td') :attr('data-sort-value', lib.ternary(type(t["newvoice"]) ~= "nil", 1, 0)) :wikitext(lib.ternary(type(t["newvoice"]) ~= "nil", tostring(availablenode), "")) :done -- Neweffects sdnode :tag('td') :attr('data-sort-value', lib.ternary(type(t["neweffects"]) ~= "nil", 1, 0)) :wikitext(lib.ternary(type(t["neweffects"]) ~= "nil", tostring(availablenode), "")) :done -- Newanimations sdnode :tag('td') :attr('data-sort-value', lib.ternary(type(t["newanimations"]) ~= "nil", 1, 0)) :wikitext(lib.ternary(type(t["newanimations"]) ~= "nil", tostring(availablenode), "")) :done -- Transforming sdnode :tag('td') :attr('data-sort-value', lib.ternary(type(t["transforming"]) ~= "nil", 1, 0)) :wikitext(lib.ternary(type(t["transforming"]) ~= "nil", tostring(availablenode), "")) :done -- Set local multiset = false if (type(t["set"]) ~= "nil") then local s = "" for i, setname in pairs(t["set"]) do                           if i == 1 then s = setname else multiset = true s = s .. ", " .. setname end end if multiset == true then sdnode :tag('td') :attr('data-sort-value', '1 Multiple') :tag('span') :attr('title', s)                                       :wikitext(tostring(availablenode)) :done :done else sdnode :tag('td') :attr('data-sort-value', s)                                   :tag('span') :attr('title', s)                                       :wikitext(tostring(availablenode)) :done :done end else sdnode :tag('td') :attr('data-sort-value', 0) :done end -- Transforming sdnode :tag('td') :attr('data-sort-value', lib.ternary(type(t["lore"]) ~= "nil", 1, 0)) :wikitext(lib.ternary(type(t["lore"]) ~= "nil", tostring(availablenode), "")) :done -- Chromas if (type(t["chromas"]) ~= "nil") then sdnode :tag('td') :addClass('chroma-icon') :attr('data-sort-value', 1) :attr('data-champion', championname) :attr('data-skin', skinname) :wikitext(tostring(availablenode)) :done else sdnode :tag('td') :attr('data-sort-value', 0) :done end -- Add skin row to the table sdtable :newline :node(sdnode) end end end -- END sdtable:allDone return tostring(sdtable) end

function p.newestSkins(frame) local args; if frame.args == nil then args = lib.arguments(frame) else args = lib.arguments(frame.args) end

local championtable = {} local releasetable = {}

for x in pairs(skinData) do       table.insert(championtable, x)    end table.sort(championtable)

for _, championname in pairs(championtable) do       local skintable  = {} for championname in pairs(skinData[championname]["skins"]) do           table.insert(skintable, championname) end for _, skinname in pairs(skintable) do           table.insert(releasetable, {championname, skinname, skinData[championname]["skins"][skinname].release}) end end function comp(a, b)       if a[3] == "Upcoming" or b[3] == "Upcoming" then return false end if a[3] > b[3] then return true end end

table.sort(releasetable, function(a, b) return a[2] > b[2] end) table.sort(releasetable, comp) local lang = mw.language.new("en") local count = tonumber(args[1]) or 7 local s = "" for i in pairs(releasetable) do       local champ      = releasetable[i][1] local skin      = releasetable[i][2] local formatname = releasetable[i][4] local cost      = p.getCost({champ, skin}) local release   = releasetable[i][3] if release > lang:formatDate("Y-m-d") then -- skip if releasedate is in the future else if skin == "Original" then -- skip else if count >= 1 then count = count - 1 s = s .. ""               end end end end return frame:preprocess(s) end

function p.skinCatalog(frame) local dlib         = require("Dev:Datecalc") local lang         = mw.language.new( "en" ) local championtable = {} local sdtable      = mw.html.create('table') sdtable :addClass('sortable article-table novpadding hcpadding sticky-header') :css('width','100%') :css('text-align','center') :css('font-size','12px') :newline :tag('tr') :tag('th') :css('font-size','12px') :css('width','140x') :wikitext('Champion') :done :newline :tag('th') :css('font-size','12px') :attr('data-sort-type', "number") :wikitext(' Available ') :done :newline :tag('th') :css('font-size','12px') :attr('data-sort-type', "number") :wikitext(' Legacy Vault ') :done :newline :tag('th') :css('font-size','12px') :attr('data-sort-type', "number") :wikitext(' Rare ') :done :newline :tag('th') :css('font-size','12px') :attr('data-sort-type', "number") :wikitext('Unavailable') :done :newline :tag('th') :css('font-size','12px') :attr('data-sort-type', "number") :wikitext('Total') :done :newline :tag('th') :css('font-size','12px') :attr('data-sort-type', "isoDate") :wikitext('Last Skin') :done :newline :tag('th') :css('font-size','12px') :attr('data-sort-type', "number") :wikitext('Days Ago') :done :newline :done :newline for x in pairs(skinData) do       table.insert(championtable, x)    end table.sort(championtable) local availablecounttotal = 0 local legacycounttotal   = 0 local rarecounttotal     = 0 local limitedcounttotal  = 0 for _, championname in pairs(championtable) do       local t                = skinData[championname]["skins"] local availablecount  = 0 local availablecircles = "" local legacycount     = 0 local legacycircles   = "" local rarecount       = 0 local rarecircles     = "" local limitedcount    = 0 local limitedcircles  = "" local result          = {"","",""} local sdnode          = mw.html.create('tr') local border          = "" local skintable       = {} for skinname in pairs(t) do           if (                championname        == "Akali"      and skinname == "Crimson"                 or                 championname        == "Amumu"      and skinname == "Sewn Chaos"                or                championname        == "Blitzcrank" and skinname == "Sewn Chaos"                or                championname        == "Ryze"       and skinname == "Human"                or                skinname            == "Original"                or                t[skinname].release == "N/A"            ) then -- skip else table.insert(skintable, skinname) end end table.sort(skintable, function(a, b) return t[a].release < t[b].release end) for i, skinname in pairs(skintable) do           if t[skintable[i]].release == t[skintable[#skintable]].release then border = "border-radius:13px; width:26px; height:26px; box-shadow: 0 0 2px 2px #70fff2, 0 0 4px #111;" end if t[skinname].availability == "Available" then availablecount     = availablecount      + 1 availablecounttotal = availablecounttotal + 1 availablecircles = availablecircles .. '' end if t[skinname].availability == "Legacy" then legacycount        = legacycount         + 1 legacycounttotal   = legacycounttotal    + 1 legacycircles = legacycircles .. '' end if t[skinname].availability == "Rare" then rarecount          = rarecount           + 1 rarecounttotal     = rarecounttotal      + 1 rarecircles = rarecircles .. '' end if t[skinname].availability == "Limited" then limitedcount       = limitedcount        + 1 limitedcounttotal  = limitedcounttotal   + 1 limitedcircles = limitedcircles .. '' end if t[skinname].release > result[2] then result[1] = skinname result[2] = t[skinname].release result[3] = t[skinname].formatname end end sdnode :tag('td') :addClass('skin-icon') :attr('data-sort-value', championname) :attr('data-champion', championname) :attr('data-skin', "Original") :css('text-align', 'left') :wikitext(' ' .. championname) :done -- Available skins sdnode :tag('td') :addClass('icon_list') :attr('data-sort-value', availablecount) :css('text-align', 'left') :css('background-color', '#0a1827') :wikitext(availablecircles) :done -- Legacy skins sdnode :tag('td') :addClass('icon_list') :attr('data-sort-value', legacycount) :css('text-align', 'left') :wikitext(legacycircles) :done -- Rare skins sdnode :tag('td') :addClass('icon_list') :attr('data-sort-value', rarecount) :css('text-align', 'left') :css('background-color', '#0a1827') :wikitext(rarecircles) :done -- Limited skins sdnode :tag('td') :addClass('icon_list') :attr('data-sort-value', limitedcount) :css('text-align', 'left') :wikitext(limitedcircles) :done -- Total sdnode :tag('td') :css('text-align','right') :wikitext(availablecount + legacycount + rarecount + limitedcount) :done

-- Last Skin local y, m, d = result[2]:match("(%d+)-(%d+)-(%d+)") if y == nil or m == nil or d == nil then sdnode :tag('td') :addClass('skin-icon') :css('white-space', 'nowrap') :attr('data-sort-value', result[2]) :attr('data-champion', championname) :attr('data-skin', result[1]) :wikitext(result[2]) :done :tag('td') :css('text-align','right') :wikitext(result[2]) :done else sdnode :tag('td') :addClass('skin-icon') :css('white-space', 'nowrap') :attr('data-sort-value', result[2]) :attr('data-champion', championname) :attr('data-skin', result[1]) :wikitext(lang:formatDate('d-M-Y', result[2])) :done :tag('td') :css('text-align','right') :wikitext(dlib.main{"diff", lang:formatDate('Y-m-d'), result[2]}) :done end -- Add skin row to the table sdtable :newline :node(sdnode) end local sdfooter = mw.html.create('tr') sdfooter :tag('th') :css('font-size','12px') :wikitext('Total') :done :newline :tag('th') :css('font-size','12px') :wikitext(availablecounttotal) :done :newline :tag('th') :css('font-size','12px') :wikitext(legacycounttotal) :done :newline :tag('th') :css('font-size','12px') :wikitext(rarecounttotal) :done :newline :tag('th') :css('font-size','12px') :wikitext(limitedcounttotal) :done :newline :tag('th') :css('font-size','12px') :wikitext(availablecounttotal + legacycounttotal + rarecounttotal + limitedcounttotal) :done :newline :tag('th') :done :newline :tag('th') :done sdtable :newline :node(sdfooter)

return sdtable end

function p.skintooltip(frame) local args; if frame.args == nil then args = lib.arguments(frame) else args = lib.arguments(frame.args) end local championname = args["champion"] local skinname    = args["skin"] or "Original" local variant     = args["variant"] local filename    = FN.skin{championname, skinname, variant} local t           = skinData[championname]["skins"][skinname] local newrecall   = t["newrecall"] local formatname  = t["formatname"] local cost        = t["cost"] local distribution = t["distribution"] local voiceactor  = p.getVoiceactor{championname, skinname} local splashartist = p.getSplashartist{championname, skinname} local set         = p.getSet{championname, skinname} local lore        = t["lore"] local filter      = t["filter"] local newquotes   = t["newquotes"] local newvoice    = t["newvoice"] local neweffects  = t["neweffects"] --local newrecall   = t["newrecall"] local newanimations= t["newanimations"] local transforming = t["transforming"] local extras      = t["extras"] local chromas     = t["chromas"] local looteligible = t["looteligible"] local variantof   = p.getVariant{championname, skinname} local rpskins     = {[260]=true, [585]=true, [790]=true, [880]=true, [390]=true, [460]=true, [500]=true, [520]=true, [750]=true, [975]=true, [1350]=true, [1820]=true, [2775]=true, [3250]=true, [5000]=true} local s           = '' s = s .. ' '       s = s .. '<div class="skin-features" style="padding:15px 45px 15px 15px; position:absolute; bottom:16px; left:16px; background-color:RGBA(10, 24, 39, 0.75); max-width:576px;">' s = s .. ' '               s = s .. ' '                   s = s .. lib.ternary(formatname ~= nil, formatname, skinname .. ' ' .. championname) .. lib.ternary(variant ~= nil, ' (' .. tostring(variant) .. ') ', '')               s = s .. ' '                   if cost == 10 then s = s .. '&#x2011; ' .. tostring(IL.basic{link = 'Gemstone', text = cost, image = 'Rare Gem.png', alttext = cost .. ' Rare Gems}', border = "false", labellink = "false"}) elseif cost == 100 then -- Prestige: distribution string elseif rpskins[cost] == true then s = s .. '&#x2011; ' .. tostring(IL.basic{link = 'Riot Points', text = cost, image = 'RP icon.png', alttext = cost .. ' RP', border = "false", labellink = "false"}) elseif cost == 150000 then s = s .. '&#x2011; ' .. tostring(IL.basic{link = 'Blue Essence', text = cost, image = 'BE icon.png', alttext = cost .. ' BE', border = "false", labellink = "false"}) else -- default: do nothing end s = s .. lib.ternary(distribution ~= nil, ' ' .. tostring(distribution), '') .. ' '           s = s .. ' '           s = s .. ' '               s = s .. lib.ternary(voiceactor ~= nil, ' ' .. tostring(voiceactor) .. ' ', '') s = s .. lib.ternary(splashartist ~= nil, ' ' .. tostring(splashartist) .. ' ', '') s = s .. lib.ternary(set ~= nil, ' ' .. tostring(set) .. ' ', '') s = s .. lib.ternary(looteligible ~= false, ' Loot eligible ', '') s = s .. lib.ternary(looteligible == false, ' Loot ineligible ', '') s = s .. lib.ternary(lore ~= nil, ' ' .. tostring(lore) .. ' ', '') if availability or filter or newquotes or newvoice or neweffects or newanimations or transforming or extras or chromas or looteligible then s = s .. ' '               if availability == 'Limited' then s = s .. '  Limited Edition  ' elseif availability == 'Legacy' then s = s .. '  Legacy Vault  ' end s = s .. lib.ternary(filter ~= nil, '  Voice Filter  ', '') s = s .. lib.ternary(newquotes ~= nil, '  Additional Quotes  ', '') s = s .. lib.ternary(newvoice ~= nil, '  New Voice  ', '') s = s .. lib.ternary(neweffects ~= nil, '  New SFX/VFX  ', '') s = s .. lib.ternary(newanimations ~= nil, '  New Animations  ', '') s = s .. lib.ternary(transforming ~= nil, '  Transforming  ', '') s = s .. lib.ternary(extras ~= nil, '  Includes Extras  ', '') s = s .. lib.ternary(chromas ~= nil, '  Chromas  ', '') s = s .. ' '           end s = s .. lib.ternary(variantof ~= nil, ' This skin is a variant of ' .. tostring(IL.skin{champion = championname, skin = variantof, circle = "true", link = '*none*'}) .. '. ', '') s = s .. ' '   s = s .. ' '   return s end

function p.chromaList(frame) local lang = mw.language.new( "en" ) local sdtable = mw.html.create('table') sdtable :addClass('sortable article-table nopadding sticky-header') :css('width','100%') :css('text-align','center') :newline :tag('tr') :tag('th') :css('width','26px') :done :newline :tag('th') :wikitext('Skin') :done :newline :tag('th') :tag('span') :attr('title','Availability') :wikitext('') :done :done :newline :tag('th') :css('width','40px') :tag('div') :attr('title','Chromas') :css('width','30px') :css('height','30px') :css('padding','5px') :wikitext('') :done :done :newline :tag('th') :css('width','40px') :tag('div') :attr('title','Bundle Chromas') :css('width','30px') :css('height','30px') :css('padding','5px') :wikitext('') :done :done :newline :tag('th') :css('width','40px') :tag('div') :attr('title','Partner Chromas') :css('width','30px') :css('height','30px') :css('padding','5px') :wikitext('') :done :done :newline :tag('th') :css('width','40px') :tag('div') :attr('title','Loot Chromas') :css('width','30px') :css('height','30px') :css('padding','5px') :wikitext('') :done :done :newline :tag('th') :css('width','40px') :tag('div') :attr('title','Distributed Chromas') :css('width','30px') :css('height','30px') :css('padding','5px') :wikitext('') :done :done :done :newline -- START local championtable = {} for x in pairs(skinData) do           table.insert(championtable, x)        end table.sort(championtable) local availablenode = mw.html.create('span') availablenode :css('color', 'green') :css('font-size', 'x-large') :css('vertical-align', 'text-top') :wikitext("✔") local legacynode = mw.html.create('span') legacynode :css('color', 'yellow') :css('font-size', 'x-large') :css('font-weight', '600') :css('vertical-align', 'text-top') :wikitext("‒") local limitednode = mw.html.create('span') limitednode :css('color', 'red') :css('font-size', 'x-large') :css('vertical-align', 'text-top') :wikitext("✘") local rarenode = mw.html.create('span') rarenode :css('color', 'orange') :css('font-size', 'x-large') :css('vertical-align', 'text-top') :wikitext("⭐") for _, championname in pairs(championtable) do           local skintable  = {} for championname in pairs(skinData[championname]["skins"]) do               table.insert(skintable, championname) end table.sort(skintable) for _, skinname in pairs(skintable) do               if skinData[championname]["skins"][skinname]["chromas"] == nil then -- skip else local t = skinData[championname]["skins"][skinname] local sdnode = mw.html.create('tr') local temp = "" -- Skincircle if (skinname == "Original") then temp = "!" .. t["release"] else temp = t["release"] end sdnode :tag('td') :addClass('champion-icon') :attr('data-sort-value', championname .. temp) :attr('data-champion', championname) :attr('data-skin', skinname) :wikitext('') :done -- Skinname sdnode :tag('td') :addClass('skin-icon') :attr('data-champion', championname) :attr('data-skin', skinname) :css('text-align', 'left') :wikitext(lib.ternary(t["formatname"] ~= nil, t["formatname"], skinname .. " " .. championname)) :done -- Availability astring = ' ⭘ ' if (t["availability"] == "Available") then astring = tostring(availablenode) end if (t["availability"] == "Legacy") then astring = tostring(legacynode) end if (t["availability"] == "Limited") then astring = tostring(limitednode) end if (t["availability"] == "Rare") then astring = tostring(rarenode) end sdnode :tag('td') :tag('span') :attr('title', t["availability"] or 'Upcoming') :wikitext(astring) :done -- Cost local image = "" if (tostring(t["cost"]) == "150000") then image = "" end if (tostring(t["cost"]) == "100") then image = "" end if (tostring(t["cost"]) == "10") then image = "" end sdnode :tag('td') :attr('data-sort-value', lib.ternary(tostring(t["cost"]) == "10" or tostring(t["cost"]) == "100", "2450", t["cost"])) :tag('span') :css('color', color.skin({t["cost"] .. ""}))                               :wikitext(image .. t["cost"]) :done :done -- Chromas if (type(t["chromas"]) ~= "nil") then sdnode :tag('td') :addClass('chroma-icon') :attr('data-sort-value', 1) :attr('data-champion', championname) :attr('data-skin', skinname) :wikitext(tostring(availablenode)) :done else sdnode :tag('td') :attr('data-sort-value', 0) :done end -- Add skin row to the table sdtable :newline :node(sdnode) end end -- END end sdtable:allDone return tostring(sdtable) end

return p

-- --