local i={}do local k={}function k.Create()local i={}local k=Instance.new("\066\105\110\100\097\098\108\101\069\118\101\110\116")local Q=nil local y=nil function i.fire(i,...)Q={...}y=select("\035",...)k:Fire()end function i.connect(T,i)if not i then error("\099\111\110\110\101\099\116\040\110\105\108\041",2)end return k.Event:connect(function()i(unpack(Q,1,y))end)end function i.wait(i)k.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,y)end return i end i.Signal=k function i.Create(i)return function(k)local Q=Instance.new(i)for i,k in pairs(k)do if type(i)=="\110\117\109\098\101\114"then k.Parent=Q else Q[i]=k end end return Q end end local function Q(i,k,Q)return math.max(math.min(k,Q),i)end i.Clamp=Q local function y()local i=workspace.CurrentCamera local k=i and i.ViewportSize.X or 0 local Q=i and i.ViewportSize.Y or 0 if k==0 then return 1024 else if k>Q then return k else return Q end end end i.ViewSizeX=y local function T()local i=workspace.CurrentCamera local k=i and i.ViewportSize.X or 0 local Q=i and i.ViewportSize.Y or 0 if Q==0 then return 768 else if k>Q then return Q else return k end end end i.ViewSizeY=T local function Y()return y()/T()end i.AspectRatio=Y local function C(i)if i then local k=i:FindFirstChild("\072\117\109\097\110\111\105\100")if k then return i,k else return C(i.Parent)end end end i.FindChacterAncestor=C local function A(i,k,Q,y,T)return T:ScreenPointToRay(i,k)end i.GetUnitRay=A local j=workspace.FindPartOnRayWithIgnoreList local function H(i,k,Q)local y=Q or{}local T,Y=j(workspace,i,y)if T then if k and T.CanCollide==false then table.insert(y,T)return H(i,k,y)end return T,Y end return nil,nil end i.Raycast=H i.Round=function(i,k)k=k or 1 return math.floor((i+k/2)/k)*k end local function v(i)local k=Vector2.new(0,0)if#i>0 then for Q=1,#i,1 do k=k+i[Q]end k=k/#i end return k end i.AveragePoints=v local function K(i,k)return i+.1>k and i-.1<k end i.FuzzyEquals=K local z=0 UIS.InputBegan:connect(function(i,k)if not k then if i.UserInputType==Enum.UserInputType.Touch or i.UserInputType==Enum.UserInputType.MouseButton1 or i.UserInputType==Enum.UserInputType.MouseButton2 then z=tick()end end end)i.GetLastInput=function()return z end end local k={}local function Q(i)local Q=i and i.Character if Q then local y=k[i]if y and y.Parent==Q then return y else k[i]=nil for Q,y in pairs(Q:GetChildren())do if y:IsA("\072\117\109\097\110\111\105\100")then k[i]=y return y end end end end end local function y(i,k)local Q=CFrame.fromAxisAngle local y=(CFrame.new()).components local T=(CFrame.new()).inverse local Y=Vector3.new local C=math.acos local A=math.sqrt local j=1/math.sqrt(2)local H,v,K,z,m,W,S,s,F,a,B,u=y(T(i)*k)local G=(((z+s)+u)-1)/2 local t=Y(B-F,W-a,S-m)local N=k.p-i.p local U if G>=.999 then return 0,function(k)return i+N*k end elseif G<=-0.999 then U=math.pi z=(z+1)/2 s=(s+1)/2 u=(u+1)/2 if z>s and z>u then if z<.001 then t=Y(0,j,j)else local i=A(z)S=(S+m)/4 a=(a+W)/4 t=Y(i,S/i,a/i)end elseif s>u then if s<.001 then t=Y(j,0,j)else local i=A(s)S=(S+m)/4 B=(B+F)/4 t=Y(S/i,i,B/i)end else if u<.001 then t=Y(j,j,0)else local i=A(u)a=(a+W)/4 B=(B+F)/4 t=Y(a/i,B/i,i)end end else U=C(G)end return U,function(k)return i*Q(t,U*k)+N*k 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 clamp(low, high, num)
		return math.max(math.min(high, num), low)
	end
	Utility.Clamp = clamp

	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 AspectRatio()
		return ViewSizeX() / ViewSizeY()
	end
	Utility.AspectRatio = AspectRatio

	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 GetUnitRay(x, y, viewWidth, viewHeight, camera)
		return camera:ScreenPointToRay(x, y)
	end
	Utility.GetUnitRay = GetUnitRay

	local RayCastIgnoreList = workspace.FindPartOnRayWithIgnoreList
	local function Raycast(ray, ignoreNonCollidable, ignoreList)
		local ignoreList = ignoreList or {}
		local hitPart, hitPos = 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
		end
		return nil, nil
	end
	Utility.Raycast = Raycast

	Utility.Round = function(num, roundToNearest)
		roundToNearest = roundToNearest or 1
		return math.floor((num + roundToNearest / 2) / roundToNearest) * roundToNearest
	end

	local function AveragePoints(positions)
		local avgPos = Vector2.new(0, 0)
		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
			for _, child in pairs(character:GetChildren()) do
				if child:IsA("Humanoid") then
					humanoidCache[player] = child
					return child
				end
			end
		end
	end
