local function k(f,v,w)if f==v then return true end local b=type(f)local N=type(v)if b~=N then return false end if b~="\116\097\098\108\101"then return false end if not w then local k=getmetatable(f)if k and k.__eq then return f==v end end local c={}for f,b in pairs(f)do local N=v[f]if N==nil or not k(b,N,w)then return false end c[f]=true end for k,f in pairs(v)do if not c[k]then return false end end return true end return k


local function deepEqual(A, B, ignoreMetatables)
	if A == B then
		return true
	end
	local AType = type(A)
	local BType = type(B)
	if AType ~= BType then
		return false
	end
	if AType ~= "table" then
		return false
	end

	if not ignoreMetatables then
		local mt1 = getmetatable(A)
		if mt1 and mt1.__eq then
			--compare using built in method
			return A == B
		end
	end

	local keySet = {}

	for key1, value1 in pairs(A) do
		local value2 = B[key1]
		if value2 == nil or not deepEqual(value1, value2, ignoreMetatables) then
			return false
		end
		keySet[key1] = true
	end

	for key2, _ in pairs(B) do
		if not keySet[key2] then
			return false
		end
	end
	return true
end

return deepEqual
