League of Legends Wiki
Advertisement
League of Legends Wiki

Данная группа модулей задает поведение таблиц, показывающих зависимость одних величин от других. По умолчанию - зависимость некоторого эффекта (урона, перезарядки и т.д.) от уровня чемпиона.

Список модулей[]

  • Модуль:Ability progression - функции по парсингу текста, который вводится через шаблон Pp2 и построение таблицы.
  • Модуль:Ability progression/parameters - список параметров, которые принимаются через шаблон: Pp2.

From Модуль:Ability progression/doc


-- Author: en:User:AnataBakka
-- <pre>
local p = {}
local lib         = require('Module:Feature')
local col         = require('Module:Color')
local userError   = require('Dev:User error')
local fd_get      = require('Module:fd').get
local fd_getmulti = require('Module:fd').getmulti

local expr	      = mw.ext.ParserFunctions.expr

local gsub        = mw.ustring.gsub
local find        = mw.ustring.find
local sub         = mw.ustring.sub
local len         = mw.ustring.len

local abs,floor,ceil = math.abs,math.floor,math.ceil
local concat = table.concat
local tostring,tonumber,match,pcall = tostring,tonumber,match,pcall

function p.test(frame)
    local args; if frame.args[1] then args = frame.args else args = frame:getParent().args end
    local doubleto = "yes"
    return string.gsub(doubleto, "true", "")
end

local function fd(val)
    return fd_get{args = {val}}
end

local function fdmulti(val)
    return fd_getmulti{args = {val}}
end

local function rounding(val, decimals)
    if decimals == nil or find(val, "[0-9]") == nil or find(val, "<span", 1, true) or find(val, ".", 1, true) == nil then
        return val
    end
	
    local a, b, c, d = tostring(val):match"([^0-9]*)([0-9]*)%.([0-9]*)(.*)"
    val = tonumber(b .. "." .. c)
	
	local round = (
		decimals == "abs" and abs(val)
		or decimals == "floor" and floor(val)
		or decimals == "ceil" and ceil(val)
		or decimals == "trunc" and sub(val, 1, (find(val, ".", 1, true) or 0) - 1)
		or floor(val * 10 ^ (decimals) + 0.5) / (10 ^ (decimals))
		)
    
    val = a .. round .. d
    
    if tonumber(val) then
    	return tonumber(val)
    end

    return val
end

local function string_to_formula(args)
    local val = gsub(args," ","")

    while find(val, "to", 1, true) do
        local to       		= sub(val, 1, find(val, "to", 1, true) - 1)
        local para         	= lib.split(to, "(",true)
		local para_len 		= #para
        local j             = para_len
		local total_times   = 0

        while j >= 2 do
            local _, times = gsub(para[j], "%)", "")
            total_times = total_times + times

            if para_len - j >= total_times then
                break
            end

            j = j - 1
        end

        local start = concat(para,"(",j)

        if pcall(expr, start .. "*2") == false then
            return args
        end

        to	       		= sub(val, find(val, "to", 1, true) + 2)
        para			= lib.split(to, ")", true)
		para_len		= #para
		j 				= 1
		total_times		= 0

        while j < para_len do
            local _, times = gsub(para[j], "%(", "")
            total_times = total_times + times

            if j > total_times then
                break
            end

            j = j + 1
        end

        local finish = concat(para,")",1,j)
		local post_finish

		if find(finish,"to",1,true) then
			post_finish = string_to_formula(finish)

			if post_finish == finish then
				return args
			end
		elseif pcall(expr, finish .. "*2") == false then
			return args
		end

        start  = gsub(start, "([%-%+%*%/%^%(%)])", "%%%1")
        finish = gsub(finish, "([%-%+%*%/%^%(%)])", "%%%1")
        val    = gsub(val, start .. "to" .. finish, "(" .. start .. ")" .. "+(" .. "(" .. (post_finish or finish) .. ")" .. "-" .. "(" .. start .. ")" .. ")/(times-1)*(x-1)")
    end

    return val
end

local function gsub_x(val1,val2)
	if val1 == "" and val2 == "" then
		return 1
	end
end

