local l=function(l,y)return l.Time<y.Time end return function(y,S,T)local s={}local i={}for l,y in next,y.Keypoints do local I,v for l,S in next,S.Keypoints do if S.Time==y.Time then I,v=S,S break elseif S.Time<y.Time and(v==nil or S.Time>v.Time)then v=S elseif S.Time>y.Time and(I==nil or S.Time<I.Time)then I=S end end local a,L if I==v then a,L=I.Value,I.Envelope else local l=(y.Time-v.Time)/(I.Time-v.Time)a=(I.Value-v.Value)*l+v.Value L=(I.Envelope-v.Envelope)*l+v.Envelope end local B=(a-y.Value)*T+y.Value local b=(L-y.Envelope)*T+y.Envelope local r=NumberSequenceKeypoint.new(y.Time,B,b)table.insert(s,r)i[y.Time]=true end for l,S in next,S.Keypoints do if not i[S.Time]then local l,i for y,T in next,y.Keypoints do if T.Time==S.Time then l,i=T,T break elseif T.Time<S.Time and(i==nil or T.Time>i.Time)then i=T elseif T.Time>S.Time and(l==nil or T.Time<l.Time)then l=T end end local I,v if l==i then I,v=l.Value,l.Envelope else local y=(S.Time-i.Time)/(l.Time-i.Time)I=(l.Value-i.Value)*y+i.Value v=(l.Envelope-i.Envelope)*y+i.Envelope end local a=(S.Value-I)*T+I local L=(S.Envelope-v)*T+v local B=NumberSequenceKeypoint.new(S.Time,a,L)table.insert(s,B)end end table.sort(s,l)return NumberSequence.new(s)end
--[[
	For each point on each line, find the values of the other sequence at that point in time through interpolation
		then interpolate between the known value and the learned value
		then use that value to create a new keypoint at the time
		then build a new sequence using all the keypoints generated
--]]

local sortByTime = function(a, b)
	return a.Time < b.Time
end

return function(a, b, t)
	local keypoints = {}
	local addedTimes = {}

	for i, ap in next, a.Keypoints do
		local closestAbove, closestBelow

		for i, bp in next, b.Keypoints do
			if bp.Time == ap.Time then
				closestAbove, closestBelow = bp, bp
				break
			elseif bp.Time < ap.Time and (closestBelow == nil or bp.Time > closestBelow.Time) then
				closestBelow = bp
			elseif bp.Time > ap.Time and (closestAbove == nil or bp.Time < closestAbove.Time) then
				closestAbove = bp
			end
		end

		local bValue, bEnvelope
		if closestAbove == closestBelow then
			bValue, bEnvelope = closestAbove.Value, closestAbove.Envelope
		else
			local p = (ap.Time - closestBelow.Time) / (closestAbove.Time - closestBelow.Time)
			bValue = (closestAbove.Value - closestBelow.Value) * p + closestBelow.Value
			bEnvelope = (closestAbove.Envelope - closestBelow.Envelope) * p + closestBelow.Envelope
		end
		local interValue = (bValue - ap.Value) * t + ap.Value
		local interEnvelope = (bEnvelope - ap.Envelope) * t + ap.Envelope
		local interp = NumberSequenceKeypoint.new(ap.Time, interValue, interEnvelope)

		table.insert(keypoints, interp)

		addedTimes[ap.Time] = true
	end
	for i, bp in next, b.Keypoints do
		if not addedTimes[bp.Time] then
			local closestAbove, closestBelow

			for i, ap in next, a.Keypoints do
				if ap.Time == bp.Time then
					closestAbove, closestBelow = ap, ap
					break
				elseif ap.Time < bp.Time and (closestBelow == nil or ap.Time > closestBelow.Time) then
					closestBelow = ap
				elseif ap.Time > bp.Time and (closestAbove == nil or ap.Time < closestAbove.Time) then
					closestAbove = ap
				end
			end

			local aValue, aEnvelope
			if closestAbove == closestBelow then
				aValue, aEnvelope = closestAbove.Value, closestAbove.Envelope
			else
				local p = (bp.Time - closestBelow.Time) / (closestAbove.Time - closestBelow.Time)
				aValue = (closestAbove.Value - closestBelow.Value) * p + closestBelow.Value
				aEnvelope = (closestAbove.Envelope - closestBelow.Envelope) * p + closestBelow.Envelope
			end
			local interValue = (bp.Value - aValue) * t + aValue
			local interEnvelope = (bp.Envelope - aEnvelope) * t + aEnvelope
			local interp = NumberSequenceKeypoint.new(bp.Time, interValue, interEnvelope)

			table.insert(keypoints, interp)
		end
	end

	table.sort(keypoints, sortByTime)

	return NumberSequence.new(keypoints)
end
