anchor.diff:  procedure TKMEdit.SetText(aText: string);
   begin
     fText := aText;
  -  CursorPos := math.min(CursorPos, Length(fText));
  +  CursorPos := Math.Min(CursorPos, Length(fText));
     //Setting the text should place cursor to the end
     fLeftIndex := 0;
     SetCursorPos(Length(Text));
  -  ValidateText();
  +  ValidateText;
   end;
   
   
   //Validates fText basing on predefined sets of allowed or disallowed chars
   //It iterates from end to start of a string - deletes chars and moves cursor appropriately
  -procedure TKMEdit.ValidateText();
  +procedure TKMEdit.ValidateText;
   var
  -  i : integer;
  +  I: Integer;
   const
     DigitChars: set of Char = ['1' .. '9', '0'];
     NonFileChars: set of Char = [#0 .. #31, '<', '>', '|', '"', '\', '/', ':', '*', '?'];
     NonTextChars: set of Char = [#0 .. #31, '|'];
   begin
  -  for i:= Length(fText) downto 1 do
  -  begin
  -    if(fAllowedChars = acDigits) and not(fText[i] in DigitChars) or
  -      (fAllowedChars = acFileName) and (fText[i] in NonFileChars) or
  -      (fAllowedChars = acText) and (fText[i] in NonTextChars) then
  -        begin
  -          Delete(fText, i, 1);
  -          if CursorPos >= i then
  -            CursorPos := CursorPos - 1;
  -        end;
  -    end;
  +  for I := Length(fText) downto 1 do
  +  if (fAllowedChars = acDigits) and not(fText[i] in DigitChars) or
  +     (fAllowedChars = acFileName) and (fText[i] in NonFileChars) or
  +     (fAllowedChars = acText) and (fText[i] in NonTextChars) then
  +  begin
  +    Delete(fText, I, 1);
  +    if CursorPos >= I then //Keep cursor in place
  +      CursorPos := CursorPos - 1;
  +  end;
   end;
   
   
  
positive.code: function TKMEdit.KeyEventHandled(Key: Word; Shift: TShiftState): Boolean;
  begin
    Result := True;
    if fText = '' then
      //Don't include backspace/delete because edits should always handle those. Otherwise when you
      //press backspace repeatedly to remove all characters it will apply other shortcuts like
      //resetting the zoom if you press it once too many times.
      case Key of
        VK_UP,
        VK_DOWN,
        VK_LEFT,
        VK_RIGHT,
        VK_HOME,
        VK_END: Result := False; //These keys have no effect when text is blank
      end;
    //We want these keys to be ignored by chat, so game shortcuts still work
    if Key in [VK_F1..VK_F12, VK_ESCAPE] then Result := False;
    //Ctrl can be used as an escape character, e.g. CTRL+B places beacon while chat is open
    if ssCtrl in Shift then Result := (Key in [Ord('C'), Ord('X'), Ord('V')]);
  end;
  
negative.code: function TKMEdit.KeyDown(Key: Word; Shift: TShiftState): Boolean;
  begin
    Result := KeyEventHandled(Key, Shift);
    if inherited KeyDown(Key, Shift) or ReadOnly then Exit;
  
    //Clipboard operations
    if (Shift = [ssCtrl]) and (Key <> VK_CONTROL) then
    begin
      case Key of
        Ord('C'): Clipboard.AsText := fText;
        Ord('X'): begin
                    Clipboard.AsText := fText;
                    Text := '';
                  end;
        Ord('V'): begin
                    Insert(Clipboard.AsText, fText, CursorPos + 1);
                    CursorPos := CursorPos + Length(Clipboard.AsText);
                    ValidateText;
                  end;
      end;
    end;
  
    case Key of
  