Patch 9.0.1309
Problem:    Scrolling two lines with even line count and 'scrolloff' set.
Solution:   Adjust how the topline is computed. (closes #10545)
Files:      src/move.c, src/proto/move.pro, src/buffer.c, src/normal.c,
            src/testdir/test_scroll_opt.vim, src/testdir/test_scrollbind.vim,
            src/testdir/dumps/Test_popupwin_previewpopup_2.dump,
            src/testdir/dumps/Test_popupwin_previewpopup_3.dump,
            src/testdir/dumps/Test_popupwin_previewpopup_4.dump,
            src/testdir/dumps/Test_popupwin_previewpopup_5.dump


*** ../vim-9.0.1308/src/move.c  2023-01-26 14:14:18.835484390 +0000
--- src/move.c  2023-02-14 16:22:03.538537809 +0000
***************
*** 396,402 ****
            // cursor in the middle of the window.  Otherwise put the cursor
            // near the top of the window.
            if (n >= halfheight)
!               scroll_cursor_halfway(FALSE);
            else
            {
                scroll_cursor_top(scrolljump_value(), FALSE);
--- 396,402 ----
            // cursor in the middle of the window.  Otherwise put the cursor
            // near the top of the window.
            if (n >= halfheight)
!               scroll_cursor_halfway(FALSE, FALSE);
            else
            {
                scroll_cursor_top(scrolljump_value(), FALSE);
***************
*** 499,505 ****
                if (line_count <= curwin->w_height + 1)
                    scroll_cursor_bot(scrolljump_value(), FALSE);
                else
!                   scroll_cursor_halfway(FALSE);
            }
        }
      }
--- 499,505 ----
                if (line_count <= curwin->w_height + 1)
                    scroll_cursor_bot(scrolljump_value(), FALSE);
                else
!                   scroll_cursor_halfway(FALSE, FALSE);
            }
        }
      }
***************
*** 2383,2389 ****
       * in a small window.
       */
      if (used > curwin->w_height)