function p.pp(frame)
    local args = (frame.args[1] and frame.args) or frame:getParent().args
	
	local userError 	= require('Dev:User error')

	do 
		--There're multiple user errors throught the function, which are used to hopefully impede users
		--from inserting junk inside the template. Can also be helpful in case the user mistypes and doesn't notice (i.e debug purpose)
		local accepted_args = mw.loadData("Module:Ability_progression/parameters")
	
	    for i in pairs(args) do
	    	if accepted_args[i] == nil then
	    		return userError("Parameter '" .. i .. "' is not accepted", "Ability progession debug error")
	    	end
	    end
	    
	    if args["changedisplay"] and args["changedisplay"] ~= "true" then
	    	return userError("Invalid value for changedisplay. Can only be 'true'", "Ability progession debug error")
	    end
	    
		if args["showtype"] and args["showtype"] ~= "false" then
	    	return userError("Invalid value for showtype. Can only be 'false'", "Ability progession debug error")
	    end
	end

	local nowiki		= mw.text.nowiki
    
    local function gsub_nowiki(val1,val2,val3) --Currently used for "<" and ">" when necessary to not break the tooltip
		if val1 == "" and val3 == "" then
			return nowiki(val2)
		end
	end

    local count, countstatic            = {30,30}, 30
    local default_fill                  = 18

    local displayformula                = args["formula"]
    local special_displayformula_values = {{},{}}
    local useformula2

    local key                           = args["key"] or ""
    local key1                          = args["key1"]
    local round                         = {
    	(args["round"] ~= "false" and (args["round"] or 2)) or nil, 
    	(args["round1"] ~= "false" and (args["round1"] or 2)) or nil
    }

    local label                         = args["label"]
    local label1                        = args["label1"] or args["type"]

    local orig                          = lib.split(args[1] or "", ";", true)
    local orig1                         = lib.split(args[2] or "", ";", true)

	local origtable                     = {orig,orig1}
    local save_to                       = {{},{}}
    local save_to_index                 = {}
    local resulttable                   = {{},{}}

	for orig_index = 1, 2 do
		local orig = origtable[orig_index]
	    local lastvalue = ""
        local i = 1
        local len_resulttable = 0

        while orig[i] and orig[i] ~= "" do
        	orig[i] = gsub(orig[i],"([^%d ]?)([<>])([^%d ]?)",gsub_nowiki)
        	local temp_find_to = find(orig[i], "to", 1, true)
        	local temp_find_x = find(orig[i], "x", 1, true)

            if (temp_find_to or temp_find_x) and find(orig[i], "<", 1, true) == nil then
            	local start, finish, times

            	if temp_find_to then
	            	start = sub(orig[i], 1, temp_find_to - 1)
	
	                if find(orig[i], "by", 1, true) then
	                    finish, times = orig[i]:match".* *to *([^ ]*) *by *([^ ]*)$"
	                elseif find(orig[i], "for", 1, true) then
	                    finish, times = orig[i]:match".* *to *([^ ]*) *for *([^ ]*)$"
	                else
	                    finish = orig[i]:match".* *to *([^ ]*)"
	                end
	            end
	            
	            start, finish, times = start or "", finish or "", times or ""
                local check_for_times = false
                
                if temp_find_x == nil and pcall(expr, start .. "*2") and pcall(expr, finish .. "*2") and 
                (pcall(expr, times .. "*2") or times == "") then
                    check_for_times = true
                    start = expr(start)
                    finish = expr(finish)

                    if displayformula == nil and orig[2] == nil then
                        special_displayformula_values[orig_index][1] = start
                        special_displayformula_values[orig_index][2] = finish
                    end

                    if times == "" then
                        if save_to_index[orig_index] then
                        	check_for_times = false
                        else
                            save_to[orig_index] = {start,finish, lastvalue}
                            save_to_index[orig_index] = len_resulttable + 1
                            lastvalue = finish
                        end
                    else
                        times = expr(times)
                        local scale
                        local formula = start

                        if find(orig[i], "by", 1, true) then
                            times = rounding(abs(finish - start) / times + 1, 0)
                            scale = (finish - start) / (times - 1)

                            if lastvalue == start then
                                times = times - 1
                            else
                                formula = formula - scale
                            end
                        elseif lastvalue == start then
                            scale = (finish - start) / times
                        else
                            scale = (finish - start) / (times - 1)
                            formula = formula - scale
                        end

                        count[orig_index] = count[orig_index] - times

                        if count[orig_index] < 0 then
                            return userError("Maximum size exceeded", "LuaError")
                        end

                        for x = 1, times do
                            formula = formula + scale
                            len_resulttable = len_resulttable + 1
                            resulttable[orig_index][len_resulttable] = rounding(formula, round[orig_index])
                        end
                        
                        lastvalue = finish
                    end
                else
                	start, finish, times = nil, nil, nil
                    local useformula, doubleto

                    if find(orig[i], "for", 1, true) then
                        useformula, times = orig[i]:match"(.*) *for *([^ ]*)$"
                    end
                    
                    useformula, times = useformula or orig[i], times or ""
                    
                    if lastvalue ~= "" then
                        useformula = gsub(useformula, "then", lastvalue,1)
                    end

                    if pcall(expr, times .. "*2") then
                    	check_for_times = true
                    	times = expr(times)
                	elseif times == "" then
                		check_for_times = true
                        times = nil
                    end
                    
                    local _,occurences = gsub(orig[i],"to","")

                    if check_for_times and occurences > 0 then
                        doubleto = string_to_formula(useformula)
                        useformula = gsub(doubleto,"times",tostring(times or "2"))
                        -- The '2' is a temporary value, until it will later on be switched with the fill one			
                    end
                    
                    times = times or ""

                    if check_for_times and pcall(expr, gsub(useformula, "([%.%d]?)x([%.%d]?)", gsub_x) .. "*2") then
    					if times == "" then
    					    if orig_index == 1 and displayformula == nil and orig[2] == nil and useformula2 == nil then
    					    	if doubleto then
    					    		useformula2 = gsub(doubleto,"times", default_fill)
    					    	else
    					    		useformula2 = useformula
    					    	end
                            end

                            if save_to_index[orig_index] then
                            	check_for_times = false
                            else
                                save_to[orig_index] = {doubleto or useformula}
                                save_to_index[orig_index] = len_resulttable + 1
                                lastvalue = ""
                            end
                        else
                            if orig_index == 1 and displayformula == nil and orig[2] == nil and useformula2 == nil then
                                useformula2 = useformula
                            end
                            
                            count[orig_index] = count[orig_index] - times

                            if count[orig_index] < 0 then
                                return userError("Maximum size exceeded", "LuaError")
                            end

                            for x = 1, times do
                                lastvalue = expr(gsub(useformula, "x", x))
                                len_resulttable = len_resulttable + 1
                                resulttable[orig_index][len_resulttable] = rounding(lastvalue, round[orig_index])
                            end
                        end
                    else
                        check_for_times = false
                    end
                end

                if check_for_times == false then
                    lastvalue = ""
                    count[orig_index] = count[orig_index] - 1

                    if count[orig_index] < 0 then
                        return userError("Maximum size exceeded", "LuaError")
                    end
					
					len_resulttable = len_resulttable + 1
                    resulttable[orig_index][len_resulttable] =  orig[i]
                end
            else
                count[orig_index] = count[orig_index] - 1

                if count[orig_index] < 0 then
                    return userError("Maximum size exceeded", "LuaError")
                end

                local value = (lastvalue == "" and orig[i]) or gsub(orig[i], "then", lastvalue,1)

                if pcall(expr, value .. "*2") then
                    value = expr(value)

                    if find(orig[i+1] or "", "to",1,true) then
                    	lastvalue = ""
                    else
                    	lastvalue = value
                    end

                    value = rounding(value, round[orig_index])
                elseif lastvalue ~= "" then
                    lastvalue = ""
                    value = orig[i]
                end
				
				len_resulttable = len_resulttable + 1
                resulttable[orig_index][len_resulttable] = value
            end

            i = i + 1
        end
    end

    local fill = {default_fill - #resulttable[1], default_fill - #resulttable[2]}

    if default_fill - fill[1] >= default_fill - fill[2] then
        if save_to_index[1] == nil then
            fill[2] = fill[2] - fill[1]
        end
    elseif save_to_index[2] == nil then
        fill[1] = fill[1] - fill[2]
    end
	
	
    if fill[1] < 0 then
        fill[1] = 0
    end
	
    if fill[2] < 0 then
        fill[2] = 0
    end
    
    local insert = table.insert

    for orig_index = 1, #save_to do
    	local to = save_to[orig_index]

        if to[1] then
            if to[2] then
                local lastvalue = to[3]
                local start, finish = to[1], to[2]
                local times = fill[orig_index]
                local scale
                local formula = start

                if lastvalue == start then
                    scale = (finish - start) / times
                else
                    scale = (finish - start) / (times - 1)
                    formula = formula - scale
                end

                count[orig_index] = count[orig_index] - times

                if count[orig_index] < 0 then
                    return userError("Maximum size exceeded", "LuaError")
                end

                for x = 1, times do
                    formula = formula + scale
                    insert(resulttable[orig_index], save_to_index[orig_index] + x - 1, rounding(formula, round[orig_index]))
                end
            else
                local useformula = gsub(to[1],"times",fill[orig_index])
                local times = fill[orig_index]
                count[orig_index] = count[orig_index] - times

                if count[orig_index] < 0 then
                    return userError("Maximum size exceeded", "LuaError")
                end

                for x = 1, times do
                    insert(resulttable[orig_index], save_to_index[orig_index] + x - 1, rounding(expr(gsub(useformula, "x", x)), round[orig_index]))
                end
            end
        end
    end
    
    if #resulttable[2] ~= 0 and #resulttable[1] ~= #resulttable[2] then
    	return userError("Variables are unmatched", "LuaError")
    end

    local s = {}
    local s_len = 1
    s[s_len] = '<span class="pp-tooltip2" style="position:relative; border-bottom:1px dotted; cursor:help;'
    
    if args["color"] then
        s_len = s_len + 1
        s[s_len] = " color:" .. require('Module:Color').keyword{args["color"]} .. ";"
    end
    
    s_len = s_len + 1
    s[s_len] = '"'
    
    if label then
        s_len = s_len + 1
        s[s_len] = ' data-bot_label="' .. label .. '"'
    end
    
    if label1 then
        s_len = s_len + 1
        s[s_len] = ' data-top_label="' .. gsub(gsub(label1, "'''", ""), "''", "") .. '"'
    end
    
    if displayformula then
        s_len = s_len + 1
        s[s_len] = ' data-displayformula="' .. displayformula .. '"'
    end
    
    if useformula2 then
        s_len = s_len + 1
        s[s_len] = ' data-useformula="' .. useformula2 .. '"'
    end
    
    if resulttable[1] then
        s_len = s_len + 1
        s[s_len] = ' data-bot_values="' .. concat(resulttable[1],";") .. '"'
    end
    
    if resulttable[2] then
        s_len = s_len + 1
        s[s_len] = ' data-top_values="' .. concat(resulttable[2],";") .. '"'
    end
    
    if key ~= "" then
        s_len = s_len + 1
        s[s_len] = ' data-bot_key="' .. key .. '"'
    end
    
    if key1 then
        s_len = s_len + 1
        s[s_len] = ' data-top_key="' .. key1 .. '"'
    end
    
    if special_displayformula_values[1][1] or special_displayformula_values[2][1] then
        s_len = s_len + 1
        s[s_len] = (
            ' data-start="' .. (special_displayformula_values[1][1] or "") .. ";" .. (special_displayformula_values[2][1] or "") .. '"' .. 
            ' data-finish="' .. (special_displayformula_values[1][2] or "") .. ";" .. (special_displayformula_values[2][2] or "") .. '"')
    end
    
    s_len = s_len + 1
    s[s_len] = ">"

    if (countstatic - count[1] > 5 and args["changedisplay"] ~= "true") or (countstatic - count[1] <= 5 and args["changedisplay"] == "true") then
        s_len = s_len + 1
        s[s_len] = fd(resulttable[1][1] or "NULL") .. key .. " &minus; " .. fd(resulttable[1][#resulttable[1]] or "NULL")  .. key
    else
        s_len = s_len + 1
        s[s_len] = fdmulti(concat(resulttable[1]," / ")) .. key
    end
    
    if args["showtype"] ~= "false" then
        s_len = s_len + 1
        s[s_len] = " (зависит от " .. (args["type"] or args["label1"] or "уровня") .. ")" 
    end
    
    s_len = s_len + 1
    s[s_len] = "</span>"
     
    return concat(s)
end

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

    local label             = (args["bot_label"] == "" and "Значение") or args["bot_label"]
    local label1            = (args["top_label"] == "" and "Уровень") or args["top_label"]
    local key               = args["bot_key"]
    local key1              = args["top_key"]
    local displayformula    = args["displayformula"]
    local useformula        = args["useformula"]
    local start             = lib.split(args["start"], ";", true)
    local start2,start3     = (tonumber(start[1]) or ""), (tonumber(start[2]) or "")
    local finish            = lib.split(args["finish"], ";", true)
    local finish2,finish3   = (tonumber(finish[1]) or ""), (tonumber(finish[2]) or "")
    
    local formulalabel1 	= gsub(label1, "[%[%]]", "")
    
    local orig  			= lib.split(args["bot_values"], ";", true)
    local orig1 			= lib.split(args["top_values"], ";", true)
    
    local s = {}
    local s_len = 0
    local i = 1

    while (orig1[i] and orig1[i] ~= "") or (orig[i] and orig[i] ~= "") do
        s_len = s_len + 1
        s[s_len] = '</th><th style="text-align: center;">'
        
        if orig1[1] == "" then
            s_len = s_len + 1
            s[s_len] = i
        else
            s_len = s_len + 1
            s[s_len] = fd(orig1[i] or "")
            
            if pcall(expr, (orig1[i] or "") .. "*2") then
                s_len = s_len + 1
                s[s_len] = key1
            end
        end

        i = i + 1
    end

    s_len = s_len + 1
    s[s_len] = '</th></tr><tr><th style="text-align: center;">' .. mw.ustring.gsub(label, "^.", mw.ustring.upper) .. '</th>'
    
    i = 1

    while orig[i] and orig[i] ~= "" do
        s_len = s_len + 1
        s[s_len] = '<td>' .. fd(orig[i])

        if pcall(expr, orig[i] .. "*2") then
            s_len = s_len + 1
            s[s_len] = key
        end

        s_len = s_len + 1
        s[s_len] = '</td>'
        i = i + 1
    end
    
    s_len = s_len + 1
    s[s_len] = '</tr></table>'
    
    s = concat(s)

    local formula = {}
    local len_formula = 0
    
    if displayformula ~= "" then
        len_formula = len_formula + 1
        formula[len_formula] = "'''Формула расчета:''' " .. displayformula
    elseif orig1[1] ~= "" then
        if start2 ~= "" and start3 ~= "" then
        	local orig1_len = #orig1
            local scale  = (finish2 - start2) / (orig1_len - 1)
            local scale1 = (finish3 - start3) / (orig1_len - 1)

            len_formula = len_formula + 1
            formula[len_formula] = "'''Формула расчета:''' "

            if start2 ~= 0 then
                len_formula = len_formula + 1
                formula[len_formula] = start2 .. key

                if scale >= 0 then
                    len_formula = len_formula + 1
                    formula[len_formula] = "+"
                end
            end

            if label1 == "Уровень" then
                len_formula = len_formula + 1
                formula[len_formula] = scale .. key .. " за каждые "

                if abs(scale1) ~= 1 then
                    len_formula = len_formula + 1
                    formula[len_formula] = scale1
                end

                len_formula = len_formula + 1
                formula[len_formula] = key1 .. " " .. label1

                if scale1 > 1 then
                    len_formula = len_formula + 1
                    formula[len_formula] = "s"
                end

                if start3 ~= 0 and start3 ~= 1 then
                	len_formula = len_formula + 1
                    formula[len_formula] = " начиная с " .. label1 .. " " .. start3 .. key1 .. " и"
                else
                	len_formula = len_formula + 1
                    formula[len_formula] = ","
                end

                len_formula = len_formula + 1
                formula[len_formula] = " достигает максимума при " .. label1 .. " " .. finish3 .. key1
            else
            	local label1_len = #label1

                len_formula = len_formula + 1
                formula[len_formula] = scale .. key .. " за каждые "

                if abs(scale1) ~= 1 then
                    len_formula = len_formula + 1
                    formula[len_formula] = scale1
                end

                len_formula = len_formula + 1
                formula[len_formula] = key1 .. " "

                if scale1 ~= 1 then
                	len_formula = len_formula + 1
                    formula[len_formula] = label1
                elseif sub(formulalabel1, -1) == "s" then
                    if sub(label1, -1) == "s" then
                    	len_formula = len_formula + 1
                        formula[len_formula] = sub(label1, 1, label1_len - 1)
                    else
                    	len_formula = len_formula + 1
                        formula[len_formula] = sub(label1, 1, label1_len - 3)
                    end
                else
                	len_formula = len_formula + 1
                    formula[len_formula] = label1
                end

                if start3 ~= 0 and start3 ~= 1 then
                	len_formula = len_formula + 1
                    formula[len_formula] = ", начиная с " .. start3 .. key1 .. " "

                    if start3 ~= 1 then
                    	len_formula = len_formula + 1
                        formula[len_formula] = label1
                    elseif sub(formulalabel1, -1) == "s" then
                        if sub(label1, -1) == "s" then
                        	len_formula = len_formula + 1
                            formula[len_formula] = sub(label1, 1, label1_len - 1)
                        else
                        	len_formula = len_formula + 1
                            formula[len_formula] = sub(label1, 1, label1_len - 3)
                        end
                    else
                    	len_formula = len_formula + 1
                        formula[len_formula] = label1
                    end

                    len_formula = len_formula + 1
                    formula[len_formula] = " и"
                else
                	len_formula = len_formula + 1
                    formula[len_formula] = ","
                end

                len_formula = len_formula + 1
                formula[len_formula] = " достигает максимума при " .. finish3 .. key1 .. " "

                if finish3 ~= 1 then
                	len_formula = len_formula + 1
                    formula[len_formula] = label1
                elseif sub(formulalabel1, -1) == "s" then
                    if sub(label1, -1) == "s" then
                    	len_formula = len_formula + 1
                        formula[len_formula] = sub(label1, 1, label1_len - 1)
                    else
                    	len_formula = len_formula + 1
                        formula[len_formula] = sub(label1, 1, label1_len - 3)
                    end
                else
                	len_formula = len_formula + 1
                    formula[len_formula] = label1
                end
            end
        end
    else
        if start2 ~= "" then
            local scale = (finish2 - start2) / (#orig - 1)
            len_formula = len_formula + 1
            formula[len_formula] = "'''Формула расчета:''' "

            if tonumber(tostring(start2)) == tonumber(tostring(scale)) then
            	len_formula = len_formula + 1
                formula[len_formula] = start2 .. key .. "&#42;" .. label1
            elseif len(sub(scale,find(scale,".",1,true) or 1)) <= 4 then
            	len_formula = len_formula + 1
                formula[len_formula] = (start2 - scale) .. key

	            if scale >= 0 then
                	len_formula = len_formula + 1
                    formula[len_formula]  = "+"

                    if scale == 1 then
                    	len_formula = len_formula + 1
                        formula[len_formula] = label1
                    else
                    	len_formula = len_formula + 1
                        formula[len_formula] = scale .. key .. "&#42;" .. label1
                    end
                elseif scale == -1 then
                	len_formula = len_formula + 1
                    formula[len_formula] = "-" .. label1
                else
                	len_formula = len_formula + 1
                    formula[len_formula] = scale .. key .. "&#42;" .. label1
                end
	        else
	        	len_formula = len_formula + 1
	        	formula[len_formula] = start2 .. key
	        	
	        	if finish2 - start2 >= 0 then
	    			len_formula = len_formula + 1
	        		formula[len_formula] = "+"
	        	end

	        	len_formula = len_formula + 1
	        	formula[len_formula] = (finish2 - start2) .. key .. "/" .. (#orig - 1) .. "&#42;(" .. label1 .. "-1)"
            end
        elseif useformula ~= "" then
            len_formula = len_formula + 1
            formula[len_formula] = "'''Формула:''' " .. useformula
        end
    end
    
    formula = concat(formula)
    
    if displayformula == "" then
        formula = gsub(gsub(gsub(gsub(gsub(formula, "%/", " &divide; "), "%*", "&#42;"), "&#42;", " &times; "), "%+", " + "), "%-", " &minus; ")

        if useformula ~= "" then
            formula = gsub(formula, "x", label1)
        end
    else
        formula = gsub(gsub(gsub(gsub(gsub(formula, "%/", "&divide;"), "%*", "&#42;"), "&#42;", "&times;"), "%+", "+"), "%-", "&minus;")
    end
    
    formula = fdmulti(formula)

	return (
		'<div ' .. (formula == "" and "" or 'class="blue-tooltip" ') .. 'style="padding: 10px; color: white;">' .. formula .. 
        '<table class="wikitable" style="text-align: center; table-layout: fixed; margin: 0;">' .. 
        '<tr><th style="text-align: center;">' .. mw.ustring.gsub(label1, "^.", mw.ustring.upper) ..
        s .. "</div>"
    )
end

function p.ap(frame)
    local args; if frame.args == nil then args = lib.arguments(frame) else args = lib.arguments(frame.args) end
    local values = ""
    local orig   = args
    local count  = 6
    local fill
    local round  = args["round"] or nil
    if args["skill"] == "R" then
        fill = 3
    else
        fill = 5
    end
    local formula
    local temp, a, b, c
    
    local i = 1
    while orig[i] ~= nil and orig[i] ~= "" do
        if (string.find(orig[i], "to") ~= nil or string.find(orig[i], "x") ~= nil) and string.find(orig[i], "%<") == nil then
            if string.find(orig[i], "to") ~= nil then
                start = string.sub(orig[i], 1, string.find(orig[i], "to") - 1)
            end
            if string.find(orig[i], "x") == nil and pcall(expr, start .. "*2") ~= false then
                finish, times = orig[i]:match".* *to *([^ ]*) *([^ ]*)"
                if finish ~= nil and pcall(expr, finish .. "*2") ~= false and ((times ~= "" and times ~= nil and pcall(expr, times .. "*2") ~= false) or times == "" or times == nil) then
                    start  = tonumber(expr(start))
                    finish = tonumber(expr(finish))
                    if times == "" or times == nil then
                        times = fill
                        fill  = 0
                    else
                        times = tonumber(expr(times))  
                    end
                    count = count - times
                    if count < 0 then
                        return userError("Достигнут максимальный размер", "LuaError")
                    end
                    x = 1
                    while x <= times do
                        if x == 1 then
                            formula = start
                            scale = (finish - start) / (times - 1)
                        else
                            formula = formula + scale
                        end
                        if values == "" then
                            values = fd(rounding(formula, round))
                        else
                            values = values .. " / " .. fd(rounding(formula, round))
                        end
                        x = x + 1
                    end
                else
                    count = count - 1
                    if count < 0 then
                        return userError("Достигнут максимальный размер", "LuaError")
                    end
                    if values == "" then
                        values = fd(rounding(orig[i], round))
                    else
                        values = values .. " / " .. fd(rounding(orig[i], round))
                    end
                end
            else
                local times
                local doubleto = orig[i]
                if last(orig[i], " ") ~= last(orig[i], "to ") then
                    times = last(orig[i], " ")
                    if pcall(expr, times .. "*2") ~= false then
                        doubleto = string.sub(doubleto, 1, #doubleto - #times)
                    else
                        times = nil
                    end
                end
                local _, occurences = string.gsub(orig[i], "to", "")
                if occurences > 0 and ((times ~= "" and times ~= nil and pcall(expr, times .. "*2") ~= false) or times == "" or times == nil) then
                    local times2
                    if times == "" or times == nil then
                        times2 = fill
                    else
                        times2 = tonumber(expr(times))  
                    end
                    doubleto = string_to_formula(doubleto, times2)
                end
                useformula = doubleto
                if useformula ~= nil and pcall(expr, string.gsub(useformula, "x", "1") .. "*2") ~= false and ((times ~= "" and times ~= nil and pcall(expr, times .. "*2") ~= false) or times == "" or times == nil) then
                    if times == "" or times == nil then
                        times = fill
                        fill = 0
                    else
                        times = tonumber(expr(times))  
                    end
                    x = 1
                    while x <= times do
                        count = count - 1
                        if count < 0 then
                            return userError("Достигнут максимальный размер", "LuaError")
                        end
                        formula = string.gsub(useformula, "x", x)
                        if values =="" then
                            values = fd(rounding(expr(formula), round))
                        else
                            values = values .. " / " .. fd(rounding(expr(formula), round))
                        end
                        x = x + 1
                    end
                else
                    count = count - 1
                    if count < 0 then
                        return userError("Достигнут максимальный размер", "LuaError")
                    end
                    if values == "" then
                        values = fd(rounding(orig[i], round))
                    else
                        values = values .. " / " .. fd(rounding(orig[i], round))
                    end
                end
            end
        else
            count = count - 1
            if count < 0 then
                return userError("Достигнут максимальный размер", "LuaError")
            end
            if values == "" then
                values = fd(rounding(orig[i], round))
            else
                values = values .. " / " .. fd(rounding(orig[i], round))
            end
        end
        i = i + 1
    end
    return values
end

local function string_to_formula(args)
    local val = gsub(args," ","")

    while find(val, "to", 1, true) do
        local to       		= sub(val, 1, find(val, "to", 1, true) - 1)
        local para         	= lib.split(to, "(",true)
		local para_len 		= #para
        local j             = para_len
		local total_times   = 0

        while j >= 2 do
            local _, times = gsub(para[j], "%)", "")
            total_times = total_times + times

            if para_len - j >= total_times then
                break
            end

            j = j - 1
        end

        local start = concat(para,"(",j)

        if pcall(expr, start .. "*2") == false then
            return args
        end

        to	       		= sub(val, find(val, "to", 1, true) + 2)
        para			= lib.split(to, ")", true)
		para_len		= #para
		j 				= 1
		total_times		= 0

        while j < para_len do
            local _, times = gsub(para[j], "%(", "")
            total_times = total_times + times

            if j > total_times then
                break
            end

            j = j + 1
        end

        local finish = concat(para,")",1,j)
		local post_finish

		if find(finish,"to",1,true) then
			post_finish = string_to_formula(finish)

			if post_finish == finish then
				return args
			end
		elseif pcall(expr, finish .. "*2") == false then
			return args
		end

        start  = gsub(start, "([%-%+%*%/%^%(%)])", "%%%1")
        finish = gsub(finish, "([%-%+%*%/%^%(%)])", "%%%1")
        val    = gsub(val, start .. "to" .. finish, "(" .. start .. ")" .. "+(" .. "(" .. (post_finish or finish) .. ")" .. "-" .. "(" .. start .. ")" .. ")/(times-1)*(x-1)")
    end

    return val
end
    
function expr(val)
    if string.find(val, "[0-9]") == nil then
        return val
    end
    local val = string.gsub(string.gsub(string.gsub(string.gsub(string.gsub(string.gsub(string.gsub(string.gsub(val, " ", ""), "(%d+%.*%d*)", " %1 "), "%(", " %("), "%)", "%) "), "([^ ])%- ", "%1 -"), "([^ ])%+ ", "%1 "), "^%- ", " -"), "^%+ ", " ")
    local i = true
    local j = 1
    local a, b, switcher, switcher2, switcher3, temp, temp2
    
    while i == true do
        temp = val
        if string.find(val, "%)") ~= nil then
            temp = last(string.sub(val, 1, string.find(val, "%)") - 1), "(")
        end
        temp2 = temp
        
        while j do
            if string.find(temp2, " %^ ") ~= nil then
                switcher  = last(string.sub(temp2, 1, string.find(temp2, " %^ ") - 1), " ")
                switcher2 = string.sub(temp2, string.find(temp2, " %^ ") + 3)
                switcher2 = string.sub(switcher2, 1, (string.find(switcher2, " ") or 0) - 1)
                switcher3 = switcher ^ switcher2
                switcher  = string.gsub(switcher, "([%.%-])", "%%%1")
                switcher2 = string.gsub(switcher2, "([%.%-])", "%%%1")
                temp2     = string.gsub(temp2, " " .. switcher .. " %^ " .. switcher2 .. " ", " " .. switcher3 .. " ")
            else
                break
            end
        end
        
        while j do
            if string.find(temp2, " %/ ") ~= nil then
                switcher  = last(string.sub(temp2, 1, string.find(temp2, " %/ ") - 1), " ")
                switcher2 = string.sub(temp2, string.find(temp2, " %/ ") + 3)
                switcher2 = string.sub(switcher2, 1, (string.find(switcher2, " ") or 0) - 1)
                switcher3 = switcher / switcher2
                switcher  = string.gsub(switcher, "([%.%-])", "%%%1")
                switcher2 = string.gsub(switcher2, "([%.%-])", "%%%1")
                temp2     = string.gsub(temp2, " " .. switcher .. " %/ " .. switcher2 .. " ", " " .. switcher3 .. " ")
            else
                break
            end
        end
        
        while j do
            if string.find(temp2, " %* ") ~= nil then
                switcher  = last(string.sub(temp2, 1, string.find(temp2, " %* ") - 1), " ")
                switcher2 = string.sub(temp2, string.find(temp2, " %* ") + 3)
                switcher2 = string.sub(switcher2, 1, (string.find(switcher2, " ") or 0) - 1)
                switcher3 = switcher * switcher2
                switcher  = string.gsub(switcher, "([%.%-])", "%%%1")
                switcher2 = string.gsub(switcher2, "([%.%-])", "%%%1")
                temp2     = string.gsub(temp2, " " .. switcher .. " %* " .. switcher2 .. " ", " " .. switcher3 .. " ")
            else
                break
            end
        end
        
        while j do
           if string.find(temp2, " %- ") ~= nil then
                switcher  = last(string.sub(temp2, 1, string.find(temp2, " %- ") - 1), " ")
                switcher2 = string.sub(temp2, string.find(temp2, " %- ") + 3)
                switcher2 = string.sub(switcher2, 1, (string.find(switcher2, " ") or 0) - 1)
                switcher3 = switcher - switcher2
                switcher  = string.gsub(switcher, "([%.%-])", "%%%1")
                switcher2 = string.gsub(switcher2, "([%.%-])", "%%%1")
                temp2     = string.gsub(temp2, " " .. switcher .. " %- " .. switcher2 .. " ", " " .. switcher3 .. " ")
            else
                break
            end
        end
        
        while j do
            if string.find(temp2, " %+ ") ~= nil then
                switcher  = last(string.sub(temp2, 1, string.find(temp2, " %+ ") - 1), " ")
                switcher2 = string.sub(temp2, string.find(temp2, " %+ ") + 3)
                switcher2 = string.sub(switcher2, 1, (string.find(switcher2, " ") or 0) - 1)
                switcher3 = switcher + switcher2
                switcher  = string.gsub(switcher, "([%.%-])", "%%%1")
                switcher2 = string.gsub(switcher2, "([%.%-])", "%%%1")
                temp2     = string.gsub(temp2, " " .. switcher .. " %+ " .. switcher2 .. " ", " " .. switcher3 .. " ")
            else
                break
            end
        end
        
        if string.find(val, "%)") ~= nil and string.find(val, "%(") ~= nil then
            temp = string.gsub(temp, "([%.%-%+%*%/%^])", "%%%1")
            val  = string.gsub(val, " %(" .. temp .. "%) ", temp2)
        else
            val = temp2
            i = false
        end
    end
    if val * 2 ~= nil then
        val = string.gsub(val, " ", "")
        return val 
    end
end

function last(val, sign)
    return string.sub(val, 1 - (string.find(string.reverse(val), string.reverse(sign), 1, true) or 0))
end

function fd(val)
    return fd_get{args = {val}}
end

function fdmulti(val)
    return fd_getmulti{args = {val}}
end

function rounding(val, decimals)
    local round
    local val = tostring(val)
    if decimals == nil or string.find(val, "[0-9]") == nil or string.find(val, "<span") ~= nil or string.find(val, "%.") == nil then
        return val
    end
    local a, b, c, d = val:match"([^0-9]*)([0-9]*).([0-9]*)(.*)"
    val = tonumber(b .. "." .. c)
    if decimals == "abs" then
        round = math.abs(val)
    end
    if decimals == "floor" then
        round = math.floor(val)
    end
    if decimals == "ceil" then
        round = math.ceil(val)
    end
    if decimals == "trunc" then
        round = string.sub(val, 1, (string.find(val, "%.") or 0) - 1)
    end
    if round == nil then
        local mult = 10 ^ (decimals)
        round = math.floor(val * mult + 0.5) / mult
    end
    return a .. round .. d
end

return p

-- </pre>
--[[Category:Lua]]
Advertisement