function AccelTween.__index(o,A)if AccelTween[A]then return AccelTween[A]elseif A=="\112"then local A,c=o:_getstate(os.clock())return A elseif A=="\118"then local A,c=o:_getstate(os.clock())return c elseif A=="\097"then return o._accel elseif A=="\116"then return o._y1 elseif A=="\114\116\105\109\101"then local A=os.clock()return A<o._t1 and o._t1-A or 0 else error(("\066\097\100 \105\110\100\101\120 \037\113"):format(tostring(A)))end end function AccelTween.__newindex(c,A,o)if A=="\112"then c:_setstate(o,nil,nil,nil)elseif A=="\118"then c:_setstate(nil,o,nil,nil)elseif A=="\097"then c:_setstate(nil,nil,o,nil)elseif A=="\116"then c:_setstate(nil,nil,nil,o)elseif A=="\112\116"then c:_setstate(o,0,nil,o)else error(("\066\097\100 \105\110\100\101\120 \037\113"):format(tostring(A)))end end function AccelTween._getstate(o,A)if A<(o._t0+o._t1)/2 then local c=A-o._t0 return o._y0+((c*c)/2)*o._a0,c*o._a0 elseif A<o._t1 then local c=A-o._t1 return o._y1+((c*c)/2)*o._a1,c*o._a1 else return o._y1,0 end end function AccelTween._setstate(f,A,o,c,U)local R=os.clock()local X,V=f:_getstate(R)X=A or X V=o or V f._accel=c or f._accel local x=U or f._y1 if f._accel*f._accel<1e-08 then f._t0,f._y0,f._a0=0,X,0 f._t1,f._y1,f._a1=math.huge,x,0 else local A=x<X local o=V<0 local c=X-(V*V)/(2*f._accel)<x local U=X+(V*V)/(2*f._accel)<x if A and(o and c)or not A and(o or not o and U)then f._a0=f._accel f._t1=R+(((2*V)*V+(4*f._accel)*(x-X))^.5-V)/f._accel else f._a0=-f._accel f._t1=R+(((2*V)*V-(4*f._accel)*(x-X))^.5+V)/f._accel end f._t0=R-V/f._a0 f._y0=X-(V*V)/(2*f._a0)f._y1=x f._a1=-f._a0 end end return AccelTween


function AccelTween:__index(index)
	if AccelTween[index] then
		return AccelTween[index]
	elseif index == "p" then
		local pos, _ = self:_getstate(os.clock())
		return pos
	elseif index == "v" then
		local _, vel = self:_getstate(os.clock())
		return vel
	elseif index == "a" then
		return self._accel
	elseif index == "t" then
		return self._y1
	elseif index == "rtime" then
		local time = os.clock()
		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 = os.clock()
	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
