anchor.diff:  destructor TEasing.Destroy;
   begin
     FreeAndNil(FTimer);
  -  updater(StopValue);
     inherited;
   end; { TEasing }
   
  +procedure TEasing.Complete;
  +begin
  +  updater(StopValue);
  +  FTimer := nil;
  +end; { TEasing.Complete }
  +
  +procedure TEasing.InOutCubic;
  +begin
  +  FEasingFunc := InOutCubicEasing;
  +  StartTimer;
  +end; { TEasing.InOutCubic }
  +
  +function TEasing.InOutCubicEasing(delta_ms: integer): integer;
  +var
  +  t : real;
  +  ts: real;
  +begin
  +  t := delta_ms/Duration_ms;
  +  ts := t*t;
  +  Result := FStartValue + Round(FValueDiff * (-2 * ts * t + 3 * ts));
  +end; { TEasing.InOutCubicEasing }
  +
  +procedure TEasing.InOutQuintic;
  +begin
  +  FEasingFunc := InOutQuinticEasing;
  +  StartTimer;
  +end; { TEasing.InOutQuintic }
  +
  +function TEasing.InOutQuinticEasing(delta_ms: integer): integer;
  +var
  +  t: real;
  +begin
  +  t := delta_ms/Duration_ms;
  +  Result := FStartValue + Round(FValueDiff * t * t * t * t);
  +end;
  +
   procedure TEasing.Linear;
   begin
  +  FEasingFunc := LinearEasing;
     StartTimer;
   end; { TEasing.Linear }
   
  +function TEasing.LinearEasing(delta_ms: integer): integer;
  +begin
  +  Result := FStartValue + Round(FValueDiff / Duration_ms * delta_ms);
  +end; { TEasing.LinearEasing }
  +
   procedure TEasing.StartTimer;
   begin
  +  FValueDiff := FStopValue - FStartValue;
     FTimer := TTimer.Create(nil);
     FTimer.Interval := Tick_ms;
     FTimer.OnTimer := UpdateValue;
  
positive.code:   DSiWin32;
  
  type
    TEasing = class
    strict private
      FDuration_ms: integer;
      FStartValue : integer;
      FStopValue  : integer;
      FTick_ms    : integer;
      FStart_ms   : int64;
      FTimer      : TTimer;
      FUpdater    : TProc<integer>;
    strict protected
      procedure StartTimer;
      procedure UpdateValue(sender: TObject);
    public
      destructor Destroy; override;
      procedure Linear;
      property Duration_ms: integer read FDuration_ms write FDuration_ms;
      property StartValue: integer read FStartValue write FStartValue;
  
negative.code:   if delta_ms >= Duration_ms then
      newValue := StopValue
    else
      newValue := FEasingFunc(delta_ms);
  
    updater(newValue);
  
    if newValue = StopValue then
      FTimer.Enabled := false;
  end; { TEasing.UpdateValue }
  
  end.
  