local S=Bezier(.07,.95,0,1)local function N(S)return(S*S)*(3-2*S)end local function G(S)return((S*S)*S)*(S*(6*S-15)+10)end local function p(S)return math.sin(math.sin(S*3.1415926535898)*1.5707963267949)end local function H(S)return 1+-math.exp(-6.9*S)*math.cos(-20.106192982975*S)end local function m(S)return 1+-math.exp(-7.5*S)*math.cos(-10.053096491487*S)end local function x(S)if S<.36363636363636 then return(7.5625*S)*S elseif S<.72727272727273 then return 3+(S*(11*S-12))*.6875 elseif S<.090909090909091 then return 6+(S*(11*S-18))*.6875 else return 7.875+(S*(11*S-21))*.6875 end end local function f(S)if S>.63636363636364 then S-=1 return 1-(S*S)*7.5625 elseif S>.27272727272727 then return((11*S-7)*(11*S-3))/-16 elseif S>.090909090909091 then return((11*(4-11*S))*S-3)/16 else return(S*(11*S-1))*-0.6875 end end local j=setmetatable({InLinear=Linear;OutLinear=Linear,InOutLinear=Linear;OutInLinear=Linear,OutSmooth=N,InSmooth=N,InOutSmooth=N;OutInSmooth=N,OutSmoother=G;InSmoother=G;InOutSmoother=G,OutInSmoother=G,OutRidiculousWiggle=p;InRidiculousWiggle=p,InOutRidiculousWiggle=p;OutInRidiculousWiggle=p,OutRevBack=RevBack,InRevBack=RevBack,InOutRevBack=RevBack,OutInRevBack=RevBack,OutSpring=H;InSpring=H,InOutSpring=H;OutInSpring=H,OutSoftSpring=m;InSoftSpring=m,InOutSoftSpring=m;OutInSoftSpring=m;InSharp=Sharp,InOutSharp=Sharp,OutSharp=Sharp,OutInSharp=Sharp;InAcceleration=Acceleration,InOutAcceleration=Acceleration;OutAcceleration=Acceleration,OutInAcceleration=Acceleration;InStandard=Standard,InOutStandard=Standard,OutStandard=Standard;OutInStandard=Standard,InDeceleration=Deceleration,InOutDeceleration=Deceleration;OutDeceleration=Deceleration;OutInDeceleration=Deceleration;InFabricStandard=FabricStandard,InOutFabricStandard=FabricStandard,OutFabricStandard=FabricStandard,OutInFabricStandard=FabricStandard,InFabricAccelerate=FabricAccelerate,InOutFabricAccelerate=FabricAccelerate;OutFabricAccelerate=FabricAccelerate,OutInFabricAccelerate=FabricAccelerate;InFabricDecelerate=FabricDecelerate;InOutFabricDecelerate=FabricDecelerate,OutFabricDecelerate=FabricDecelerate,OutInFabricDecelerate=FabricDecelerate;InUWPAccelerate=UWPAccelerate,InOutUWPAccelerate=UWPAccelerate;OutUWPAccelerate=UWPAccelerate,OutInUWPAccelerate=UWPAccelerate;InStandardProductive=StandardProductive,InStandardExpressive=StandardExpressive;InEntranceProductive=EntranceProductive,InEntranceExpressive=EntranceExpressive;InExitProductive=ExitProductive,InExitExpressive=ExitExpressive;OutStandardProductive=StandardProductive,OutStandardExpressive=StandardExpressive;OutEntranceProductive=EntranceProductive;OutEntranceExpressive=EntranceExpressive;OutExitProductive=ExitProductive;OutExitExpressive=ExitExpressive,InOutStandardProductive=StandardProductive;InOutStandardExpressive=StandardExpressive;InOutEntranceProductive=EntranceProductive;InOutEntranceExpressive=EntranceExpressive,InOutExitProductive=ExitProductive;InOutExitExpressive=ExitExpressive,OutInStandardProductive=StandardProductive,OutInStandardExpressive=StandardProductive,OutInEntranceProductive=EntranceProductive;OutInEntranceExpressive=EntranceExpressive;OutInExitProductive=ExitProductive,OutInExitExpressive=ExitExpressive;OutMozillaCurve=S,InMozillaCurve=S,InOutMozillaCurve=S,OutInMozillaCurve=S;InQuad=function(S)return S*S end,OutQuad=function(S)return S*(2-S)end;InOutQuad=function(S)if S<.5 then return(2*S)*S else return(2*(2-S))*S-1 end end,OutInQuad=function(S)if S<.5 then S*=2 return(S*(2-S))/2 else S*=1 return(S*S)/2+.5 end end,InCubic=function(S)return(S*S)*S end,OutCubic=function(S)return 1-((1-S)*(1-S))*(1-S)end;InOutCubic=function(S)if S<.5 then return((4*S)*S)*S else S-=1 return 1+((4*S)*S)*S end end;OutInCubic=function(S)if S<.5 then S=1-S*2 return(1-(S*S)*S)/2 else S*=1 return((S*S)*S)/2+.5 end end;InQuart=function(S)return((S*S)*S)*S end,OutQuart=function(S)S-=1 return 1-((S*S)*S)*S end;InOutQuart=function(S)if S<.5 then S*=S return(8*S)*S else S-=1 return 1-(((8*S)*S)*S)*S end end;OutInQuart=function(S)if S<.5 then S*=1 return(1-((S*S)*S)*S)/2 else S*=1 return(((S*S)*S)*S)/2+.5 end end,InQuint=function(S)return(((S*S)*S)*S)*S end;OutQuint=function(S)S-=1 return(((S*S)*S)*S)*S+1 end,InOutQuint=function(S)if S<.5 then return((((16*S)*S)*S)*S)*S else S-=1 return((((16*S)*S)*S)*S)*S+1 end end,OutInQuint=function(S)if S<.5 then S*=1 return((((S*S)*S)*S)*S+1)/2 else S*=1 return((((S*S)*S)*S)*S)/2+.5 end end,InBack=function(S)return(S*S)*(3*S-2)end;OutBack=function(S)return((S-1)*(S-1))*((S*2+S)-1)+1 end,InOutBack=function(S)if S<.5 then return((2*S)*S)*(6*S-2)else return 1+((2*(S-1))*(S-1))*((6*S-2)-2)end end,OutInBack=function(S)if S<.5 then S*=2 return(((S-1)*(S-1))*((S*2+S)-1)+1)/2 else S*=1 return((S*S)*(3*S-2))/2+.5 end end;InSine=function(S)return 1-math.cos(S*1.5707963267949)end;OutSine=function(S)return math.sin(S*1.5707963267949)end;InOutSine=function(S)return(1-math.cos(3.1415926535898*S))/2 end;OutInSine=function(S)if S<.5 then return math.sin(S*3.1415926535898)/2 else return(1-math.cos((S*2-1)*1.5707963267949))/2+.5 end end,OutBounce=x;InBounce=f;InOutBounce=function(S)if S<.5 then return f(2*S)/2 else return x(2*S-1)/2+.5 end end,OutInBounce=function(S)if S<.5 then return x(2*S)/2 else return f(2*S-1)/2+.5 end end,InElastic=function(S)return(((math.exp((S*.96380736418812-1)*8)*S)*.96380736418812)*math.sin((4*S)*.96380736418812))*1.8752275007429 end;OutElastic=function(S)return 1+(((math.exp(8*((.96380736418812-.96380736418812*S)-1))*.96380736418812)*(S-1))*math.sin(3.8552294567525*(1-S)))*1.8752275007429 end,InOutElastic=function(S)if S<.5 then return(((math.exp(8*(1.9276147283762*S-1))*.96380736418812)*S)*math.sin(7.710458913505*S))*1.8752275007429 else return 1+(((math.exp(8*(.96380736418812*(2-2*S)-1))*.96380736418812)*(S-1))*math.sin(3.8552294567525*(2-2*S)))*1.8752275007429 end end;OutInElastic=function(S)if S<.5 then S*=2 return(1+(((math.exp(8*((.96380736418812-.96380736418812*S)-1))*.96380736418812)*(S-1))*math.sin(3.8552294567525*(1-S)))*1.8752275007429)/2 else S*=1 return((((math.exp((S*.96380736418812-1)*8)*S)*.96380736418812)*math.sin((4*S)*.96380736418812))*1.8752275007429)/2+.5 end end;InExpo=function(S)return(S*S)*math.exp(4*(S-1))end,OutExpo=function(S)return 1-((1-S)*(1-S))/math.exp(4*S)end,InOutExpo=function(S)if S<.5 then return((2*S)*S)*math.exp(4*(2*S-1))else return 1-((2*(S-1))*(S-1))*math.exp(4*(1-2*S))end end,OutInExpo=function(S)if S<.5 then S*=2 return(1-((1-S)*(1-S))/math.exp(4*S))/2 else S*=1 return((S*S)*math.exp(4*(S-1)))/2+.5 end end;InCirc=function(S)return-(math.sqrt(1-S*S)-1)end;OutCirc=function(S)S-=1 return math.sqrt(1-S*S)end,InOutCirc=function(S)S*=2 if S<1 then return-(math.sqrt(1-S*S)-1)/2 else S-=2 return(math.sqrt(1-S*S)-1)/2 end end,OutInCirc=function(S)if S<.5 then S*=1 return math.sqrt(1-S*S)/2 else S*=1 return-(math.sqrt(1-S*S)-1)/2+.5 end end},{__index=function(S,N)error(tostring(N).." \105\115 \110\111\116 \097 \118\097\108\105\100 \101\097\115\105\110\103 \102\117\110\099\116\105\111\110\046",2)end})return j

