function AccelTween.__index(N,U)if AccelTween[U]then return AccelTween[U]elseif U=="\112"then local U,u=N:_getstate(tick())return U elseif U=="\118"then local U,u=N:_getstate(tick())return u elseif U=="\097"then return N._accel elseif U=="\116"then return N._y1 elseif U=="\114\116\105\109\101"then local U=tick()return U<N._t1 and N._t1-U or 0 else error(("\066\097\100 \105\110\100\101\120 \037\113"):format(tostring(U)))end end function AccelTween.__newindex(u,U,N)if U=="\112"then u:_setstate(N,nil,nil,nil)elseif U=="\118"then u:_setstate(nil,N,nil,nil)elseif U=="\097"then u:_setstate(nil,nil,N,nil)elseif U=="\116"then u:_setstate(nil,nil,nil,N)elseif U=="\112\116"then u:_setstate(N,0,nil,N)else error(("\066\097\100 \105\110\100\101\120 \037\113"):format(tostring(U)))end end function AccelTween._getstate(N,U)if U<(N._t0+N._t1)/2 then local u=U-N._t0 return N._y0+((u*u)/2)*N._a0,u*N._a0 elseif U<N._t1 then local u=U-N._t1 return N._y1+((u*u)/2)*N._a1,u*N._a1 else return N._y1,0 end end function AccelTween._setstate(G,U,N,u,M)local t=tick()local L,z=G:_getstate(t)L=U or L z=N or z G._accel=u or G._accel local y=M or G._y1 if G._accel*G._accel<1e-08 then G._t0,G._y0,G._a0=0,L,0 G._t1,G._y1,G._a1=math.huge,y,0 else local U=y<L local N=z<0 local u=L-(z*z)/(2*G._accel)<y local M=L+(z*z)/(2*G._accel)<y if U and(N and u)or not U and(N or not N and M)then G._a0=G._accel G._t1=t+(((2*z)*z+(4*G._accel)*(y-L))^.5-z)/G._accel else G._a0=-G._accel G._t1=t+(((2*z)*z-(4*G._accel)*(y-L))^.5+z)/G._accel end G._t0=t-z/G._a0 G._y0=L-(z*z)/(2*G._a0)G._y1=y G._a1=-G._a0 end end return AccelTween


function AccelTween:__index(index)
	if AccelTween[index] then
		return AccelTween[index]
	elseif index == "p" then
		local pos, _ = self:_getstate(tick())
		return pos
	elseif index == "v" then
		local _, vel = self:_getstate(tick())
		return vel
	elseif index == "a" then
		return self._accel
	elseif index == "t" then
		return self._y1
	elseif index == "rtime" then
		local time = tick()
		return time < self._t1 and self._t1 - time or 0
	else
		error(("Bad index %q"):format(tostring(index)))
	end
end

function AccelTween:__newindex(index, value)
	if index == "p" then
		self:_setstate(value, nil, nil, nil)
	elseif index == "v" then
		self:_setstate(nil, value, nil, nil)
	elseif index == "a" then
		self:_setstate(nil, nil, value, nil)
	elseif index == "t" then
		self:_setstate(nil, nil, nil, value)
	elseif index == "pt" then
		self:_setstate(value, 0, nil, value)
	else
		error(("Bad index %q"):format(tostring(index)))
	end
end

function AccelTween:_getstate(time)
	if time < (self._t0 + self._t1)/2 then
		local t = time - self._t0
		return self._y0 + t*t/2*self._a0, t*self._a0
	elseif time < self._t1 then
		local t = time - self._t1
		return self._y1 + t*t/2*self._a1, t*self._a1
	else
		return self._y1, 0
	end
end

function AccelTween:_setstate(newpos, newvel, newaccel, newtarg)
	local time = tick()
	local pos, vel = self:_getstate(time)
	pos = newpos or pos
	vel = newvel or vel
	self._accel = newaccel or self._accel
	local targ = newtarg or self._y1

	if self._accel*self._accel < 1e-8 then
		self._t0, self._y0, self._a0 = 0, pos, 0
		self._t1, self._y1, self._a1 = math.huge, targ, 0
	else
		local conda = targ < pos
		local condb = vel < 0
		local condc = pos - vel*vel/(2*self._accel) < targ
		local condd = pos + vel*vel/(2*self._accel) < targ
		if conda and condb and condc or not conda and (condb or not condb and condd) then
			self._a0 = self._accel
			self._t1 = time + ((2*vel*vel + 4*self._accel*(targ - pos))^0.5 - vel)/self._accel
		else
			self._a0 = -self._accel
			self._t1 = time + ((2*vel*vel - 4*self._accel*(targ - pos))^0.5 + vel)/self._accel
		end
		self._t0 = time - vel/self._a0
		self._y0 = pos - vel*vel/(2*self._a0)
		self._y1 = targ
		self._a1 = -self._a0
	end
end

return AccelTween
