local z={"\095\095\097\100\100";"\095\095\099\097\108\108";"\095\095\099\111\110\099\097\116";"\095\095\100\105\118";"\095\095\108\101";"\095\095\108\116";"\095\095\109\111\100","\095\095\109\117\108","\095\095\112\111\119","\095\095\115\117\098";"\095\095\116\111\115\116\114\105\110\103";"\095\095\117\110\109"}local function U(U,Q)for z,M in ipairs(z)do Q[M]=U[M]end end local function Q(z,Q)setmetatable(z,Q)U(Q,z)end local function M(z)local U={}U.__index=U U.ClassName=z function U.new(...)local z={}setmetatable(z,U)if z.__init then z:__init(...)end return z end return U end local function v(z,U)assert(type(z)=="\115\116\114\105\110\103","\070\105\114\115\116 \097\114\103\117\109\101\110\116 \116\111 \099\108\097\115\115\040\041 \109\117\115\116 \098\101 \097 \115\116\114\105\110\103 \102\111\114 \116\104\101 \067\108\097\115\115\078\097\109\101")local v=M(z)if U then Q(v,U)end return v,U end return v
-- This is the list of metamethods that are copied from one class to another.
local INHERITED_METAMETHODS = {
	"__add",
	"__call",
	"__concat",
	"__div",
	"__le",
	"__lt",
	"__mod",
	"__mul",
	"__pow",
	"__sub",
	"__tostring",
	"__unm",
}

-- Copies the metamethods from one class to another.
-- `from` is typically the super, and `to` is the subclass.
local function copyMetaMethods(from, to)
	for _, metamethodName in ipairs(INHERITED_METAMETHODS) do
		to[metamethodName] = from[metamethodName]
	end
end

local function subclass(NewClass, SuperClass)
	setmetatable(NewClass, SuperClass)
	copyMetaMethods(SuperClass, NewClass)
end

local function getNewClass(className)
	local NewClass = {}
	NewClass.__index = NewClass
	NewClass.ClassName = className

	function NewClass.new(...)
		local self = {}
		setmetatable(self, NewClass)

		if self.__init then
			self:__init(...)
		end

		return self
	end

	return NewClass
end

local function class(className, SuperClass)
	assert(type(className) == "string", "First argument to class() must be a string for the ClassName")

	local NewClass = getNewClass(className)

	if SuperClass then
		subclass(NewClass, SuperClass)
	end

	return NewClass, SuperClass
end

return class
