League of Legends Wiki
Advertisement
League of Legends Wiki

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

-- <pre>
local p    = {}

local lib          = require('Module:Feature')
local IL
local sort = table.sort
local lower = string.lower
local insert = table.insert
local concat = table.concat

-- HELPER FUNCTIONS:

local function csl(champion, skin, wr)
    return tostring(IL{
            ["champion"] = champion,
            ["skin"]     = skin,
            ["link"]     = champion .. (wr ~= "true" and "/LoL/Cosmetics" or "/WR"),
            ["circle"]   = "true"
        })
end

local function jsontolua(pagename)
    return require('Module:JSON').decode(mw.title.new(pagename):getContent())
end

local function orderup(a,b)
    a = lower(a)
    b = lower(b)

    if a == 'n/a' then 
        return false 
    end

    if b == 'n/a' then 
        return true 
    end

    return b > a
end

-- getsetcategory used in Template:Image header/skin
function p.getsetcategory(frame)
    local args; if frame.args == nil then args = lib.arguments(frame) else args = lib.arguments(frame.args) end
        
    args['champion']	= args['champion']	or args[1]
    args['skin']		= args['skin']		or args[2]
    
    local skinDataModule = require('Module:SkinData')
    if skinDataModule.gameexclusive{args['champion'], args['skin']} == "wr" then
    	skinDataModule = require('Module:SkinDataWR')
    end
    
    args['theme'] = skinDataModule.getSet{['champion'] = args['champion'], ['skin'] = args['skin']}
    if args['champion'] == "Lux" and args['skin'] == "Elementalist" then args['theme'] = "Elementalist" end
    if args['champion'] == "Udyr" and args['skin'] == "Spirit Guard" then args['theme'] = "Spirit Guard" end
    if args['champion'] == "Sona" and args['skin'] == "DJ" then args['theme'] = "DJ" end
    
    args['date'] = skinDataModule.getRelease{['champion'] = args['champion'], ['skin'] = args['skin']}
    
    return p.handleThemes(args)
end

