t.Axes=primitive("\065\120\101\115")t.BrickColor=primitive("\066\114\105\099\107\067\111\108\111\114")t.CFrame=primitive("\067\070\114\097\109\101")t.Color3=primitive("\067\111\108\111\114\051")t.ColorSequence=primitive("\067\111\108\111\114\083\101\113\117\101\110\099\101")t.ColorSequenceKeypoint=primitive("\067\111\108\111\114\083\101\113\117\101\110\099\101\075\101\121\112\111\105\110\116")t.DockWidgetPluginGuiInfo=primitive("\068\111\099\107\087\105\100\103\101\116\080\108\117\103\105\110\071\117\105\073\110\102\111")t.Faces=primitive("\070\097\099\101\115")t.Instance=primitive("\073\110\115\116\097\110\099\101")t.NumberRange=primitive("\078\117\109\098\101\114\082\097\110\103\101")t.NumberSequence=primitive("\078\117\109\098\101\114\083\101\113\117\101\110\099\101")t.NumberSequenceKeypoint=primitive("\078\117\109\098\101\114\083\101\113\117\101\110\099\101\075\101\121\112\111\105\110\116")t.PathWaypoint=primitive("\080\097\116\104\087\097\121\112\111\105\110\116")t.PhysicalProperties=primitive("\080\104\121\115\105\099\097\108\080\114\111\112\101\114\116\105\101\115")t.Random=primitive("\082\097\110\100\111\109")t.Ray=primitive("\082\097\121")t.Rect=primitive("\082\101\099\116")t.Region3=primitive("\082\101\103\105\111\110\051")t.Region3int16=primitive("\082\101\103\105\111\110\051\105\110\116\049\054")t.TweenInfo=primitive("\084\119\101\101\110\073\110\102\111")t.UDim=primitive("\085\068\105\109")t.UDim2=primitive("\085\068\105\109\050")t.Vector2=primitive("\086\101\099\116\111\114\050")t.Vector3=primitive("\086\101\099\116\111\114\051")t.Vector3int16=primitive("\086\101\099\116\111\114\051\105\110\116\049\054")t.Enum=primitive("\069\110\117\109")t.EnumItem=primitive("\069\110\117\109\073\116\101\109")t.RBXScriptSignal=primitive("\082\066\088\083\099\114\105\112\116\083\105\103\110\097\108")t.RBXScriptConnection=primitive("\082\066\088\083\099\114\105\112\116\067\111\110\110\101\099\116\105\111\110")function t.literal(...)local n=select("\035",...)if n==1 then local n=...return function(F)if F~=n then return false end return true end else local F={}for n=1,n,1 do local C=select(n,...)F[n]=t.literal(C)end return t.union(table.unpack(F,1,n))end end t.exactly=t.literal function t.keyOf(n)local F={}local C=0 for n in pairs(n)do C=C+1 F[C]=n end return t.literal(table.unpack(F,1,C))end function t.valueOf(n)local F={}local C=0 for n,a in pairs(n)do C=C+1 F[C]=a end return t.literal(table.unpack(F,1,C))end function t.integer(n)local F=t.number(n)if not F then return false end if n%1==0 then return true else return false end end function t.numberMin(n)return function(F)local C=t.number(F)if not C then return false end if F>=n then return true else return false end end end function t.numberMax(n)return function(F)local C=t.number(F)if not C then return false end if F<=n then return true else return false end end end function t.numberMinExclusive(n)return function(F)local C=t.number(F)if not C then return false end if n<F then return true else return false end end end function t.numberMaxExclusive(n)return function(F)local C=t.number(F)if not C then return false end if F<n then return true else return false end end end t.numberPositive=t.numberMinExclusive(0)t.numberNegative=t.numberMaxExclusive(0)function t.numberConstrained(n,F)assert(t.number(n)and t.number(F))local C=t.numberMin(n)local a=t.numberMax(F)return function(n)local F=C(n)if not F then return false end local E=a(n)if not E then return false end return true end end function t.numberConstrainedExclusive(n,F)assert(t.number(n)and t.number(F))local C=t.numberMinExclusive(n)local a=t.numberMaxExclusive(F)return function(n)local F=C(n)if not F then return false end local E=a(n)if not E then return false end return true end end function t.match(n)assert(t.string(n))return function(F)local C=t.string(F)if not C then return false end if string.match(F,n)==nil then return false end return true end end function t.optional(n)assert(t.callback(n))return function(F)if F==nil then return true end local C=n(F)if C then return true else return false end end end function t.tuple(...)local n={...}return function(...)local F={...}for n,C in ipairs(n)do local a=C(F[n])if a==false then return false end end return true end end function t.keys(n)assert(t.callback(n))return function(F)local C=t.table(F)if C==false then return false end for F in pairs(F)do local C=n(F)if C==false then return false end end return true end end function t.values(n)assert(t.callback(n))return function(F)local C=t.table(F)if C==false then return false end for F,C in pairs(F)do local a=n(C)if a==false then return false end end return true end end function t.map(n,F)assert(t.callback(n),t.callback(F))local C=t.keys(n)local a=t.values(F)return function(n)local F=C(n)if not F then return false end local E=a(n)if not E then return false end return true end end function t.set(n)return t.map(n,t.literal(true))end do local n=t.keys(t.integer)function t.array(F)assert(t.callback(F))local C=t.values(F)return function(F)local a=n(F)if a==false then return false end local E=0 for n in ipairs(F)do E=E+1 end for n in pairs(F)do if n<1 or n>E then return false end end local l=C(F)if not l then return false end return true end end function t.strictArray(...)local F={...}assert((t.array(t.callback))(F))return function(C)local a=n(C)if a==false then return false end if#F<#C then return false end for n,F in pairs(F)do local a=F(C[n])if not a then return false end end return true end end end do local n=t.array(t.callback)function t.union(...)local F={...}assert(n(F))return function(n)for F,C in ipairs(F)do if C(n)then return true end end return false end end function t.intersection(...)local F={...}assert(n(F))return function(n)for F,C in ipairs(F)do local a=C(n)if not a then return false end end return true end end end do local n=t.map(t.any,t.callback)function t.interface(F)assert(n(F))return function(n)local C=t.table(n)if C==false then return false end for F,C in pairs(F)do local a=C(n[F])if a==false then return false end end return true end end function t.strictInterface(F)assert(n(F))return function(n)local C=t.table(n)if C==false then return false end for F,C in pairs(F)do local a=C(n[F])if a==false then return false end end for n in pairs(n)do if not F[n]then return false end end return true end end end function t.instanceOf(n)assert(t.string(n))return function(F)local C=t.Instance(F)if not C then return false end if F.ClassName~=n then return false end return true end end t.instance=t.instanceOf function t.instanceIsA(n)assert(t.string(n))return function(F)local C=t.Instance(F)if not C then return false end if not F:IsA(n)then return false end return true end end function t.enum(n)assert(t.Enum(n))return function(F)local C=t.EnumItem(F)if not C then return false end if F.EnumType==n then return true else return false end end end do local n=t.tuple(t.callback,t.callback)function t.wrap(F,C)assert(n(F,C))return function(...)assert(C(...))return F(...)end end end function t.strict(n)return function(...)assert(n(...))end end do local n=t.map(t.string,t.callback)function t.children(F)assert(n(F))return function(n)local C=t.Instance(n)if not C then return false end local a={}for n,C in ipairs(n:GetChildren())do local E=C.Name if F[E]then if a[E]then return false end a[E]=C end end for n,F in pairs(F)do local C=F(a[n])if not C then return false end end return true end end end return{t=t}


