10753 Commits

Author SHA1 Message Date
zeertzjq
19f64a2680 vim-patch:9.2.0708: Leaks in do_autocmd in error case (#40386)
Problem:  Leak in do_autocmd in error case (Cheng)
Solution: goto err_exit in the error case and clean up, make the double
          ++once an actual error

closes: vim/vim#20606

98f5171ef6

Co-authored-by: Christian Brabandt <cb@256bit.org>
2026-06-24 08:23:32 +08:00
luukvbaal
28ffb334cf fix(autocmd): never draw aucmd_prepbuf temp win #40379
Problem:  An autocommand that redraws may do so while curwin is
          temporarily set for the autocommand scope. This can result in
          flickering or unexpected state with UI components (statusline,
          winbar, decor providers...) that depend on the current window.
          Current workaround for statusline and winbar specifically
          delays the redraw, which can itself be unexpected for the
          autocommand.

Solution: If redrawing happens with a temporary autocmd current window,
          temporarily restore the current window while redrawing.
2026-06-23 16:05:26 -04:00
zeertzjq
ceaf2baa60 test: fix confusing behavior of eq() with context (#40375) 2026-06-23 18:30:23 +08:00
Barrett Ruth
db30608058 fix(tui): attribute TermResponse to source channel #40330
Problem: Attach-time terminal probes cannot distinguish responses from
different attached UIs.

Solution: Identify the UI by RPC channel id in `TermResponse` and make
`vim.tty.request()` filter responses by channel.
2026-06-23 06:19:56 -04:00
Barrett Ruth
e4fbe162c1 fix(statusline): defer redraw in aucmd context #40309
Problem: `nvim_exec_autocmds({buf=...})` may temporarily switch curwin/curbuf
through `aucmd_prepbuf()`. Requested statuslines/winbars before
`aucmd_restbuf()` may erroneously see the target window as current.

Solution: Track `aucmd_prepbuf()` window-switch depth and leave statusline/winbar
redraws marked dirty until the original window is restored.
2026-06-23 06:05:11 -04:00
zeertzjq
eb0bd381e5 vim-patch:9.2.0707: completion: popup misplaced when text before it is concealed (#40374)
Problem:  When the cursor line has concealed text before the start of the
          completion, the insert-mode completion popup is drawn at the wrong
          screen column and the cursor no longer lines up with the completed
          text.
Solution: Record the concealed width before the cursor on its screen line in
          a new `win_T` field while `win_line()` draws it, subtract it in
          `pum_display()` to place the menu over the visible text, and redraw
          the cursor line so `win_line()` corrects the cursor too.

closes: vim/vim#20539

d167c50de4

Co-authored-by: Barrett Ruth <br@barrettruth.com>
2026-06-23 08:51:03 +00:00
Shiva Priyan
e750f7c357 vim-patch:9.2.0702: :windo and :tabdo create an extra window with 'winfixbuf' (#40358)
Problem:  With 'winfixbuf' set in the current window, :windo and :tabdo
          create an extra split window, even though they only visit
          existing windows/tabpages and don't change the current
          window's buffer (Collin Kennedy)
Solution: Skip the 'winfixbuf' escape in ex_listdo() for :windo and
          :tabdo (ShivaPriyanShanmuga)

fixes:  vim/vim#14301
closes: vim/vim#20600

5767d80b37
2026-06-23 01:13:18 +00:00
zeertzjq
8832c381e1 vim-patch:9.2.0705: :delete # silently fails to update "# and clobbers "0 (#40371)
Problem:  ':delete #' silently fails to update "# and clobbers "0.
Solution: Treat "# like "/, writable only with :let and setreg().

closes: vim/vim#20592

7aeab74687

Co-authored-by: Doug Kearns <dougkearns@gmail.com>
2026-06-23 00:52:39 +00:00
Luuk van Baal
e542b42903 fix(ui2): message before empty prompt not shown
Problem:  Message before empty input() is not visible.
Solution: Route to dialog window with active prompt (hl_id >= 0).
2026-06-22 15:56:26 +02:00
Luuk van Baal
d16bd456a8 fix(cmdline): encode no prompt in cmdline_show.hl_id
Problem:  Unable to distinguish an empty prompt from no prompt in
          cmdline_show event.
Solution: Set cmdline_show.hl_id to -1 when no prompt is active.
2026-06-22 15:56:26 +02:00
Luuk van Baal
60a46036c0 fix(ui2): clear search_count after clearing the screen
Problem:  Clearing the screen doesn't clear the "last" virtual text.
          Dupe counter virtual text is not increased beyond 1.
Solution: Clear "last" virtual text when clearing the screen.
          Restore assignment lost in a previous commit.
2026-06-22 15:14:53 +02:00
zeertzjq
259f1173e4 vim-patch:9.2.0698: [security]: Out-of-bounds write with soundfold() (#40362)
Problem:  [security]: Out-of-bounds write with soundfold()
          (cipher-creator)
Solution: Add an abort condition to the for loop to validate the buffer
          size.

Github Security Advisory:
https://github.com/vim/vim/security/advisories/GHSA-q8mh-6qm3-25g4

Supported by AI

497f931f85

This is N/A as it only changes the !has_mbyte code path.

Co-authored-by: Christian Brabandt <cb@256bit.org>
2026-06-22 02:34:22 +00:00
zeertzjq
257701b17b vim-patch:9.2.0689: the "%" command is slow on a long line with many slashes (#40361)
Problem:  The "%" command can be very slow on a long line that contains
          many slashes, for example a line of base64 data.
Solution: When looking for a line comment, scan the line only once while
          skipping over strings, instead of rescanning from the start for
          every slash.  Move check_linecomment() to cindent.c so it can
          reuse the file-local skip_string().

related: vim/vim#20491
fixes:   vim/vim#20557
closes:  vim/vim#20575

9f9af034ad

Co-authored-by: Hirohito Higashi <h.east.727@gmail.com>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-22 02:28:15 +00:00
zeertzjq
7d0adc08f7 vim-patch:9.2.0699: [security]: possible code execution with python complete (#40363)
Problem:  [security]: possible code execution with python complete
          (morningbread)
Solution: Use repr() to quote the doc strings correctly

Github Security Advisory:
https://github.com/vim/vim/security/advisories/GHSA-ppj8-wqjf-6fp3

Supported by AI

cce141c427

Co-authored-by: Christian Brabandt <cb@256bit.org>
2026-06-22 02:26:37 +00:00
Jan Edmund Lazo
264631c4c1 vim-patch:8.2.1888: Vim9: getbufline(-1, 1, '$') gives an error
Problem:    Vim9: Getbufline(-1, 1, '$') gives an error.
Solution:   Return an empty list. (closes vim/vim#7180)

e6e70a10f1

Co-authored-by: Bram Moolenaar <Bram@vim.org>
2026-06-21 21:03:40 -04:00
zeertzjq
9c900c1255 vim-patch:9.2.0684: :reg # does not display the value of the '#' register (#40352)
Problem:  ':registers #' does not display the value of the '#' register.
Solution: Filter the '#' :registers output on a '#' arg instead of '%'
          (Doug Kearns).

closes: vim/vim#20589

0cafe56b74

Co-authored-by: Doug Kearns <dougkearns@gmail.com>
2026-06-21 22:18:08 +08:00
zeertzjq
dc0b54276d vim-patch:9.2.0683: filetype completion mishandles finished sub options (#40351)
Problem:  ":filetype plugin<Tab>" gives "pluginindent" because a
          sub option before the cursor is treated as already given.
Solution: only skip plugin and indent when followed by white space.
          (glepnir)

closes: vim/vim#20594

fe65f23aca

Co-authored-by: glepnir <glephunter@gmail.com>
2026-06-21 14:16:03 +00:00
zeertzjq
9607e53cea vim-patch:9.2.0682: Wrong dot-repeat when calling complete() while filtering completion (#40350)
Problem:  Wrong dot-repeat when calling complete() while filtering
          Ctrl-N completion.
Solution: Also check compl_started for whether completion is active.
          (zeertzjq)

related: neovim/neovim#40346
closes:  vim/vim#20595

37a7e4944f
2026-06-21 14:09:43 +00:00
Jan Edmund Lazo
d40c07511a vim-patch:9.0.1328: error when using "none" for GUI color is confusing (#40347)
Problem:    Error when using "none" for GUI color is confusing.
Solution:   Mention that the name should perhaps be "NONE". (closes vim/vim#1400)

5b9f57262f

Co-authored-by: Bram Moolenaar <Bram@vim.org>
2026-06-21 02:42:07 +00:00
zeertzjq
1724096ae0 vim-patch:9.2.0680: keytrans() doesn't replace '|' and '\' (#40345)
Problem:  keytrans() doesn't replace '|' and '\' (user202729)
Solution: Replace '|' and '\' with "<Bar>" and "<Bslash>" respectively.
          (zeertzjq)

fixes:  vim/vim#20585
closes: vim/vim#20586

47fd183c4e
2026-06-21 08:24:52 +08:00
Barrett Ruth
74f163c67d fix(defaults): detect 'background'/'termguicolors' on UI attach #40175
Problem:  Terminal background and truecolor detection runs only at startup,
          gated on a UI being attached. A headless server has no UI then, so
          `'background'` and `'termguicolors'` are never detected and remote
          UIs ignore the terminal's theme.
Solution: Also (re)detect on UIEnter. The most recently attached terminal
          wins; an explicit user value is preserved.
2026-06-20 20:09:34 -04:00
Justin M. Keyes
c18a63a462 refactor(test): move swapfile test 2026-06-20 21:49:00 +02:00
Justin M. Keyes
07f02ae8de test: cleanup mksession_spec 2026-06-20 19:55:29 +02:00
jdrouhard
54188fa242 fix(lsp): make LspNotify more robust #40332
Problem: LspNotify never passed a buffer when executing the autocmds, so
buffer-local LspNotify autocmd subscriptions didn't have the correct buf
in the event metadata. It was also wrapped in a schedule() so the actual
autocmd was delayed until after the event loop.

This could result in the wrong buffer receiving the notification if
multiple LspNotify autocmds with buffer filters were added. Only the
"latest" one would actually receive non-buffer-filtered autocmds, not
the matching one. It also caused listeners to receive the notification
"out of sync" with when the notification is actually sent. If a buffer
is being deleted (which fires a textDocument/didClose notification), the
notification is scheduled and fired after the buffer is already gone.

Solution: For LSP notifications that pertain to a particular buffer, set
it when executing the LspNotify autocmds so the callback functions that
are filtered on that buffer will get the correct notifications and the
metadata buf field will be correct. Additionally, there is no need to
wrap the LspNotify callback in vim.schedule when it can be called inline
when the notification to the rpc server is fired.

This is tested by removing now-unnecessary autocmds from semantic tokens
(InsertEnter and BufWinEnter should no longer be necessary now that
requests are fired by LspNotify). Without this fix, simply modifying a
buffer doesn't actually trigger LspNotify correctly, and the test for
that fails.
2026-06-20 12:46:58 -04:00
jdrouhard
6bc6461eac fix(lsp): multiline semantic token processing #40339
Problem: When multiline semantic token support was introduced, the loop
that finds the end line for a particular token didn't sanitize the token
length sent back by the LSP server. If the server returned an overflowed
length (near uint32 max), neovim would burn cpu and loop for an
extremely long time while trying to find the "end line" represented by
the massively large token, causing neovim to seemingly hang.

Solution: Stop looping once the calculated end_line reaches the actual
last line of the buffer.

Fixes #36257
2026-06-20 10:51:21 -04:00
luukvbaal
69160854c5 feat(column): per row click handlers for 'statuscolumn' (#40265)
Problem:
- Current 'statuscolumn' click label caveat is restrictive.
- v:virtnum is not unique to a line if it has both above and
  below virtual lines.
- 'statuscolumn' click handler may expect v:virt/lnum to be set.

Solution:
- Store per-row click definitions for the statuscolumn in a
  (nested line/virt number) map.
- Implement strategy that gives each 'statuscolumn' row a unique
  v:virtnum.
- Set v:virt/lnum when determining which line is clicked.
2026-06-20 15:59:08 +02:00
zeertzjq
f876fd906e test(tui_spec): remove unnecessary job_opts variable (#40334)
This was initially added so that the __NVIM_DETACH environment variable
can be added to the jobs started in this test. That environment variable
is no longer needed, and there is also vim.tbl_extend() that can be used
to add an environment variable to a job anyway.

Also, make a shallow copy of opts.env in setup_child_nvim(), as mutating
the opts.env passed in may mask problems in other tests.
2026-06-20 01:17:32 +00:00
Sam Reynoso
6be9459d35 fix(cmdline): avoid redraw loop after wrapped line #40240
Problem:  A wrapped command line and screen width may be redrawn
          repeatedly after calls to `redrawstatus` from lua.

Solution: redrawcmd() redraws the command line, but msg_clr_eos() may
          invalidate cmdline_was_last_drawn during the redraw process.
          Restore cmdline_was_last_drawn when redrawcmd() completes.

Co-authored-by: Sam Reynoso <sam@codeoutpost.com>
Co-authored-by: Luuk van Baal <luukvbaal@gmail.com>
2026-06-19 16:24:53 -04:00
bfredl
f653ca5ace Merge pull request #40323 from bfredl/no_default_again
fix(tests): use builtin default attributes in more places
2026-06-19 21:11:13 +02:00
bfredl
90157d3790 fix(tests): use builtin default attributes in more places 2026-06-19 19:42:28 +02:00
Ryan Patterson
08b47b1964 test: wasm tree-sitter #40304
Problem:
No CI coverage for wasm builds.

Solution:
Add a basic workflow that builds with ENABLE_WASMTIME
and runs wasm-specific tests.
2026-06-19 05:51:30 -04:00
zeertzjq
1e30f5d242 fix(:checkhealth): open after current tabpage (#40319) 2026-06-19 17:45:21 +08:00
zeertzjq
dc1393d9c1 vim-patch:9.2.0675: tests: Test_cd_from_non_existing_dir() fails on Solaris
Problem:  tests: Test_cd_from_non_existing_dir() fails on Solaris
Solution: Skip the test on Solaris (Vladimír Marek).

Test_cd_from_non_existing_dir() depends on deleting the current working
directory.  Solaris does not allow that, so skip the test there.

closes: vim/vim#20563

b464c36bf9

Co-authored-by: Vladimír Marek <vlmarek13@gmail.com>
2026-06-19 09:44:42 +08:00
zeertzjq
147872452e vim-patch:9.2.0673: tests: Test_recover_corrupted_swap_file() cannot handle symlinks
Problem:  tests: Test_recover_corrupted_swap_file() cannot handle
          symlinks
Solution: Use writefile(readblob()) instead (Vladimír Marek)

Test_recover_corrupted_swap_file1() copies prebuilt corrupt swap samples
before recovering them.  In an out-of-source-tree build those sample
files may be symlinks into the source tree.  filecopy() preserves
symlinks, so the copied target may remain a symlink.  Recovery opens
swap files with O_NOFOLLOW, so that copied symlink cannot be opened.
Read the sample as a blob and write it back so the recovery target is a
real swap file.

closes: vim/vim#20561

88cbd00312

Co-authored-by: Vladimír Marek <vlmarek13@gmail.com>
2026-06-19 09:43:55 +08:00
zeertzjq
025a3e2baf vim-patch:9.2.0479: [security]: runtime(tar): command injection in tar plugin
Problem:  [security]: runtime(tar): command injection in tar plugin
          (Christopher Lusk)
Solution: Use the correct shellescape(args, 1) form for a :! command

Github Advisory:
https://github.com/vim/vim/security/advisories/GHSA-2fpv-9ff7-xg5w

3fb5e58fbc

Co-authored-by: Christian Brabandt <cb@256bit.org>
2026-06-19 09:43:55 +08:00
zeertzjq
f5ad6763b6 vim-patch:9.2.0677: Cannot clear the alternate file register # (#40316)
Problem:  Cannot clear the alternate file register #
Solution: Allow to clear it (Christoffer Aasted)

closes: vim/vim#20537

9db6fe4b17

Co-authored-by: Christoffer Aasted <dezzadk@gmail.com>
2026-06-19 01:30:41 +00:00
zeertzjq
1cfbf104f5 vim-patch:9.2.0676: MS-Windows: cannot switch to a buffer with '%' in its name (#40315)
Problem:  On MS-Windows it is not possible to switch to a buffer by name
          with ":b" (including via command-line completion) when the
          buffer name contains '%'.
Solution: Do not escape '%' and '#' for the ":buffer" command on
          MS-Windows.  Since ":buffer" has no EX_XFILE these are not
          expanded, and escaping them as "\%"/"\#" makes buffer name
          matching fail when '%'/'#' is in 'isfname' (the backslash is
          treated as a path separator).

fixes:  vim/vim#20529
closes: vim/vim#20548

1a96e07bf6

Co-authored-by: Hirohito Higashi <h.east.727@gmail.com>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-19 08:57:03 +08:00
Jan Edmund Lazo
2370fc1d91 vim-patch:9.2.0586: Crash with TextPut autocmd when pasting in terminal buffer (#40314)
Problem:  Crash with TextPut autocmd when pasting in normal mode in a
          terminal buffer.
Solution: Skip the TextPut autocmds when reg and insert are both NULL
          and regname is not '.' (Foxe Chen).

closes: vim/vim#20407

2e7833bde9

Co-authored-by: Foxe Chen <chen.foxe@gmail.com>
2026-06-19 08:41:56 +08:00
Nathan Zeng
ae426ee465 feat(:restart): v:startreason #40186
Problem:
It's clumsy for scripts to handle a "restart", without custom mappings or
global vars.

Solution:
Introduce `v:startreason`
2026-06-18 15:49:12 -04:00
zeertzjq
c4ce10930c vim-patch:9.2.0663: [security]: runtime(netrw): code injection in local file deletion
Problem:  [security]: s:NetrwLocalRmFile() escapes only the backslash in
          the file name before passing it to :execute, so a name
          containing "|" injects arbitrary Ex commands when the file is
          deleted (cipher-creator)
Solution: Use fnameescape() to correctly escape the file name
          (Yasuhiro Matsumoto).

Github Security Advisory:
https://github.com/vim/vim/security/advisories/GHSA-vhh8-v6wx-hjjh

Supported by AI

55bc757a5d

Co-authored-by: Yasuhiro Matsumoto <mattn.jp@gmail.com>
2026-06-17 15:22:04 +08:00
zeertzjq
52d7bbd1a0 vim-patch:9.2.0662: [security] Stack out-of-bounds write in dump_prefixes()
Problem:  [security]: a crafted spell file with a self-referential
          BY_INDEX node in the prefix tree can drive dump_prefixes()
          past the end of its MAXWLEN-sized depth arrays on :spelldump
          (cipher-creator)
Solution: only descend while depth < MAXWLEN - 1, as the sibling trie
          walkers already do (Yasuhiro Matsumoto)

Github Security Advisory:
https://github.com/vim/vim/security/advisories/GHSA-qm9w-fmpj-879h

Supported by AI

8325b193bb

Co-authored-by: Yasuhiro Matsumoto <mattn.jp@gmail.com>
2026-06-17 15:22:04 +08:00
zeertzjq
62cb36927d vim-patch:9.2.0651: completion: 'smartcase' doesn't work with 'longest'
Problem:  With 'longest', 'smartcase' is ignored when filtering matches:
          "inp" offers only "InputEvent", and an uppercase pattern gives
          different results for CTRL-N and CTRL-P.
Solution: 'longest' rewrites the leader with the common prefix, picking
          up uppercase the user never typed.  Judge case from the typed
          text instead, and match the auto-inserted part of the leader
          case-insensitively so CTRL-N and CTRL-P give the same result.
          (glepnir)

related: neovim/neovim#40259
closes:  vim/vim#20533

50fe45aca7

Co-authored-by: glepnir <glephunter@gmail.com>
2026-06-17 08:56:24 +08:00
tao
0a5f40c207 fix(path): open swapfile when using device path #39982
Problem:
Can't open swapfile when using a device path starting with `//?/`,
because `?` is a reserved char on Widnows.

Solution:
For device UNC paths, replace `//?/UNC/` and `//./UNC/` with `//`.
For other device paths, just strip their prefix (i.e. `//?/`, `//./`).
This aligns swapfile naming for device paths with regular UNC and DOS
paths.

Co-authored-by: Justin M. Keyes <justinkz@gmail.com>
2026-06-16 12:34:43 -04:00
glepnir
823517ad1d fix(highlight): keep guisp underline color in float with 'winblend' #40283
Problem:
A colored (guisp) underline showing through a 'winblend' float
lost its special color and followed the foreground instead.

Solution:
In the blend-through case, blend the underline's special color
only when the cell below sets sp explicitly; otherwise clear it.
2026-06-16 07:39:32 -04:00
zeertzjq
635939da3e vim-patch:9.2.0653: [security]: out-of-bounds write in tree_count_words() (#40279)
Problem:  [security]: a crafted spell file can drive tree_count_words()
          past the end of its MAXWLEN-sized depth arrays; the descent
          loop has no depth bound.
Solution: only descend while depth < MAXWLEN - 1, as the sibling trie
          walkers already do; apply the same guard to sug_filltree().

Github Security Advisory:
https://github.com/vim/vim/security/advisories/GHSA-wgh4-64f7-q3jq

Supported by AI.

a80874d9b8

Co-authored-by: Christian Brabandt <cb@256bit.org>
2026-06-16 09:57:45 +08:00
zeertzjq
17d4f4c5d8 Merge pull request #40255 from janlazo/vim-8.2.1821
vim-patch:8.2.1821,9.0.{927,2123},9.1.1233
2026-06-16 09:53:21 +08:00
glepnir
02b7415324 fix(lsp): requery empty isIncomplete completion lists #40100
Problem:
an empty `{ isIncomplete = true, items = {} }` ends completion
instead of requerying.

Solution:
keep isIncomplete on empty lists and retrigger on keypress while incomplete.
Reset on <C-e> so it doesn't immediately re-query.
2026-06-15 18:29:27 -04:00
glepnir
724e1421f8 fix(api): keep highlight font through set/get and redraws #40200
Problem: a font set via nvim_set_hl is lost or corrupted with font-only groups,
attribute combining, and update=true, and is dropped on any attr-table rebuild.
nvim__inspect_cell also frees the font name while a returned dict still borrows it.

Solution: register font-only groups, carry font through hl_combine_attr, inherit
it on update, and persist sg_font so a rebuild can restore it. Keep interned font
names across a rebuild instead of clearing them. Add the missing font field to
get_hl_info.

Co-authored-by: Ryan Patterson <cgamesplay@cgamesplay.com>
2026-06-15 17:51:42 -04:00
Oleh Volynets
b55a868309 feat(diagnostic): debounce current-line render #39542
Problem: vim.diagnostic.Opts.VirtualLines.current_line and
         vim.diagnostic.Opts.VirtualText.current_line cause redraw
         on every CursorMoved event that makes the text jump
         uncomfortably with rapid cursor movement.

Solution: `current_line` state is applied only on CursorHold,
          while still being cleared on CursorMoved making it so that
          until the cursor has stopped on a line, its diagnostic
          looks like cursor is not on the line preventing flicker.
2026-06-15 11:11:57 -04:00
Justin M. Keyes
145b20eb89 test: unreliable "with 'statuscolumn' wraps text" #40273
Problem:
flaky test:

    FAILED   ...st_xdg_terminal/test/functional/terminal/window_spec.lua @ 175: :terminal window with 'statuscolumn' wraps text
    ...st_xdg_terminal/test/functional/terminal/window_spec.lua:175: Row 1 did not match.
    Expected:
      |*{121:++ 7  }                                            |
      |*{121:++ 8  }abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQR|
      |*{121:++ 9  }STUVWXYZ                                    |
      |*{121:++10  }abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQR|
      |*{121:++11  }STUVWXYZrows: 6, cols: 44                   |
      |*{121:++12  }^                                            |
      |{5:-- TERMINAL --}                                    |
    Actual:
      |*{121:++ 8  }                                            |
      |*{121:++ 9  }abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQR|
      |*{121:++10  }STUVWXYZ                                    |
      |*{121:++11  }abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQR|
      |*{121:++12  }STUVWXYZrows: 6, cols: 44                   |
      |*{121:++13  }^                                            |
      |{5:-- TERMINAL --}                                    |

Solution:
Relax the screen test. The `feed_data` + `tty-test` handling is racey;
'statusline' is correctly reporting the line-numbers, and that's all
that matters.
2026-06-15 10:30:55 -04:00