-- split up from p.getsetcategory because other modules may need it.
function p.handleThemes(frame) 
    local args; if frame.args == nil then args = lib.arguments(frame) else args = lib.arguments(frame.args) end
	
    local luauniverseData = mw.loadData('Module:SkinData/universes')
    local set_to_universe = {}
    local theme           = {args['theme']}
    local date			  = args['date']
    local s               = ""
    
	if args['theme'] then -- this line skips the whole module, if the skindata does not include any set
    	if not theme[1] then
        	theme[1] = args['theme']:gsub("&nbsp;", " ")
    	end
    
    	for universename, universedata in pairs(luauniverseData) do
        	for _, universeset in pairs(universedata) do
            	set_to_universe[universeset] = universename
        	end
    	end

		for tableindex, tabletheme in pairs (theme) do
        	s = s .. (set_to_universe[tabletheme] or tabletheme)
    	end
	
		-- correction for some special snowflakes (work in progress)
    	if     s == "High Noon Gothic"      		   then s = "High Noon"
    	elseif string.find(s, "World Champions")	   then s = "World Championship"
    	elseif s == "Victorious"					   then s = "World Championship"
    	elseif string.find(s, "Chosen")				   then s = s:gsub("Chosen", "Chosen and Forsaken")
    	elseif string.find(s, "Forsaken")			   then s = s:gsub("Forsaken", "Chosen and Forsaken")
    	elseif s == "Bilgewater"					   then s = "Bilgewater skins"
    	elseif s == "Freljord"						   then s = "Freljord skins"
    	elseif s == "Hextech skins"					   then s = "Hextech"
    	elseif string.find(s, "Warring Kingdoms")	   then s = s:gsub("Warring Kingdoms", "Lunar Revel")
    	elseif string.find(s, "Firecracker")		   then s = s:gsub("Lunar Revel: Firecracker", "Lunar Revel")
    	elseif s == "Mecha Kingdoms"				   then s = "Lunar Revel"
		elseif string.find(s, "Riot")				   then s = "Cops and Robbers"
		elseif string.find(s, "Crime City")			   then s = "Cops and Robbers"
		elseif string.find(s, "Trick%-or%-Treat")	   then s = s:gsub("Trick%-or%-Treat", "Harrowing")
		elseif string.find(s, "Zombies VS Slayers")    then s = s:gsub("Zombies VS Slayers", "Harrowing")
		elseif string.find(s, "Riftquest")  		   then s = s:gsub("Riftquest", "Rift Quest")
		elseif string.find(s, "Winter Wonder")         then s = s:gsub("Winter Wonder", "Snowdown Showdown")
		end
		if string.find(s, "Cosmic")         	   then s = s:gsub("Cosmic", "Event Horizon") end
		if string.find(s, "Dark Star")      	   then s = s:gsub("Dark Star", "Event Horizon") end
    	if string.find(s, "Star Wars") then
    		if string.find(s, "Chosen and Forsaken") then
    			s = s:gsub(", Star Wars", "")
    			s = s:gsub("Star Wars, ", "")
    		else
    			s = s:gsub("Star Wars", "Chosen and Forsaken")
    		end
    	end
   		if string.find(s, "Star Guardian Season") then
    		s = s:gsub("Star Guardian Season 1", "Star Guardian")
    		s = s:gsub("Star Guardian Season 2", "Star Guardian")
    		s = s:gsub("Star Guardian Season 3", "Star Guardian")
    		s = s:gsub("Star Guardian Season 4", "Star Guardian")
    		s = s:gsub("Star Guardian Season 5", "Star Guardian")
    	end
    	
    	-- special cases, for events
    	if string.find(s, "Harrowing") then
	    	if not (date == "N/A") then
    			local year = mw.ustring.sub(date, 1, 4)
    			s = s .. ", " .. year .. " Harrowing"
	    	end
	    elseif date == "2010-10-19" then
			s = s.. ", Harrowing, 2010 Harrowing"
		elseif date == "2011-10-19" then
			s = s.. ", Harrowing, 2011 Harrowing"
		elseif date == "2012-10-26" then
			s = s.. ", Harrowing, 2012 Harrowing"
		elseif date == "2013-10-29" then
			s = s.. ", Harrowing, 2013 Harrowing"
		elseif date == "2014-11-05" or date == "2014-10-28" then
			s = s.. ", Harrowing, 2014 Harrowing"
		elseif date == "2015-11-05" then
			s = s.. ", Harrowing, 2015 Harrowing"
		elseif date == "2016-10-19" then
			s = s.. ", Harrowing, 2016 Harrowing"
		elseif date == "2017-10-25" then
			s = s.. ", Harrowing, 2017 Harrowing"
		elseif date == "2018-10-24" then
			s = s.. ", Harrowing, 2018 Harrowing"
		elseif date == "2019-10-24" then
			s = s.. ", Harrowing, 2019 Harrowing"
		elseif date == "2020-10-22" then
			s = s.. ", Harrowing, 2020 Harrowing"
		end
		
	    if string.find(s, "Snowdown Showdown") or string.find(s, "Snowdown") then
    		s = s:gsub("Snowdown", "Snowdown Showdown")
    		s = s:gsub("Snowdown Showdown Showdown", "Snowdown Showdown")
	   	    if not (date == "N/A") then
    			local year = mw.ustring.sub(date, 1, 4)
    			s = s..", "..year .. " Snowdown Showdown"
	    	end
		elseif date == "2011-12-14" then
			s = s..", Snowdown Showdown, 2011 Snowdown Showdown"
		elseif date == "2019-12-17"  then
			s = s.. ", Snowdown Showdown, 2019 Snowdown Showdown"
		end

		if string.find(s, "Lunar Revel") then
    		if not (date == "N/A") then
    			local year = mw.ustring.sub(date, 1, 4)
    			s = s .. ", " .. year .. " Lunar Revel"
	    	end
		end
	
		if string.find(s, "Heartbreakers") or string.find(s, "Debonair") then
    		if not (date == "N/A") then
    			local year = mw.ustring.sub(date, 1, 4)
    			s = s .. ", " .. year .. " Valentines Day, Valentines Day"
	    	end
		end
	
		if string.find(s, "Pool Party") then
    	    if not (date == "N/A") then
    			local year = mw.ustring.sub(date, 1, 4)
    			s = s..", ".. year .. " Pool Party"
	    	end
		end
	
		if string.find(s, "Winter Sports") then
    		if date == "2010-02-12" then
    			s = s .. ", 2010 Winter Games Celebration"
	    	end
		end
	
		if string.find(s, "Soccer Cup") then
    		if date == "2010-06-24" then
    			s = s .. ", 2010 FIFA World Cup"
	    	elseif date == "2014-06-18" then
    			s = s .. ", 2014 FIFA World Cup"
    		elseif date == "2018-06-14" then
    			s = s .. ", 2018 FIFA World Cup"
	    	end
		end
	
		-- april fools days
		if date == "2010-03-31" then
    		s = s..", 2010 April Fools Day, April Fools Day"
		end
		if date == "2011-04-04" then
   			s = s..", 2011 April Fools Day, April Fools Day"
		end
		if date == "2012-04-01" then
    		s = s..", 2012 April Fools Day, April Fools Day"
		end
		if date == "2015-03-31" then
    		s = s..", 2015 April Fools Day, April Fools Day"
		end
		if date == "2016-03-31" then
    		s = s..", 2016 April Fools Day, April Fools Day"
		end
		if date == "2017-03-29" then
    		s = s..", 2017 April Fools Day, April Fools Day"
		end
		if date == "2018-03-29" then
    		s = s..", 2018 April Fools Day, April Fools Day"
		end
		if date == "2019-03-27" then
    		s = s..", 2019 April Fools Day, April Fools Day"
		end
		if date == "2020-04-01" then
    		s = s..", 2020 April Fools Day, April Fools Day"
		end

		if s == "" then
		else
			s = s:gsub(",", "]][[Category:")
			s = "[[Category:"..s
			s = s.."]]"
		end
	
    	return s
    end	