t.Axes = primitive("Axes")
t.BrickColor = primitive("BrickColor")
t.CFrame = primitive("CFrame")
t.Color3 = primitive("Color3")
t.ColorSequence = primitive("ColorSequence")
t.ColorSequenceKeypoint = primitive("ColorSequenceKeypoint")
t.DockWidgetPluginGuiInfo = primitive("DockWidgetPluginGuiInfo")
t.Faces = primitive("Faces")
t.Instance = primitive("Instance")
t.NumberRange = primitive("NumberRange")
t.NumberSequence = primitive("NumberSequence")
t.NumberSequenceKeypoint = primitive("NumberSequenceKeypoint")
t.PathWaypoint = primitive("PathWaypoint")
t.PhysicalProperties = primitive("PhysicalProperties")
t.Random = primitive("Random")
t.Ray = primitive("Ray")
t.Rect = primitive("Rect")
t.Region3 = primitive("Region3")
t.Region3int16 = primitive("Region3int16")
t.TweenInfo = primitive("TweenInfo")
t.UDim = primitive("UDim")
t.UDim2 = primitive("UDim2")
t.Vector2 = primitive("Vector2")
t.Vector3 = primitive("Vector3")
t.Vector3int16 = primitive("Vector3int16")
t.Enum = primitive("Enum")
t.EnumItem = primitive("EnumItem")
t.RBXScriptSignal = primitive("RBXScriptSignal")
t.RBXScriptConnection = primitive("RBXScriptConnection")