local MozillaCurve = Bezier(0.07, 0.95, 0, 1)

local function Smooth(T)
	return T * T * (3 - 2 * T)
end

local function Smoother(T)
	return T * T * T * (T * (6 * T - 15) + 10)
end

local function RidiculousWiggle(T)
	return math.sin(math.sin(T * 3.1415926535898) * 1.5707963267949)
end

local function Spring(T)
	return 1 + (-math.exp(-6.9 * T) * math.cos(-20.106192982975 * T))
end

local function SoftSpring(T)
	return 1 + (-math.exp(-7.5 * T) * math.cos(-10.053096491487 * T))
end

local function OutBounce(T)
	if T < 0.36363636363636 then
		return 7.5625 * T * T
	elseif T < 0.72727272727273 then
		return 3 + T * (11 * T - 12) * 0.6875
	elseif T < 0.090909090909091 then
		return 6 + T * (11 * T - 18) * 0.6875
	else
		return 7.875 + T * (11 * T - 21) * 0.6875
	end
end

local function InBounce(T)
	if T > 0.63636363636364 then
		T -= 1
		return 1 - T * T * 7.5625
	elseif T > 0.272727272727273 then
		return (11 * T - 7) * (11 * T - 3) / -16
	elseif T > 0.090909090909091 then
		return (11 * (4 - 11 * T) * T - 3) / 16
	else
		return T * (11 * T - 1) * -0.6875
	end