end

-- EXTRACTING LUA FUNCTIONS:

function p.get(frame)
    local args = (frame.args[1] and frame.args) or frame:getParent().args
    
    local wr = args["wr"]
    local luauniverseData, lualinkData, luaskinData
    
    if wr ~= "true" then
    	luauniverseData	= mw.loadData('Module:SkinData/universes')
	    lualinkData   	= mw.loadData('Module:SkinData/setlinks')
	    luaskinData		= mw.loadData('Module:SkinData/data')
		IL          	= require('Module:ImageLink').skin
	else
		luauniverseData	= mw.loadData('Module:SkinDataWR/universes')
	    lualinkData   	= mw.loadData('Module:SkinDataWR/setlinks')
	    luaskinData		= mw.loadData('Module:SkinDataWR/data')
	    IL          	= require('Module:ImageLink').WRskin
    end

    local exclude       	= lib.validateName(args[2] or nil)
    local set_to_universe	= {}
    local theme         	= {args[1] or nil}
    local len_theme         = #theme
    local pairs = pairs
    
    for universename, universedata in pairs(luauniverseData) do
        for _, universeset in pairs(universedata) do
            set_to_universe[universeset] = universename
        end
    end
    
    local inputskinname

    if theme[1] ~= nil and luaskinData[exclude] ~= nil then
        local t = luaskinData[exclude]["skins"]

        for skinname, sdata in pairs(t) do
            if theme[1] == skinname then
                local luatheme = sdata["set"]
                
                if luatheme == nil or sdata["id"] == nil then
                	return ""
                end

                inputskinname = theme[1]
                theme[1]      = nil
                len_theme = 0
                
                for _, skintheme in pairs(luatheme) do
                    local themeexists = false
                    
                    for i = 1, len_theme do
                    	local tabletheme = theme[i]

                        if skintheme == tabletheme or set_to_universe[skintheme] == tabletheme then
                           themeexists = true
                           break
                        end
                    end
                    
                    if not themeexists then
                    	len_theme = len_theme + 1
                        theme[len_theme] = set_to_universe[skintheme] or skintheme
                    end
                end

                break
            end
        end
    end
    
    if theme[1] == nil then
        return ""
    end

	local s               = {"\n<ul>"}
	local s_len			  = 1
	local gsub = string.gsub

    for tableindex = 1, len_theme do
    	local tabletheme = theme[tableindex]
    	local skintable       = {}
        local len_skin = 0
        local resulttable     = {}

        for championname, cdata in pairs(luaskinData) do
            local t = cdata["skins"]
            
            for skinname,sdata in pairs(t) do
                if sdata["id"] ~= nil and (inputskinname == nil or (skinname .. " " .. championname) ~= (inputskinname .. " " .. exclude)) then
                    local luatheme = sdata["set"]
                    
                    if luatheme ~= nil then
                        for _, subtheme in pairs(luatheme) do
                            if subtheme == tabletheme or set_to_universe[subtheme] == tabletheme then
                                if resulttable[skinname] == nil then
                                    resulttable[skinname] = {}
                                    len_skin = len_skin + 1
                                    skintable[len_skin] = skinname
                                end

                                insert(resulttable[skinname],championname)
                                break
                            end
                        end
                    end
                end
            end
        end
        
        sort(skintable,orderup)

        local s2 = {"<ul>"}
        local s2_len = 1
        local skincount = 0
        
        for i = 1, len_skin do
        	local skinname = skintable[i]
            sort(resulttable[skinname],orderup)
            skincount = skincount + #resulttable[skinname]
            
            for i = 1, #resulttable[skinname] do
            	local championname = resulttable[skinname][i]
            	s2_len = s2_len + 1
                s2[s2_len] = "<li>" .. csl(championname, skinname, wr) .. "</li>"
            end
        end
        
        s2_len = s2_len + 1
        s2[s2_len] = "</ul>"
        
        if s2[2] ~= "</ul>" then
            if tableindex == 1 then
            	s_len = s_len + 1
                s[s_len] = "<li>This skin shares the "
            else
            	s_len = s_len + 1
                s[s_len] = "<li>It also shares the "
            end

			local link = set_to_universe[tabletheme] and lualinkData[set_to_universe[tabletheme]] or lualinkData[tabletheme]

            if link == false then
            	s_len = s_len + 1
                s[s_len] = "'" .. tabletheme .. "'"
        	else
        		local temp_link = set_to_universe[tabletheme] or tabletheme
				temp_link = luauniverseData[temp_link] and temp_link .. " (Universe)" or temp_link
            	s_len = s_len + 1
                s[s_len] = "[[" .. (link or gsub(temp_link, ": ", "/")) .. "|" .. tabletheme .. "]]"
            end

            s_len = s_len + 1
            s[s_len] = ' theme with: '

            if skincount > 5 then
            	s_len = s_len + 1
            	s[s_len] = '<div class="columntemplate" style="-moz-column-count:2; -webkit-column-count:2; column-count:2;">' .. concat(s2) .. '</div>'
            else
            	s_len = s_len + 1
            	s[s_len] = concat(s2)
            end
            
            s_len = s_len + 1
            s[s_len] = "</li>"
        end
    end
	
	s_len = s_len + 1
    s[s_len] = "</ul>"
    return concat(s)
