local g=math.pi local C=2*g local Q,D=math.cos,math.sin local q=math.sqrt local S=math.atan2 local W=math.max local z=Vector3.new local X=CFrame.new local t=z()local R={1;0,0,0}local L={}local function x(g,C,Q,D,q)local S=1-q return((((g*S)*S)*S+(((3*g+Q)*q)*S)*S)+(((3*C-D)*q)*q)*S)+((C*q)*q)*q end L.BezierPosition=x local function v(g,C,Q,D,q)local S=1-q return((Q*S)*S+((2*(3*(C-g)-(D+Q)))*q)*S)+(D*q)*q end L.BezierVelocity=v local function s(g,C)local Q,D,q,S,W,z,X,t=g[1],g[2],g[3],g[4],C[1],C[2],C[3],C[4]return{((Q*W-D*z)-q*X)-S*t;((Q*z+D*W)+q*t)-S*X;((Q*X-D*t)+q*W)+S*z,((Q*t+D*X)-q*z)+S*W}end L.Qmul=s local function n(g)local C,Q,D,q=g[1],g[2],g[3],g[4]local S=((C*C+Q*Q)+D*D)+q*q if S>0 then return{C/S,-Q/S,-D/S,-q/S}else return{0;0,0;0}end end L.Qinv=n local function p(W,z,X)X=X or 0 local t,R,L,x=W[1],W[2],W[3],W[4]local v=(R*R+L*L)+x*x if v>0 then local g=q(v)local W=(t*t+v)^(.5*z)local s=z*(S(g,t)+C*X)local n=(W*D(s))/g return{W*Q(s),R*n;L*n,x*n}else if t<0 then local C=(-t)^z local S=((C*D(g*z))*q(3))/3 return{C*Q(g*z),S;S;S}else return{t^z;0;0,0}end end end L.Qpow=p local function J(g)local C,Q,D,S,z,X,t,R,L,x,v,s=g:components()local n=(S+R)+s if n>0 then local g=q(1+n)local C=.5/g return g*.5,(v-L)*C,(X-x)*C,(t-z)*C else local g=W(S,R,s)if g==S then local g=q(((1+S)-R)-s)local C=.5/g return(v-L)*C,.5*g,(t+z)*C,(X+x)*C elseif g==R then local g=q(((1-S)+R)-s)local C=.5/g return(X-x)*C,(t+z)*C,.5*g,(v+L)*C elseif g==s then local g=q(((1-S)-R)+s)local C=.5/g return(t-z)*C,(X+x)*C,(v+L)*C,.5*g end end end L.QuaternionFromCFrame=J local function f(g,C,Q)return s(g,p(s(C,n(g)),Q))end L.SlerpQuaternions=f local function e(g)local C,Q,D,q=g[1],g[2],g[3],g[4]local S,W,z=Q+Q,D+D,q+q local X,t,R=C*S,C*W,C*z local L,x,v,s,n,p=Q*S,Q*W,Q*z,D*W,D*z,q*z return 1-(s+p),x-R,v+t,x+R,1-(L+p),n-X,v-t,n+X,1-(L+s)end L.QuaternionToCFrame=e local function b(g,C,Q,D,q)local S,W,z,X=g,s(g,Q),s(C,n(D)),C local t,R,L=s(S,p(s(n(S),W),q)),s(W,p(s(n(W),z),q)),s(z,p(s(n(z),X),q))local x,v=s(t,p(s(n(t),R),q)),s(R,p(s(n(R),L),q))local J=s(x,p(s(n(x),v),q))return J end L.BezierRotation=b local function c(g,C,Q,D,q)local S,W,z,X=g,s(g,Q),s(C,n(D)),C local t,R,L=s(n(S),W),s(n(W),z),s(n(z),X)local x,v=s(t,p(s(n(t),R),q)),s(R,p(s(n(R),L),q))local J=s(x,p(s(n(x),v),q))return J end L.BezierAngularV=c local r={}local i=setmetatable({},{__index=function(g,C)local Q=r[C]if Q then local g,C,D=tick(),Q.t0,Q.t1 if g>C and g<D then return x(Q.x0,Q.x1,Q.v0,Q.v1,(g-C)/(D-C))elseif g>=D then return Q.x1 elseif g<=C then return Q.x0 end end end;__newindex=function(g,C,Q)local D=r[C]if D then local g,C,q,S,W,z,X=tick(),D.t0,D.t1 if g>C and g<q then local t=q-C local R=(g-C)/t S,W,z,X=x(D.x0,D.x1,D.v0,D.v1,R),Q,v(D.x0,D.x1,D.v0,D.v1,R)/t,Q*0 elseif g>=q then S,W,z,X=D.x1,Q,Q*0,Q*0 elseif g<=C then S,W,z,X=D.x0,Q,Q*0,Q*0 end local t,R=1,D.time local L=type(R)if L=="\110\117\109\098\101\114"then t=R elseif L=="\102\117\110\099\116\105\111\110"then t=R(S,W,z,X)end D.x0,D.x1,D.v0,D.v1,D.t0,D.t1,D.tweening=S,W,t*z,t*X,g,g+t,true else print("\065 \118\097\108\117\101 \110\097\109\101\100 "..(tostring(C).." \104\097\115 \110\111\116 \121\101\116 \098\101\101\110 \099\114\101\097\116\101\100\046"))end end})L.Tweens=i local B={}local A=setmetatable({},{__index=function(g,C)local Q=B[C]if Q then local g,C,D=tick(),Q.t0,Q.t1 if g>C and g<D then return b(Q.q0,Q.q1,Q.w0,Q.w1,(g-C)/(D-C))elseif g>=D then return Q.q1 elseif g<=C then return Q.q0 end end end,__newindex=function(g,C,Q)local D=B[C]if D then local g,C,q,S,W,z,X=tick(),D.t0,D.t1 if g>C and g<q then local t=q-C local L=(g-C)/t S,W,z,X=b(D.q0,D.q1,D.w0,D.w1,L),Q,p(c(D.q0,D.q1,D.w0,D.w1,L),1/t),R elseif g>=q then S,W,z,X=D.q1,Q,R,R elseif g<=C then S,W,z,X=D.q0,Q,R,R end if D.autoChoose then if((S[1]*W[1]+S[2]*W[2])+S[3]*W[3])+S[4]*W[4]<0 then W={-W[1],-W[2],-W[3],-W[4]}end end local t,L=1,D.time local x=type(L)if x=="\110\117\109\098\101\114"then t=L elseif x=="\102\117\110\099\116\105\111\110"then t=L(S,W,z,X)end D.q0,D.q1,D.w0,D.w1,D.t0,D.t1,D.tweening=S,W,p(z,t),p(X,t),g,g+t,true else print("\065 \118\097\108\117\101 \110\097\109\101\100 "..(tostring(C).." \104\097\115 \110\111\116 \121\101\116 \098\101\101\110 \099\114\101\097\116\101\100\046"))end end})L.QuaternionTweens=A local j={}local I=setmetatable({},{__index=function(g,C)local Q=j[C]if Q then local g,C,D=tick(),Q.t0,Q.t1 if g>C and g<D then local q=(g-C)/(D-C)local S=x(Q.x0,Q.x1,Q.v0,Q.v1,q)return X(S.x,S.y,S.z,e(b(Q.q0,Q.q1,Q.w0,Q.w1,q)))elseif g>=D then return Q.c1 elseif g<=C then return Q.c0 end end end,__newindex=function(g,C,Q)local D=j[C]if D then local g,C,q,S,W,z,L,s,n,f,r=tick(),D.t0,D.t1 if g>C and g<q then local X=q-C local e=(g-C)/X S,W,z,L,s,n,f,r=x(D.x0,D.x1,D.v0,D.v1,e),Q.p,v(D.x0,D.x1,D.v0,D.v1,e)/X,t,b(D.q0,D.q1,D.w0,D.w1,e),{J(Q)},p(c(D.q0,D.q1,D.w0,D.w1,e),1/X),R elseif g>=q then S,W,z,L,s,n,f,r=D.x1,Q.p,t,t,D.q1,{J(Q)},R,R elseif g<=C then S,W,z,L,s,n,f,r=D.x0,Q.p,t,t,D.q0,{J(Q)},R,R end local i,B,A,j,I,G,u,w=s[1]-n[1],s[2]-n[2],s[3]-n[3],s[4]-n[4],s[1]+n[1],s[2]+n[2],s[3]+n[3],s[4]+n[4]if((i*i+B*B)+A*A)+j*j>((I*I+G*G)+u*u)+w*w then n={-n[1],-n[2],-n[3],-n[4]}end local H=X(S.x,S.y,S.z,e(s))local d,O=1,D.time local h=type(O)if h=="\110\117\109\098\101\114"then d=O elseif h=="\102\117\110\099\116\105\111\110"then d=O(H,Q,S,W,z,L,s,n,f,r)end D.c0,D.c1,D.x0,D.x1,D.v0,D.v1,D.q0,D.q1,D.w0,D.w1,D.t0,D.t1,D.tweening=H,Q,S,W,z*d,L*d,s,n,p(f,d),p(r,d),g,g+d,true else print("\065 \118\097\108\117\101 \110\097\109\101\100 "..(tostring(C).." \104\097\115 \110\111\116 \121\101\116 \098\101\101\110 \099\114\101\097\116\101\100\046"))end end})L.CFrameTweens=I local function G(g)for C,Q in next,r do local D,q,S=Q.update,Q.t0,Q.t1 if D then if Q.tweening then if g>q and g<S then D(x(Q.x0,Q.x1,Q.v0,Q.v1,(g-q)/(S-q)))elseif g>=S then D(Q.x1)Q.tweening=false end elseif g<=q then Q.tweening=true end end end end L.updateTweens=G local function u(g)for C,Q in next,B do local D,q,S=Q.update,Q.t0,Q.t1 if D then if Q.tweening then if g>q and g<S then D(b(Q.q0,Q.q1,Q.w0,Q.w1,(g-q)/(S-q)))elseif g>=S then D(Q.q1)Q.tweening=false end elseif g<=q then Q.tweening=true end end end end L.updateQuaternionTweens=u local function w(g)for C,Q in next,j do local D,q,S=Q.update,Q.t0,Q.t1 if D then if Q.tweening then if g>q and g<S then local C=(g-q)/(S-q)local W=x(Q.x0,Q.x1,Q.v0,Q.v1,C)D(X(W.x,W.y,W.z,e(b(Q.q0,Q.q1,Q.w0,Q.w1,C))))elseif g>=S then D(Q.c1)Q.tweening=false end elseif g<=q then Q.tweening=true end end end end L.updateCFrameTweens=w local function H(g,C,Q,D)r[g]={x0=C;x1=C;v0=C*0;v1=C*0;t0=0;t1=tick();time=D or 1;update=Q,tweening=false}if Q then Q(C)end end L.newTween=H local function d(g,C,Q,D,q)B[g]={q0=C;q1=C;w0=R,w1=R;t0=0;t1=tick();time=D or 1;update=Q;tweening=false;autoChoose=q==nil or q}if Q then Q(C)end end L.newQuaternionTween=d local function O(g,C,Q,D)local q={J(C)}j[g]={c0=C;c1=C;x0=C.p,x1=C.p,v0=t;v1=t,q0=q;q1=q,w0=R,w1=R;t0=0,t1=tick(),time=D or 1;update=Q;tweening=false}if Q then Q(C)end end L.newCFrameTween=O return L
--- Quaternion data type
-- @module Quaternion
-- @author xXxMoNkEyMaNxXx

