| Commit message (Collapse) | Author | Age | Files | Lines |
... | |
|
|
|
|
|
|
|
|
|
|
|
| |
Do not store the dependency in tools.go as there may be conflicts with
some indirect dependencies of aerc.
Run gofumpt and golangci-lint from their latest tagged release. This
should fix issues with go 1.20. Bonus, it drains a bit of fat from
go.sum.
Signed-off-by: Robin Jarry <robin@jarry.cc>
Acked-by: Moritz Poldrack <moritz@poldrack.dev>
|
|
|
|
|
|
|
|
|
|
|
| |
Inserting a solitary "-- " delimiter without any signature after it
makes no sense. Skip the whole delimiter check if the signature is
empty. Trim leading and trailing white space along the way.
Fixes: a553b33ebcbd ("compose: ensure signature uses standard delimiter")
Reported-by: Ben Cohen <ben@bencohen.net>
Signed-off-by: Robin Jarry <robin@jarry.cc>
Tested-by: Ben Cohen <ben@bencohen.net>
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Update tcell-term to v0.6.0:
- Fixes several leaking goroutines
- Adds an EventBell, enabled aerc to know when a terminal has a BEL
event
- Fixes a panic on \x1b[0G
Signed-off-by: Tim Culverhouse <tim@timculverhouse.com>
Tested-by: Bence Ferdinandy <bence@ferdinandy.com>
Acked-by: Robin Jarry <robin@jarry.cc>
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
strings.SplitN is not like python str.split() method... It requires an
exact number of items including the trailing non split part.
Add unit tests to ensure it works.
Fixes: 6cfbc87d8ab0 ("dirlist: use templates instead of % mini language")
Reported-by: John Mcenroy <handplanet@outlook.com>
Signed-off-by: Robin Jarry <robin@jarry.cc>
Tested-by: Ben Lee-Cohen <ben@lee-cohen.com>
Reviewed-by: Vincenzo Palazzo <vincenzopalazzodev@gmail.com>
|
|
|
|
| |
Signed-off-by: Robin Jarry <robin@jarry.cc>
|
|
|
|
|
|
| |
When running :toggle-headers, pipe the output in colorize by default.
Signed-off-by: Robin Jarry <robin@jarry.cc>
|
|
|
|
|
|
|
|
|
|
|
| |
Replace dirlist-format with two settings: dirlist-left & dirlist-right.
These two settings take aerc-templates(7) and may be left empty.
Add automatic translation of dirlist-format to these new settings.
Display a warning on startup if dirlist-format has been converted.
Signed-off-by: Robin Jarry <robin@jarry.cc>
Acked-by: Tim Culverhouse <tim@timculverhouse.com>
|
|
|
|
|
|
|
| |
This will be used in the dirtree-format replacement by templates.
Signed-off-by: Robin Jarry <robin@jarry.cc>
Acked-by: Tim Culverhouse <tim@timculverhouse.com>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
In the spirit of commit 535300cfdbfc ("config: add columns based index
format"), reuse the column definitions and table widget.
Add automatic translation of render-format to column definitions. Allow
empty columns to be compatible with the %m (mute) flag.
Rename the State object to AccountState to be more precise. Reuse that
object in state.TempateData to expose account state info. Move actual
status line rendering in StatusLine.Draw().
Add new template fields for status specific data:
{{.ConnectionInfo}}
Connection state.
{{.ContentInfo}}
General status information (e.g. filter, search)
{{.StatusInfo}}
Combination of {{.ConnectionInfo}} and {{.StatusInfo}}
{{.TrayInfo}}
General on/off information (e.g. passthrough, threading,
sorting)
{{.PendingKeys}}
Currently pressed key sequence that does not match any key
binding and/or is incomplete.
Display a warning on startup if render-format has been converted to
status-columns.
Signed-off-by: Robin Jarry <robin@jarry.cc>
Acked-by: Tim Culverhouse <tim@timculverhouse.com>
|
|
|
|
|
|
|
|
| |
These modules will not handle statusline rendering after next commit.
Move them in lib/state to make next commit easier to review.
Signed-off-by: Robin Jarry <robin@jarry.cc>
Acked-by: Tim Culverhouse <tim@timculverhouse.com>
|
|
|
|
|
|
|
|
|
| |
The width is only required when rendering the table in Draw. Remove the
redundant width attribute.
Fixes: 012be0192c88 ("ui: add reusable table widget")
Signed-off-by: Robin Jarry <robin@jarry.cc>
Acked-by: Tim Culverhouse <tim@timculverhouse.com>
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
When a column uses WIDTH_FIT and its contents are empty, the column is
not rendered at all, neither is its separator. This can cause display
artifacts (interruption of background color, etc.).
Make sure to differentiate between zero-width columns and columns that
overflow screen width.
Fixes: 012be0192c88 ("ui: add reusable table widget")
Acked-by: Tim Culverhouse <tim@timculverhouse.com>
Signed-off-by: Robin Jarry <robin@jarry.cc>
|
|
|
|
|
|
|
| |
Now that this is not used anywhere, remove it.
Signed-off-by: Robin Jarry <robin@jarry.cc>
Acked-by: Tim Culverhouse <tim@timculverhouse.com>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Since previous commit, all commands now support expanding text/template
markup. Reuse that for the new-email trigger command.
Update commands.ExecuteCommand to take optional *AccountConfig and
*MessageInfo arguments. If these are nil, fallback to using the
currently selected account and message (if any).
Pass the proper *AccountConfig and *MessageInfo objects when firing the
trigger command so that these are used instead of the currently selected
ones.
If new-email contains % placeholders, try to convert them to template
markup reusing the same conversion added in commit 535300cfdbfc
("config: add columns based index format"). Warn the user that they need
to update their configuration file.
Signed-off-by: Robin Jarry <robin@jarry.cc>
Reviewed-by: Moritz Poldrack <moritz@poldrack.dev>
|
|
|
|
|
|
|
|
|
| |
Interpret go template constructs in all aerc command arguments based on
the currently selected account, folder and message (if any).
Signed-off-by: Aivars Vaivods <aivars@vaivods.lv>
Signed-off-by: Robin Jarry <robin@jarry.cc>
Reviewed-by: Tim Culverhouse <tim@timculverhouse.com>
|
|
|
|
|
|
|
| |
This allows to get the current local time.
Signed-off-by: Robin Jarry <robin@jarry.cc>
Acked-by: Moritz Poldrack <moritz@poldrack.dev>
|
|
|
|
|
|
|
| |
These can be handy for tab-title-composer.
Signed-off-by: Robin Jarry <robin@jarry.cc>
Reviewed-by: Moritz Poldrack <moritz@poldrack.dev>
|
|
|
|
|
|
|
|
|
| |
Change the {{.Recent}}, {{.Unread}} and {{.Exists}} template fields to
take an arbitrary number of folder names as arguments. If no folder name
is specified, these return the counts for all folders.
Signed-off-by: Robin Jarry <robin@jarry.cc>
Acked-by: Tim Culverhouse <tim@timculverhouse.com>
|
|
|
|
|
|
|
|
|
|
| |
mboxes currently returns the same value that emails. The SplitN API is
misleading, to actually split something, the N value must be greater
than 1...
Fixes: d758441fe0c4 ("templates: add more fields and functions")
Signed-off-by: Robin Jarry <robin@jarry.cc>
Acked-by: Moritz Poldrack <moritz@poldrack.dev>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Require that all aerc template data objects implement the same
TemplateData interface.
Implement that interface in two different places:
1) state.TemplateData (renamed/moved from templates.TemplateData).
This structure (along with all its methods) needs to be decoupled
from the templates package to break the import cycle with the config
package. This allows much simpler construction of this object and
ensure that values are calculated only when requested.
2) config.dummyData (extracted from templates).
This is only used in the config package to validate user templates.
Putting it here allows also to break an import cycle.
Use state.TemplateData everywhere (including for account tabs title
rendering).
Signed-off-by: Robin Jarry <robin@jarry.cc>
Reviewed-by: Moritz Poldrack <moritz@poldrack.dev>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Fix the following error:
panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x130 pc=0x8769b4]
goroutine 1 [running]:
git.sr.ht/~rjarry/aerc/lib.(*MessageStore).Uids(0x40ffa5?)
git.sr.ht/~rjarry/aerc/lib/msgstore.go:579 +0x14
git.sr.ht/~rjarry/aerc/widgets.(*AccountView).SelectedMessage(0xc0000f41c0)
git.sr.ht/~rjarry/aerc/widgets/account.go:198 +0x33
Signed-off-by: Robin Jarry <robin@jarry.cc>
Acked-by: Moritz Poldrack <moritz@poldrack.dev>
|
|
|
|
|
|
|
|
|
|
|
|
| |
When handling a mailto-Link or opening an mbox file, another update is
required before the composer is shown. This is caused by the view not
being invalidated and no redraw being queued.
Invalidate the UI and queue a redraw when an IPC command is received.
Fixes: 7a489cb0011a ("Add Unix socket for communicating with aerc")
Signed-off-by: Moritz Poldrack <git@moritz.sh>
Acked-by: Robin Jarry <robin@jarry.cc>
|
|
|
|
|
|
|
|
| |
Make it easier to debug send configurations.
References: https://todo.sr.ht/~rjarry/aerc/127
Signed-off-by: Bence Ferdinandy <bence@ferdinandy.com>
Acked-by: Robin Jarry <robin@jarry.cc>
|
|
|
|
|
|
|
|
|
|
|
|
| |
Since it has recently been a topic on IRC, and to guide users new to
"raw" email, add a note on how signatures are detected and what they
should look like.
Prepend signature-file and signature-cmd with the standard delimiter if
missing.
Signed-off-by: Moritz Poldrack <git@moritz.sh>
Signed-off-by: Robin Jarry <robin@jarry.cc>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Use a template for compose tabs.
Other available values:
Account string
Subject string
To []*mail.Address
From []*mail.Address
Cc []*mail.Address
Bcc []*mail.Address
OriginalFrom []*mail.Address
When you use To, From, CC, BCC, or OriginalFrom the title will only be
updated when an editing field has lost focus. This is so we don't end up
calling "PrepareHeader" on every keystroke, which will likely error out
anyways since it will be an invalid header.
Subject still updates every keystroke.
Signed-off-by: Tim Culverhouse <tim@timculverhouse.com>
Acked-by: Robin Jarry <robin@jarry.cc>
|
|
|
|
|
|
|
|
|
|
| |
When listing all addresses with names, in for example the To field, one
might end up with a very long string. Add the initials function, which
extracts the names from addresses and then shortens each of them to the
initials of the name.
Signed-off-by: Bence Ferdinandy <bence@ferdinandy.com>
Acked-by: Robin Jarry <robin@jarry.cc>
|
|
|
|
|
|
|
|
| |
The edge branch sometimes has pre-release go versions which do not play
well with some of our dependencies. Make sure to stay on the latest
stable version.
Signed-off-by: Robin Jarry <robin@jarry.cc>
|
|
|
|
|
|
|
|
|
|
| |
index-format may be used in contextual [ui] sections. Display a warning
for every converted section so that users don't miss any.
Fixes: 535300cfdbfc ("config: add columns based index format")
Reported-by: Bence Ferdinandy <bence@ferdinandy.com>
Signed-off-by: Robin Jarry <robin@jarry.cc>
Tested-by: Bence Ferdinandy <bence@ferdinandy.com>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Expose go-smtp functionality for setting the domain name as a config
option. This allows aerc to communicate with SMTP servers with strict
antispam measures without relying on sendmail.
In theory, this should be set to a fully qualified domain name, but some
servers simply forbid the use of "localhost", so it is reasonable to let
the user set whatever value works for them.
For comparison, this is equivalent to the functionality of the "domain"
option of msmtp.
Signed-off-by: Karel D. Kopecký <kdk@freeshell.de>
Acked-by: Robin Jarry <robin@jarry.cc>
|
|
|
|
|
|
|
|
|
|
|
| |
Restore the default theme from the previous colorize awk script. It is
more colorful and may be more appealing to new users out of the box.
Since colorize is now configurable via stylesets, power users can do
whatever they like.
Requested-by: Andrea Pappacoda <andrea@pappacoda.it>
Signed-off-by: Robin Jarry <robin@jarry.cc>
Agreed-by: Bence Ferdinandy <bence@ferdinandy.com>
|
|
|
|
|
|
|
|
|
| |
When [ui].show-headers is true, use textproto.WriteHeader instead of
manually writing the header values. This allows displaying the original
header buffer with on-the-wire format (and with lines wrapped).
Signed-off-by: Robin Jarry <robin@jarry.cc>
Tested-by: Bence Ferdinandy <bence@ferdinandy.com>
|
|
|
|
|
|
|
|
|
|
|
| |
Some contacts, especially corporate, include a wall of text in their
signatures. To not clutter the reply chain, this commit introduces a new
function to the templating engine that removes the signature from
a message.
Link: https://learn.microsoft.com/en-us/microsoft-365/admin/setup/create-signatures-and-disclaimers
Signed-off-by: Moritz Poldrack <git@moritz.sh>
Acked-by: Robin Jarry <robin@jarry.cc>
|
|
|
|
|
|
|
|
|
| |
Remove unused "RenderAccountTabs" field from config. This field is not
used anywhere in the codebase and does not appear anywhere in the docs
nor default configs.
Signed-off-by: Tim Culverhouse <tim@timculverhouse.com>
Acked-by: Robin Jarry <robin@jarry.cc>
|
|
|
|
|
|
|
| |
Reuse the newly-added GetRUECount method to simplify getRUEString
Signed-off-by: Tim Culverhouse <tim@timculverhouse.com>
Acked-by: Robin Jarry <robin@jarry.cc>
|
|
|
|
|
|
|
|
|
|
|
| |
Use a go template to render the account tab display. Add config option
for setting a specific template for the account. Add a method on Tab to
allow setting a title, which may be different than the tab Name.
The default template is {{.Account}}.
Signed-off-by: Tim Culverhouse <tim@timculverhouse.com>
Acked-by: Robin Jarry <robin@jarry.cc>
|
|
|
|
|
|
|
| |
Add account name to log of all Post/Process Message/Action logs.
Signed-off-by: Tim Culverhouse <tim@timculverhouse.com>
Acked-by: Robin Jarry <robin@jarry.cc>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
On (some?) MacOS systems there is no C.UTF-8 locale available. Instead
there is a non-standard "UTF-8" (encoding only) replacement. Running
wrap on MacOS results in an error:
error: failed to set locale: Bad file descriptor
Instead of expecting that C.UTF-8 will always be available, try to use
the user set locale (either from the $LC_ALL or $LANG environment
variables). If these variables are unset or if they are set to an
invalid/non-existent locale, fallback on C.UTF-8. If C.UTF-8 is not
available, make one last desperate attempt for this UTF-8 non-standard
locale (MacOS only).
aerc will always send UTF-8 encoded text to the filter commands, If the
locale that we managed to load does not use the UTF-8 character
encoding, exit with an explicit error instead of risking undefined
behaviour.
Reported-by: Ben Cohen <ben@bencohen.net>
Signed-off-by: Robin Jarry <robin@jarry.cc>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The previous URL regex was too lax, allowing all "[:graph:]" characters
after the protocol:// part. This caused the script to mark as part of an
URL also things like ">", which is commonly used as a URL delimiter in
plain text and Markdown; the url() function tried to account for this
with some heuristic to remove trailing characters, but it didn't always
work (see the screenshots below).
As RFC 3986 specifies the list of allowed characters in URLs, we can
simply make our regex stricter and only mark characters as part of an
URL if they match the allowed set. As the number of allowed characters
has been reduced, the aforementioned heuristic has been slightly
simplified.
I've also removed the backslash escapes from the bracket expressions,
as POSIX regular expressions do not require them; the only characters
that need special handling are ']' and '-', which need to be placed at
the start and at the end of the expression, respectively.
Signed-off-by: Andrea Pappacoda <andrea@pappacoda.it>
Acked-by: Robin Jarry <robin@jarry.cc>
|
|
|
|
|
|
|
|
|
| |
This adds a styleset using the solarized theme to aerc which affects the
tui and the colorize wrapper.
Link: https://ethanschoonover.com/solarized/
Signed-off-by: Jens Grassel <jens@wegtam.com>
Acked-by: Robin Jarry <robin@jarry.cc>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Fix the following obscure build error:
gcc -O2 -g -Wall -Wextra -Werror -Wformat-security -Wstack-protector -fstack-protector-strong -fanalyzer
gcc: fatal error: no input files
The issue is that CFLAGS contains newline characters '\n' because of the
yaml > continuation. I had misinterpreted the spec hoping that the final
newline will also be stripped which is not.
Put all CFLAGS on a single line.
Link: https://yaml.org/spec/1.0/#id2567537
Fixes: 3191ee171c43 ("filters: rewrite wrap in c")
Signed-off-by: Robin Jarry <robin@jarry.cc>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Allow composing and sending messages with:
Content-Type: text/plain; Format=Flowed
This requires additional configuration in the text editor to actually
produce the required trailing spaces at the end of lines that are part
of the same paragraph. For example, with vim:
"~/.vim/ftplugin/mail.vim
setlocal textwidth=72
setlocal formatoptions=1jnwtcql
setlocal comments+=nb:>
Link: https://www.rfc-editor.org/rfc/rfc3676.html
Signed-off-by: Robin Jarry <robin@jarry.cc>
Tested-by: Moritz Poldrack <moritz@poldrack.dev>
|
|
|
|
|
|
|
|
| |
Allow defining a .headers special filter command that will be used only
to process email headers (when [viewer].show-headers=true).
Signed-off-by: Robin Jarry <robin@jarry.cc>
Tested-by: Kt Programs <ktprograms@gmail.com>
|
|
|
|
|
|
|
| |
The config objects are now globally available.
Signed-off-by: Robin Jarry <robin@jarry.cc>
Tested-by: Kt Programs <ktprograms@gmail.com>
|
|
|
|
|
|
|
| |
This has setting never been used.
Signed-off-by: Robin Jarry <robin@jarry.cc>
Tested-by: Kt Programs <ktprograms@gmail.com>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Since its introduction, we had multiple issues with the colorize awk
script with regard to non-GNU awk compatibility.
Also, this script is standalone and the color theme must be hard coded
into it. Reading from an external configuration file (aerc's styleset)
from a non-GNU awk is close to impossible (and even far from trivial
with GNU awk).
Rewrite the builtin colorize filter in C to allow getting the color
theme from aerc's active styleset. The theme is configured using the
existing styleset syntax and attributes under a separate [viewer]
section (see examples and man page).
Export the active styleset file path to AERC_STYLESET env var when
invoking the filter command so that colorize can access it and use it.
I have tested compilation (with clang-analyzer and gcc -fanalyzer) and
basic operation on FreeBSD, Fedora (glibc) and Alpine (muslibc). More
tests would probably be required on MacOSX and older Linux distros.
I also added test vectors to give some confidence that this works as
expected. The execution with these vectors passed valgrind
--leak-check=full without errors.
NB: the default theme has changed to be more minimal. Sample stylesets
have more colorful examples. The awk -v theme=xxx option is no longer
supported.
usage: colorize [-h] [-s FILE] [-f FILE]
options:
-h show this help message
-s FILE use styleset file (default $AERC_STYLESET)
-f FILE read from filename (default stdin)
Signed-off-by: Robin Jarry <robin@jarry.cc>
Tested-by: Bence Ferdinandy <bence@ferdinandy.com>
Acked-by: Moritz Poldrack <moritz@poldrack.dev>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
This utility introduced in commit c9524d265793 ("filters: add wrap
utility written in go") allows to reflow text to view emails that have
very long lines without breaking quotes, lists and indentation.
For such a simple task, go produces a binary that is 2.0M bytes on disk.
After stripping debugging symbols, it can be reduced to 1.2M bytes. All
of this for 267 lines of source code. This is a bit ridiculous, provided
people may load this binary into memory multiple times per minute. This
tool is a small side-project that seems not suitable for golang.
Rewrite it in C. It now only depends on a POSIX libc to run. It is safe
to assume that there is one available on all *NIX systems in the world
of 2023. The resulting binary is now 27K bytes (15K after stripping).
To build it, a C compiler and libc headers are required. These should
most likely be available since they are dependencies of the go compiler
toolchain.
I have tested compilation (with clang-analyzer and gcc -fanalyzer) and
basic operation on FreeBSD, Fedora (glibc) and Alpine (musl libc). More
tests would probably be required on MacOSX and older Linux distros.
I also added test vectors to give some confidence that this works as
expected.
Update CI with aggressive gcc hardening flags and to run these tests
with valgrind --leak-check=full.
Command line options are unchanged:
usage: wrap [-h] [-w INT] [-r] [-l INT] [-f FILE]
Wrap text without messing up email quotes.
options:
-h show this help message
-w INT preferred wrap margin (default 80)
-r reflow all paragraphs even if no trailing space
-l INT minimum percentage of letters in a line to be considered
a paragaph
-f FILE read from filename (default stdin)
Signed-off-by: Robin Jarry <robin@jarry.cc>
Tested-by: Bence Ferdinandy <bence@ferdinandy.com>
Tested-by: Maxwell G <gotmax@e.email>
|
|
|
|
|
|
|
| |
Allow defining <obj>.dim=true to turn on half-bright text.
Signed-off-by: Robin Jarry <robin@jarry.cc>
Acked-by: Moritz Poldrack <moritz@poldrack.dev>
|
|
|
|
|
|
|
|
|
| |
When switching accounts, headers were updated, but not the account
configurations in the composer. Switch the account config also and add
a debug log to send with the uri being used.
Signed-off-by: Bence Ferdinandy <bence@ferdinandy.com>
Acked-by: Robin Jarry <robin@jarry.cc>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Normally for emails with xoauth2, the help page says to pass the refresh
token as the password. When the refresh token expires, aerc can't fetch
the access token, and you must get a new refresh token from the external
script.
This patch implements a cycle of refresh tokens so you only need
to use an external script to fetch the refresh token once.
Once you have fetched the initial refresh token (with an external script
like mutt_xoauth2.py or https://github.com/gaoDean/oauthRefreshToken),
that refresh token is inputted as the password to aerc (as normal) to
fetch the access token. Before this patch aerc used to only fetch the
access token, but now it fetches that and a new refresh token, which it
caches in $XDG_CONFIG_HOME/aerc/<account>-xoauth2.token. In the next
opening of aerc, aerc will pull the refresh token from the cache, and
use it instead of the inputted refresh token from the password. If it is
not present in the cache, the refresh token is taken from the password
as usual.
Signed-off-by: Dean <gao.dean@hotmail.com>
Acked-by: Robin Jarry <robin@jarry.cc>
|
|
|
|
|
|
|
|
|
| |
A previous commit introduced a trace loglevel, but aerc doesn't make
much use of it. Logging is not very informative either. Add a log.Tracef
to every command and log the provided arguments as well.
Signed-off-by: Bence Ferdinandy <bence@ferdinandy.com>
Acked-by: Robin Jarry <robin@jarry.cc>
|