function t.literal(...)
	local size = select("#", ...)
	if size == 1 then
		local literal = ...
		return function(value)
			if value ~= literal then
				return false
			end

			return true
		end
	else
		local literals = {}
		for i = 1, size do
			local value = select(i, ...)
			literals[i] = t.literal(value)
		end

		return t.union(table.unpack(literals, 1, size))
	end
end

t.exactly = t.literal

function t.keyOf(keyTable)
	local keys = {}
	local length = 0
	for key in pairs(keyTable) do
		length = length + 1
		keys[length] = key
	end

	return t.literal(table.unpack(keys, 1, length))
end

function t.valueOf(valueTable)
	local values = {}
	local length = 0
	for _, value in pairs(valueTable) do
		length = length + 1
		values[length] = value
	end

	return t.literal(table.unpack(values, 1, length))
end

function t.integer(value)
	local success = t.number(value)
	if not success then
		return false
	end

	if value % 1 == 0 then
		return true
	else
		return false
	end
end

function t.numberMin(min)
	return function(value)
		local success = t.number(value)
		if not success then
			return false
		end
		if value >= min then
			return true
		else
			return false
		end
	end
end

function t.numberMax(max)
	return function(value)
		local success = t.number(value)
		if not success then
			return false
		end
		if value <= max then
			return true
		else
			return false
		end
	end
end

function t.numberMinExclusive(min)
	return function(value)
		local success = t.number(value)
		if not success then
			return false
		end
		if min < value then
			return true
		else
			return false
		end
	end
end

function t.numberMaxExclusive(max)
	return function(value)
		local success = t.number(value)
		if not success then
			return false
		end
		if value < max then
			return true
		else
			return false
		end
	end
end

t.numberPositive = t.numberMinExclusive(0)
t.numberNegative = t.numberMaxExclusive(0)

function t.numberConstrained(min, max)
	assert(t.number(min) and t.number(max))
	local minCheck = t.numberMin(min)
	local maxCheck = t.numberMax(max)
	return function(value)
		local minSuccess = minCheck(value)
		if not minSuccess then
			return false
		end

		local maxSuccess = maxCheck(value)
		if not maxSuccess then
			return false
		end

		return true
	end
end

function t.numberConstrainedExclusive(min, max)
	assert(t.number(min) and t.number(max))
	local minCheck = t.numberMinExclusive(min)
	local maxCheck = t.numberMaxExclusive(max)
	return function(value)
		local minSuccess = minCheck(value)
		if not minSuccess then
			return false
		end

		local maxSuccess = maxCheck(value)
		if not maxSuccess then
			return false
		end

		return true
	end
end

function t.match(pattern)
	assert(t.string(pattern))
	return function(value)
		local stringSuccess = t.string(value)
		if not stringSuccess then
			return false
		end

		if string.match(value, pattern) == nil then
			return false
		end

		return true
	end
end

function t.optional(check)
	assert(t.callback(check))
	return function(value)
		if value == nil then
			return true
		end
		local success = check(value)
		if success then
			return true
		else
			return false
		end
	end
end

function t.tuple(...)
	local checks = { ... }
	return function(...)
		local args = { ... }
		for i, check in ipairs(checks) do
			local success = check(args[i])
			if success == false then
				return false
			end
		end

		return true
	end
end

function t.keys(check)
	assert(t.callback(check))
	return function(value)
		local tableSuccess = t.table(value)
		if tableSuccess == false then
			return false
		end

		for key in pairs(value) do
			local success = check(key)
			if success == false then
				return false
			end
		end

		return true
	end
end

function t.values(check)
	assert(t.callback(check))
	return function(value)
		local tableSuccess = t.table(value)
		if tableSuccess == false then
			return false
		end

		for _, val in pairs(value) do
			local success = check(val)
			if success == false then
				return false
			end
		end

		return true
	end
end

function t.map(keyCheck, valueCheck)
	assert(t.callback(keyCheck), t.callback(valueCheck))
	local keyChecker = t.keys(keyCheck)
	local valueChecker = t.values(valueCheck)
	return function(value)
		local keySuccess = keyChecker(value)
		if not keySuccess then
			return false
		end

		local valueSuccess = valueChecker(value)
		if not valueSuccess then
			return false
		end

		return true
	end