--[[
God, grant me the serenity to accept the things I cannot change,
The courage to change the things I can,
And wisdom to know the difference.

I cannot change most of this.
]]

local pi = math.pi
local tau = 2*pi
local cos,sin = math.cos,math.sin
local sqrt = math.sqrt
local atan2 = math.atan2
local max = math.max

local vec3 = Vector3.new
local CF = CFrame.new

local iv = vec3()
local iq = {1,0,0,0}

local lib = {}

local function BezierPosition(x0,x1,v0,v1,t)
	local T=1-t
	return x0*T*T*T+(3*x0+v0)*t*T*T+(3*x1-v1)*t*t*T+x1*t*t*t
end
lib.BezierPosition = BezierPosition

local function BezierVelocity(x0,x1,v0,v1,t)
	local T=1-t
	return v0*T*T+2*(3*(x1-x0)-(v1+v0))*t*T+v1*t*t
end
lib.BezierVelocity = BezierVelocity

local function Qmul(q1,q2) -- Multiply
	local w1,x1,y1,z1,w2,x2,y2,z2=q1[1],q1[2],q1[3],q1[4],q2[1],q2[2],q2[3],q2[4]
	return {w1*w2-x1*x2-y1*y2-z1*z2,w1*x2+x1*w2+y1*z2-z1*y2,w1*y2-x1*z2+y1*w2+z1*x2,w1*z2+x1*y2-y1*x2+z1*w2}