end

function p.unofficialtable(frame)
    local args = (frame.args[1] and frame.args) or frame:getParent().args

	local wr = args["wr"]
    local luauniverseData, luaskinData
    
    if wr ~= "true" then
    	luauniverseData	= mw.loadData('Module:SkinData/universes')
	    luaskinData		= mw.loadData('Module:SkinData/data')
		IL          	= require('Module:ImageLink').skin
	else
		luauniverseData	= mw.loadData('Module:SkinDataWR/universes')
	    luaskinData		= mw.loadData('Module:SkinDataWR/data')
	    IL          	= require('Module:ImageLink').WRskin
    end

    local setnames      = {}
    local skintable     = {}
    local universenames = {}
    local universeids   = {}
    local resulttable   = {}

    local len_universe = 0
    local s             = {}
    local s_len			= 1
    local pairs = pairs
    
    s[s_len] = (
    	'<table class="wikitable">\n' ..
    	'<tr><th width="20%">Universe Name</th><th width="20%">Set Name</th><th>Skins</th></tr>\n')
    
    for universename, universedata in pairs(luauniverseData) do
        for _, setname in pairs(universedata) do
            if universeids[setname] == nil then
                universeids[setname] = {}
            end

            insert(universeids[setname], universename or "nil")
        end
    end
    
    for championname,cdata in pairs(luaskinData) do
        for skinname,sdata in pairs(cdata["skins"]) do
            if sdata["id"] ~= nil and sdata["set"] ~= nil then
                for _,set in pairs(sdata["set"]) do 
                    if universeids[set] == nil then
                        universeids[set] = {}
                        insert(universeids[set], "N/A")
                    end

                    for i = 1, #universeids[set] do
                    	local universe = universeids[set][i]

                        if resulttable[universe] == nil then
                            resulttable[universe] = {}
                            setnames[universe]    = {}
                            skintable[universe]   = {}
                            len_universe = len_universe + 1
                            universenames[len_universe] = universe
                        end
                        
                        if resulttable[universe][set] == nil then
                            resulttable[universe][set] = {}
                            skintable[universe][set]   = {}
                            insert(setnames[universe], set)
                        end
                        
                        if resulttable[universe][set][skinname] == nil then
                            resulttable[universe][set][skinname] = {}
                            insert(skintable[universe][set], skinname)
                        end

                        insert(resulttable[universe][set][skinname], championname)
                    end
                end
            end
        end
    end
    
    sort(universenames, orderup)
    
    for i = 1, len_universe do
    	local universe = universenames[i]
        sort(setnames[universe], orderup)
        s_len = s_len + 1
        s[s_len] = '<tr><th rowspan="' .. #setnames[universe] .. '">' .. universe .. '</th>'
        
        for index = 1, #setnames[universe] do
        	local set = setnames[universe][index]
            sort(skintable[universe][set], orderup)

            if index ~= 1 then
                s_len = s_len + 1
        		s[s_len] = '<tr>'
            end
            
            s_len = s_len + 1
        	s[s_len] = '<th>' .. set .. '</th><td><ul>'
            
            for i = 1, #skintable[universe][set] do
            	local skin = skintable[universe][set][i]
                sort(resulttable[universe][set][skin], orderup)
                
                for i = 1, #resulttable[universe][set][skin] do
                	local champion = resulttable[universe][set][skin][i]
                    s_len = s_len + 1
        			s[s_len] = '<li>' .. csl(champion, skin, wr) .. '</li>'
                end
            end

        	s_len = s_len + 1
        	s[s_len] = '</ul></td></tr>\n'
        end
    end
    
    s_len = s_len + 1
    s[s_len] = '</table>'
    return concat(s)