!       scroll_cursor_halfway(FALSE);
      else
      {
        /*
--- 2383,2389 ----
       * in a small window.
       */
      if (used > curwin->w_height)
!       scroll_cursor_halfway(FALSE, FALSE);
      else
      {
        /*
***************
*** 2720,2726 ****
       * Otherwise put it at 1/2 of the screen.
       */
      if (line_count >= curwin->w_height && line_count > min_scroll)
!       scroll_cursor_halfway(FALSE);
      else
      {
        // With 'smoothscroll' scroll at least the height of the cursor line,
--- 2720,2726 ----
       * Otherwise put it at 1/2 of the screen.
       */
      if (line_count >= curwin->w_height && line_count > min_scroll)
!       scroll_cursor_halfway(FALSE, TRUE);
      else
      {
        // With 'smoothscroll' scroll at least the height of the cursor line,
***************
*** 2760,2766 ****
   * If "atend" is TRUE, also put it halfway at the end of the file.
   */
      void
! scroll_cursor_halfway(int atend)
  {
      int               above = 0;
      linenr_T  topline;
--- 2760,2766 ----
   * If "atend" is TRUE, also put it halfway at the end of the file.
   */
      void
! scroll_cursor_halfway(int atend, int prefer_above)
  {
      int               above = 0;
      linenr_T  topline;
***************
*** 2841,2883 ****
  
        // If not using smoothscroll, we have to iteratively find how many
        // lines to scroll down to roughly fit the cursor.
!       // This may not be right in the middle if the lines' physical height >
!       // 1 (e.g. 'wrap' is on).
  
!       if (below <= above)         // add a line below the cursor first
        {
!           if (boff.lnum < curbuf->b_ml.ml_line_count)
            {
!               botline_forw(&boff);
!               used += boff.height;
!               if (used > curwin->w_height)
!                   break;
!               below += boff.height;
!           }
!           else
!           {
!               ++below;            // count a "~" line
!               if (atend)
!                   ++used;
            }
-       }
  
!       if (below > above)          // add a line above the cursor
!       {
!           topline_back(&loff);
!           if (loff.height == MAXCOL)
!               used = MAXCOL;
!           else
!               used += loff.height;
!           if (used > curwin->w_height)
!               break;
!           above += loff.height;
!           topline = loff.lnum;
  #ifdef FEAT_DIFF
!           topfill = loff.fill;
  #endif
        }
      }
  #ifdef FEAT_FOLDING
      if (!hasFolding(topline, &curwin->w_topline, NULL))
  #endif
--- 2841,2902 ----
  
        // If not using smoothscroll, we have to iteratively find how many
        // lines to scroll down to roughly fit the cursor.
!       // This may not be right in the middle if the lines'
!       // physical height > 1 (e.g. 'wrap' is on).
  
!       // Depending on "prefer_above" we add a line above or below first.
!       // Loop twice to avoid duplicating code.
!       int done = FALSE;
!       for (int round = 1; round <= 2; ++round)
        {
!           if (prefer_above ? (round == 2 && below < above)
!                            : (round == 1 && below <= above))
            {
!               // add a line below the cursor
!               if (boff.lnum < curbuf->b_ml.ml_line_count)
!               {
!                   botline_forw(&boff);
!                   used += boff.height;
!                   if (used > curwin->w_height)
!                   {
!                       done = TRUE;
!                       break;
!                   }
!                   below += boff.height;
!               }
!               else
!               {
!                   ++below;        // count a "~" line
!                   if (atend)
!                       ++used;
!               }
            }
  
!           if (prefer_above ? (round == 1 && below >= above)
!                            : (round == 1 && below > above))
!           {
!               // add a line above the cursor
!               topline_back(&loff);
!               if (loff.height == MAXCOL)
!                   used = MAXCOL;
!               else
!                   used += loff.height;
!               if (used > curwin->w_height)
!               {
!                   done = TRUE;
!                   break;
!               }
!               above += loff.height;
!               topline = loff.lnum;
  #ifdef FEAT_DIFF
!               topfill = loff.fill;
  #endif
+           }
        }
+       if (done)
+           break;
      }
+ 
  #ifdef FEAT_FOLDING
      if (!hasFolding(topline, &curwin->w_topline, NULL))
  #endif
*** ../vim-9.0.1308/src/proto/move.pro  2022-12-02 20:46:01.940019452 +0000
--- src/proto/move.pro  2023-02-14 15:46:57.503311034 +0000
***************
*** 43,49 ****
  void scroll_cursor_top(int min_scroll, int always);
  void set_empty_rows(win_T *wp, int used);
  void scroll_cursor_bot(int min_scroll, int set_topbot);
! void scroll_cursor_halfway(int atend);
  void cursor_correct(void);
  int onepage(int dir, long count);
  void halfpage(int flag, linenr_T Prenum);
--- 43,49 ----
  void scroll_cursor_top(int min_scroll, int always);
  void set_empty_rows(win_T *wp, int used);
  void scroll_cursor_bot(int min_scroll, int set_topbot);
! void scroll_cursor_halfway(int atend, int prefer_above);
  void cursor_correct(void);
  int onepage(int dir, long count);
  void halfpage(int flag, linenr_T Prenum);
*** ../vim-9.0.1308/src/buffer.c        2023-02-11 11:15:19.999085252 +0000
--- src/buffer.c        2023-02-14 15:45:39.203316628 +0000
***************
*** 1953,1959 ****
      maketitle();
        // when autocmds didn't change it
      if (curwin->w_topline == 1 && !curwin->w_topline_was_set)
!       scroll_cursor_halfway(FALSE);   // redisplay at correct position
  
  #ifdef FEAT_NETBEANS_INTG
      // Send fileOpened event because we've changed buffers.
--- 1953,1959 ----
      maketitle();
        // when autocmds didn't change it
      if (curwin->w_topline == 1 && !curwin->w_topline_was_set)
!       scroll_cursor_halfway(FALSE, FALSE);    // redisplay at correct position
  
  #ifdef FEAT_NETBEANS_INTG
      // Send fileOpened event because we've changed buffers.
*** ../vim-9.0.1308/src/normal.c        2023-02-01 17:33:14.863435888 +0000
--- src/normal.c        2023-02-14 15:46:54.063311282 +0000
***************
*** 2712,2718 ****
      case '.': beginline(BL_WHITE | BL_FIX);
                // FALLTHROUGH
  
!     case 'z': scroll_cursor_halfway(TRUE);
                redraw_later(UPD_VALID);
                set_fraction(curwin);
                break;
--- 2712,2718 ----
      case '.': beginline(BL_WHITE | BL_FIX);
                // FALLTHROUGH
  
!     case 'z': scroll_cursor_halfway(TRUE, FALSE);
                redraw_later(UPD_VALID);
                set_fraction(curwin);
                break;
*** ../vim-9.0.1308/src/testdir/test_scroll_opt.vim     2023-01-28 
19:18:56.733720607 +0000
--- src/testdir/test_scroll_opt.vim     2023-02-14 15:50:46.447294487 +0000
***************
*** 38,43 ****
--- 38,60 ----
    quit!
  endfunc
  
+ func Test_scolloff_even_line_count()
+    new
+    resize 6
+    setlocal scrolloff=3
+    call setline(1, range(20))
+    normal 2j
+    call assert_equal(1, getwininfo(win_getid())[0].topline)
+    normal j
+    call assert_equal(1, getwininfo(win_getid())[0].topline)
+    normal j
+    call assert_equal(2, getwininfo(win_getid())[0].topline)
+    normal j
+    call assert_equal(3, getwininfo(win_getid())[0].topline)
+ 
+    bwipe!
+ endfunc
+ 
  func Test_CtrlE_CtrlY_stop_at_end()
    enew
    call setline(1, ['one', 'two'])
*** ../vim-9.0.1308/src/testdir/test_scrollbind.vim     2020-08-12 
17:43:41.000000000 +0100
--- src/testdir/test_scrollbind.vim     2023-02-14 17:30:47.298376937 +0000
***************
*** 218,225 ****
              \ '7 line 02 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ 02',
              \ '56789ABCDEFGHIJKLMNOPQRSTUVWXYZ 02',
              \ 'UTSRQPONMLKJIHGREDCBA9876543210 02',
!             \ '. line 11 ZYXWVUTSRQPONMLKJIHGREDCBA9876543210 11',
!             \ '. line 11 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ 11',
              \ ''],  getline(1, '$'))
    enew!
  
--- 218,225 ----
              \ '7 line 02 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ 02',
              \ '56789ABCDEFGHIJKLMNOPQRSTUVWXYZ 02',
              \ 'UTSRQPONMLKJIHGREDCBA9876543210 02',
!             \ '. line 10 ZYXWVUTSRQPONMLKJIHGREDCBA9876543210 10',
!             \ '. line 10 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ 10',
              \ ''],  getline(1, '$'))
    enew!
  