end
lib.Qmul = Qmul

local function Qinv(q)--Inverse. (q^-1)
	local w,x,y,z=q[1],q[2],q[3],q[4]
	local m=w*w+x*x+y*y+z*z
	if m>0 then
		return {w/m,-x/m,-y/m,-z/m}
	else
		return {0,0,0,0}
	end
end
lib.Qinv = Qinv

local function Qpow(q,exponent,choice)
	choice=choice or 0
	local w,x,y,z=q[1],q[2],q[3],q[4]
	local vv=x*x+y*y+z*z
	if vv>0 then
		--Convert to polar form and exponentiate (all in one go)
		local v=sqrt(vv)
		local m=(w*w+vv)^(0.5*exponent)
		local theta=exponent*(atan2(v,w)+tau*choice)--swag
		local s=m*sin(theta)/v
		return {m*cos(theta),x*s,y*s,z*s}
	else--This is a regular number.  srs.  lol.
		if w<0 then--Quaternions, umad? u dun fool me nub
			local m=(-w)^exponent
			local s=m*sin(pi*exponent)*sqrt(3)/3
			return {m*cos(pi*exponent),s,s,s}
		else
			return {w^exponent,0,0,0}
		end
	end
end
lib.Qpow = Qpow

local function QuaternionFromCFrame(cf)
	local mx,my,mz,m00,m01,m02,m10,m11,m12,m20,m21,m22=cf:components()
	local trace=m00+m11+m22
	if trace>0 then
		local s=sqrt(1+trace)
		local recip=0.5/s
		return s*0.5,(m21-m12)*recip,(m02-m20)*recip,(m10-m01)*recip
	else
		local big=max(m00,m11,m22)
		if big==m00 then
			local s=sqrt(1+m00-m11-m22)
			local recip=0.5/s
			return (m21-m12)*recip,0.5*s,(m10+m01)*recip,(m02+m20)*recip
		elseif big==m11 then
			local s=sqrt(1-m00+m11-m22)
			local recip=0.5/s
			return (m02-m20)*recip,(m10+m01)*recip,0.5*s,(m21+m12)*recip
		elseif big==m22 then
			local s=sqrt(1-m00-m11+m22)
			local recip=0.5/s
			return (m10-m01)*recip,(m02+m20)*recip,(m21+m12)*recip,0.5*s
		end
	end