end

-- COMPARING LUA / JSON FUNCTIONS:

function p.synchronize(frame)
    local jsonskins     = jsontolua("Template:Set/skins.json")
    local luaskinData  = mw.loadData('Module:SkinData/data')
	IL          	= require('Module:ImageLink').skin
    local s             = {}
	local s_len			= 0
	local pairs,tostring,tonumber = pairs, tostring,tonumber
	local floor = math.floor
	local gsub = string.gsub
	local sub = string.sub
	
	local ordered_ids = {}
	local ordered_ids_len = 0
	
	for jsonid in pairs(jsonskins) do
		ordered_ids_len = ordered_ids_len + 1
		ordered_ids[ordered_ids_len] = tonumber(jsonid)
	end
	
	table.sort(ordered_ids)
	local championid, championname, lua_cdata
	local temp_lua_skins = {}

	for i = 1, ordered_ids_len do
		local sdata = jsonskins[tostring(ordered_ids[i])]
		
		if tonumber(sub(ordered_ids[i],-3)) == 0 then
			temp_lua_skins = {}
			championname = sdata.name
			lua_cdata = luaskinData[championname].skins

			for skin, sdata in pairs(lua_cdata) do
				temp_lua_skins[gsub(sdata.formatname or skin," " .. championname,"")] = skin
			end
			
			if ordered_ids[i] ~= luaskinData[championname].id * 1000 then
				s_len = s_len + 1
	        	s[s_len] = "\n* " .. championname .. " ----> incorrect id"
			end
		end

		for _, temp_sdata in pairs(sdata.questSkinInfo and sdata.questSkinInfo.tiers or {sdata}) do
			local skinname = (temp_sdata.name == championname and
				"Original" or
				gsub(temp_sdata.name," " .. championname,"")
			)

			local lua_sdata = lua_cdata[temp_lua_skins[skinname]]
        	
        	local temp_s = {}
        	local temp_s_len = 0

        	if lua_sdata == nil then
        		temp_s_len = temp_s_len + 1
	        	temp_s[temp_s_len] = "skin name"
        	else
        		if lua_sdata.id ~= tonumber(sub(temp_sdata.id,-3)) then
	        		temp_s_len = temp_s_len + 1
	        		temp_s[temp_s_len] = "skin id"
	        	end
	        	
	        	if temp_sdata.description ~= nil and lua_sdata.lore ~= temp_sdata.description then
	        		temp_s_len = temp_s_len + 1
	        		temp_s[temp_s_len] = "lore"
	        	end
        	end
        	
        	temp_s = concat(temp_s,", ")

        	if temp_s ~= "" then
        		s_len = s_len + 1
        		s[s_len] = "\n* " .. temp_sdata.id .. " " .. championname .. " " .. skinname .. " ----> incorrect " .. temp_s
        	end
        end
	end

    s = concat(s)

    if s == "" then
        return "All champion skin ids, skin names and lores are synchronized."
    end

    return "The following champion skins are not synchronized:" .. s