*** ../vim-9.0.1308/src/testdir/dumps/Test_popupwin_previewpopup_2.dump 
2021-03-04 20:31:23.000000000 +0000
--- src/testdir/dumps/Test_popupwin_previewpopup_2.dump 2023-02-14 
16:25:08.154498876 +0000
***************
*** 2,11 ****
  |#|i|n|c|l|u|d|e| |"|X|h|e|a|d|e|r|.|h|"| @54
  |t|h|r|e@1| @69
  |f|o|u|r| @3|╔+0&#afffff255| |X|t|a|g|f|i|l|e| |═@30|X| +0&#ffffff0@23
! |f|i|v|e| @3|║+0&#afffff255|2|7| @37| +0&#a8a8a8255|║+0&#afffff255| 
+0&#ffffff0@23
! |s|i|x| @4|║+0&#afffff255|t|h|i|s| |i|s| |a|n|o|t|h|e|r| |p|l|a|c|e| @18| 
+0&#a8a8a8255|║+0&#afffff255| +0&#ffffff0@23
! |s|e|v|e|n| @2|║+0&#afffff255|2|9| @37| +0&#0000001|║+0&#afffff255| 
+0&#ffffff0@23
! |f|i|n|d| |t|h|e|║+0&#afffff255|3|0| @37| +0&#a8a8a8255|║+0&#afffff255| 
+0&#ffffff0@23
  |n|i|n|e| @3|╚+0&#afffff255|═@40|⇲| +0&#ffffff0@23
  |t|h|i|s| |i|s| >a|n|o|t|h|e|r| |w|o|r|d| @54
  |v|e|r|y| |l|o|n|g| |l|i|n|e| |w|h|e|r|e| |t|h|e| |w|o|r|d| |i|s| |a|l|s|o| 