end

function t.set(valueCheck)
	return t.map(valueCheck, t.literal(true))
end

do
	local arrayKeysCheck = t.keys(t.integer)

	function t.array(check)
		assert(t.callback(check))
		local valuesCheck = t.values(check)
		return function(value)
			local keySuccess = arrayKeysCheck(value)
			if keySuccess == false then
				return false
			end

			-- # is unreliable for sparse arrays
			-- Count upwards using ipairs to avoid false positives from the behavior of #
			local arraySize = 0

			for _ in ipairs(value) do
				arraySize = arraySize + 1
			end

			for key in pairs(value) do
				if key < 1 or key > arraySize then
					return false
				end
			end

			local valueSuccess = valuesCheck(value)
			if not valueSuccess then
				return false
			end

			return true
		end
	end

	function t.strictArray(...)
		local valueTypes = { ... }
		assert(t.array(t.callback)(valueTypes))

		return function(value)
			local keySuccess = arrayKeysCheck(value)
			if keySuccess == false then
				return false
			end

			-- If there's more than the set array size, disallow
			if #valueTypes < #value then
				return false
			end

			for idx, typeFn in pairs(valueTypes) do
				local typeSuccess = typeFn(value[idx])
				if not typeSuccess then
					return false
				end
			end

			return true
		end
	end
end

do
	local callbackArray = t.array(t.callback)

	function t.union(...)
		local checks = { ... }
		assert(callbackArray(checks))

		return function(value)
			for _, check in ipairs(checks) do
				if check(value) then
					return true
				end
			end

			return false
		end
	end

	function t.intersection(...)
		local checks = { ... }
		assert(callbackArray(checks))

		return function(value)
			for _, check in ipairs(checks) do
				local success = check(value)
				if not success then
					return false
				end
			end

			return true
		end
	end
end

do
	local checkInterface = t.map(t.any, t.callback)

	function t.interface(checkTable)
		assert(checkInterface(checkTable))
		return function(value)
			local tableSuccess = t.table(value)
			if tableSuccess == false then
				return false
			end

			for key, check in pairs(checkTable) do
				local success = check(value[key])
				if success == false then
					return false
				end
			end
			return true
		end
	end

	function t.strictInterface(checkTable)
		assert(checkInterface(checkTable))
		return function(value)
			local tableSuccess = t.table(value)
			if tableSuccess == false then
				return false
			end

			for key, check in pairs(checkTable) do
				local success = check(value[key])
				if success == false then
					return false
				end
			end

			for key in pairs(value) do
				if not checkTable[key] then
					return false
				end
			end

			return true
		end
	end
end

function t.instanceOf(className)
	assert(t.string(className))

	return function(value)
		local instanceSuccess = t.Instance(value)
		if not instanceSuccess then
			return false
		end

		if value.ClassName ~= className then
			return false
		end

		return true
	end
end

t.instance = t.instanceOf

function t.instanceIsA(className)
	assert(t.string(className))

	return function(value)
		local instanceSuccess = t.Instance(value)
		if not instanceSuccess then
			return false
		end

		if not value:IsA(className) then
			return false
		end

		return true
	end
end

function t.enum(enum)
	assert(t.Enum(enum))
	return function(value)
		local enumItemSuccess = t.EnumItem(value)
		if not enumItemSuccess then
			return false
		end

		if value.EnumType == enum then
			return true
		else
			return false
		end
	end
end

do
	local checkWrap = t.tuple(t.callback, t.callback)

	function t.wrap(callback, checkArgs)
		assert(checkWrap(callback, checkArgs))
		return function(...)
			assert(checkArgs(...))
			return callback(...)
		end
	end
end

function t.strict(check)
	return function(...)
		assert(check(...))
	end
end

do
	local checkChildren = t.map(t.string, t.callback)
	function t.children(checkTable)
		assert(checkChildren(checkTable))

		return function(value)
			local instanceSuccess = t.Instance(value)
			if not instanceSuccess then
				return false
			end

			local childrenByName = {}
			for _, child in ipairs(value:GetChildren()) do
				local name = child.Name
				if checkTable[name] then
					if childrenByName[name] then
						return false
					end

					childrenByName[name] = child
				end
			end

			for name, check in pairs(checkTable) do
				local success = check(childrenByName[name])
				if not success then
					return false
				end
			end

			return true
		end
	end
end

return { t = t }