end
lib.QuaternionFromCFrame = QuaternionFromCFrame

local function SlerpQuaternions(q0, q1, t)
	return Qmul(q0, Qpow(Qmul(q1, Qinv(q0)), t))
end
lib.SlerpQuaternions = SlerpQuaternions

local function QuaternionToCFrame(q)
	local w,x,y,z=q[1],q[2],q[3],q[4]
	local xs,ys,zs=x+x,y+y,z+z
	local wx,wy,wz=w*xs,w*ys,w*zs
	local xx,xy,xz,yy,yz,zz=x*xs,x*ys,x*zs,y*ys,y*zs,z*zs
	return 1-(yy+zz),xy-wz,xz+wy,xy+wz,1-(xx+zz),yz-wx,xz-wy,yz+wx,1-(xx+yy)
end
lib.QuaternionToCFrame = QuaternionToCFrame

local function BezierRotation(q0,q1,w0,w1,t)
	local _30,_31,_32,_33=q0,Qmul(q0,w0),Qmul(q1,Qinv(w1)),q1
	local _20,_21,_22=Qmul(_30,Qpow(Qmul(Qinv(_30),_31),t)),Qmul(_31,Qpow(Qmul(Qinv(_31),_32),t)),Qmul(_32,Qpow(Qmul(Qinv(_32),_33),t))
	local _10,_11=Qmul(_20,Qpow(Qmul(Qinv(_20),_21),t)),Qmul(_21,Qpow(Qmul(Qinv(_21),_22),t))
	local _00=Qmul(_10,Qpow(Qmul(Qinv(_10),_11),t))
	return _00
