local P={}do local O={}function O.Create()local P={}local O=Instance.new("\066\105\110\100\097\098\108\101\069\118\101\110\116")local Q=nil local G=nil function P.fire(P,...)Q={...}G=select("\035",...)O:Fire()end function P.connect(v,P)if not P then error("\099\111\110\110\101\099\116\040\110\105\108\041",2)end return O.Event:connect(function()P(unpack(Q,1,G))end)end function P.wait(P)O.Event:wait()assert(Q,"\077\105\115\115\105\110\103 \097\114\103 \100\097\116\097\044 \108\105\107\101\108\121 \100\117\101 \116\111 \058\084\119\101\101\110\083\105\122\101\047\080\111\115\105\116\105\111\110 \099\111\114\114\117\112\116\105\110\103 \116\104\114\101\097\100\114\101\102\115\046")return unpack(Q,1,G)end return P end P.Signal=O function P.Create(P)return function(O)local Q=Instance.new(P)for P,O in pairs(O)do if type(P)=="\110\117\109\098\101\114"then O.Parent=Q else Q[P]=O end end return Q end end local function Q()local P=workspace.CurrentCamera local O=P and P.ViewportSize.X or 0 local Q=P and P.ViewportSize.Y or 0 if O==0 then return 1024 else if O>Q then return O else return Q end end end P.ViewSizeX=Q local function G()local P=workspace.CurrentCamera local O=P and P.ViewportSize.X or 0 local Q=P and P.ViewportSize.Y or 0 if Q==0 then return 768 else if O>Q then return Q else return O end end end P.ViewSizeY=G local function v(P)if P then local O=P:FindFirstChild("\072\117\109\097\110\111\105\100")if O then return P,O else return v(P.Parent)end end end P.FindChacterAncestor=v local function T(P,O,Q)local G=Q or{}local v,n,j,U=RayCastIgnoreList(workspace,P,G)if v then if O and v.CanCollide==false then table.insert(G,v)return T(P,O,G)end return v,n,j,U end return nil,nil end P.Raycast=T local function n(P)local O=ZERO_VECTOR2 if#P>0 then for Q=1,#P,1 do O=O+P[Q]end O=O/#P end return O end P.AveragePoints=n local function j(P,O)return P+.1>O and P-.1<O end P.FuzzyEquals=j local U=0 UIS.InputBegan:connect(function(P,O)if not O then if P.UserInputType==Enum.UserInputType.Touch or P.UserInputType==Enum.UserInputType.MouseButton1 or P.UserInputType==Enum.UserInputType.MouseButton2 then U=tick()end end end)P.GetLastInput=function()return U end end local O={}local function Q(P)local Q=P and P.Character if Q then local G=O[P]if G and G.Parent==Q then return G else O[P]=nil local G=Q:FindFirstChildOfClass("\072\117\109\097\110\111\105\100")if G then O[P]=G end return G end end end
--------------------------UTIL LIBRARY-------------------------------
local Utility = {}
do
	local Signal = {}
	function Signal.Create()
		local sig = {}

		local mSignaler = Instance.new("BindableEvent")

		local mArgData = nil
		local mArgDataCount = nil

		function sig:fire(...)
			mArgData = { ... }
			mArgDataCount = select("#", ...)
			mSignaler:Fire()
		end

		function sig:connect(f)
			if not f then
				error("connect(nil)", 2)
			end
			return mSignaler.Event:connect(function()
				f(unpack(mArgData, 1, mArgDataCount))
			end)
		end

		function sig:wait()
			mSignaler.Event:wait()
			assert(mArgData, "Missing arg data, likely due to :TweenSize/Position corrupting threadrefs.")
			return unpack(mArgData, 1, mArgDataCount)
		end

		return sig
	end
	Utility.Signal = Signal

	function Utility.Create(instanceType)
		return function(data)
			local obj = Instance.new(instanceType)
			for k, v in pairs(data) do
				if type(k) == "number" then
					v.Parent = obj
				else
					obj[k] = v
				end
			end
			return obj
		end
	end

	local function ViewSizeX()
		local camera = workspace.CurrentCamera
		local x = camera and camera.ViewportSize.X or 0
		local y = camera and camera.ViewportSize.Y or 0
		if x == 0 then
			return 1024
		else
			if x > y then
				return x
			else
				return y
			end
		end
	end
	Utility.ViewSizeX = ViewSizeX

	local function ViewSizeY()
		local camera = workspace.CurrentCamera
		local x = camera and camera.ViewportSize.X or 0
		local y = camera and camera.ViewportSize.Y or 0
		if y == 0 then
			return 768
		else
			if x > y then
				return y
			else
				return x
			end
		end
	end
	Utility.ViewSizeY = ViewSizeY

	local function FindChacterAncestor(part)
		if part then
			local humanoid = part:FindFirstChild("Humanoid")
			if humanoid then
				return part, humanoid
			else
				return FindChacterAncestor(part.Parent)
			end
		end
	end
	Utility.FindChacterAncestor = FindChacterAncestor

	local function Raycast(ray, ignoreNonCollidable, ignoreList)
		local ignoreList = ignoreList or {}
		local hitPart, hitPos, hitNorm, hitMat = RayCastIgnoreList(workspace, ray, ignoreList)
		if hitPart then
			if ignoreNonCollidable and hitPart.CanCollide == false then
				table.insert(ignoreList, hitPart)
				return Raycast(ray, ignoreNonCollidable, ignoreList)
			end
			return hitPart, hitPos, hitNorm, hitMat
		end
		return nil, nil
	end
	Utility.Raycast = Raycast

	local function AveragePoints(positions)
		local avgPos = ZERO_VECTOR2
		if #positions > 0 then
			for i = 1, #positions do
				avgPos = avgPos + positions[i]
			end
			avgPos = avgPos / #positions
		end
		return avgPos
	end
	Utility.AveragePoints = AveragePoints

	local function FuzzyEquals(numa, numb)
		return numa + 0.1 > numb and numa - 0.1 < numb
	end
	Utility.FuzzyEquals = FuzzyEquals

	local LastInput = 0
	UIS.InputBegan:connect(function(inputObject, wasSunk)
		if not wasSunk then
			if
				inputObject.UserInputType == Enum.UserInputType.Touch
				or inputObject.UserInputType == Enum.UserInputType.MouseButton1
				or inputObject.UserInputType == Enum.UserInputType.MouseButton2
			then
				LastInput = tick()
			end
		end
	end)
	Utility.GetLastInput = function()
		return LastInput
	end
end

local humanoidCache = {}
local function findPlayerHumanoid(player)
	local character = player and player.Character
	if character then
		local resultHumanoid = humanoidCache[player]
		if resultHumanoid and resultHumanoid.Parent == character then
			return resultHumanoid
		else
			humanoidCache[player] = nil -- Bust Old Cache
			local humanoid = character:FindFirstChildOfClass("Humanoid")
			if humanoid then
				humanoidCache[player] = humanoid
			end
			return humanoid
		end
	end
end