|a|n|o|t|h|e|r| @29
--- 2,11 ----
  |#|i|n|c|l|u|d|e| |"|X|h|e|a|d|e|r|.|h|"| @54
  |t|h|r|e@1| @69
  |f|o|u|r| @3|╔+0&#afffff255| |X|t|a|g|f|i|l|e| |═@30|X| +0&#ffffff0@23
! |f|i|v|e| @3|║+0&#afffff255|2|6| @37| +0&#a8a8a8255|║+0&#afffff255| 
+0&#ffffff0@23
! |s|i|x| @4|║+0&#afffff255|2|7| @37| +0&#a8a8a8255|║+0&#afffff255| 
+0&#ffffff0@23
! |s|e|v|e|n| @2|║+0&#afffff255|t|h|i|s| |i|s| |a|n|o|t|h|e|r| |p|l|a|c|e| @18| 
+0&#0000001|║+0&#afffff255| +0&#ffffff0@23
! |f|i|n|d| |t|h|e|║+0&#afffff255|2|9| @37| +0&#a8a8a8255|║+0&#afffff255| 
+0&#ffffff0@23
  |n|i|n|e| @3|╚+0&#afffff255|═@40|⇲| +0&#ffffff0@23
  |t|h|i|s| |i|s| >a|n|o|t|h|e|r| |w|o|r|d| @54
  |v|e|r|y| |l|o|n|g| |l|i|n|e| |w|h|e|r|e| |t|h|e| |w|o|r|d| |i|s| |a|l|s|o| 
|a|n|o|t|h|e|r| @29
*** ../vim-9.0.1308/src/testdir/dumps/Test_popupwin_previewpopup_3.dump 
2021-03-04 20:31:24.000000000 +0000
--- src/testdir/dumps/Test_popupwin_previewpopup_3.dump 2023-02-14 
16:25:09.322498635 +0000
***************
*** 2,11 ****
  |#|i|n|c|l|u|d|e| |"|X|h|e|a|d|e|r|.|h|"| @54
  |t|h|r|e@1| @69
  |f|o|u|r| @9|╔+0&#afffff255| |X|t|a|g|f|i|l|e| |═@30|X| +0&#ffffff0@17
! |f|i|v|e| @9|║+0&#afffff255|2|7| @37| +0&#a8a8a8255|║+0&#afffff255| 
+0&#ffffff0@17
! |s|i|x| @10|║+0&#afffff255|t|h|i|s| |i|s| |a|n|o|t|h|e|r| |p|l|a|c|e| @18| 
+0&#a8a8a8255|║+0&#afffff255| +0&#ffffff0@17
! |s|e|v|e|n| @8|║+0&#afffff255|2|9| @37| +0&#0000001|║+0&#afffff255| 
+0&#ffffff0@17
! |f|i|n|d| |t|h|e|w|o|r|d| |s|║+0&#afffff255|3|0| @37| 
+0&#a8a8a8255|║+0&#afffff255| +0&#ffffff0@17
  |n|i|n|e| @9|╚+0&#afffff255|═@40|⇲| +0&#ffffff0@17
  |t|h|i|s| |i|s| >a|n|o|t|h|e|r| |w|o|r|d| @54
  |v|e|r|y| |l|o|n|g| |l|i|n|e| |w|h|e|r|e| |t|h|e| |w|o|r|d| |i|s| |a|l|s|o| 
|a|n|o|t|h|e|r| @29
--- 2,11 ----
  |#|i|n|c|l|u|d|e| |"|X|h|e|a|d|e|r|.|h|"| @54
  |t|h|r|e@1| @69
  |f|o|u|r| @9|╔+0&#afffff255| |X|t|a|g|f|i|l|e| |═@30|X| +0&#ffffff0@17
