--Cache global variables local error = error local geterrorhandler = geterrorhandler local loadstring = loadstring local pairs = pairs local pcall = pcall local tonumber = tonumber local tostring = tostring local type = type local unpack = unpack local abs, ceil, exp, floor = math.abs, math.ceil, math.exp, math.floor local find, format, gfind, gsub, len, sub = string.find, string.format, string.gfind, string.gsub, string.len, string.sub local concat, getn, setn = table.concat, table.getn, table.setn math.fmod = math.mod math.huge = 1/0 string.gmatch = string.gfind function difftime(time2, time1) if type(time2) ~= "number" then error(format("bad argument #1 to 'difftime' (number expected, got %s)", time2 and type(time2) or "no value"), 2) elseif time1 and type(time1) ~= "number" then error(format("bad argument #2 to 'difftime' (number expected, got %s)", time1 and type(time1) or "no value"), 2) end return time1 and time2 - time1 or time2 end function select(n, ...) if not (type(n) == "number" or (type(n) == "string" and n == "#")) then error(format("bad argument #1 to 'select' (number expected, got %s)", n and type(n) or "no value"), 2) end if n == "#" then return getn(arg) elseif n == 1 then return unpack(arg) end local args = {} for i = n, getn(arg) do args[i-n+1] = arg[i] end return unpack(args) end local huge = math.huge function math.modf(i) i = type(i) ~= "number" and tonumber(i) or i if type(i) ~= "number" then error(format("bad argument #1 to 'modf' (number expected, got %s)", i and type(i) or "no value"), 2) end if i == 0 then return i, i elseif abs(i) == huge then return i, i > 0 and 0 or -0 end local int = i >= 0 and floor(i) or ceil(i) return int, i - int end function math.modulo(x, y) x = type(x) ~= "number" and tonumber(i) or x y = type(y) ~= "number" and tonumber(i) or y if type(x) ~= "number" then error(format("bad argument #1 to 'modulo' (number expected, got %s)", x and type(x) or "no value"), 2) elseif type(y) ~= "number" then error(format("bad argument #2 to 'modulo' (number expected, got %s)", y and type(y) or "no value"), 2) end return x - floor(x / y) * y end function math.cosh(i) i = type(i) ~= "number" and tonumber(i) or i if type(i) ~= "number" then error(format("bad argument #1 to 'cosh' (number expected, got %s)", i and type(i) or "no value"), 2) end if i < 0 then i = -i end if i > 21 then return exp(i) / 2 end return (exp(i) + exp(-i)) / 2 end local sinhC = { ["P0"] = -0.6307673640497716991184787251e+6, ["P1"] = -0.8991272022039509355398013511e+5, ["P2"] = -0.2894211355989563807284660366e+4, ["P3"] = -0.2630563213397497062819489e+2, ["Q0"] = -0.6307673640497716991212077277e+6, ["Q1"] = 0.1521517378790019070696485176e+5, ["Q2"] = -0.173678953558233699533450911e+3 } function math.sinh(i) i = type(i) ~= "number" and tonumber(i) or i if type(i) ~= "number" then error(format("bad argument #1 to 'sinh' (number expected, got %s)", i and type(i) or "no value"), 2) end local neg, x if i < 0 then i = -i neg = true end if i > 21 then x = exp(i) / 2 elseif i > 0.5 then x = (exp(i) - exp(-i)) / 2 else local sq = i * i x = (((sinhC["P3"] * sq + sinhC["P2"]) * sq + sinhC["P1"]) * sq + sinhC["P0"]) * i x = x / (((sq + sinhC["Q2"]) * sq + sinhC["Q1"]) * sq + sinhC["Q0"]) end if neg then x = -x end return x end local MAXLOG2 = 8.8029691931113054295988e+01 * 0.5 local tanhP = { -9.64399179425052238628E-1, -9.92877231001918586564E1, -1.61468768441708447952E3, } local tanhQ = { 1.12811678491632931402E2, 2.23548839060100448583E3, 4.84406305325125486048E3, } function math.tanh(i) i = type(i) ~= "number" and tonumber(i) or i if type(i) ~= "number" then error(format("bad argument #1 to 'tanh' (number expected, got %s)", i and type(i) or "no value"), 2) end if i == 0 then return i end local x = abs(i) if x > MAXLOG2 then return i < 0 and -1 or 1 elseif x >= 0.625 then local s = exp(2 * x) x = 1 - 2 / (s + 1) if i < 0 then x = -x end else local sq = i * i x = i + i * sq * ((tanhP[1] * sq + tanhP[2]) * sq + tanhP[3]) / (((sq + tanhQ[1]) * sq + tanhQ[2]) * sq + tanhQ[3]) end return x end function string.join(delimiter, ...) if type(delimiter) ~= "string" and type(delimiter) ~= "number" then error(format("bad argument #1 to 'join' (string expected, got %s)", delimiter and type(delimiter) or "no value"), 2) end if getn(arg) == 0 then return "" end return concat(arg, delimiter) end strjoin = string.join function string.match(str, pattern, index) if type(str) ~= "string" and type(str) ~= "number" then error(format("bad argument #1 to 'match' (string expected, got %s)", str and type(str) or "no value"), 2) elseif type(pattern) ~= "string" and type(pattern) ~= "number" then error(format("bad argument #2 to 'match' (string expected, got %s)", pattern and type(pattern) or "no value"), 2) elseif index and type(index) ~= "number" and (type(index) ~= "string" or index == "") then error(format("bad argument #3 to 'match' (number expected, got %s)", index and type(index) or "no value"), 2) end local i1, i2, match, match2 = find(str, pattern, index) if not match and i2 and i2 >= i1 then return sub(str, i1, i2) elseif match2 then local matches = {find(str, pattern, index)} tremove(matches, 2) tremove(matches, 1) return unpack(matches) end return match end strmatch = string.match function string.reverse(str) if type(str) ~= "string" and type(str) ~= "number" then error(format("bad argument #1 to 'reverse' (string expected, got %s)", str and type(str) or "no value"), 2) end local size = len(str) if size > 1 then local reversed = "" for i = size, 1, -1 do reversed = reversed .. sub(str, i, i) end return reversed end return str end function string.split(delimiter, str) if type(delimiter) ~= "string" and type(delimiter) ~= "number" then error(format("bad argument #1 to 'split' (string expected, got %s)", delimiter and type(delimiter) or "no value"), 2) elseif type(str) ~= "string" and type(str) ~= "number" then error(format("bad argument #2 to 'split' (string expected, got %s)", str and type(str) or "no value"), 2) end local fields = {} gsub(str, format("([^%s]+)", delimiter), function(c) fields[getn(fields) + 1] = c end) return unpack(fields) end strsplit = string.split local escapeSequences = { ["\a"] = "\\a", -- Bell ["\b"] = "\\b", -- Backspace ["\t"] = "\\t", -- Horizontal tab ["\n"] = "\\n", -- Newline ["\v"] = "\\v", -- Vertical tab ["\f"] = "\\f", -- Form feed ["\r"] = "\\r", -- Carriage return ["\\"] = "\\\\", -- Backslash ["\""] = "\\\"", -- Quotation mark ["|"] = "||", [" "] = "%s", ["!"] = "\\!", ["#"] = "\\#", ["$"] = "\\$", ["%"] = "\\%", ["&"] = "\\&", ["'"] = "\\'", ["("] = "\\(", [")"] = "\\)", ["*"] = "\\*", ["+"] = "\\+", [","] = "\\,", ["-"] = "\\-", ["."] = "\\.", ["/"] = "\\/" } function string.trim(str, chars) if type(str) ~= "string" and type(str) ~= "number" then error(format("bad argument #1 to 'trim' (string expected, got %s)", str and type(str) or "no value"), 2) elseif chars and (type(chars) ~= "string" and type(chars) ~= "number") then error(format("bad argument #2 to 'trim' (string expected, got %s)", chars and type(chars) or "no value"), 2) end if chars then local tokens = {} local size = 0 for token in gfind(chars, "[%z\1-\255]") do size = size + 1 tokens[size] = token end local pattern = "" for i = 1, size do pattern = pattern..(escapeSequences[tokens[i]] or tokens[i]).."+" if i < size then pattern = pattern.."|" end end local patternStart = loadstring("return \"^["..pattern.."](.-)$\"")() local patternEnd = loadstring("return \"^(.-)["..pattern.."]$\"")() local trimed, x, y = 1 while trimed > 0 do str, x = gsub(str, patternStart, "%1") str, y = gsub(str, patternEnd, "%1") trimed = x + y end return str elseif type(str) == "string" then -- remove leading/trailing [space][tab][return][newline] return gsub(str, "^%s*(.-)%s*$", "%1") else return tostring(str) end end strtrim = string.trim function table.wipe(t) if type(t) ~= "table" then error(format("bad argument #1 to 'wipe' (table expected, got %s)", t and type(t) or "no value"), 2) end for k in pairs(t) do t[k] = nil end if getn(t) ~= 0 then setn(t, 0) end return t end wipe = table.wipe local LOCAL_ToStringAllTemp = {} function tostringall(...) local n = getn(arg) -- Simple versions for common argument counts if (n == 1) then return tostring(arg[1]) elseif (n == 2) then return tostring(arg[1]), tostring(arg[2]) elseif (n == 3) then return tostring(arg[1]), tostring(arg[2]), tostring(arg[3]) elseif (n == 0) then return end local needfix for i = 1, n do local v = arg[i] if (type(v) ~= "string") then needfix = i break end end if (not needfix) then return unpack(arg) end wipe(LOCAL_ToStringAllTemp) for i = 1, needfix - 1 do LOCAL_ToStringAllTemp[i] = arg[i] end for i = needfix, n do LOCAL_ToStringAllTemp[i] = tostring(arg[i]) end return unpack(LOCAL_ToStringAllTemp) end local strjoin = strjoin local LOCAL_PrintHandler = function(...) DEFAULT_CHAT_FRAME:AddMessage(strjoin(" ", tostringall(unpack(arg)))) end function setprinthandler(func) if (type(func) ~= "function") then error("Invalid print handler") else LOCAL_PrintHandler = func end end function getprinthandler() return LOCAL_PrintHandler end local function print_inner(...) local ok, err = pcall(LOCAL_PrintHandler, unpack(arg)) if (not ok) then local func = geterrorhandler() func(err) end end function print(...) pcall(print_inner, unpack(arg)) end SLASH_PRINT1 = "/print" SlashCmdList["PRINT"] = print