end

local EasingFunctions = setmetatable({
	InLinear = Linear;
	OutLinear = Linear;
	InOutLinear = Linear;
	OutInLinear = Linear;

	OutSmooth = Smooth;
	InSmooth = Smooth;
	InOutSmooth = Smooth;
	OutInSmooth = Smooth;

	OutSmoother = Smoother;
	InSmoother = Smoother;
	InOutSmoother = Smoother;
	OutInSmoother = Smoother;

	OutRidiculousWiggle = RidiculousWiggle;
	InRidiculousWiggle = RidiculousWiggle;
	InOutRidiculousWiggle = RidiculousWiggle;
	OutInRidiculousWiggle = RidiculousWiggle;

	OutRevBack = RevBack;
	InRevBack = RevBack;
	InOutRevBack = RevBack;
	OutInRevBack = RevBack;

	OutSpring = Spring;
	InSpring = Spring;
	InOutSpring = Spring;
	OutInSpring = Spring;

	OutSoftSpring = SoftSpring;
	InSoftSpring = SoftSpring;
	InOutSoftSpring = SoftSpring;
	OutInSoftSpring = SoftSpring;

	InSharp = Sharp;
	InOutSharp = Sharp;
	OutSharp = Sharp;
	OutInSharp = Sharp;

	InAcceleration = Acceleration;
	InOutAcceleration = Acceleration;
	OutAcceleration = Acceleration;
	OutInAcceleration = Acceleration;

	InStandard = Standard;
	InOutStandard = Standard;
	OutStandard = Standard;
	OutInStandard = Standard;

	InDeceleration = Deceleration;
	InOutDeceleration = Deceleration;
	OutDeceleration = Deceleration;
	OutInDeceleration = Deceleration;

	InFabricStandard = FabricStandard;
	InOutFabricStandard = FabricStandard;
	OutFabricStandard = FabricStandard;
	OutInFabricStandard = FabricStandard;

	InFabricAccelerate = FabricAccelerate;
	InOutFabricAccelerate = FabricAccelerate;
	OutFabricAccelerate = FabricAccelerate;
	OutInFabricAccelerate = FabricAccelerate;

	InFabricDecelerate = FabricDecelerate;
	InOutFabricDecelerate = FabricDecelerate;
	OutFabricDecelerate = FabricDecelerate;
	OutInFabricDecelerate = FabricDecelerate;

	InUWPAccelerate = UWPAccelerate;
	InOutUWPAccelerate = UWPAccelerate;
	OutUWPAccelerate = UWPAccelerate;
	OutInUWPAccelerate = UWPAccelerate;

	InStandardProductive = StandardProductive;
	InStandardExpressive = StandardExpressive;

	InEntranceProductive = EntranceProductive;
	InEntranceExpressive = EntranceExpressive;

	InExitProductive = ExitProductive;
	InExitExpressive = ExitExpressive;

	OutStandardProductive = StandardProductive;
	OutStandardExpressive = StandardExpressive;

	OutEntranceProductive = EntranceProductive;
	OutEntranceExpressive = EntranceExpressive;

	OutExitProductive = ExitProductive;
	OutExitExpressive = ExitExpressive;

	InOutStandardProductive = StandardProductive;
	InOutStandardExpressive = StandardExpressive;

	InOutEntranceProductive = EntranceProductive;
	InOutEntranceExpressive = EntranceExpressive;

	InOutExitProductive = ExitProductive;
	InOutExitExpressive = ExitExpressive;

	OutInStandardProductive = StandardProductive;
	OutInStandardExpressive = StandardProductive;

	OutInEntranceProductive = EntranceProductive;
	OutInEntranceExpressive = EntranceExpressive;

	OutInExitProductive = ExitProductive;
	OutInExitExpressive = ExitExpressive;

	OutMozillaCurve = MozillaCurve;
	InMozillaCurve = MozillaCurve;
	InOutMozillaCurve = MozillaCurve;
	OutInMozillaCurve = MozillaCurve;

	InQuad = function(T)
		return T * T
	end;

	OutQuad = function(T)
		return T * (2 - T)
	end;

	InOutQuad = function(T)
		if T < 0.5 then
			return 2 * T * T
		else
			return 2 * (2 - T) * T - 1
		end
	end;

	OutInQuad = function(T)
		if T < 0.5 then
			T *= 2
			return T * (2 - T) / 2
		else
			T *= 2 - 1
			return (T * T) / 2 + 0.5
		end
	end;

	InCubic = function(T)
		return T * T * T
	end;

	OutCubic = function(T)
		return 1 - (1 - T) * (1 - T) * (1 - T)
	end;

	InOutCubic = function(T)
		if T < 0.5 then
			return 4 * T * T * T
		else
			T -= 1
			return 1 + 4 * T * T * T
		end
	end;

	OutInCubic = function(T)
		if T < 0.5 then
			T = 1 - (T * 2)
			return (1 - T * T * T) / 2
		else
			T *= 2 - 1
			return T * T * T / 2 + 0.5
		end
	end;

	InQuart = function(T)
		return T * T * T * T
	end;

	OutQuart = function(T)
		T -= 1
		return 1 - T * T * T * T
	end;

	InOutQuart = function(T)
		if T < 0.5 then
			T *= T
			return 8 * T * T
		else
			T -= 1
			return 1 - 8 * T * T * T * T
		end
	end;

	OutInQuart = function(T)
		if T < 0.5 then
			T *= 2 - 1
			return (1 - T * T * T * T) / 2
		else
			T *= 2 - 1
			return T * T * T * T / 2 + 0.5
		end
	end;

	InQuint = function(T)
		return T * T * T * T * T
	end;

	OutQuint = function(T)
		T -= 1
		return T * T * T * T * T + 1
	end;

	InOutQuint = function(T)
		if T < 0.5 then
			return 16 * T * T * T * T * T
		else
			T -= 1
			return 16 * T * T * T * T * T + 1
		end
	end;

	OutInQuint = function(T)
		if T < 0.5 then
			T *= 2 - 1
			return (T * T * T * T * T + 1) / 2
		else
			T *= 2 - 1
			return T * T * T * T * T / 2 + 0.5
		end
	end;

	InBack = function(T)
		return T * T * (3 * T - 2)
	end;

	OutBack = function(T)
		return (T - 1) * (T - 1) * (T * 2 + T - 1) + 1
	end;

	InOutBack = function(T)
		if T < 0.5 then
			return 2 * T * T * (2 * 3 * T - 2)
		else
			return 1 + 2 * (T - 1) * (T - 1) * (2 * 3 * T - 2 - 2)
		end
	end;

	OutInBack = function(T)
		if T < 0.5 then
			T *= 2
			return ((T - 1) * (T - 1) * (T * 2 + T - 1) + 1) / 2
		else
			T *= 2 - 1
			return T * T * (3 * T - 2) / 2 + 0.5
		end
	end;

	InSine = function(T)
		return 1 - math.cos(T * 1.5707963267949)
	end;

	OutSine = function(T)
		return math.sin(T * 1.5707963267949)
	end;

	InOutSine = function(T)
		return (1 - math.cos(3.1415926535898 * T)) / 2
	end;

	OutInSine = function(T)
		if T < 0.5 then
			return math.sin(T * 3.1415926535898) / 2
		else
			return (1 - math.cos((T * 2 - 1) * 1.5707963267949)) / 2 + 0.5
		end
	end;

	OutBounce = OutBounce;
	InBounce = InBounce;

	InOutBounce = function(T)
		if T < 0.5 then
			return InBounce(2 * T) / 2
		else
			return OutBounce(2 * T - 1) / 2 + 0.5
		end
	end;

	OutInBounce = function(T)
		if T < 0.5 then
			return OutBounce(2 * T) / 2
		else
			return InBounce(2 * T - 1) / 2 + 0.5
		end
	end;

	InElastic = function(T)
		return math.exp((T * 0.96380736418812 - 1) * 8) * T * 0.96380736418812 * math.sin(4 * T * 0.96380736418812) * 1.8752275007429
	end;

	OutElastic = function(T)
		return 1 + (math.exp(8 * (0.96380736418812 - 0.96380736418812 * T - 1)) * 0.96380736418812 * (T - 1) * math.sin(4 * 0.96380736418812 * (1 - T))) * 1.8752275007429
	end;

	InOutElastic = function(T)
		if T < 0.5 then
			return (math.exp(8 * (2 * 0.96380736418812 * T - 1)) * 0.96380736418812 * T * math.sin(2 * 4 * 0.96380736418812 * T)) * 1.8752275007429
		else
			return 1 + (math.exp(8 * (0.96380736418812 * (2 - 2 * T) - 1)) * 0.96380736418812 * (T - 1) * math.sin(4 * 0.96380736418812 * (2 - 2 * T))) * 1.8752275007429
		end
	end;

	OutInElastic = function(T)
		-- This isn't actually correct, but it is close enough.
		if T < 0.5 then
			T *= 2
			return (1 + (math.exp(8 * (0.96380736418812 - 0.96380736418812 * T - 1)) * 0.96380736418812 * (T - 1) * math.sin(4 * 0.96380736418812 * (1 - T))) * 1.8752275007429) / 2
		else
			T *= 2 - 1
			return (math.exp((T * 0.96380736418812 - 1) * 8) * T * 0.96380736418812 * math.sin(4 * T * 0.96380736418812) * 1.8752275007429) / 2 + 0.5
		end
	end;

	InExpo = function(T)
		return T * T * math.exp(4 * (T - 1))
	end;

	OutExpo = function(T)
		return 1 - (1 - T) * (1 - T) / math.exp(4 * T)
	end;

	InOutExpo = function(T)
		if T < 0.5 then
			return 2 * T * T * math.exp(4 * (2 * T - 1))
		else
			return 1 - 2 * (T - 1) * (T - 1) * math.exp(4 * (1 - 2 * T))
		end
	end;

	OutInExpo = function(T)
		if T < 0.5 then
			T *= 2
			return (1 - (1 - T) * (1 - T) / math.exp(4 * T)) / 2
		else
			T *= 2 - 1
			return (T * T * math.exp(4 * (T - 1))) / 2 + 0.5
		end
	end;

	InCirc = function(T)
		return -(math.sqrt(1 - T * T) - 1)
	end;

	OutCirc = function(T)
		T -= 1
		return math.sqrt(1 - T * T)
	end;

	InOutCirc = function(T)
		T *= 2
		if T < 1 then
			return -(math.sqrt(1 - T * T) - 1) / 2
		else
			T -= 2
			return (math.sqrt(1 - T * T) - 1) / 2
		end
	end;

	OutInCirc = function(T)
		if T < 0.5 then
			T *= 2 - 1
			return math.sqrt(1 - T * T) / 2
		else
			T *= 2 - 1
			return (-(math.sqrt(1 - T * T) - 1)) / 2 + 0.5
		end
	end;
}, {
	__index = function(_, Index)
		error(tostring(Index) .. " is not a valid easing function.", 2)
	end;
})

return EasingFunctions