! |f|i|v|e| @9|║+0&#afffff255|2|6| @37| +0&#a8a8a8255|║+0&#afffff255| 
+0&#ffffff0@17
! |s|i|x| @10|║+0&#afffff255|2|7| @37| +0&#a8a8a8255|║+0&#afffff255| 
+0&#ffffff0@17
! |s|e|v|e|n| @8|║+0&#afffff255|t|h|i|s| |i|s| |a|n|o|t|h|e|r| |p|l|a|c|e| @18| 
+0&#0000001|║+0&#afffff255| +0&#ffffff0@17
! |f|i|n|d| |t|h|e|w|o|r|d| |s|║+0&#afffff255|2|9| @37| 
+0&#a8a8a8255|║+0&#afffff255| +0&#ffffff0@17
  |n|i|n|e| @9|╚+0&#afffff255|═@40|⇲| +0&#ffffff0@17
  |t|h|i|s| |i|s| >a|n|o|t|h|e|r| |w|o|r|d| @54
  |v|e|r|y| |l|o|n|g| |l|i|n|e| |w|h|e|r|e| |t|h|e| |w|o|r|d| |i|s| |a|l|s|o| 
|a|n|o|t|h|e|r| @29
*** ../vim-9.0.1308/src/testdir/dumps/Test_popupwin_previewpopup_4.dump 
2022-04-02 13:54:32.000000000 +0100
--- src/testdir/dumps/Test_popupwin_previewpopup_4.dump 2023-02-14 
16:25:10.486498393 +0000
***************
*** 3,12 ****
  |t|h|r|e@1| @69
  |f|o|u|r| @70
  |f|i|v|e| @27|╔+0&#afffff255| |X|t|a|g|f|i|l|e| |═@30|X
! |s+0&#ffffff0|i|x| @28|║+0&#afffff255|2|7| @37| +0&#a8a8a8255|║+0&#afffff255
! |s+0&#ffffff0|e|v|e|n| @26|║+0&#afffff255|t|h|i|s| |i|s| |a|n|o|t|h|e|r| 
|p|l|a|c|e| @18| +0&#a8a8a8255|║+0&#afffff255
! |f+0&#ffffff0|i|n|d| |t|h|e|w|o|r|d| |s|o|m|e|w|h|e|r|e| 
@9|║+0&#afffff255|2|9| @37| +0&#0000001|║+0&#afffff255
! |n+0&#ffffff0|i|n|e| @27|║+0&#afffff255|3|0| @37| +0&#a8a8a8255|║+0&#afffff255
  |t+0&#ffffff0|h|i|s| |i|s| |a|n|o|t|h|e|r| |w|o|r|d| @11|╚+0&#afffff255|═@40|⇲
  |v+0&#ffffff0|e|r|y| |l|o|n|g| |l|i|n|e| |w|h|e|r|e| |t|h|e| |w|o|r|d| |i|s| 
|a|l|s|o| >a|n|o|t|h|e|r| @29
  |~+0#4040ff13&| @73
--- 3,12 ----
  |t|h|r|e@1| @69
  |f|o|u|r| @70
  |f|i|v|e| @27|╔+0&#afffff255| |X|t|a|g|f|i|l|e| |═@30|X
! |s+0&#ffffff0|i|x| @28|║+0&#afffff255|2|6| @37| +0&#a8a8a8255|║+0&#afffff255
! |s+0&#ffffff0|e|v|e|n| @26|║+0&#afffff255|2|7| @37| 
+0&#a8a8a8255|║+0&#afffff255
! |f+0&#ffffff0|i|n|d| |t|h|e|w|o|r|d| |s|o|m|e|w|h|e|r|e| 
@9|║+0&#afffff255|t|h|i|s| |i|s| |a|n|o|t|h|e|r| |p|l|a|c|e| @18| 
+0&#0000001|║+0&#afffff255
! |n+0&#ffffff0|i|n|e| @27|║+0&#afffff255|2|9| @37| +0&#a8a8a8255|║+0&#afffff255
  |t+0&#ffffff0|h|i|s| |i|s| |a|n|o|t|h|e|r| |w|o|r|d| @11|╚+0&#afffff255|═@40|⇲
  |v+0&#ffffff0|e|r|y| |l|o|n|g| |l|i|n|e| |w|h|e|r|e| |t|h|e| |w|o|r|d| |i|s| 
|a|l|s|o| >a|n|o|t|h|e|r| @29
  |~+0#4040ff13&| @73