end
lib.BezierRotation = BezierRotation

local function BezierAngularV(q0,q1,w0,w1,t)
	local _30,_31,_32,_33=q0,Qmul(q0,w0),Qmul(q1,Qinv(w1)),q1
	local _20,_21,_22=Qmul(Qinv(_30),_31),Qmul(Qinv(_31),_32),Qmul(Qinv(_32),_33)
	local _10,_11=Qmul(_20,Qpow(Qmul(Qinv(_20),_21),t)),Qmul(_21,Qpow(Qmul(Qinv(_21),_22),t))
	local _00=Qmul(_10,Qpow(Qmul(Qinv(_10),_11),t))
	return _00
end
lib.BezierAngularV = BezierAngularV

--Regular tweening
local TweenData={}
local Tweens=setmetatable({},{
	__index=function(self,i)
		local data=TweenData[i]
		if data then
			local timeNow,t0,t1=tick(),data.t0,data.t1
			if timeNow>t0 and timeNow<t1 then
				return BezierPosition(data.x0,data.x1,data.v0,data.v1,(timeNow-t0)/(t1-t0))
			elseif timeNow>=t1 then
				return data.x1
			elseif timeNow<=t0 then--Whatever.
				return data.x0
			end
		end
	end,
	__newindex=function(self,i,v)
		local data=TweenData[i]
		if data then
			local timeNow,t0,t1,x0,x1,v0,v1=tick(),data.t0,data.t1
			if timeNow>t0 and timeNow<t1 then
				local dt=t1-t0
				local t=(timeNow-t0)/dt
				x0,x1,v0,v1=BezierPosition(data.x0,data.x1,data.v0,data.v1,t),v,BezierVelocity(data.x0,data.x1,data.v0,data.v1,t)/dt,v*0
			elseif timeNow>=t1 then
				x0,x1,v0,v1=data.x1,v,v*0,v*0
			elseif timeNow<=t0 then
				x0,x1,v0,v1=data.x0,v,v*0,v*0
			end
			local dt,time=1,data.time
			local timeType=type(time)
			if timeType=="number" then
				dt=time
			elseif timeType=="function" then
				dt=time(x0,x1,v0,v1)
			end
			data.x0,data.x1,data.v0,data.v1,data.t0,data.t1,data.tweening=x0,x1,dt*v0,dt*v1,timeNow,timeNow+dt,true
		else
			print("A value named "..tostring(i).." has not yet been created.")
		end
	end,
})
lib.Tweens = Tweens