end

function p.missing(frame)
    local luauniverseData = mw.loadData('Module:SkinData/universes')
    local jsonskins       = jsontolua("Template:Set/skins.json")
    local jsonsets        = jsontolua("Template:Set/sets.json")
    local jsonuniverses   = jsontolua("Template:Set/universes.json")
    local luaskinData  = mw.loadData('Module:SkinData/data')
    IL          	= require('Module:ImageLink').skin
    local setids          = {}
    local setdata         = {}
    local s               = {}
    local s_len			  = 0
    local pairs,tostring = pairs,tostring
    
    for _, setdata in pairs(jsonsets) do
        setids[setdata.id] = setdata.name or "nil"
    end
    
    for _, universedata in pairs(jsonuniverses) do
        for _, setid in pairs(universedata.skinSets) do
            if setdata[universedata.name] == nil then
                setdata[universedata.name] = {}
            end

            insert(setdata[universedata.name], setids[setid])
        end
    end

    for jsonuniversename,jsonuniverse in pairs (setdata) do
        if luauniverseData[jsonuniversename] ~= nil then
            for i = 1, #jsonuniverse do
            	local jsonsetname = jsonuniverse[i]
                local check = true
                
                for _,luasetname in pairs (luauniverseData[jsonuniversename]) do
                    if jsonsetname == luasetname then
                        check = false
                        break
                    end
                end
                
                if check then
                	s_len = s_len + 1
                    s[s_len] = "\n* Missing " .. jsonsetname .. " Set In " .. jsonuniversename .. " Universe" 
                end
            end
        else
            s_len = s_len + 1
            s[s_len] = "\n* " .. jsonuniversename .. " Universe Missing" 
        end
    end

    for championname, cdata in pairs(luaskinData) do
        for skinname, sdata in pairs(cdata["skins"]) do
            if sdata["id"] ~= nil then
                local setid
                local skinid   = cdata["id"] * 1000 + sdata["id"]
                local jsonname = jsonskins[tostring(skinid)]
                
                if jsonname ~= nil then
                    setid = jsonname.skinLines
                end
                
                local luaset = sdata["set"]
                    
                if luaset ~= nil then
                    if setid ~= nil and setid ~= "null" then
                        for _,champsetid in pairs(setid) do
                            local jsonset      = setids[champsetid.id] or "nil"
                            local check = true
                            
                            for _, subtheme in pairs(luaset) do
                                if subtheme == jsonset then
                                    check = false
                                    break
                                end
                            end
                            
                            if check then
                                s_len = s_len + 1
                    			s[s_len] = "\n* " .. skinid .. " " .. csl(championname,skinname) .. " ----> " .. jsonset .. " Set Missing" 
                            end
                        end
                    end
                elseif setid ~= nil and setid ~= "null" then
                    for _,champsetid in pairs(setid) do
                        local jsonset      = setids[champsetid.id] or "nil"
                        s_len = s_len + 1
                    	s[s_len] = "\n* " .. skinid .. " " .. csl(championname,skinname) .. " ----> " .. jsonset .. " Set Missing" 
                    end
                end
            end
        end
    end
    
    s = concat(s)

    if s == "" then
        return "Nothing is missing."
    end

    return "The following stuff is missing:" .. s