end

local function CFrameInterpolator(c0, c1) -- (CFrame from, CFrame to) -> (float theta, (float fraction -> CFrame between))
	local fromAxisAngle = CFrame.fromAxisAngle
	local components = CFrame.new().components
	local inverse = CFrame.new().inverse
	local v3 = Vector3.new
	local acos = math.acos
	local sqrt = math.sqrt
	local invroot2 = 1 / math.sqrt(2)
	-- The expanded matrix
	local _, _, _, xx, yx, zx, xy, yy, zy, xz, yz, zz = components(inverse(c0) * c1)
	-- The cos-theta of the axisAngles from
	local cosTheta = (xx + yy + zz - 1) / 2
	-- Rotation axis
	local rotationAxis = v3(yz - zy, zx - xz, xy - yx)
	-- The position to tween through
	local positionDelta = (c1.p - c0.p)
	-- Theta
	local theta
	-- Catch degenerate cases
	if cosTheta >= 0.999 then
		-- Case same rotation, just return an interpolator over the positions
		return 0, function(t)
			return c0 + positionDelta * t
		end
	elseif cosTheta <= -0.999 then
		-- Case exactly opposite rotations, disambiguate
		theta = math.pi
		xx = (xx + 1) / 2
		yy = (yy + 1) / 2
		zz = (zz + 1) / 2
		if xx > yy and xx > zz then
			if xx < 0.001 then
				rotationAxis = v3(0, invroot2, invroot2)
			else
				local x = sqrt(xx)
				xy = (xy + yx) / 4
				xz = (xz + zx) / 4
				rotationAxis = v3(x, xy / x, xz / x)
			end
		elseif yy > zz then
			if yy < 0.001 then
				rotationAxis = v3(invroot2, 0, invroot2)
			else
				local y = sqrt(yy)
				xy = (xy + yx) / 4
				yz = (yz + zy) / 4
				rotationAxis = v3(xy / y, y, yz / y)
			end
		else
			if zz < 0.001 then
				rotationAxis = v3(invroot2, invroot2, 0)
			else
				local z = sqrt(zz)
				xz = (xz + zx) / 4
				yz = (yz + zy) / 4
				rotationAxis = v3(xz / z, yz / z, z)
			end
		end
	else
		-- Normal case, get theta from cosTheta
		theta = acos(cosTheta)
	end
	-- Return the interpolator
	return theta, function(t)
		return c0 * fromAxisAngle(rotationAxis, theta * t) + positionDelta * t
	end
end