--Quaternion tweening
local QuaternionTweenData={}
local QuaternionTweens=setmetatable({},{
	__index=function(self,i)
		local data=QuaternionTweenData[i]
		if data then
			local timeNow,t0,t1=tick(),data.t0,data.t1
			if timeNow>t0 and timeNow<t1 then
				return BezierRotation(data.q0,data.q1,data.w0,data.w1,(timeNow-t0)/(t1-t0))
			elseif timeNow>=t1 then
				return data.q1
			elseif timeNow<=t0 then--Whatever.
				return data.q0
			end
		end
	end,
	__newindex=function(self,i,v)
		local data=QuaternionTweenData[i]
		if data then
			local timeNow,t0,t1,q0,q1,w0,w1=tick(),data.t0,data.t1
			if timeNow>t0 and timeNow<t1 then
				local dt=t1-t0
				local t=(timeNow-t0)/dt
				q0,q1,w0,w1=BezierRotation(data.q0,data.q1,data.w0,data.w1,t),v,Qpow(BezierAngularV(data.q0,data.q1,data.w0,data.w1,t),1/dt),iq
			elseif timeNow>=t1 then
				q0,q1,w0,w1=data.q1,v,iq,iq
			elseif timeNow<=t0 then
				q0,q1,w0,w1=data.q0,v,iq,iq
			end
			if data.autoChoose then
				if q0[1]*q1[1]+q0[2]*q1[2]+q0[3]*q1[3]+q0[4]*q1[4]<0 then
					q1={-q1[1],-q1[2],-q1[3],-q1[4]}
				end
			end
			local dt,time=1,data.time
			local timeType=type(time)
			if timeType=="number" then
				dt=time
			elseif timeType=="function" then
				dt=time(q0,q1,w0,w1)
			end
			data.q0,data.q1,data.w0,data.w1,data.t0,data.t1,data.tweening=q0,q1,Qpow(w0,dt),Qpow(w1,dt),timeNow,timeNow+dt,true
		else
			print("A value named "..tostring(i).." has not yet been created.")
		end
	end,
})
lib.QuaternionTweens = QuaternionTweens

--CFrame tweening
local CFrameTweenData={}
local CFrameTweens=setmetatable({},{
	__index=function(self,i)
		local data=CFrameTweenData[i]
		if data then
			local timeNow,t0,t1=tick(),data.t0,data.t1
			if timeNow>t0 and timeNow<t1 then
				local t=(timeNow-t0)/(t1-t0)
				local p=BezierPosition(data.x0,data.x1,data.v0,data.v1,t)
				return CF(p.x,p.y,p.z,QuaternionToCFrame(BezierRotation(data.q0,data.q1,data.w0,data.w1,t)))
			elseif timeNow>=t1 then
				return data.c1
			elseif timeNow<=t0 then--Whatever.
				return data.c0
			end
		end
	end,
	__newindex=function(self,i,v)
		local data=CFrameTweenData[i]
		if data then
			local timeNow,t0,t1,x0,x1,v0,v1,q0,q1,w0,w1=tick(),data.t0,data.t1
			if timeNow>t0 and timeNow<t1 then
				local dt=t1-t0
				local t=(timeNow-t0)/dt
				x0,x1,v0,v1,q0,q1,w0,w1=BezierPosition(data.x0,data.x1,data.v0,data.v1,t),v.p,BezierVelocity(data.x0,data.x1,data.v0,data.v1,t)/dt,iv,BezierRotation(data.q0,data.q1,data.w0,data.w1,t),{QuaternionFromCFrame(v)},Qpow(BezierAngularV(data.q0,data.q1,data.w0,data.w1,t),1/dt),iq
			elseif timeNow>=t1 then
				x0,x1,v0,v1,q0,q1,w0,w1=data.x1,v.p,iv,iv,data.q1,{QuaternionFromCFrame(v)},iq,iq
			elseif timeNow<=t0 then
				x0,x1,v0,v1,q0,q1,w0,w1=data.x0,v.p,iv,iv,data.q0,{QuaternionFromCFrame(v)},iq,iq
			end
			local a1,b1,c1,d1,a2,b2,c2,d2=q0[1]-q1[1],q0[2]-q1[2],q0[3]-q1[3],q0[4]-q1[4],q0[1]+q1[1],q0[2]+q1[2],q0[3]+q1[3],q0[4]+q1[4]
			if a1*a1+b1*b1+c1*c1+d1*d1>a2*a2+b2*b2+c2*c2+d2*d2 then
				q1={-q1[1],-q1[2],-q1[3],-q1[4]}
			end
			local c0=CF(x0.x,x0.y,x0.z,QuaternionToCFrame(q0))
			local dt,time=1,data.time
			local timeType=type(time)
			if timeType=="number" then
				dt=time
			elseif timeType=="function" then
				dt=time(c0,v,x0,x1,v0,v1,q0,q1,w0,w1)--lol
			end
			data.c0,data.c1,data.x0,data.x1,data.v0,data.v1,data.q0,data.q1,data.w0,data.w1,data.t0,data.t1,data.tweening=c0,v,x0,x1,v0*dt,v1*dt,q0,q1,Qpow(w0,dt),Qpow(w1,dt),timeNow,timeNow+dt,true
		else
			print("A value named "..tostring(i).." has not yet been created.")
		end
	end,
})
lib.CFrameTweens = CFrameTweens