end

function p.added(frame)
    local luauniverseData = mw.loadData('Module:SkinData/universes')
    local jsonskins       = jsontolua("Template:Set/skins.json")
    local jsonsets        = jsontolua("Template:Set/sets.json")
    local jsonuniverses   = jsontolua("Template:Set/universes.json")
    local luaskinData  = mw.loadData('Module:SkinData/data') 
	IL          	= require('Module:ImageLink').skin
    local setids          = {}
    local setdata         = {}
    local s               = {}
    local s_len			  = 0
    local pairs,tostring = pairs,tostring
    
    for _, setdata in pairs(jsonsets) do
        setids[setdata.id] = setdata.name or "nil"
    end
    
    for _, universedata in pairs(jsonuniverses) do
        for _, setid in pairs(universedata.skinSets) do
            if setdata[universedata.name] == nil then
                setdata[universedata.name] = {}
            end

            insert(setdata[universedata.name], setids[setid])
        end
    end

    for luauniversename,luauniverse in pairs (luauniverseData) do
        if setdata[luauniversename] ~= nil then
            for _,luasetname in pairs (luauniverse) do
                local check = true
                
                for i = 1, #setdata[luauniversename] do
                	local jsonsetname = setdata[luauniversename][i]

                    if jsonsetname == luasetname then
                        check = false
                        break
                    end
                end
                
                if check then
                    s_len = s_len + 1
                    s[s_len] = "\n* " .. luasetname .. " Unofficial Set Added In " .. luauniversename .. " Universe" 
                end
            end
        else
            s_len = s_len + 1
            s[s_len] = "\n* " .. luauniversename .. " Unofficial Universe Added" 
        end
    end

    for championname, cdata in pairs(luaskinData) do
        for skinname, sdata in pairs(cdata["skins"]) do
            if sdata["id"] ~= nil then
                local skinid   = cdata["id"] * 1000 + sdata["id"]
                local jsonname = jsonskins[tostring(skinid)]
                
                if jsonname ~= nil then
                    setid = jsonname.skinLines
                end
                
                local luaset = sdata["set"]
                    
                if luaset ~= nil then
                    if setid ~= nil and setid ~= "null" then
                        for _, subtheme in pairs(luaset) do
                            local check = true
                            
                            for _,champsetid in pairs(setid) do
                                local jsonset = setids[champsetid.id] or "nil"
                                
                                if subtheme == jsonset then
                                    check = false
                                end
                            end
                            
                            if check then
                                s_len = s_len + 1
                    			s[s_len] = "\n* " .. skinid .. " " .. csl(championname,skinname) .. " ----> " .. subtheme .. " Unoffical Set Added" 
                            end
                        end
                    else
                        for _, subtheme in pairs(luaset) do
                            s_len = s_len + 1
                    		s[s_len] = "\n* " .. skinid .. " " .. csl(championname,skinname) .. " ----> " .. subtheme .. " Unoffical Set Added"
                        end
                    end
                end
            end
        end
    end
    
    s = concat(s)

    if s == "" then
        return "Nothing unofficial has been added."
    end

    return "The following unofficial stuff has been added:" .. s