*** ../vim-9.0.1308/src/testdir/dumps/Test_popupwin_previewpopup_5.dump 
2022-04-02 14:00:29.000000000 +0100
--- src/testdir/dumps/Test_popupwin_previewpopup_5.dump 2023-02-14 
16:25:11.650498157 +0000
***************
*** 3,12 ****
  |t|h|r|e@1| @69
  |f|o|u|r| @70
  |f|i|v|e| @27|╔+0&#afffff255| |t|e|s|t|d|i|r|/|X|t|a|g|f|i|l|e| |═@22|X
! |s+0&#ffffff0|i|x| @28|║+0&#afffff255|2|7| @37| +0&#a8a8a8255|║+0&#afffff255
! |s+0&#ffffff0|e|v|e|n| @26|║+0&#afffff255|t|h|i|s| |i|s| |a|n|o|t|h|e|r| 
|p|l|a|c|e| @18| +0&#a8a8a8255|║+0&#afffff255
! |f+0&#ffffff0|i|n|d| |t|h|e|w|o|r|d| |s|o|m|e|w|h|e|r|e| 
@9|║+0&#afffff255|2|9| @37| +0&#0000001|║+0&#afffff255
! |n+0&#ffffff0|i|n|e| @27|║+0&#afffff255|3|0| @37| +0&#a8a8a8255|║+0&#afffff255
  |t+0&#ffffff0|h|i|s| |i|s| |a|n|o|t|h|e|r| |w|o|r|d| @11|╚+0&#afffff255|═@40|⇲
  |v+0&#ffffff0|e|r|y| |l|o|n|g| |l|i|n|e| |w|h|e|r|e| |t|h|e| |w|o|r|d| |i|s| 
|a|l|s|o| >a|n|o|t|h|e|r| @29
  |~+0#4040ff13&| @73
--- 3,12 ----
  |t|h|r|e@1| @69
  |f|o|u|r| @70
  |f|i|v|e| @27|╔+0&#afffff255| |t|e|s|t|d|i|r|/|X|t|a|g|f|i|l|e| |═@22|X
! |s+0&#ffffff0|i|x| @28|║+0&#afffff255|2|6| @37| +0&#a8a8a8255|║+0&#afffff255
! |s+0&#ffffff0|e|v|e|n| @26|║+0&#afffff255|2|7| @37| 
+0&#a8a8a8255|║+0&#afffff255
! |f+0&#ffffff0|i|n|d| |t|h|e|w|o|r|d| |s|o|m|e|w|h|e|r|e| 
@9|║+0&#afffff255|t|h|i|s| |i|s| |a|n|o|t|h|e|r| |p|l|a|c|e| @18| 
+0&#0000001|║+0&#afffff255
! |n+0&#ffffff0|i|n|e| @27|║+0&#afffff255|2|9| @37| +0&#a8a8a8255|║+0&#afffff255
  |t+0&#ffffff0|h|i|s| |i|s| |a|n|o|t|h|e|r| |w|o|r|d| @11|╚+0&#afffff255|═@40|⇲
  |v+0&#ffffff0|e|r|y| |l|o|n|g| |l|i|n|e| |w|h|e|r|e| |t|h|e| |w|o|r|d| |i|s| 
|a|l|s|o| >a|n|o|t|h|e|r| @29
  |~+0#4040ff13&| @73
*** ../vim-9.0.1308/src/version.c       2023-02-14 13:07:14.415465757 +0000
--- src/version.c       2023-02-14 15:13:52.127400985 +0000
***************
*** 697,698 ****
--- 697,700 ----
  {   /* Add new patch number below this line */
+ /**/
+     1309,
  /**/

-- 
hundred-and-one symptoms of being an internet addict:
124. You begin conversations with, "Who is your internet service provider?"

 /// Bram Moolenaar -- [email protected] -- http://www.Moolenaar.net   \\\
///                                                                      \\\
\\\        sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ ///
 \\\            help me help AIDS victims -- http://ICCF-Holland.org    ///

-- 
-- 
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

--- 
You received this message because you are subscribed to the Google Groups 
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/vim_dev/20230214174149.3090A1C0B09%40moolenaar.net.

Raspunde prin e-mail lui