local function updateTweens(timeNow)
	for _, data in next,TweenData do
		local f,t0,t1=data.update,data.t0,data.t1
		if f then
			if data.tweening then
				if timeNow>t0 and timeNow<t1 then
					f(BezierPosition(data.x0,data.x1,data.v0,data.v1,(timeNow-t0)/(t1-t0)))
				elseif timeNow>=t1 then
					f(data.x1)
					data.tweening=false
				end
			elseif timeNow<=t0 then
				data.tweening=true
			end
		end
	end
end
lib.updateTweens = updateTweens

local function updateQuaternionTweens(timeNow)
	for _, data in next,QuaternionTweenData do
		local f,t0,t1=data.update,data.t0,data.t1
		if f then
			if data.tweening then
				if timeNow>t0 and timeNow<t1 then
					f(BezierRotation(data.q0,data.q1,data.w0,data.w1,(timeNow-t0)/(t1-t0)))
				elseif timeNow>=t1 then
					f(data.q1)
					data.tweening=false
				end
			elseif timeNow<=t0 then
				data.tweening=true
			end
		end
	end
end
lib.updateQuaternionTweens = updateQuaternionTweens

local function updateCFrameTweens(timeNow)
	for _, data in next,CFrameTweenData do
		local f,t0,t1=data.update,data.t0,data.t1
		if f then
			if data.tweening then
				if timeNow>t0 and timeNow<t1 then
					local t=(timeNow-t0)/(t1-t0)
					local p=BezierPosition(data.x0,data.x1,data.v0,data.v1,t)
					f(CF(p.x,p.y,p.z,QuaternionToCFrame(BezierRotation(data.q0,data.q1,data.w0,data.w1,t))))
				elseif timeNow>=t1 then
					f(data.c1)
					data.tweening=false
				end
			elseif timeNow<=t0 then
				data.tweening=true
			end
		end
	end
end
lib.updateCFrameTweens = updateCFrameTweens

local function newTween(name,value,updateFunction,time)
	TweenData[name]={x0=value,x1=value,v0=value*0,v1=value*0,t0=0,t1=tick(),time=time or 1,update=updateFunction,tweening=false}
	if updateFunction then
		updateFunction(value)--Just in case c:
	end
end
lib.newTween = newTween

local function newQuaternionTween(name,value,updateFunction,time,autoChoose)
	QuaternionTweenData[name]={q0=value,q1=value,w0=iq,w1=iq,t0=0,t1=tick(),time=time or 1,update=updateFunction,tweening=false,autoChoose=autoChoose==nil or autoChoose}
	if updateFunction then
		updateFunction(value)--Just in case c:
	end
end
lib.newQuaternionTween = newQuaternionTween

local function newCFrameTween(name,value,updateFunction,time)
	local q={QuaternionFromCFrame(value)}
	CFrameTweenData[name]={c0=value,c1=value,x0=value.p,x1=value.p,v0=iv,v1=iv,q0=q,q1=q,w0=iq,w1=iq,t0=0,t1=tick(),time=time or 1,update=updateFunction,tweening=false}
	if updateFunction then
		updateFunction(value)--Just in case c:
	end
end
lib.newCFrameTween = newCFrameTween

return lib