end    
    
-- EXTRACTING JSON FUNCTIONS:
    
function p.officialtable(frame)
    local jsonskins     = jsontolua("Template:Set/skins.json")
    local jsonsets      = jsontolua("Template:Set/sets.json")
    local jsonuniverses = jsontolua("Template:Set/universes.json")
    local luaskinData  = mw.loadData('Module:SkinData/data') 
    IL          	= require('Module:ImageLink').skin
    local setnames      = {}
    local skintable     = {}
    local setids        = {}
    local universenames = {}
    local universeids   = {}
    local resulttable   = {}

    local len_universe = 0
    local s             = {}
    local s_len			= 1
    local pairs,tostring = pairs,tostring
    
    s[s_len] = (
    	'<table class="wikitable">\n' .. 
    	'<tr><th width="20%">Universe Name</th><th width="20%">Set Name</th><th>Skins</th></tr>\n')
    
    for _, setdata in pairs(jsonsets) do
        setids[setdata.id] = setdata.name or "nil"
    end
    
    for _, universedata in pairs(jsonuniverses) do
        for _, setid in pairs(universedata.skinSets) do
            if universeids[setid] == nil then
                universeids[setid] = {}
            end

            insert(universeids[setid], universedata.name or "nil")
        end
    end

    for championname,cdata in pairs(luaskinData) do
        for skinname,sdata in pairs(cdata["skins"]) do
            if sdata["id"] ~= nil then
                local skinid     = cdata["id"] * 1000 + sdata["id"]
                local setid = jsonskins[tostring(skinid)]
                
                if setid ~= nil then
                    setid = setid.skinLines
                end
                
                if setid ~= nil and setid ~= "null" then
                    for _,champsetid in pairs(setid) do 
                        if universeids[champsetid.id] == nil then
                            universeids[champsetid.id] = {}
                            insert(universeids[champsetid.id], "N/A")
                        end

                        for i = 1, #universeids[champsetid.id] do
                        	local universe = universeids[champsetid.id][i]
                            local set = setids[champsetid.id] or "nil"
                            
                            if resulttable[universe] == nil then
                                resulttable[universe] = {}
                                setnames[universe]    = {}
                                skintable[universe]   = {}
                                len_universe = len_universe + 1
                                universenames[len_universe] = universe
                            end
                            
                            if resulttable[universe][set] == nil then
                                resulttable[universe][set] = {}
                                skintable[universe][set]   = {}
                                insert(setnames[universe], set)
                            end
                            
                            if resulttable[universe][set][skinname] == nil then
                                resulttable[universe][set][skinname] = {}
                                insert(skintable[universe][set], skinname)
                            end

                            insert(resulttable[universe][set][skinname], championname)
                        end
                    end
                end
            end
        end
    end
    
    sort(universenames, orderup)
    
    for i = 1, len_universe do
    	local universe = universenames[i]
        sort(setnames[universe], orderup)
        s_len = s_len + 1
        s[s_len] = '<tr><th rowspan="' .. #setnames[universe] .. '">' .. universe .. '</th>'
        
        for index = 1, #setnames[universe] do
        	local set = setnames[universe][index]
            sort(skintable[universe][set], orderup)

            if index ~= 1 then
                s_len = s_len + 1
                s[s_len] = '<tr>'
            end
            
            s_len = s_len + 1
            s[s_len] = '<th>' .. set .. '</th><td><ul>'
            
            for i = 1, #skintable[universe][set] do
            	local skin = skintable[universe][set][i]
                sort(resulttable[universe][set][skin], orderup)
                
                for i = 1, #resulttable[universe][set][skin] do
                	local champion = resulttable[universe][set][skin][i]
                    s_len = s_len + 1
                    s[s_len] = '<li>' .. csl(champion, skin) .. '</li>'
                end
            end

            s_len = s_len + 1
            s[s_len] = '</ul></td></tr>\n'
        end
    end
    
    s_len = s_len + 1
    s[s_len] = '</table>'
    return concat(s) 
end

return p
-- </pre>