Compare commits

...

119 Commits

Author SHA1 Message Date
azalea e64f7efca6 [F] Fix escaping (Fix #500)
Shellcheck / check (push) Has been cancelled
2026-04-20 23:45:57 -04:00
azalea 7bfb750f63 [F] Fix #499: neowofetch not found 2026-04-20 01:43:50 -04:00
azalea 7433df5d74 [O] Dockerize AI github moderator 2026-04-20 01:33:44 -04:00
azalea 2361be73ba [F] Update AI github moderator usage 2026-04-20 01:33:44 -04:00
azalea 5f8a34142e [U] Release 2.1.0 2026-04-20 01:33:44 -04:00
azalea 36c081c2ce [F] Order ascii checks 2026-04-12 18:53:27 +00:00
azalea 4ee3cd6b85 [O] Remove unused 2026-04-12 18:40:57 +00:00
azalea 5b9865382e [F] Maybe fix path escaping issue #496 2026-04-12 18:36:46 +00:00
Luna Jernberg 6241531ce9 Update Slackware installation instructions (#495)
Updated Slackware installation instructions to include new maintainer MDKDIO.
2026-04-12 05:53:54 +08:00
Zzyzx Wolfe 2196517709 [+] Queer Villain Pride flag. (#497)
Sourced from https://distressedegg.fun/qvp
2026-04-12 05:53:32 +08:00
azalea 7a2b2ba744 Revise change log and notation details
Reintroduce About Notation section and update change log.
2026-04-08 22:00:11 +08:00
azalea 4b7c92ba4b [F] Fix build pkg 2026-04-07 21:39:20 +00:00
azalea 9cf9985973 [U] Release 2.1.0-rc1 2026-04-07 16:14:21 -04:00
azalea 18bb479415 [U] Update fastfetch 2026-04-07 20:06:41 +00:00
azalea b667cc8ad6 [U] Changelog 2026-04-07 17:11:36 +00:00
azalea e838166b16 [F] Fix background color detection timeout (#453) 2026-04-07 17:04:55 +00:00
azalea 43e1dc1067 [F] poor cat 2026-04-07 16:32:08 +00:00
azalea cc5d7570fb [+] CLI for selecting multiple flags at random (#487) 2026-04-07 16:13:17 +00:00
azalea b05d9c44b4 [+] Option to select random flags (#487) 2026-04-07 15:50:30 +00:00
azalea 2995c78e66 [U] Update deps 2026-04-07 15:39:18 +00:00
azalea 1d89f237db [F] Fix build 2026-04-07 15:39:12 +00:00
azalea 75cde60494 [U] Changelog 2026-04-07 15:39:04 +00:00
azalea fa71dfb84e [+] Haruhi Suzumiya flag (#486) 2026-04-07 15:26:24 +00:00
azalea c147a2ffc6 [-] export distros 2026-04-07 07:42:18 +00:00
azalea 9cc0f9a111 [O] Dedup 2026-04-07 07:15:27 +00:00
azalea 0aa7731c17 [O] No need to export distros 2026-04-07 07:08:23 +00:00
azalea 255dd3e630 [U] Changelog 2026-04-07 06:57:02 +00:00
azalea 7100f7a682 [F] Fix first line missing 2026-04-07 06:23:16 +00:00
azalea 68cb804ccf [+] Read from distro data in python 2026-04-07 06:05:18 +00:00
azalea e9b65287a3 [+] Read from distro data in rust 2026-04-07 06:00:01 +00:00
azalea 5ff0a8d49a [O] Distro as data 2026-04-07 05:58:09 +00:00
azalea 635fbfff01 [F] Fix bash in MINGW64 2026-04-07 02:29:26 +00:00
azalea 13e56f621b [F] Fix macchina #491 2026-04-07 01:55:11 +00:00
Joanna Hartley 9500e8c0aa Add support for QNX/Blackberry 10 (#480)
* Add support for QNX 8.x/Blackberry 10

* Maybe the real uptime was the friends we made along the way

* Detect name of the terminal application

* Re-run the list distros script

* Fix for incorrect memory utilization, and various copilot suggestions. Removed code providing unreliable detection of the terminal application

* Apply suggestion from @Copilot

Ignore header lines for qpkg package manager

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* Remove erroneous dependencies

---------

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2026-04-07 09:10:05 +08:00
thea e5ba2b3be9 [+] Add custom_presets config option (#481)
* [+] Add custom_presets config option

* [F] Resolve Copilot issues
2026-04-07 09:09:52 +08:00
thea e78e60da3d [+] Live filter preset selection (#482)
* [+] Live filter preset selection

* [F] Resolve Copilot issues
2026-04-07 09:09:42 +08:00
joyous.fart 809b9c34f4 added peter griffin pride flag (#489)
added peter griffin pride flag (inspired by a yahiamice video i think (i dont remember which one sadly))
2026-03-24 09:03:22 +08:00
Enid Brown 352a1ba086 Fix terminal font output in kitty (#484)
[fix] fix terminal font output in kitty
2026-03-08 22:06:08 +08:00
azalea b81d5fed1b [F] Continue even when current path is not found (Fixes #426) 2026-02-11 21:47:27 -05:00
azalea f32e2df4fa [F] Fallback for OS unsupported by rust (Fix #474) 2026-02-11 21:26:36 -05:00
azalea abcc1d265b [F] Prioritize CLI-specified ASCII art by reading it early to prevent file descriptor issues and ensure it overrides configuration. (#475) 2026-02-11 20:57:49 -05:00
notfrants 25824da0e0 Added codex linux and re-run the list distros script (#477)
* Add codex linux

* Fix zirconium (#468)

* Remove non-existing distros (re-run the list_distros.py script)

* Add codex linux to the help message
2026-02-12 09:39:26 +08:00
Theo Haines 5e0f1ee909 [+] Add rubber flag (#479) 2026-02-12 09:28:14 +08:00
Andrin Haldner 62b0fd959f Fix shell detection by using os.execv instead of subprocess.run (#469)
Replace subprocess.run with os.execv to directly exec the Rust binary
2026-01-24 00:17:55 -05:00
bri 9a66c10afd [+] Add zirconium distro (#468)
add zirconium to neofetch
2026-01-24 00:16:32 -05:00
azalea 62fdc22c00 [U] Release 2.0.5 2025-11-21 07:21:23 -05:00
azalea 1fdcfa66b8 Update neofetch 2025-11-21 20:20:39 +08:00
azalea d08a0745a5 [F] Fix shell check 2025-11-21 20:18:44 +08:00
azalea 4ee5344209 Update deploy.md 2025-11-21 20:10:23 +08:00
azalea 26030b0628 [+] Changelogs 2025-11-21 20:04:03 +08:00
azalea 9b376f97c0 [F] Fix #460: Hyfetch panics upon entering invalid alignment option after roll 2025-11-21 19:38:19 +08:00
azalea 2dc18050ca [F] Fix warning 2025-11-21 19:32:14 +08:00
azalea e816235637 [F] Fix #462 Python version prints Traceback on KeyboardInterrupt 2025-11-21 19:27:52 +08:00
azalea 8046e9bab3 [F] Fix #465 2025-11-21 19:21:23 +08:00
ruby_rose e03cda1475 Added femme flag (#456)
* Added femme

* Properly added femme to the list in build.rs

* Revert "Properly added femme to the list in build.rs"

This reverts commit be7f0748ac042bb824a074a664d9978e835a3a58.

---------

Co-authored-by: Azalea <22280294+hykilpikonna@users.noreply.github.com>
2025-11-21 19:14:56 +08:00
Tini 20e5fb3f89 issue #440 void_old added (#457) 2025-11-21 19:10:36 +08:00
LithTheFox e253a75924 Added back the flags that were lost in the python and rust presets merge (#466)
* Added flags that were lost in the Python and Rust presets merge

* [F] Should be above meme flags

---------

Co-authored-by: Azalea <22280294+hykilpikonna@users.noreply.github.com>
2025-11-21 19:09:54 +08:00
azalea 2252fc36e7 Merge branch 'master' of github.com:hykilpikonna/hyfetch 2025-10-22 13:15:42 +08:00
azalea 4e23243384 [O] Colorize secureblue (#434) 2025-10-22 13:15:17 +08:00
azalea f6dc68d7dc [+] Secureblue (closes #434) 2025-10-22 13:02:53 +08:00
azalea f947373a23 [U] Release 2.0.4 2025-10-22 00:46:55 -04:00
azalea 5b745cde01 [U] Changelog 2025-10-22 00:29:49 -04:00
azalea 1afbd66355 [O] Specify python 3.7 to be min version 2025-10-22 12:29:29 +08:00
azalea 2fe21deea8 [F] Fix windows binary mixed with unix 2025-10-22 12:08:39 +08:00
azalea 37a19901bb [U] Update build tool to work with new builder 2025-10-22 11:56:40 +08:00
azalea 063679b72d [O] Moderize python build tool from setup-tools to hatchling 2025-10-22 11:55:07 +08:00
azalea 264cf11690 Merge branch 'master' of github.com:hykilpikonna/hyfetch 2025-10-22 11:34:09 +08:00
azalea 6280d370bc [U] Clarify notes 2025-10-22 11:30:49 +08:00
azalea 6cfc337d83 [O] Fix unused warning on non-windows 2025-10-22 11:28:52 +08:00
azalea 533de96e80 [U] Update notes 2025-10-22 11:24:49 +08:00
azalea dee984f931 [U] Release 2.0.3 2025-10-21 23:20:52 -04:00
azalea 959d42ee9c [F] Typo 2025-10-21 23:20:00 -04:00
azalea eb349aa1aa [U] Changelog 2025-10-21 23:17:56 -04:00
azalea d5751e06af [O] Shorten 2025-10-22 10:53:51 +08:00
azalea 981602b690 [O] Anyhow 2025-10-22 10:42:58 +08:00
azalea a8d752aa9f [F] Preserve preset order in codegen 2025-10-22 10:33:11 +08:00
azalea c57e8a4a49 [+] Rust codegen for presets
#451
2025-10-22 10:27:18 +08:00
azalea 67ae918ae8 [O] Fix weights
#451
2025-10-22 09:53:46 +08:00
azalea e788f93c2b [F] from __future__ import annotations 2025-10-22 08:27:50 +08:00
azalea 75a2e9d8d3 [O] Python load presets from json
#451
2025-10-22 08:24:32 +08:00
azalea 23888c0e3e Merge branch 'SHORTEN' 2025-10-21 19:52:01 +08:00
azalea e5ad9e564d Merge branch 'master' of github.com:hykilpikonna/hyfetch 2025-10-21 19:51:35 +08:00
azalea 328381b336 [+] presets.json 2025-10-21 19:50:59 +08:00
ObsoleteDev 28a181d97b [+] Transbian pride flag (#449)
* [+] Transbian flag py

* [C} Update wording on py Transbian flag

* [+] Add Transbian flag to rust

---------

Co-authored-by: Azalea <22280294+hykilpikonna@users.noreply.github.com>
2025-10-21 19:28:46 +08:00
ObsoleteDev bb514f8fd9 [+] Autism pride flag (py & rust) (#450)
Co-authored-by: Azalea <22280294+hykilpikonna@users.noreply.github.com>
2025-10-21 19:27:26 +08:00
ObsoleteDev b585ee1e26 [+] Add Transneutral & Cenelian flags (#452) 2025-10-21 19:26:14 +08:00
ObsoleteDev de2141347e Fix: Hyfetch panics on some distros that are not defined (#455) 2025-10-21 19:25:48 +08:00
Un1q32 ba88581ed4 Support iOS 1.x (#444)
* support iOS 1.x

* add comment

* reword and fix typo
2025-10-13 15:24:39 +08:00
apaz 932042b62c Swap inside fstring to double quote (#442) 2025-10-10 12:48:03 +08:00
thea f5c5e31691 [F] Fix 3-length hex codes in Python when using custom preset (#443)
[F] Fix 3-length hex codes in Python
2025-10-10 12:46:41 +08:00
azalea 15ca855a04 [O] Shorten 2025-10-02 02:11:58 +08:00
azalea 666d2dc90a Update hyfetch.rs 2025-10-02 01:33:25 +08:00
azalea 34583294c6 [O] Make code more readable 2025-10-02 01:25:07 +08:00
azalea 03615ab4ee [O] Make code more readable 2025-10-02 01:06:39 +08:00
azalea c722c73e79 [O] shorten code 2025-10-02 00:44:05 +08:00
azalea 8f5199974b [F] Fix windows build #439 2025-10-02 00:43:25 +08:00
azalea 8168877fb1 [U] Update crates 2025-10-02 00:40:05 +08:00
azalea 4e20b18d45 [U] Upgrade deps 2025-10-01 23:58:01 +08:00
thea 5dc1709f58 [+] Allow passing hex colors as preset (#435) 2025-10-01 08:13:09 -07:00
Un1q32 fb1e35172e Support old Apple TV models (#438) 2025-10-01 08:12:37 -07:00
ObsoleteDev fc9292be3f 🌈 Support custom ASCII art file path (#429)
* Feature: Add custom ascii file saving to python version of hyfetch

* Feature: Add custom ascii file saving to rust version of hyfetch

* [-] Remove test ascii

---------

Co-authored-by: Azalea <22280294+hykilpikonna@users.noreply.github.com>
2025-10-01 08:12:05 -07:00
ObsoleteDev 3f41cb40e2 [+] Add fluidflux flags (#437)
* [+] Add fluidflux flags to py

* [+] Add fluidflux flags rust
2025-09-18 21:48:54 -07:00
ObsoleteDev 729024a45f [+] libragender flags (#433)
* [+] libragender flags py

* [+] libragender flags rust
2025-09-13 02:21:01 +09:00
ObsoleteDev ef1407d00e [F] Only mark pride month easter egg as displayed when its june (rust) (#430)
fix(rust): Only mark pride month easter egg as displayed when its june
2025-09-10 07:49:32 -07:00
Thundertides 075fc467d2 Temporary fix to GH-399 (#428) 2025-09-07 09:59:02 -07:00
azalea a463f4234c [U] Release 2.0.2 2025-09-04 07:12:01 -04:00
azalea beb04101db [F] Fix script 2025-09-04 07:09:56 -04:00
azalea bf60e4265b [F] Fix script 2025-09-04 07:05:40 -04:00
azalea 42421bc57d [+] Changelog 2025-09-04 06:52:58 -04:00
azalea f64ee7b7e9 [O] Better warning message #419 2025-09-04 06:46:20 -04:00
azalea 1fa29cf831 [+] Adipophilia flag (#424) 2025-09-04 06:24:10 -04:00
azalea 4861dd5d4a [+] Nullflux flag #397 2025-09-04 06:11:55 -04:00
azalea 5614b723fd [+] Hypergender flags
Fixes hykilpikonna/hyfetch#422
2025-09-04 06:04:37 -04:00
azalea 5e1e13b091 [M] Move flag order 2025-09-04 05:52:17 -04:00
azalea 79ddb3ca92 [+] Fictosexual flag (#394) 2025-09-04 05:41:49 -04:00
azalea 684929edea [U] gitignore 2025-09-04 05:41:49 -04:00
Emi f02ec8c4ba Fix nixos_small logo (#421)
* [F] Fix nixos_small logo

* [F] Fix nixos_small logo missing line break

* [?] i was trying to fix a difference between the python version and the rust version what the hell dude
2025-08-27 15:10:59 +09:00
azalea 5fd4ed9b0c [F] Fix #420 fastfetch custom config 2025-08-25 02:20:24 -04:00
a catgirl 003c295084 [F] fix: custom *fetch configurations breaking hyfetch (#420)
if the backend is fastfetch, hyfetch calls
`/bin/fastfetch --logo none -s OS --disable-linewrap`
which for me returns:
`  Artix Linux x86_64`
... and that breaks hyfetch

instead, get the information from the source (/etc/os-release), which im
pretty sure most fetch backends read from anyway

this won't work on *BSD though, because those lack
/etc/os-release, so unless calling `uname -s` is alright, BSDs would
still have the problem

related pull: https://github.com/hykilpikonna/hyfetch/issues/418
2025-08-23 17:34:57 -07:00
663 changed files with 6889 additions and 8251 deletions
+12 -1
View File
@@ -120,4 +120,15 @@ webhook-log
start_moderation.sh
gh_moderator.toml
moderator-data
hyfetch/git
hyfetch/git
build
dist
target
.vscode
.idea
*.iml
*.egg-info
__pycache__
*.pyc
*.pyo
*.pyd
Generated
+310 -351
View File
File diff suppressed because it is too large Load Diff
+8 -8
View File
@@ -3,7 +3,7 @@ resolver = "2"
members = ["crates/*"]
[workspace.package]
version = "2.0.1"
version = "2.1.0"
authors = ["Azalea Gui <azalea@hydev.org>"]
edition = "2021"
rust-version = "1.75.0"
@@ -17,14 +17,14 @@ ansi_colours = { version = "1.2.2", default-features = false }
anstream = { version = "0.6.14", default-features = false }
anyhow = { version = "1.0.86", default-features = false }
bpaf = { version = "0.9.12", default-features = false }
crossterm = { version = "0.27.0", default-features = false }
crossterm = { version = "0.29.0", default-features = false }
deranged = { version = "0.3.11", default-features = false }
directories = { version = "5.0.1", default-features = false }
directories = { version = "6.0.0", default-features = false }
enable-ansi-support = { version = "0.2.1", default-features = false }
enterpolation = { version = "0.2.1", default-features = false }
fastrand = { version = "2.1.0", default-features = false }
indexmap = { version = "2.2.6", default-features = false }
itertools = { version = "0.13.0", default-features = false }
itertools = { version = "0.14.0", default-features = false }
normpath = { version = "1.2.0", default-features = false }
palette = { version = "0.7.6", default-features = false }
regex = { version = "1.10.5", default-features = false }
@@ -33,14 +33,14 @@ serde = { version = "1.0.203", default-features = false }
serde_json = { version = "1.0.118", default-features = false }
serde_path_to_error = { version = "0.1.16", default-features = false }
shell-words = { version = "1.1.0", default-features = false }
strum = { version = "0.26.3", default-features = false }
strum = { version = "0.27.2", default-features = false }
supports-color = { version = "3.0.0", default-features = false }
tempfile = { version = "3.10.1", default-features = false }
terminal-colorsaurus = { version = "0.4.3", default-features = false }
terminal_size = { version = "0.3.0", default-features = false }
terminal-colorsaurus = { version = "1.0.0", default-features = false }
terminal_size = { version = "0.4.3", default-features = false }
thiserror = { version = "1.0.61", default-features = false }
time = { version = "0.3.36", default-features = false }
toml_edit = { version = "0.22.16", default-features = false }
toml_edit = { version = "0.23.6", default-features = false }
tracing = { version = "0.1.40", default-features = false }
tracing-subscriber = { version = "0.3.18", default-features = false }
unicode-normalization = { version = "0.1.23", default-features = false }
-9
View File
@@ -1,9 +0,0 @@
include hyfetch/scripts/*
recursive-exclude tools *
recursive-exclude .github *
recursive-exclude .vscode *
exclude .gitignore
exclude .gitattributes
exclude package.json
exclude CONTRIBUTING.md
+109 -11
View File
@@ -37,7 +37,7 @@ Currently, these distributions have existing packages for HyFetch:
* Nix: `nix-env -i hyfetch` (Thanks to [@YisuiDenghua](https://github.com/YisuiDenghua))
* Nix Profile: `nix profile install nixpkgs#hyfetch`
* Guix: `guix install hyfetch` (Thanks to [@WammKD](https://github.com/WammKD))
* Slackware: `sbopkg -b hyfetch` [Slackbuild](https://slackbuilds.org/repository/15.0/desktop/hyfetch/?search=hyfetch) (Thanks to [@bittin](https://github.com/bittin) , willysr (https://github.com/willysr), jebrhansen and Urchlay)
* Slackware: `sbopkg -b hyfetch` [Slackbuild](https://slackbuilds.org/repository/15.0/desktop/hyfetch/?search=hyfetch) (Thanks to [@bittin](https://github.com/bittin) , willysr (https://github.com/willysr), jebrhansen and Urchlay and new maintainer MDKDIO)
* Homebrew: `brew install hyfetch` (Thanks to [@catumin](https://github.com/catumin) and [@osalbahr](https://github.com/osalbahr))
* openSUSE Tumbleweed: `zypper in python311-hyfetch` (Thanks to [@catumin](https://github.com/catumin))
* Gentoo: `emerge --ask app-misc/hyfetch` (Thanks to [@catumin](https://github.com/catumin))
@@ -109,16 +109,6 @@ You can also install your version locally by running `pip install .` in the repo
## Change Log
### About Notation
Updates to HyFetch begins with the emoji 🌈
Updates to `neowofetch` begins with the emoji 🖼️
### TODO
* [ ] (Important!) Refactor flag storage & coloring to support non-stride patterns
* [ ] Config menu: Allow left-right arrow keys for pagination
### Nightly
Note: You can install the latest nightly version by using:
@@ -129,6 +119,109 @@ cargo install --git https://github.com/hykilpikonna/hyfetch
<!-- CHANGELOG STARTS HERE --->
### 2.1.0
### 2.1.0-rc1
### 2.1.0
(changelog is generated by Gemini from commit history)
**✨ Features & Enhancements**
* Random Preset: Now can select multiple presets and let it randomly choose one on each run ([#487](https://github.com/hykilpikonna/hyfetch/issues/487)).
* Distro as Data: Migrated distribution ASCII art and metadata to a unified JSON-header format, enabling shared usage across Python and Rust implementations.
* Distro Parity: Added missing ASCII art and distros from [fastfetch](https://github.com/fastfetch-cli/fastfetch).
* New OS Support: Added support for QNX/Blackberry 10 ([#480](https://github.com/hykilpikonna/hyfetch/issues/480)).
* Custom Presets: Added `custom_presets` configuration option to allow user-defined color presets ([#481](https://github.com/hykilpikonna/hyfetch/issues/481)).
* Interactive Filtering: Added live filter for preset selection in the configuration menu ([#482](https://github.com/hykilpikonna/hyfetch/issues/482)).
* New Distros: Added support for Codex Linux ([#477](https://github.com/hykilpikonna/hyfetch/issues/477)) and Zirconium ([#468](https://github.com/hykilpikonna/hyfetch/issues/468)).
* New Flags: Added Peter Griffin pride flag ([#489](https://github.com/hykilpikonna/hyfetch/issues/489)), Rubber flag ([#479](https://github.com/hykilpikonna/hyfetch/issues/479)), and Haruhi Suzumiya flag ([#486](https://github.com/hykilpikonna/hyfetch/issues/486)).
**🐛 Bug Fixes**
* Windows/MSYS2: Fixed bash path detection and execution in MINGW64 environment ([#488](https://github.com/hykilpikonna/hyfetch/issues/488)).
* Backend Fixes: Fixed issues with the `macchina` backend crashing or reporting incorrect distribution ([#491](https://github.com/hykilpikonna/hyfetch/issues/491)).
* Terminal Fixes: Fixed terminal font output issues in Kitty terminal ([#484](https://github.com/hykilpikonna/hyfetch/issues/484)).
* Reliability:
* Improved path detection to continue even when current path is not found ([#426](https://github.com/hykilpikonna/hyfetch/issues/426)).
* Added fallback for operating systems unsupported by the Rust implementation ([#474](https://github.com/hykilpikonna/hyfetch/issues/474)).
* Fixed prioritization of CLI-specified ASCII art to ensure it correctly overrides configuration ([#475](https://github.com/hykilpikonna/hyfetch/issues/475)).
* Shell Detection: Switched to `os.execv` for more reliable shell detection and transition ([#469](https://github.com/hykilpikonna/hyfetch/issues/469)).
* Background Detection Timeout: Prevent crash due to timeout in background color detection ([#453](https://github.com/hykilpikonna/hyfetch/issues/453)).
### 2.0.5
**✨ Features & Enhancements**
* Added support for Secureblue ([#434](https://github.com/hykilpikonna/hyfetch/pull/434)).
* Added `void_old` logo variant ([#457](https://github.com/hykilpikonna/hyfetch/pull/457)).
* Added Femme flag ([#456](https://github.com/hykilpikonna/hyfetch/pull/456)).
**🐛 Bug Fixes**
* Fixed a panic when entering an invalid alignment option after rolling ([#460](https://github.com/hykilpikonna/hyfetch/issues/460)).
* Fixed Traceback printing on KeyboardInterrupt ([#462](https://github.com/hykilpikonna/hyfetch/issues/462)).
* Restored flags lost during Python/Rust presets merge ([#466](https://github.com/hykilpikonna/hyfetch/pull/466)).
* Fixed a panic with file metadata access ([#465](https://github.com/hykilpikonna/hyfetch/issues/465)).
### 2.0.4
**🔧 Building Pipeline Refactoring**
* Modernize Python building toolchain from `setup.py` to `pyproject.toml`
* Fixed a bug where Windows binaries are mistakenly built into Unix packages.
* Fixed a bug where `presets.json` was not being included in the built package.
### 2.0.3
(changelog is generated by Gemini from commit history)
This update brings a significant internal refactor to how color presets are managed, along with a new batch of pride flags and several important bug fixes.
**✨ Features & Enhancements**
* **Custom ASCII Art**: You can now specify a file path for custom ASCII art ([#429](https://github.com/hykilpikonna/hyfetch/pull/429)).
* **Hex Color Presets**: Added the ability to pass a custom comma-separated hex color string list (e.g., `#RRGGBB,#RRGGBB`) directly as a preset ([#435](https://github.com/hykilpikonna/hyfetch/pull/435)).
**🏳️‍🌈 New Flags**
* Added Transbian flag ([#449](https://github.com/hykilpikonna/hyfetch/pull/449))
* Added Autism Pride flag ([#450](https://github.com/hykilpikonna/hyfetch/pull/450))
* Added Transneutral & Cenelian flags ([#452](https://github.com/hykilpikonna/hyfetch/pull/452))
* Added Fluidflux flags ([#437](https://github.com/hykilpikonna/hyfetch/pull/437))
* Added Libragender flags ([#433](https://github.com/hykilpikonna/hyfetch/pull/433))
**🐛 Bug Fixes**
* **Crash Fix**: Fixed a panic that could occur if hyfetch was run on a distro with no defined ASCII art ([#455](https://github.com/hykilpikonna/hyfetch/pull/455)).
* **OS Support**: Added support for iOS 1.x ([#444](https://github.com/hykilpikonna/hyfetch/pull/444)) and old Apple TV models ([#438](https://github.com/hykilpikonna/hyfetch/pull/438)).
* **Python**:
* Fixed a bug where 3-length hex codes (e.g., `#FFF`) does not work properly ([#443](https://github.com/hykilpikonna/hyfetch/pull/443)).
* Fixed a string formatting issue for python 3.11 and earlier versions ([#442](https://github.com/hykilpikonna/hyfetch/pull/442)).
* Fixed a bug where extra top padding would appear above output ascii art ([#428](https://github.com/hykilpikonna/hyfetch/pull/428)).
* **Rust**:
* Fixed the logic for the pride month easter egg so it only marks itself as "displayed" during June ([#430](https://github.com/hykilpikonna/hyfetch/pull/430)).
* Fixed a build issue on Windows ([#439](https://github.com/hykilpikonna/hyfetch/pull/439)).
**🔧 Maintenance & Refactoring**
* **Preset Refactor**: Color presets are now stored in a central `presets.json` file. ([#451](https://github.com/hykilpikonna/hyfetch/issues/451)).
* **Dependency Updates**: Upgraded various Rust crates and other dependencies to their latest versions.
* **Code Cleanup**: General code shortening and readability improvements.
### 2.0.2
This is a small patch release that adds more flags and fixes some bugs from the recent Rust rewrite.
* 🏳️‍🌈 **New Flags**: Added new pride flags for Nullflux ([#397](https://github.com/hykilpikonna/hyfetch/pull/397)), Hypergender ([#422](https://github.com/hykilpikonna/hyfetch/pull/422)), Fictosexual ([#394](https://github.com/hykilpikonna/hyfetch/pull/394)), and Adipophilia ([#424](https://github.com/hykilpikonna/hyfetch/pull/424)).
* 🐛 **Bug Fixes**:
* Fixed a critical bug where custom `fastfetch` configurations could break hyfetch ([#420](https://github.com/hykilpikonna/hyfetch/pull/420)).
* Corrected the `nixos_small` ASCII logo to display properly ([#421](https://github.com/hykilpikonna/hyfetch/pull/421)).
* 🔧 **Improvements**:
* Improved a warning message for better clarity ([#419](https://github.com/hykilpikonna/hyfetch/issues/419)).
### 2.0.1
(changelog is generated by Gemini from commit history)
@@ -176,6 +269,11 @@ This is a massive update, rewriting the entire hyfetch core from Python to Rust
This version would be the last version of HyFetch on Python as we migrate to Rust (Huge thanks to everyone on [#317](https://github.com/hykilpikonna/hyfetch/pull/317)!). It will also be an effort to start a transition that phases out the neowofetch/neofetch backend in favor of FastFetch, since the time needed to maintain the NF backend currently exceed our capacity. If you are willing to help maintaining it, please let us know!
### About Notation
Updates to HyFetch begins with the emoji 🌈
Updates to `neowofetch` begins with the emoji 🖼️
* 🌈 **Improve Windows support**
* 🌈 **Include FastFetch into HyFetch PyPI package**
* 🌈 Detached our fork from neofetch
+6 -2
View File
@@ -15,7 +15,7 @@ ansi_colours = { workspace = true, features = [] }
anstream = { workspace = true, features = [], optional = true }
anyhow = { workspace = true, features = ["std"] }
bpaf = { workspace = true, features = [] }
crossterm = { workspace = true, features = [] }
crossterm = { workspace = true, features = ["events"] }
deranged = { workspace = true, features = ["serde", "std"] }
directories = { workspace = true, features = [] }
enterpolation = { workspace = true, features = ["bspline", "std"] }
@@ -41,10 +41,14 @@ unicode-segmentation = { workspace = true, features = [] }
which = { workspace = true, features = [] }
[build-dependencies]
indexmap = { workspace = true, features = ["std"] }
indexmap = { workspace = true, features = ["std", "serde"] }
regex = { workspace = true, features = ["perf", "std", "unicode"] }
unicode-normalization = { workspace = true, features = ["std"] }
fs_extra = "1.3.0"
serde = { workspace = true, features = ["derive", "std"] }
serde_json = { workspace = true, features = ["std"] }
anyhow = { workspace = true, features = ["std"] }
heck = "0.5.0"
[target.'cfg(windows)'.dependencies]
enable-ansi-support = { workspace = true, features = [] }
+212 -114
View File
@@ -1,19 +1,33 @@
use std::env;
use std::fmt::Write as _;
use std::fs;
use std::io::{BufWriter, Write};
use std::path::{Path, PathBuf};
use fs_extra::dir::{CopyOptions};
use anyhow::{Context, Result};
use fs_extra::dir::CopyOptions;
use heck::ToUpperCamelCase;
use indexmap::IndexMap;
use regex::Regex;
use serde::Deserialize;
use unicode_normalization::UnicodeNormalization as _;
#[derive(Debug)]
struct AsciiDistro {
pattern: String,
color: String,
foreground: Vec<u8>,
background: Option<u8>,
art: String,
}
#[derive(Deserialize, Debug)]
struct DistroHeader {
#[serde(rename = "match")]
pattern: String,
color: serde_json::Value,
foreground: Option<Vec<u8>>,
background: Option<u8>,
}
impl AsciiDistro {
fn friendly_name(&self) -> String {
self.pattern
@@ -29,35 +43,40 @@ fn anything_that_exist(paths: &[&Path]) -> Option<PathBuf> {
paths.iter().copied().find(|p| p.exists()).map(Path::to_path_buf)
}
fn main() {
fn main() -> Result<()> {
// Path hack to make file paths work in both workspace and manifest directory
let dir = PathBuf::from(env::var_os("CARGO_WORKSPACE_DIR").unwrap_or_else(|| env::var_os("CARGO_MANIFEST_DIR").unwrap()));
let o = PathBuf::from(env::var_os("OUT_DIR").unwrap());
for file in &["neofetch", "hyfetch"] {
let src = anything_that_exist(&[
&dir.join(file),
&dir.join("../../").join(file),
]).expect("couldn't find neofetch");
let dst = o.join(file);
println!("cargo:rerun-if-changed={}", src.display());
let data_dir = anything_that_exist(&[
&dir.join("hyfetch/data"),
&dir.join("../../hyfetch/data"),
]).context("couldn't find hyfetch/data")?;
let dst_root = o.join("hyfetch");
fs::create_dir_all(&dst_root)?;
// Copy hyfetch/data
let opt = CopyOptions { overwrite: true, copy_inside: true, ..CopyOptions::default() };
fs_extra::dir::copy(&data_dir, &dst_root, &opt)?;
// Copy either file or directory
if src.is_dir() {
let opt = CopyOptions { overwrite: true, copy_inside: true, ..CopyOptions::default() };
fs_extra::dir::copy(&src, &dst, &opt).expect("Failed to copy directory to OUT_DIR");
}
else { fs::copy(&src, &dst).expect("Failed to copy file to OUT_DIR"); }
}
// Copy neofetch
let neofetch_src = anything_that_exist(&[
&dir.join("neofetch"),
&dir.join("../../neofetch"),
]).context("couldn't find neofetch")?;
fs::copy(&neofetch_src, o.join("neofetch"))?;
export_distros(&o.join("neofetch"), &o);
preset_codegen(&o.join("hyfetch/data/presets.json"), &o.join("presets.rs"))?;
let distros_dir = data_dir.join("distros");
export_distros(&distros_dir, &o)?;
Ok(())
}
fn export_distros<P>(neofetch_path: P, out_path: &Path)
where
P: AsRef<Path>,
fn export_distros(distro_dir: &Path, out_path: &Path) -> Result<()>
{
let distros = parse_ascii_distros(neofetch_path);
let distros = parse_ascii_distros(distro_dir)?;
let mut variants = IndexMap::with_capacity(distros.len());
for distro in &distros {
@@ -80,18 +99,13 @@ where
let mut buf = r###"
#[derive(Clone, Eq, PartialEq, Hash, Debug)]
pub enum Distro {
"###
.to_owned();
"###.to_string();
for (variant, AsciiDistro { pattern, .. }) in &variants {
write!(
buf,
r###"
write!(buf, r###"
// {pattern})
{variant},
"###,
)
.unwrap();
"###)?;
}
buf.push_str(
@@ -132,9 +146,7 @@ impl Distro {
// Both sides are *
if m.starts_with('*') && m.ends_with('*') {
conds.push(format!(
r#"name.starts_with("{stripped}") || name.ends_with("{stripped}")"#
));
conds.push(format!(r#"name.contains("{stripped}")"#));
continue;
}
@@ -153,15 +165,11 @@ impl Distro {
let condition = conds.join(" || ");
write!(
buf,
r###"
write!(buf, r###"
if {condition} {{
return Some(Self::{variant});
}}
"###
)
.unwrap();
"###)?;
}
buf.push_str(
@@ -169,6 +177,66 @@ impl Distro {
None
}
pub fn color(&self) -> &str {
match self {
"###,
);
for (variant, AsciiDistro { color, .. }) in &variants {
write!(buf, r###"
Self::{variant} => {color:?},
"###, color = color)?;
}
buf.push_str(
r###"
}
}
pub fn foreground(&self) -> &[u8] {
match self {
"###,
);
for (variant, AsciiDistro { foreground, .. }) in &variants {
if foreground.is_empty() {
write!(buf, r###"
Self::{variant} => &[],
"###)?;
} else {
write!(buf, r###"
Self::{variant} => &{:?},
"###, foreground)?;
}
}
buf.push_str(
r###"
}
}
pub fn background(&self) -> Option<u8> {
match self {
"###,
);
for (variant, AsciiDistro { background, .. }) in &variants {
if let Some(b) = background {
write!(buf, r###"
Self::{variant} => Some({b}),
"###)?;
} else {
write!(buf, r###"
Self::{variant} => None,
"###)?;
}
}
buf.push_str(
r###"
}
}
pub fn ascii_art(&self) -> &str {
let art = match self {
"###,
@@ -176,15 +244,11 @@ impl Distro {
let quotes = "#".repeat(80);
for (variant, AsciiDistro { art, .. }) in &variants {
write!(
buf,
r###"
write!(buf, r###"
Self::{variant} => r{quotes}"
{art}
"{quotes},
"###,
)
.unwrap();
"###)?;
}
buf.push_str(
@@ -196,78 +260,112 @@ impl Distro {
"###,
);
fs::write(out_path.join("distros.rs"), buf).expect("couldn't write distros.rs");
fs::write(out_path.join("distros.rs"), buf)?;
Ok(())
}
/// Parses ascii distros from neofetch script.
fn parse_ascii_distros<P>(neofetch_path: P) -> Vec<AsciiDistro>
where
P: AsRef<Path>,
fn parse_ascii_distros(distro_dir: &Path) -> Result<Vec<AsciiDistro>>
{
let neofetch_path = neofetch_path.as_ref();
let mut distros = Vec::new();
let mut paths: Vec<_> = fs::read_dir(distro_dir)?
.filter_map(|e| e.ok())
.map(|e| e.path())
.collect();
// Sort by name length descending, then name descending.
// This ensures that more specific distros (e.g. windows_11, arch_small) are
// checked before more general ones (e.g. windows, arch).
paths.sort_by(|a, b| {
b.to_str()
.map_or(0, |s| s.len())
.cmp(&a.to_str().map_or(0, |s| s.len()))
.then(b.cmp(a))
});
let nf = {
let nf = fs::read_to_string(neofetch_path).expect("couldn't read neofetch script");
// Get the content of "get_distro_ascii" function
let (_, nf) = nf
.split_once("get_distro_ascii() {\n")
.expect("couldn't find get_distro_ascii function");
let (nf, _) = nf
.split_once("\n}\n")
.expect("couldn't find end of get_distro_ascii function");
let mut nf = nf.replace('\t', &" ".repeat(4));
// Remove trailing spaces
while nf.contains(" \n") {
nf = nf.replace(" \n", "\n");
for path in paths {
if path.extension().and_then(|s| s.to_str()) == Some("ascii") {
let content = fs::read_to_string(&path)?;
let (header_line, art) = content.split_once('\n').context("invalid distro file")?;
let header: DistroHeader = serde_json::from_str(header_line)?;
let color = match header.color {
serde_json::Value::String(s) => s,
serde_json::Value::Number(n) => n.to_string(),
_ => "7".to_owned(),
};
distros.push(AsciiDistro {
pattern: header.pattern,
color,
foreground: header.foreground.unwrap_or_default(),
background: header.background,
art: art.to_owned(),
});
}
nf
};
let case_re = Regex::new(r"case .*? in\n").expect("couldn't compile case regex");
let eof_re = Regex::new(r"EOF[ \n]*?;;").expect("couldn't compile eof regex");
// Split by blocks
let mut blocks = Vec::new();
for b in case_re.split(&nf) {
blocks.extend(eof_re.split(b).map(|sub| sub.trim()));
}
// Parse blocks
fn parse_block(block: &str) -> Option<AsciiDistro> {
let (block, art) = block.split_once("'EOF'\n")?;
// Join \
//
// > A <backslash> that is not quoted shall preserve the literal value of the
// > following character, with the exception of a <newline>. If a <newline>
// > follows the <backslash>, the shell shall interpret this as line
// > continuation. The <backslash> and <newline> shall be removed before
// > splitting the input into tokens. Since the escaped <newline> is removed
// > entirely from the input and is not replaced by any white space, it cannot
// > serve as a token separator.
// See https://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_02_01
let block = block.replace("\\\n", "");
// Get case pattern
let pattern = block
.split('\n')
.next()
.and_then(|pattern| pattern.trim().strip_suffix(')'))?;
// Unescape backslashes here because backslashes are escaped in neofetch
// for printf
let art = art.replace(r"\\", r"\");
Some(AsciiDistro {
pattern: pattern.to_owned(),
art,
})
}
blocks
.iter()
.filter_map(|block| parse_block(block))
.collect()
Ok(distros)
}
// Preset parsing
#[derive(Deserialize, Debug)]
#[serde(untagged)]
enum PresetEntry {
Simple(Vec<String>),
Complex { colors: Vec<String>, weights: Option<Vec<u32>> },
}
type PresetMap = IndexMap<String, PresetEntry>;
fn preset_codegen(json_path: &Path, out_path: &Path) -> Result<()> {
// 1. Read and parse the JSON file
let json_str = fs::read_to_string(json_path)?;
let map: PresetMap = serde_json::from_str(&json_str)?;
let mut f = BufWriter::new(fs::File::create(&out_path)?);
// 2. Build the code string
let mut code_decl = String::new();
let mut code_match = String::new();
for (key, data) in map.iter() {
let colors = match data {
PresetEntry::Simple(c) => c,
PresetEntry::Complex { colors, .. } => colors,
};
let colors = colors.iter().map(|s| format!("\"{}\"", s)).collect::<Vec<_>>().join(", ");
let uck = key.to_upper_camel_case();
code_decl += &format!(r#"
#[serde(rename = "{key}")]
#[strum(serialize = "{key}")]
{uck},
"#);
let w = if let PresetEntry::Complex { weights: Some(w), .. } = data {
format!(".and_then(|c| c.with_weights(vec![{}]))", w.iter().map(|n| n.to_string()).collect::<Vec<_>>().join(", "))
} else { "".to_string() };
code_match += &format!(r#"
Preset::{uck} => ColorProfile::from_hex_colors(vec![{colors}]){w},
"#);
}
// 3. Write the static map to the generated file
writeln!(f, r#"
pub use crate::color_profile::ColorProfile;
use serde::{{Deserialize, Serialize}};
use strum::{{AsRefStr, EnumCount, EnumString, VariantArray, VariantNames}};
#[derive(Copy, Clone, Hash, Debug, AsRefStr, Deserialize, EnumCount, EnumString, Serialize, VariantArray, VariantNames)]
pub enum Preset {{
{code_decl}
}}
impl Preset {{
pub fn color_profile(&self) -> ColorProfile {{
(match self {{
{code_match}
}})
.expect("preset color profiles should be valid")
}}
}}"#)?;
f.flush()?;
Ok(())
}
+3 -9
View File
@@ -61,8 +61,8 @@ impl RawAsciiArt {
Ok(NormalizedAsciiArt {
lines,
w,
h,
w: w.try_into().context("width does not fit in u8")?,
h: h.try_into().context("height does not fit in u8")?,
fg: self.fg.clone(),
})
}
@@ -372,12 +372,7 @@ impl NormalizedAsciiArt {
// Line starts with neofetch color code
last = Some(&line[m.span()]);
},
Some(_) => {
new.push_str(last.context(
"failed to find neofetch color code from a previous line",
)?);
},
None => {
_ => {
new.push_str(last.unwrap_or(NEOFETCH_COLOR_PATTERNS[0]));
},
}
@@ -385,7 +380,6 @@ impl NormalizedAsciiArt {
// Get the last placeholder for the next line
if let Some(m) = matches.last() {
last.context("non-space character seen before first color code")?;
last = Some(&line[m.span()]);
}
File diff suppressed because it is too large Load Diff
+4 -27
View File
@@ -8,7 +8,7 @@ use bpaf::ShellComp;
use bpaf::{construct, long, OptionParser, Parser as _};
use directories::BaseDirs;
use itertools::Itertools as _;
use strum::{VariantArray, VariantNames};
use strum::VariantNames;
use crate::color_util::{color, Lightness};
use crate::presets::Preset;
@@ -18,7 +18,7 @@ use crate::types::{AnsiMode, Backend};
pub struct Options {
pub config: bool,
pub config_file: PathBuf,
pub preset: Option<Preset>,
pub preset: Option<String>,
pub mode: Option<AnsiMode>,
pub backend: Option<Backend>,
pub args: Option<Vec<String>>,
@@ -55,7 +55,7 @@ pub fn options() -> OptionParser<Options> {
let preset = long("preset")
.short('p')
.help(&*format!(
"Use preset
"Use preset or comma-separated color list or comma-separated hex colors (e.g., \"#ff0000,#00ff00,#0000ff\"). Comma-separated preset names will pick one randomly.
PRESET={{{presets}}}",
presets = <Preset as VariantNames>::VARIANTS
.iter()
@@ -65,30 +65,7 @@ PRESET={{{presets}}}",
.argument::<String>("PRESET");
#[cfg(feature = "autocomplete")]
let preset = preset.complete(complete_preset);
let preset = preset
.parse(|s| {
Preset::from_str(&s)
.or_else(|e| {
if s == "random" {
let mut rng = fastrand::Rng::new();
Ok(*rng
.choice(<Preset as VariantArray>::VARIANTS)
.expect("preset iterator should not be empty"))
} else {
Err(e)
}
})
.with_context(|| {
format!(
"PRESET should be one of {{{presets}}}",
presets = <Preset as VariantNames>::VARIANTS
.iter()
.chain(iter::once(&"random"))
.join(",")
)
})
})
.optional();
let preset = preset.optional();
let mode = long("mode")
.short('m')
.help(&*format!(
+232
View File
@@ -0,0 +1,232 @@
use std::iter;
use std::num::{NonZeroU8, NonZeroUsize};
use anyhow::{anyhow, Result, Context as _};
use indexmap::IndexSet;
use palette::num::ClampAssign as _;
use palette::{IntoColorMut as _, LinSrgb, Okhsl, Srgb};
use tracing::debug;
use unicode_segmentation::UnicodeSegmentation as _;
use crate::color_util::{ForegroundBackground, Lightness, ToAnsiString as _};
use crate::types::{AnsiMode, TerminalTheme};
#[derive(Clone, Eq, PartialEq, Debug)]
pub struct ColorProfile {
pub colors: Vec<Srgb<u8>>,
}
#[derive(Clone, PartialEq, Debug)]
pub enum AssignLightness {
Replace(Lightness),
ClampMax(Lightness),
ClampMin(Lightness),
}
impl ColorProfile {
pub fn new(colors: Vec<Srgb<u8>>) -> Self {
Self { colors }
}
pub fn from_hex_colors<S>(hex_colors: Vec<S>) -> Result<Self>
where
S: AsRef<str>,
{
let colors = hex_colors
.into_iter()
.map(|s| s.as_ref().parse())
.collect::<Result<_, _>>()
.context("failed to parse hex colors")?;
Ok(Self::new(colors))
}
/// Maps colors based on weights.
///
/// # Arguments
///
/// * `weights` - Weights of each color (`weights[i]` = how many times
/// `colors[i]` appears)
pub fn with_weights(&self, weights: Vec<u8>) -> Result<Self> {
if weights.len() != self.colors.len() {
debug!(?weights, ?self.colors, "length mismatch between `weights` and `colors`");
return Err(anyhow!(
"`weights` should have the same number of elements as `colors`"
));
}
let mut weighted_colors = Vec::new();
for (i, w) in weights.into_iter().enumerate() {
weighted_colors.extend(iter::repeat(self.colors[i]).take(usize::from(w)));
}
Ok(Self::new(weighted_colors))
}
/// Creates a new color profile, with the colors spread to the specified
/// length.
pub fn with_length(&self, length: NonZeroU8) -> Result<Self> {
let orig_len = self.colors.len();
let orig_len: NonZeroUsize = orig_len.try_into().expect("`colors` should not be empty");
let orig_len: NonZeroU8 = orig_len
.try_into()
.expect("`colors` should not have more than 255 elements");
// TODO: I believe weird things can happen because of this...
// if length < orig_len {
// unimplemented!("compressing length of color profile not implemented");
// }
let center_i = usize::from(orig_len.get() / 2);
// How many copies of each color should be displayed at least?
let repeats = length.get().div_euclid(orig_len.get());
let mut weights = vec![repeats; NonZeroUsize::from(orig_len).get()];
// How many extra spaces left?
let mut extras = length.get().rem_euclid(orig_len.get());
// If there is an odd space left, extend the center by one space
if extras % 2 == 1 {
weights[center_i] = weights[center_i].checked_add(1).unwrap();
extras = extras.checked_sub(1).unwrap();
}
// Add weight to border until there's no space left (extras must be even at this
// point)
let weights_len = weights.len();
for border_i in 0..usize::from(extras / 2) {
weights[border_i] = weights[border_i].checked_add(1).unwrap();
let border_opp = weights_len
.checked_sub(border_i)
.unwrap()
.checked_sub(1)
.unwrap();
weights[border_opp] = weights[border_opp].checked_add(1).unwrap();
}
self.with_weights(weights)
}
/// Colors a text.
///
/// # Arguments
///
/// * `foreground_background` - Whether the color is shown on the foreground
/// text or the background block
/// * `space_only` - Whether to only color spaces
pub fn color_text<S>(
&self,
txt: S,
color_mode: AnsiMode,
foreground_background: ForegroundBackground,
space_only: bool,
) -> Result<String>
where
S: AsRef<str>,
{
let txt = txt.as_ref();
let txt: Vec<&str> = txt.graphemes(true).collect();
let ColorProfile { colors } = {
let length = txt.len();
let length: NonZeroUsize = length.try_into().context("`txt` should not be empty")?;
let length: NonZeroU8 = length.try_into().with_context(|| {
format!(
"`txt` should not have more than {limit} characters",
limit = u8::MAX
)
})?;
self.with_length(length)
.with_context(|| format!("failed to spread color profile to length {length}"))?
};
let mut buf = String::new();
for (i, &gr) in txt.iter().enumerate() {
if space_only && gr != " " {
if i > 0 && txt[i.checked_sub(1).unwrap()] == " " {
buf.push_str("\x1b[39;49m");
}
buf.push_str(gr);
} else {
buf.push_str(&colors[i].to_ansi_string(color_mode, foreground_background));
buf.push_str(gr);
}
}
buf.push_str("\x1b[39;49m");
Ok(buf)
}
/// Creates a new color profile, with the colors lightened by a multiplier.
pub fn lighten(&self, multiplier: f32) -> Self {
let mut rgb_f32_colors: Vec<LinSrgb> =
self.colors.iter().map(|c| c.into_linear()).collect();
{
let okhsl_f32_colors: &mut [Okhsl] = &mut rgb_f32_colors.into_color_mut();
for okhsl_f32_color in okhsl_f32_colors {
okhsl_f32_color.lightness *= multiplier;
}
}
let rgb_u8_colors: Vec<_> = rgb_f32_colors
.into_iter()
.map(Srgb::<u8>::from_linear)
.collect();
Self {
colors: rgb_u8_colors,
}
}
/// Creates a new color profile, with the colors set to the specified
/// [`Okhsl`] lightness value.
pub fn with_lightness(&self, assign_lightness: AssignLightness) -> Self {
let mut rgb_f32_colors: Vec<LinSrgb> =
self.colors.iter().map(|c| c.into_linear()).collect();
{
let okhsl_f32_colors: &mut [Okhsl] = &mut rgb_f32_colors.into_color_mut();
for okhsl_f32_color in okhsl_f32_colors {
match assign_lightness {
AssignLightness::Replace(lightness) => {
okhsl_f32_color.lightness = lightness.into();
},
AssignLightness::ClampMax(lightness) => {
okhsl_f32_color.lightness.clamp_max_assign(lightness.into());
},
AssignLightness::ClampMin(lightness) => {
okhsl_f32_color.lightness.clamp_min_assign(lightness.into());
},
}
}
}
let rgb_u8_colors: Vec<Srgb<u8>> = rgb_f32_colors
.into_iter()
.map(Srgb::<u8>::from_linear)
.collect();
Self {
colors: rgb_u8_colors,
}
}
/// Creates a new color profile, with the colors set to the specified
/// [`Okhsl`] lightness value, adapted to the terminal theme.
pub fn with_lightness_adaptive(&self, lightness: Lightness, theme: TerminalTheme) -> Self {
match theme {
TerminalTheme::Dark => self.with_lightness(AssignLightness::ClampMin(lightness)),
TerminalTheme::Light => self.with_lightness(AssignLightness::ClampMax(lightness)),
}
}
/// Creates another color profile with only the unique colors.
pub fn unique_colors(&self) -> Self {
let unique_colors: IndexSet<[u8; 3]> = self.colors.iter().map(|&c| c.into()).collect();
let unique_colors: Vec<Srgb<u8>> = unique_colors.into_iter().map(|c| c.into()).collect();
Self::new(unique_colors)
}
}
+9 -7
View File
@@ -403,18 +403,20 @@ where
Ok(dst)
}
#[macro_export]
macro_rules! printc {
($($arg:tt)*) => {
println!("{}", color(format!("{}&r", format!($($arg)*)), AnsiMode::Rgb).expect("failed to color message"));
};
}
/// Prints with color.
pub fn printc<S>(msg: S, mode: AnsiMode) -> Result<()>
where
S: AsRef<str>,
{
writeln!(
io::stdout(),
"{msg}",
msg = color(format!("{msg}&r", msg = msg.as_ref()), mode)
.context("failed to color message")?
)
.context("failed to write message to stdout")
println!("{msg}", msg = color(format!("{msg}&r", msg = msg.as_ref()), mode).context("failed to color message")?);
Ok(())
}
/// Clears screen using ANSI escape codes.
+1
View File
@@ -9,3 +9,4 @@ pub mod presets;
pub mod pride_month;
pub mod types;
pub mod utils;
pub mod color_profile;
+71 -2
View File
@@ -1,13 +1,16 @@
use std::collections::HashMap;
use anyhow::{Context as _, Result};
use serde::{Deserialize, Serialize};
use crate::color_profile::ColorProfile;
use crate::color_util::Lightness;
use crate::neofetch_util::ColorAlignment;
use crate::presets::Preset;
use crate::types::{AnsiMode, Backend, TerminalTheme};
#[derive(Clone, Debug, Deserialize, Serialize)]
pub struct Config {
pub preset: Preset,
pub preset: PresetValue,
pub mode: AnsiMode,
pub auto_detect_light_dark: Option<bool>,
pub light_dark: Option<TerminalTheme>,
@@ -19,6 +22,8 @@ pub struct Config {
pub args: Option<Vec<String>>,
pub distro: Option<String>,
pub pride_month_disable: bool,
pub custom_ascii_path: Option<String>,
pub custom_presets: Option<HashMap<String, Vec<String>>>,
}
impl Config {
@@ -32,6 +37,40 @@ impl Config {
},
}
}
pub fn custom_preset_profiles(&self) -> Result<HashMap<String, ColorProfile>> {
let mut profiles = HashMap::new();
if let Some(custom_presets) = &self.custom_presets {
for (preset_name, colors) in custom_presets {
if preset_name == "random" {
return Err(anyhow::anyhow!("custom preset key `random` is reserved"));
}
let color_profile = build_hex_color_profile(colors).with_context(|| {
format!("failed to validate custom preset key `{preset_name}`")
})?;
profiles.insert(preset_name.clone(), color_profile);
}
}
Ok(profiles)
}
}
pub fn build_hex_color_profile(hex_colors: &[String]) -> Result<ColorProfile> {
if hex_colors.is_empty() {
return Err(anyhow::anyhow!("hex color list cannot be empty"));
}
for color in hex_colors {
if !color.starts_with('#')
|| (color.len() != 4 && color.len() != 7)
|| !color[1..].chars().all(|c| c.is_ascii_hexdigit())
{
return Err(anyhow::anyhow!("invalid hex color: {color}"));
}
}
ColorProfile::from_hex_colors(hex_colors.to_vec())
.context("failed to create color profile from hex")
}
mod args_serde {
@@ -117,3 +156,33 @@ mod args_serde {
deserializer.deserialize_option(OptionVisitor)
}
}
#[derive(Clone, Debug, Serialize, Deserialize)]
#[serde(untagged)]
pub enum PresetValue {
Single(String),
Multiple(Vec<String>),
}
impl From<String> for PresetValue {
fn from(s: String) -> Self {
PresetValue::Single(s)
}
}
impl PresetValue {
pub fn get_random_if_multiple(&self) -> String {
match self {
PresetValue::Single(s) => s.clone(),
PresetValue::Multiple(v) => {
if v.is_empty() {
"random".to_owned()
} else {
let mut rng = fastrand::Rng::new();
let selected_index = rng.usize(0..v.len());
v[selected_index].clone()
}
}
}
}
}
+79 -121
View File
@@ -2,7 +2,7 @@ use std::borrow::Cow;
use std::ffi::OsStr;
#[cfg(feature = "macchina")]
use std::fs;
use std::io::{self, Write as _};
use std::io::{Write as _};
use std::path::PathBuf;
use std::process::Command;
use std::sync::OnceLock;
@@ -113,16 +113,12 @@ where
};
if let Some(selected) = find_selection(&selection, options) {
writeln!(io::stdout()).context("failed to write to stdout")?;
println!();
return Ok(selected);
} else {
let options_text = options.iter().map(AsRef::as_ref).join("|");
writeln!(
io::stdout(),
"Invalid selection! {selection} is not one of {options_text}"
)
.context("failed to write message to stdout")?;
println!("Invalid selection! {selection} is not one of {options_text}");
}
}
@@ -157,7 +153,13 @@ pub fn add_pkg_path() -> Result<()> {
// Get PATH
let pv = &env::var_os("PATH").context("`PATH` env var is not set or invalid")?;
let mut path = env::split_paths(pv).collect::<Vec<_>>();
let exe = env::current_exe().context("failed to get path of current running executable")?;
let exe = match env::current_exe() {
Ok(exe) => exe,
Err(e) => {
debug!("Failed to get path of current running executable: {}", e);
return Ok(());
}
};
let base = exe.parent().unwrap();
// Add from bin: ../git, ../fastfetch, ../scripts
@@ -237,27 +239,27 @@ pub fn get_distro_ascii<S>(distro: Option<S>, backend: Backend) -> Result<RawAsc
where
S: AsRef<str> + fmt::Debug,
{
let distro: Cow<_> = if let Some(distro) = distro.as_ref() {
let distro_name: Cow<_> = if let Some(distro) = distro.as_ref() {
distro.as_ref().into()
} else {
get_distro_name(backend)
.context("failed to get distro name")?
.into()
};
debug!(%distro, "distro name");
debug!(%distro_name, "distro name");
// Try new codegen-based detection method
if let Some(distro) = Distro::detect(&distro) {
if let Some(distro) = Distro::detect(&distro_name) {
let asc = distro.ascii_art().to_owned();
let fg = ascii_foreground(&distro);
return Ok(RawAsciiArt { asc, fg });
}
debug!(%distro, "could not find a match for distro; falling back to neofetch");
debug!(%distro_name, "could not find a match for distro; falling back to neofetch");
// Old detection method that calls neofetch
let asc = run_neofetch_command_piped(&["print_ascii", "--ascii_distro", distro.as_ref()])
let asc = run_neofetch_command_piped(&["print_ascii", "--ascii_distro", distro_name.as_ref()])
.context("failed to get ascii art from neofetch")?;
// Unescape backslashes here because backslashes are escaped in neofetch for
@@ -285,7 +287,7 @@ pub fn run(asc: RecoloredAsciiArt, backend: Backend, args: Option<&Vec<String>>)
}
/// Gets distro ascii width and height, ignoring color code.
pub fn ascii_size<S>(asc: S) -> Result<(u8, u8)>
pub fn ascii_size<S>(asc: S) -> Result<(u16, u16)>
where
S: AsRef<str>,
{
@@ -307,56 +309,64 @@ where
return Ok((0, 0));
}
let width = asc
.lines()
.map(|line| line.graphemes(true).count())
.max()
let width = asc.lines()
.map(|line| line.graphemes(true).count()).max()
.expect("line iterator should not be empty");
let width: u8 = width.try_into().with_context(|| {
format!(
"`asc` should not have more than {limit} characters per line",
limit = u8::MAX
)
})?;
let height = asc.lines().count();
let height: u8 = height.try_into().with_context(|| {
format!(
"`asc` should not have more than {limit} lines",
limit = u8::MAX
)
})?;
let width: u16 = width.try_into().context("ascii art width should fit in u16")?;
let height: u16 = asc.lines().count().try_into().context("ascii art height should fit in u16")?;
Ok((width, height))
}
/// Gets the absolute path of the bash command.
#[cfg(windows)]
fn bash_path() -> Result<PathBuf> {
// Find `bash.exe` in `PATH`, but exclude the known bad paths
if let Some(bash_path) = find_in_path("bash.exe").context("bash.exe not found")? {
// Check if it's not MSYS bash https://stackoverflow.com/a/58418686/1529493
if !bash_path.ends_with(r"Git\usr\bin\bash.exe") {
// Check if it's not WSL bash
// See https://github.com/hykilpikonna/hyfetch/issues/233
let windir = env::var_os("windir").context("`windir` environ not found")?;
match is_same_file(&bash_path, Path::new(&windir).join(r"System32\bash.exe")) {
Ok(false) => return Ok(bash_path),
Err(err) if err.kind() == io::ErrorKind::NotFound => return Ok(bash_path),
_ => {}
// 1. Try to find a good bash.exe in PATH
let bash_in_path = find_in_path("bash.exe").unwrap_or(None);
if let Some(pth) = &bash_in_path {
// Check if it's not WSL bash
// See https://github.com/hykilpikonna/hyfetch/issues/233
let is_wsl = (|| {
let windir = env::var_os("windir")?;
let wsl_bash = Path::new(&windir).join(r"System32\bash.exe");
Some(is_same_file(pth, &wsl_bash).unwrap_or(false))
})()
.unwrap_or(false);
if !is_wsl {
// Check if it's not MSYS bash https://stackoverflow.com/a/58418686/1529493
// We prefer the Git wrapper bash if possible, but we'll accept this if it's all we have.
if !pth.ends_with(r"Git\usr\bin\bash.exe") {
return Ok(pth.clone());
}
}
}
if let Some(bash_path) = find_in_path("git.exe").context("failed to find `git.exe` in `PATH`")? {
if bash_path.ends_with(r"Git\cmd\git.exe") {
let pth = bash_path.parent().unwrap().parent().unwrap().join(r"bin\bash.exe");
if pth.is_file() {
return Ok(pth);
// 2. Try to find git.exe in PATH and look for bash.exe relative to it
if let Ok(Some(git_path)) = find_in_path("git.exe") {
let mut current = git_path.clone();
for _ in 0..3 {
if let Some(parent) = current.parent() {
let bin_bash = parent.join(r"bin\bash.exe");
if bin_bash.is_file() {
return Ok(bin_bash);
}
let usr_bin_bash = parent.join(r"usr\bin\bash.exe");
if usr_bin_bash.is_file() {
return Ok(usr_bin_bash);
}
current = parent.to_path_buf();
} else {
break;
}
}
}
Err(anyhow!("bash.exe not found"))
// 3. Fallback to whatever bash we found in PATH (even if it was the MSYS one)
if let Some(pth) = bash_in_path {
return Ok(pth);
}
Err(anyhow!("bash.exe not found. Please ensure Git for Windows is installed and in your PATH."))
}
/// Runs neofetch command, returning the piped stdout output.
@@ -399,8 +409,14 @@ where
{
let bash_path = bash_path().context("failed to get bash path")?;
let mut command = Command::new(bash_path);
command.arg(neofetch_path);
command.args(args);
// Convert path to use forward slashes because bash will interpret backslashes as escapes
command.arg(neofetch_path.to_string_lossy().replace('\\', "/"));
for arg in args {
// Also convert any backslashes in arguments to forward slashes for bash
command.arg(arg.as_ref().to_string_lossy().replace('\\', "/"));
}
Ok(command)
}
}
@@ -486,13 +502,8 @@ pub fn get_distro_name(backend: Backend) -> Result<String> {
match backend {
Backend::Neofetch => run_neofetch_command_piped(&["ascii_distro_name"])
.context("failed to get distro name from neofetch"),
Backend::Fastfetch => Ok(run_fastfetch_command_piped(&[
"--logo",
"none",
"-s",
"OS",
"--disable-linewrap",
]).context("failed to get distro name from fastfetch")?.replace("OS: ", "")),
Backend::Fastfetch => Ok(run_fastfetch_command_piped(&["--logo", "none", "-c", "none", "-s", "OS",])
.context("failed to get distro name from fastfetch")?.replace("OS: ", "")),
#[cfg(feature = "macchina")]
Backend::Macchina => {
// Write ascii art to temp file
@@ -524,7 +535,7 @@ pub fn get_distro_name(backend: Backend) -> Result<String> {
doc["spacing"] = value(0);
doc["padding"] = value(0);
// See https://github.com/Macchina-CLI/macchina/issues/319
// doc["hide_ascii"] = value(true);
doc["hide_ascii"] = value(false);
doc["separator"] = value("");
doc["custom_ascii"] = Item::Table(Table::from_iter([(
"path",
@@ -555,8 +566,11 @@ pub fn get_distro_name(backend: Backend) -> Result<String> {
];
run_macchina_command_piped(&args[..])
.map(|s| {
anstream::adapter::strip_str(&s)
.to_string()
let s = anstream::adapter::strip_str(&s).to_string();
let s = s.trim();
s.splitn(2, '-')
.last()
.expect("splitn with 2 should always have at least 1 element")
.trim()
.to_owned()
})
@@ -676,6 +690,7 @@ fn run_macchina(asc: String, args: Option<&Vec<String>>) -> Result<()> {
.context("failed to create temp file for macchina theme")?;
let theme_doc = {
let mut doc = DocumentMut::new();
doc["hide_ascii"] = value(false);
doc["custom_ascii"] = Item::Table(Table::from_iter([(
"path",
&*asc_file_path.to_string_lossy(),
@@ -717,65 +732,8 @@ fn run_macchina(asc: String, args: Option<&Vec<String>>) -> Result<()> {
/// Gets the color indices that should be considered as foreground, for a
/// particular distro's ascii art.
fn ascii_foreground(distro: &Distro) -> Vec<NeofetchAsciiIndexedColor> {
let fg: Vec<u8> = match distro {
Distro::Anarchy => vec![2],
Distro::Android => vec![2],
Distro::Antergos => vec![1],
Distro::ArchStrike => vec![2],
Distro::Arkane => vec![1],
Distro::Asahi => vec![5],
Distro::Astra_Linux => vec![2],
Distro::BlackArch => vec![3],
Distro::CelOS => vec![3],
Distro::Chapeau => vec![2],
Distro::Chrom => vec![5],
Distro::Clear_Linux_OS => vec![2],
Distro::Container_Linux_by_CoreOS => vec![3],
Distro::CRUX => vec![3],
Distro::EuroLinux => vec![2],
Distro::eweOS => vec![3],
Distro::Fedora => vec![2],
Distro::Fedora_Sericea => vec![2],
Distro::Fedora_Silverblue => vec![2],
Distro::GalliumOS => vec![2],
Distro::Gentoo => vec![1],
Distro::HarDClanZ => vec![2],
Distro::Kibojoe => vec![3],
Distro::KrassOS => vec![2],
Distro::Kubuntu => vec![2],
Distro::Linux => vec![1],
Distro::LinuxFromScratch => vec![1, 3],
Distro::Lubuntu => vec![2],
Distro::openEuler => vec![2],
Distro::orchid => vec![1],
Distro::Panwah => vec![1],
Distro::Peppermint => vec![2],
Distro::PNM_Linux => vec![2],
Distro::Pop__OS => vec![2],
Distro::Reborn_OS => vec![1],
Distro::SalentOS => vec![4],
Distro::Septor => vec![2],
Distro::Ubuntu_Cinnamon => vec![2],
Distro::Ubuntu_Kylin => vec![2],
Distro::Ubuntu_MATE => vec![2],
Distro::Ubuntu_old => vec![2],
Distro::Ubuntu_Studio => vec![2],
Distro::Ubuntu_Sway => vec![2],
Distro::Ultramarine_Linux => vec![2],
Distro::Univention => vec![2],
Distro::uwuntu => vec![2],
Distro::Vanilla => vec![2],
Distro::VNux => vec![3, 5],
Distro::Void => vec![2],
Distro::Xray_OS => vec![2, 3],
Distro::Xubuntu => vec![2],
_ => Vec::new(),
};
fg.into_iter()
.map(|fore| {
fore.try_into()
.expect("`fore` should be a valid neofetch color index")
})
distro.foreground()
.iter()
.map(|&f| f.try_into().expect("neofetch color index should be valid"))
.collect()
}
+2 -858
View File
@@ -1,859 +1,3 @@
use std::iter;
use std::num::{NonZeroU8, NonZeroUsize};
#![allow(non_camel_case_types)]
use anyhow::{anyhow, Context as _, Result};
use indexmap::IndexSet;
use palette::num::ClampAssign as _;
use palette::{IntoColorMut as _, LinSrgb, Okhsl, Srgb};
use serde::{Deserialize, Serialize};
use strum::{AsRefStr, EnumCount, EnumString, VariantArray, VariantNames};
use tracing::debug;
use unicode_segmentation::UnicodeSegmentation as _;
use crate::color_util::{ForegroundBackground, Lightness, ToAnsiString as _};
use crate::types::{AnsiMode, TerminalTheme};
#[derive(
Copy,
Clone,
Hash,
Debug,
AsRefStr,
Deserialize,
EnumCount,
EnumString,
Serialize,
VariantArray,
VariantNames,
)]
#[serde(rename_all = "kebab-case")]
#[strum(serialize_all = "kebab-case")]
pub enum Preset {
Rainbow,
Transgender,
Nonbinary,
Xenogender,
Agender,
Queer,
Genderfluid,
Bisexual,
Pansexual,
Polysexual,
Omnisexual,
Omniromantic,
GayMen,
Lesbian,
Abrosexual,
Asexual,
Aromantic,
Aroace1,
Aroace2,
Aroace3,
Greysexual,
Autosexual,
Intergender,
Greygender,
Akiosexual,
Bigender,
Demigender,
Demiboy,
Demigirl,
Transmasculine,
Transfeminine,
Genderfaun,
Demifaun,
Genderfae,
Demifae,
Neutrois,
Biromantic1,
Autoromantic,
Boyflux2,
Girlflux,
Genderflux,
Finsexual,
Unlabeled1,
Unlabeled2,
Pangender,
/// High-contrast version of pangender flag
#[serde(rename = "pangender.contrast")]
#[strum(serialize = "pangender.contrast")]
PangenderContrast,
#[serde(rename = "gendernonconforming1")]
#[strum(serialize = "gendernonconforming1")]
GenderNonconforming1,
#[serde(rename = "gendernonconforming2")]
#[strum(serialize = "gendernonconforming2")]
GenderNonconforming2,
Femboy,
Tomboy,
Gynesexual,
Androsexual,
Gendervoid,
Voidgirl,
Voidboy,
NonhumanUnity,
/// For all the dogs
Caninekin,
Plural,
Fraysexual,
Bear,
Butch,
Leather,
Otter,
Twink,
Kenochoric,
Veldian,
Solian,
Lunian,
Polyam,
Sapphic,
Androgyne,
Interprogress,
Progress,
Intersex,
OldPolyam,
EqualRights,
Drag,
Pronounfluid,
Pronounflux,
Exipronoun,
Neopronoun,
Neofluid,
Genderqueer,
Cisgender,
/// Colors from Gilbert Baker's original 1978 flag design
Baker,
/// Meme flag
Beiyang,
/// Meme flag
Burger,
/// Meme flag
#[serde(rename = "throatlozenges")]
#[strum(serialize = "throatlozenges")]
ThroatLozenges,
/// Meme flag
Band,
}
#[derive(Clone, Eq, PartialEq, Debug)]
pub struct ColorProfile {
pub colors: Vec<Srgb<u8>>,
}
#[derive(Clone, PartialEq, Debug)]
pub enum AssignLightness {
Replace(Lightness),
ClampMax(Lightness),
ClampMin(Lightness),
}
impl Preset {
pub fn color_profile(&self) -> ColorProfile {
(match self {
Self::Rainbow => ColorProfile::from_hex_colors(vec![
"#E50000", "#FF8D00", "#FFEE00", "#028121", "#004CFF", "#770088",
]),
Self::Transgender => ColorProfile::from_hex_colors(vec![
"#55CDFD", "#F6AAB7", "#FFFFFF", "#F6AAB7", "#55CDFD",
]),
Self::Nonbinary => {
ColorProfile::from_hex_colors(vec!["#FCF431", "#FCFCFC", "#9D59D2", "#282828"])
},
// sourced from https://commons.wikimedia.org/wiki/File:Xenogender_pride_flag.svg
Self::Xenogender => ColorProfile::from_hex_colors(vec![
"#FF6692", "#FF9A98", "#FFB883", "#FBFFA8", "#85BCFF", "#9D85FF", "#A510FF",
]),
Self::Agender => ColorProfile::from_hex_colors(vec![
"#000000", "#BABABA", "#FFFFFF", "#BAF484", "#FFFFFF", "#BABABA", "#000000",
]),
Self::Queer => ColorProfile::from_hex_colors(vec!["#B57FDD", "#FFFFFF", "#49821E"]),
Self::Genderfluid => ColorProfile::from_hex_colors(vec![
"#FE76A2", "#FFFFFF", "#BF12D7", "#000000", "#303CBE",
]),
Self::Bisexual => ColorProfile::from_hex_colors(vec!["#D60270", "#9B4F96", "#0038A8"]),
Self::Pansexual => ColorProfile::from_hex_colors(vec!["#FF1C8D", "#FFD700", "#1AB3FF"]),
Self::Polysexual => {
ColorProfile::from_hex_colors(vec!["#F714BA", "#01D66A", "#1594F6"])
},
// sourced from https://www.flagcolorcodes.com/omnisexual
Self::Omnisexual => ColorProfile::from_hex_colors(vec![
"#FE9ACE", "#FF53BF", "#200044", "#6760FE", "#8EA6FF",
]),
Self::Omniromantic => ColorProfile::from_hex_colors(vec![
"#FEC8E4", "#FDA1DB", "#89739A", "#ABA7FE", "#BFCEFF",
]),
// sourced from https://www.flagcolorcodes.com/gay-men
Self::GayMen => ColorProfile::from_hex_colors(vec![
"#078D70", "#98E8C1", "#FFFFFF", "#7BADE2", "#3D1A78",
]),
Self::Lesbian => ColorProfile::from_hex_colors(vec![
"#D62800", "#FF9B56", "#FFFFFF", "#D462A6", "#A40062",
]),
// used colorpicker to source from https://fyeahaltpride.tumblr.com/post/151704251345/could-you-guys-possibly-make-an-abrosexual-pride
Self::Abrosexual => ColorProfile::from_hex_colors(vec![
"#46D294", "#A3E9CA", "#FFFFFF", "#F78BB3", "#EE1766",
]),
Self::Asexual => {
ColorProfile::from_hex_colors(vec!["#000000", "#A4A4A4", "#FFFFFF", "#810081"])
},
Self::Aromantic => ColorProfile::from_hex_colors(vec![
"#3BA740", "#A8D47A", "#FFFFFF", "#ABABAB", "#000000",
]),
// sourced from https://flag.library.lgbt/flags/aroace/
Self::Aroace1 => ColorProfile::from_hex_colors(vec![
"#E28C00", "#ECCD00", "#FFFFFF", "#62AEDC", "#203856",
]),
// sourced from https://flag.library.lgbt/flags/aroace/
Self::Aroace2 => ColorProfile::from_hex_colors(vec![
"#000000", "#810081", "#A4A4A4", "#FFFFFF", "#A8D47A", "#3BA740",
]),
// sourced from https://flag.library.lgbt/flags/aroace/
Self::Aroace3 => ColorProfile::from_hex_colors(vec![
"#3BA740", "#A8D47A", "#FFFFFF", "#ABABAB", "#000000", "#A4A4A4", "#FFFFFF",
"#810081",
]),
// sourced from https://www.flagcolorcodes.com/greysexual
Self::Greysexual => ColorProfile::from_hex_colors(vec![
"#740194", "#AEB1AA", "#FFFFFF", "#AEB1AA", "#740194",
]),
// sourced from https://www.flagcolorcodes.com/autosexual
Self::Autosexual => ColorProfile::from_hex_colors(vec!["#99D9EA", "#7F7F7F"]),
// sourced from https://www.flagcolorcodes.com/intergender
Self::Intergender => {
ColorProfile::from_hex_colors(vec!["#900DC2", "#FFE54F", "#900DC2"])
.and_then(|c| c.with_weights(vec![2, 1, 2]))
},
// sourced from https://www.flagcolorcodes.com/greygender
Self::Greygender => ColorProfile::from_hex_colors(vec![
"#B3B3B3", "#FFFFFF", "#062383", "#FFFFFF", "#535353",
])
.and_then(|c| c.with_weights(vec![2, 1, 2, 1, 2])),
// sourced from https://www.flagcolorcodes.com/akiosexual
Self::Akiosexual => ColorProfile::from_hex_colors(vec![
"#F9485E", "#FEA06A", "#FEF44C", "#FFFFFF", "#000000",
]),
// sourced from https://www.flagcolorcodes.com/bigender
Self::Bigender => ColorProfile::from_hex_colors(vec![
"#C479A2", "#EDA5CD", "#D6C7E8", "#FFFFFF", "#D6C7E8", "#9AC7E8", "#6D82D1",
]),
// yellow sourced from https://lgbtqia.fandom.com/f/p/4400000000000041031
// other colors sourced from demiboy and demigirl flags
Self::Demigender => ColorProfile::from_hex_colors(vec![
"#7F7F7F", "#C4C4C4", "#FBFF75", "#FFFFFF", "#FBFF75", "#C4C4C4", "#7F7F7F",
]),
// sourced from https://www.flagcolorcodes.com/demiboy
Self::Demiboy => ColorProfile::from_hex_colors(vec![
"#7F7F7F", "#C4C4C4", "#9DD7EA", "#FFFFFF", "#9DD7EA", "#C4C4C4", "#7F7F7F",
]),
// sourced from https://www.flagcolorcodes.com/demigirl
Self::Demigirl => ColorProfile::from_hex_colors(vec![
"#7F7F7F", "#C4C4C4", "#FDADC8", "#FFFFFF", "#FDADC8", "#C4C4C4", "#7F7F7F",
]),
// sourced from https://www.flagcolorcodes.com/transmasculine
Self::Transmasculine => ColorProfile::from_hex_colors(vec![
"#FF8ABD", "#CDF5FE", "#9AEBFF", "#74DFFF", "#9AEBFF", "#CDF5FE", "#FF8ABD",
]),
// used colorpicker to source from https://www.deviantart.com/pride-flags/art/Trans-Woman-Transfeminine-1-543925985
// linked from https://gender.fandom.com/wiki/Transfeminine
Self::Transfeminine => ColorProfile::from_hex_colors(vec![
"#73DEFF", "#FFE2EE", "#FFB5D6", "#FF8DC0", "#FFB5D6", "#FFE2EE", "#73DEFF",
]),
// sourced from https://www.flagcolorcodes.com/genderfaun
Self::Genderfaun => ColorProfile::from_hex_colors(vec![
"#FCD689", "#FFF09B", "#FAF9CD", "#FFFFFF", "#8EDED9", "#8CACDE", "#9782EC",
]),
// sourced from https://www.flagcolorcodes.com/demifaun
Self::Demifaun => ColorProfile::from_hex_colors(vec![
"#7F7F7F", "#C6C6C6", "#FCC688", "#FFF19C", "#FFFFFF", "#8DE0D5", "#9682EC",
"#C6C6C6", "#7F7F7F",
])
.and_then(|c| c.with_weights(vec![2, 2, 1, 1, 1, 1, 1, 2, 2])),
// sourced from https://www.flagcolorcodes.com/genderfae
Self::Genderfae => ColorProfile::from_hex_colors(vec![
"#97C3A5", "#C3DEAE", "#F9FACD", "#FFFFFF", "#FCA2C4", "#DB8AE4", "#A97EDD",
]),
// used colorpicker to source form https://www.deviantart.com/pride-flags/art/Demifae-870194777
Self::Demifae => ColorProfile::from_hex_colors(vec![
"#7F7F7F", "#C5C5C5", "#97C3A4", "#C4DEAE", "#FFFFFF", "#FCA2C5", "#AB7EDF",
"#C5C5C5", "#7F7F7F",
])
.and_then(|c| c.with_weights(vec![2, 2, 1, 1, 1, 1, 1, 2, 2])),
// sourced from https://www.flagcolorcodes.com/neutrois
Self::Neutrois => ColorProfile::from_hex_colors(vec!["#FFFFFF", "#1F9F00", "#000000"]),
// sourced from https://www.flagcolorcodes.com/biromantic-alternate-2
Self::Biromantic1 => ColorProfile::from_hex_colors(vec![
"#8869A5", "#D8A7D8", "#FFFFFF", "#FDB18D", "#151638",
]),
// sourced from https://www.flagcolorcodes.com/autoromantic
Self::Autoromantic => ColorProfile::from_hex_colors(
// symbol interpreted
vec!["#99D9EA", "#3DA542", "#7F7F7F"],
)
.and_then(|c| c.with_weights(vec![2, 1, 2])),
// sourced from https://www.flagcolorcodes.com/boyflux-alternate-2
Self::Boyflux2 => ColorProfile::from_hex_colors(vec![
"#E48AE4", "#9A81B4", "#55BFAB", "#FFFFFF", "#A8A8A8", "#81D5EF", "#69ABE5",
"#5276D4",
])
.and_then(|c| c.with_weights(vec![1, 1, 1, 1, 1, 5, 5, 5])),
// sourced from https://commons.wikimedia.org/wiki/File:Girlflux_Pride_Flag.jpg
Self::Girlflux => ColorProfile::from_hex_colors(vec![
"f9e6d7", "f2526c", "bf0311", "e9c587", "bf0311", "f2526c", "f9e6d7",
]),
// sourced from https://www.deviantart.com/pride-flags/art/Genderflux-1-543925589
Self::Genderflux => ColorProfile::from_hex_colors(vec![
"f47694", "f2a2b9", "cecece", "7ce0f7", "3ecdf9", "fff48d",
]),
// sourced from https://lgbtqia.wiki/wiki/Finsexual
Self::Finsexual => ColorProfile::from_hex_colors(vec![
"#B18EDF", "#D7B1E2", "#F7CDE9", "#F39FCE", "#EA7BB3",
]),
// sourced from https://web.archive.org/web/20221002181913/https://unlabeledinfo.carrd.co/#flags
Self::Unlabeled1 => {
ColorProfile::from_hex_colors(vec!["#EAF8E4", "#FDFDFB", "#E1EFF7", "#F4E2C4"])
},
// sourced from https://web.archive.org/web/20221002181913/https://unlabeledinfo.carrd.co/#flags
Self::Unlabeled2 => ColorProfile::from_hex_colors(vec![
"#250548", "#FFFFFF", "#F7DCDA", "#EC9BEE", "#9541FA", "#7D2557",
]),
Self::Pangender => ColorProfile::from_hex_colors(vec![
"#FFF798", "#FEDDCD", "#FFEBFB", "#FFFFFF", "#FFEBFB", "#FEDDCD", "#FFF798",
]),
// high-contrast version of pangender flag
Self::PangenderContrast => ColorProfile::from_hex_colors(vec![
"#ffe87f", "#fcbaa6", "#fbc9f3", "#FFFFFF", "#fbc9f3", "#fcbaa6", "#ffe87f",
]),
Self::GenderNonconforming1 => ColorProfile::from_hex_colors(vec![
"#50284d", "#96467b", "#5c96f7", "#ffe6f7", "#5c96f7", "#96467b", "#50284d",
])
.and_then(|c| c.with_weights(vec![4, 1, 1, 1, 1, 1, 4])),
Self::GenderNonconforming2 => ColorProfile::from_hex_colors(vec![
"#50284d", "#96467b", "#5c96f7", "#ffe6f7", "#5c96f7", "#96467b", "#50284d",
]),
Self::Femboy => ColorProfile::from_hex_colors(vec![
"#d260a5", "#e4afcd", "#fefefe", "#57cef8", "#fefefe", "#e4afcd", "#d260a5",
]),
Self::Tomboy => ColorProfile::from_hex_colors(vec![
"#2f3fb9", "#613a03", "#fefefe", "#f1a9b7", "#fefefe", "#613a03", "#2f3fb9",
]),
// sourced from https://lgbtqia.fandom.com/wiki/Gynesexual
Self::Gynesexual => {
ColorProfile::from_hex_colors(vec!["#F4A9B7", "#903F2B", "#5B953B"])
},
// sourced from https://lgbtqia.fandom.com/wiki/Androsexual
Self::Androsexual => {
ColorProfile::from_hex_colors(vec!["#01CCFF", "#603524", "#B799DE"])
},
// sourced from: https://gender.fandom.com/wiki/Gendervoid
Self::Gendervoid => ColorProfile::from_hex_colors(vec![
"#081149", "#4B484B", "#000000", "#4B484B", "#081149",
]),
// sourced from: https://gender.fandom.com/wiki/Gendervoid
Self::Voidgirl => ColorProfile::from_hex_colors(vec![
"#180827", "#7A5A8B", "#E09BED", "#7A5A8B", "#180827",
]),
// sourced from: https://gender.fandom.com/wiki/Gendervoid
Self::Voidboy => ColorProfile::from_hex_colors(vec![
"#0B130C", "#547655", "#66B969", "#547655", "#0B130C",
]),
// used https://twitter.com/foxbrained/status/1667621855518236674/photo/1 as source and colorpicked
Self::NonhumanUnity => {
ColorProfile::from_hex_colors(vec!["#177B49", "#FFFFFF", "#593C90"])
},
// used https://www.tumblr.com/zombpawcoins/745062851267493888/caninekin-canine-therian-flag
Self::Caninekin => ColorProfile::from_hex_colors(vec![
"#2d2822", "#543d25", "#9c754d", "#e8dac2", "#cfad8c", "#b77b55", "#954e31",
]),
// used https://pluralpedia.org/w/Plurality#/media/File:Plural-Flag-1.jpg as source and colorpicked
Self::Plural => ColorProfile::from_hex_colors(vec![
"#2D0625", "#543475", "#7675C3", "#89C7B0", "#F3EDBD",
]),
// sampled from https://es.m.wikipedia.org/wiki/Archivo:Fraysexual_flag.jpg
Self::Fraysexual => {
ColorProfile::from_hex_colors(vec!["#226CB5", "#94E7DD", "#FFFFFF", "#636363"])
},
// sourced from https://commons.wikimedia.org/wiki/File:Bear_Brotherhood_flag.svg
Self::Bear => ColorProfile::from_hex_colors(vec![
"#623804", "#D56300", "#FEDD63", "#FEE6B8", "#FFFFFF", "#555555",
]),
// colorpicked from https://commons.wikimedia.org/wiki/File:Butch_Flag.png
Self::Butch => ColorProfile::from_hex_colors(vec![
"#D72800", "#F17623", "#FF9C56", "#FFFDF6", "#FFCE89", "#FEAF02", "#A37000",
]),
// colorpicked from https://commons.wikimedia.org/wiki/File:Leather,_Latex,_and_BDSM_pride_-_Light.svg
Self::Leather => ColorProfile::from_hex_colors(vec![
"#000000", "#252580", "#000000", "#252580", "#FFFFFF", "#252580", "#000000",
"#252580", "#000000",
]),
// colorpicked from https://commons.wikimedia.org/wiki/File:Official_Otter_Pride_Flag_by_Bearbackgear.jpg
Self::Otter => ColorProfile::from_hex_colors(vec![
"#263881", "#5C9DC9", "#FFFFFF", "#3A291D", "#5C9DC9", "#263881",
]),
// colorpicked from https://commons.wikimedia.org/wiki/File:Twink_Pride_Flag_(proposed).svg
Self::Twink => ColorProfile::from_hex_colors(vec!["#FFB2FF", "#FFFFFF", "#FFFF81"]),
Self::Kenochoric => {
ColorProfile::from_hex_colors(vec!["#000000", "#2E1569", "#824DB7", "#C7A1D6"])
},
Self::Veldian => ColorProfile::from_hex_colors(vec![
"#D182A8", "#FAF6E0", "#69ACBE", "#5D448F", "#3A113E",
]),
Self::Solian => ColorProfile::from_hex_colors(vec![
"#FFF8ED", "#FFE7A8", "#F1B870", "#A56058", "#46281E",
]),
Self::Lunian => ColorProfile::from_hex_colors(vec![
"#2F0E62", "#6F41B1", "#889FDF", "#7DDFD5", "#D2F2E2",
]),
// pulled from https://polyamproud.com/flag
Self::Polyam => ColorProfile::from_hex_colors(vec![
"#FFFFFF", "#FCBF00", "#009FE3", "#E50051", "#340C46",
]),
Self::Sapphic => ColorProfile::from_hex_colors(vec![
"#FD8BA8", "#FBF2FF", "#C76BC5", "#FDD768", "#C76BC5", "#FBF2FF", "#FD8BA8",
]),
Self::Androgyne => ColorProfile::from_hex_colors(vec!["#FE007F", "#9832FF", "#00B8E7"]),
Self::Interprogress => ColorProfile::from_hex_colors(vec![
"#FFD800", "#7902AA", "#FFFFFF", "#FFAFC8", "#74D7EE", "#613915", "#000000",
"#E50000", "#FF8D00", "#FFEE00", "#028121", "#004CFF", "#770088",
]),
Self::Progress => ColorProfile::from_hex_colors(vec![
"#FFFFFF", "#FFAFC8", "#74D7EE", "#613915", "#000000", "#E50000", "#FF8D00",
"#FFEE00", "#028121", "#004CFF", "#770088",
]),
Self::Intersex => ColorProfile::from_hex_colors(vec!["#FFD800", "#7902AA", "#FFD800"])
.and_then(|c| c.with_weights(vec![2, 1, 2])),
Self::OldPolyam => ColorProfile::from_hex_colors(vec![
"#0000FF", "#FF0000", "#FFFF00", "#FF0000", "#000000",
]),
Self::EqualRights => ColorProfile::from_hex_colors(vec![
"#0000FF", "#FFFF00", "#0000FF", "#FFFF00", "#0000FF",
])
.and_then(|c| c.with_weights(vec![2, 1, 2, 1, 2])),
Self::Drag => ColorProfile::from_hex_colors(vec![
"#CC67FF", "#FFFFFF", "#FFA3E3", "#FFFFFF", "#3366FF",
]),
Self::Pronounfluid => ColorProfile::from_hex_colors(vec![
"#FFB3F9", "#FFFFFF", "#D1FDCB", "#C7B0FF", "#000000", "#B8CCFF",
]),
Self::Pronounflux => ColorProfile::from_hex_colors(vec![
"#FDB3F8", "#B6CCFA", "#18DDD3", "#64FF89", "#FF7690", "#FFFFFF",
]),
Self::Exipronoun => {
ColorProfile::from_hex_colors(vec!["#1C3D34", "#FFFFFF", "#321848", "#000000"])
},
Self::Neopronoun => {
ColorProfile::from_hex_colors(vec!["#BCEC64", "#FFFFFF", "#38077A"])
},
Self::Neofluid => ColorProfile::from_hex_colors(vec![
"#FFECA0", "#FFFFFF", "#FFECA0", "#38087A", "#BCEC64",
]),
Self::Genderqueer => ColorProfile::from_hex_colors(vec![
"#B57EDC", "#FFFFFF", "#4A8123"
]),
Self::Cisgender => ColorProfile::from_hex_colors(vec![
"#D70270", "#0038A7"
]),
// used https://gilbertbaker.com/rainbow-flag-color-meanings/ as source and colorpicked
Self::Baker => ColorProfile::from_hex_colors(vec![
"#F23D9E", "#F80A24", "#F78022", "#F9E81F", "#1E972E", "#1B86BC", "#243897", "#6F0A82",
]),
Self::Beiyang => ColorProfile::from_hex_colors(vec![
"#DF1B12", "#FFC600", "#01639D", "#FFFFFF", "#000000",
]),
Self::Burger => ColorProfile::from_hex_colors(vec![
"#F3A26A", "#498701", "#FD1C13", "#7D3829", "#F3A26A",
]),
Self::ThroatLozenges => ColorProfile::from_hex_colors(vec![
"#2759DA", "#03940D", "#F5F100", "#F59B00", "#B71212",
]),
Self::Band => ColorProfile::from_hex_colors(vec![
"#2670C0", "#F5BD00", "#DC0045", "#E0608E"
]),
})
.expect("preset color profiles should be valid")
}
}
impl ColorProfile {
pub fn new(colors: Vec<Srgb<u8>>) -> Self {
Self { colors }
}
pub fn from_hex_colors<S>(hex_colors: Vec<S>) -> Result<Self>
where
S: AsRef<str>,
{
let colors = hex_colors
.into_iter()
.map(|s| s.as_ref().parse())
.collect::<Result<_, _>>()
.context("failed to parse hex colors")?;
Ok(Self::new(colors))
}
/// Maps colors based on weights.
///
/// # Arguments
///
/// * `weights` - Weights of each color (`weights[i]` = how many times
/// `colors[i]` appears)
pub fn with_weights(&self, weights: Vec<u8>) -> Result<Self> {
if weights.len() != self.colors.len() {
debug!(?weights, ?self.colors, "length mismatch between `weights` and `colors`");
return Err(anyhow!(
"`weights` should have the same number of elements as `colors`"
));
}
let mut weighted_colors = Vec::new();
for (i, w) in weights.into_iter().enumerate() {
weighted_colors.extend(iter::repeat(self.colors[i]).take(usize::from(w)));
}
Ok(Self::new(weighted_colors))
}
/// Creates a new color profile, with the colors spread to the specified
/// length.
pub fn with_length(&self, length: NonZeroU8) -> Result<Self> {
let orig_len = self.colors.len();
let orig_len: NonZeroUsize = orig_len.try_into().expect("`colors` should not be empty");
let orig_len: NonZeroU8 = orig_len
.try_into()
.expect("`colors` should not have more than 255 elements");
// TODO: I believe weird things can happen because of this...
// if length < orig_len {
// unimplemented!("compressing length of color profile not implemented");
// }
let center_i = usize::from(orig_len.get() / 2);
// How many copies of each color should be displayed at least?
let repeats = length.get().div_euclid(orig_len.get());
let mut weights = vec![repeats; NonZeroUsize::from(orig_len).get()];
// How many extra spaces left?
let mut extras = length.get().rem_euclid(orig_len.get());
// If there is an odd space left, extend the center by one space
if extras % 2 == 1 {
weights[center_i] = weights[center_i].checked_add(1).unwrap();
extras = extras.checked_sub(1).unwrap();
}
// Add weight to border until there's no space left (extras must be even at this
// point)
let weights_len = weights.len();
for border_i in 0..usize::from(extras / 2) {
weights[border_i] = weights[border_i].checked_add(1).unwrap();
let border_opp = weights_len
.checked_sub(border_i)
.unwrap()
.checked_sub(1)
.unwrap();
weights[border_opp] = weights[border_opp].checked_add(1).unwrap();
}
self.with_weights(weights)
}
/// Colors a text.
///
/// # Arguments
///
/// * `foreground_background` - Whether the color is shown on the foreground
/// text or the background block
/// * `space_only` - Whether to only color spaces
pub fn color_text<S>(
&self,
txt: S,
color_mode: AnsiMode,
foreground_background: ForegroundBackground,
space_only: bool,
) -> Result<String>
where
S: AsRef<str>,
{
let txt = txt.as_ref();
let txt: Vec<&str> = txt.graphemes(true).collect();
let ColorProfile { colors } = {
let length = txt.len();
let length: NonZeroUsize = length.try_into().context("`txt` should not be empty")?;
let length: NonZeroU8 = length.try_into().with_context(|| {
format!(
"`txt` should not have more than {limit} characters",
limit = u8::MAX
)
})?;
self.with_length(length)
.with_context(|| format!("failed to spread color profile to length {length}"))?
};
let mut buf = String::new();
for (i, &gr) in txt.iter().enumerate() {
if space_only && gr != " " {
if i > 0 && txt[i.checked_sub(1).unwrap()] == " " {
buf.push_str("\x1b[39;49m");
}
buf.push_str(gr);
} else {
buf.push_str(&colors[i].to_ansi_string(color_mode, foreground_background));
buf.push_str(gr);
}
}
buf.push_str("\x1b[39;49m");
Ok(buf)
}
/// Creates a new color profile, with the colors lightened by a multiplier.
pub fn lighten(&self, multiplier: f32) -> Self {
let mut rgb_f32_colors: Vec<LinSrgb> =
self.colors.iter().map(|c| c.into_linear()).collect();
{
let okhsl_f32_colors: &mut [Okhsl] = &mut rgb_f32_colors.into_color_mut();
for okhsl_f32_color in okhsl_f32_colors {
okhsl_f32_color.lightness *= multiplier;
}
}
let rgb_u8_colors: Vec<_> = rgb_f32_colors
.into_iter()
.map(Srgb::<u8>::from_linear)
.collect();
Self {
colors: rgb_u8_colors,
}
}
/// Creates a new color profile, with the colors set to the specified
/// [`Okhsl`] lightness value.
pub fn with_lightness(&self, assign_lightness: AssignLightness) -> Self {
let mut rgb_f32_colors: Vec<LinSrgb> =
self.colors.iter().map(|c| c.into_linear()).collect();
{
let okhsl_f32_colors: &mut [Okhsl] = &mut rgb_f32_colors.into_color_mut();
for okhsl_f32_color in okhsl_f32_colors {
match assign_lightness {
AssignLightness::Replace(lightness) => {
okhsl_f32_color.lightness = lightness.into();
},
AssignLightness::ClampMax(lightness) => {
okhsl_f32_color.lightness.clamp_max_assign(lightness.into());
},
AssignLightness::ClampMin(lightness) => {
okhsl_f32_color.lightness.clamp_min_assign(lightness.into());
},
}
}
}
let rgb_u8_colors: Vec<Srgb<u8>> = rgb_f32_colors
.into_iter()
.map(Srgb::<u8>::from_linear)
.collect();
Self {
colors: rgb_u8_colors,
}
}
/// Creates a new color profile, with the colors set to the specified
/// [`Okhsl`] lightness value, adapted to the terminal theme.
pub fn with_lightness_adaptive(&self, lightness: Lightness, theme: TerminalTheme) -> Self {
match theme {
TerminalTheme::Dark => self.with_lightness(AssignLightness::ClampMin(lightness)),
TerminalTheme::Light => self.with_lightness(AssignLightness::ClampMax(lightness)),
}
}
/// Creates another color profile with only the unique colors.
pub fn unique_colors(&self) -> Self {
let unique_colors: IndexSet<[u8; 3]> = self.colors.iter().map(|&c| c.into()).collect();
let unique_colors: Vec<Srgb<u8>> = unique_colors.into_iter().map(|c| c.into()).collect();
Self::new(unique_colors)
}
}
include!(concat!(env!("OUT_DIR"), "/presets.rs"));
+25 -85
View File
@@ -47,58 +47,32 @@ pub fn start_animation(color_mode: AnsiMode) -> Result<()> {
};
let text = &TEXT_ASCII[1..TEXT_ASCII.len().checked_sub(1).unwrap()];
let (text_width, text_height) =
ascii_size(text).expect("text ascii should have valid width and height");
let (text_w, text_h) = ascii_size(text)?;
let (text, text_width, text_height) = {
const TEXT_BORDER_WIDTH: u16 = 2;
const NOTICE_BORDER_WIDTH: u16 = 1;
const VERTICAL_MARGIN: u16 = 1;
let notice_w = NOTICE.len();
let notice_w: u8 = notice_w
.try_into()
.expect("`NOTICE` width should fit in `u8`");
let notice_h = NOTICE.lines().count();
let notice_h: u8 = notice_h
.try_into()
.expect("`NOTICE` height should fit in `u8`");
let notice_w: u16 = NOTICE.len().try_into()?;
let notice_h: u16 = NOTICE.lines().count().try_into()?;
let term_w_min = cmp::max(
u16::from(text_width)
.checked_add(TEXT_BORDER_WIDTH.checked_mul(2).unwrap())
.unwrap(),
u16::from(notice_w)
.checked_add(NOTICE_BORDER_WIDTH.checked_mul(2).unwrap())
.unwrap(),
text_w + TEXT_BORDER_WIDTH * 2,
notice_w + NOTICE_BORDER_WIDTH * 2,
);
let term_h_min = u16::from(text_height)
.checked_add(notice_h.into())
.unwrap()
.checked_add(VERTICAL_MARGIN.checked_mul(2).unwrap())
.unwrap();
let term_h_min = u16::from(text_h) + notice_h + VERTICAL_MARGIN * 2;
if w.get() >= term_w_min && h.get() >= term_h_min {
(text, text_width, text_height)
(text, text_w, text_h)
} else {
let text = &TEXT_ASCII_SMALL[1..TEXT_ASCII_SMALL.len().checked_sub(1).unwrap()];
let (text_width, text_height) =
ascii_size(text).expect("text ascii should have valid width and height");
let (text_w, text_h) = ascii_size(text)?;
let term_w_min = cmp::max(
u16::from(text_width)
.checked_add(TEXT_BORDER_WIDTH.checked_mul(2).unwrap())
.unwrap(),
u16::from(notice_w)
.checked_add(NOTICE_BORDER_WIDTH.checked_mul(2).unwrap())
.unwrap(),
text_w + TEXT_BORDER_WIDTH * 2,
notice_w + NOTICE_BORDER_WIDTH * 2,
);
let term_h_min = u16::from(text_height)
.checked_add(notice_h.into())
.unwrap()
.checked_add(VERTICAL_MARGIN.checked_mul(2).unwrap())
.unwrap();
let term_h_min = text_h + notice_h + VERTICAL_MARGIN * 2;
if w.get() < term_w_min || h.get() < term_h_min {
return Err(anyhow!(
"terminal size should be at least ({term_w_min} * {term_h_min})"
));
return Err(anyhow!("terminal size should be at least ({term_w_min} * {term_h_min})"));
}
(text, text_width, text_height)
(text, text_w, text_h)
}
};
let text_lines: Vec<&str> = text.lines().collect();
@@ -165,8 +139,7 @@ pub fn start_animation(color_mode: AnsiMode) -> Result<()> {
.rem_euclid(colors.len())]
.to_ansi_string(color_mode, ForegroundBackground::Background),
fg = fg.to_ansi_string(color_mode, ForegroundBackground::Foreground)
)
.unwrap();
)?;
// Loop over the width
for x in 0..w.get() {
@@ -176,27 +149,11 @@ pub fn start_animation(color_mode: AnsiMode) -> Result<()> {
.wrapping_add_signed((2.0 * (y as f64 + 0.5 * frame as f64).sin()) as isize);
let y_text = text_start_y <= y && y < text_end_y;
let border = 1u16
.checked_add(
if y == text_start_y || y == text_end_y.checked_sub(1).unwrap() {
0
} else {
1
},
)
.unwrap();
let text_bounds_x1 = text_start_x
.checked_sub(border)
.expect("`text_start_x - border` should not underflow `u16`");
let text_bounds_x2 = text_end_x
.checked_add(border)
.expect("`text_end_x + border` should not overflow `u16`");
let notice_bounds_x1 = notice_start_x
.checked_sub(1)
.expect("`notice_start_x - 1` should not underflow `u16`");
let notice_bounds_x2 = notice_end_x
.checked_add(1)
.expect("`notice_end_x + 1` should not overflow `u16`");
let border = 1u16 + if y == text_start_y || y == (text_end_y - 1) { 0 } else { 1 };
let text_bounds_x1 = text_start_x - border;
let text_bounds_x2 = text_end_x - border;
let notice_bounds_x1 = notice_start_x - 1;
let notice_bounds_x2 = notice_end_x - 1;
// If it's a switching point
if idx.rem_euclid(NonZeroUsize::from(block_width).get()) == 0
@@ -215,19 +172,9 @@ pub fn start_animation(color_mode: AnsiMode) -> Result<()> {
{
let c: LinSrgba = c.with_alpha(1.0).into_linear();
let c = Srgb::<u8>::from_linear(c.overlay(black).without_alpha());
write!(
buf,
"{bg}",
bg = c.to_ansi_string(color_mode, ForegroundBackground::Background),
)
.unwrap();
write!(buf, "{bg}", bg = c.to_ansi_string(color_mode, ForegroundBackground::Background))?;
} else {
write!(
buf,
"{bg}",
bg = c.to_ansi_string(color_mode, ForegroundBackground::Background),
)
.unwrap();
write!(buf, "{bg}", bg = c.to_ansi_string(color_mode, ForegroundBackground::Background))?;
}
}
@@ -240,8 +187,7 @@ pub fn start_animation(color_mode: AnsiMode) -> Result<()> {
.chars()
.nth(usize::from(x.checked_sub(text_start_x).unwrap()))
.unwrap(),
)
.unwrap();
)?;
} else if y == notice_y && notice_start_x <= x && x < notice_end_x {
write!(
buf,
@@ -250,21 +196,15 @@ pub fn start_animation(color_mode: AnsiMode) -> Result<()> {
.chars()
.nth(usize::from(x.checked_sub(notice_start_x).unwrap()))
.unwrap(),
)
.unwrap();
)?;
} else {
write!(buf, " ").unwrap();
write!(buf, " ")?;
}
}
// New line if it isn't the last line
if y != h.get().checked_sub(1).unwrap() {
writeln!(
buf,
"{reset}",
reset = color("&r", color_mode).expect("reset should be valid"),
)
.unwrap();
writeln!(buf, "{reset}", reset = color("&r", color_mode)?)?;
}
}
+1 -6
View File
@@ -85,12 +85,7 @@ where
let metadata = match fs::metadata(path) {
Ok(metadata) => metadata,
Err(err) if err.kind() == io::ErrorKind::NotFound => {
return Ok(None);
},
Err(err) => {
return Err(err).with_context(|| format!("failed to get metadata for {path:?}"));
},
Err(_) => return Ok(None)
};
if !metadata.is_file() {
+6 -4
View File
@@ -1,7 +1,7 @@
.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.49.3.
.TH VERSION: "1" "August 2025" "Version: 2.0.1" "User Commands"
.TH VERSION: "1" "April 2026" "Version: 2.1.0" "User Commands"
.SH NAME
Version: \- manual page for Version: 2.0.1
Version: \- manual page for Version: 2.1.0
.SH SYNOPSIS
.B hyfetch
[\fI\,-c\/\fR] [\fI\,-C=CONFIG_FILE\/\fR] [\fI\,-p=PRESET\/\fR] [\fI\,-m=MODE\/\fR] [\fI\,-b=BACKEND\/\fR] [\fI\,--args=ARGS\/\fR] [\fI\,--c-scale=\/\fR
@@ -20,8 +20,10 @@ Use another config file
[default: "/home/azalea/.config/hyfetch.json"]
.TP
\fB\-p\fR, \fB\-\-preset\fR=\fI\,PRESET\/\fR
Use preset
PRESET={rainbow,transgender,nonbinary,xenogender,agender,queer,genderfluid,bisexual,pansexual,polysexual,omnisexual,omniromantic,gay\-men,lesbian,abrosexual,asexual,aromantic,aroace1,aroace2,aroace3,greysexual,autosexual,intergender,greygender,akiosexual,bigender,demigender,demiboy,demigirl,transmasculine,transfeminine,genderfaun,demifaun,genderfae,demifae,neutrois,biromantic1,autoromantic,boyflux2,girlflux,genderflux,finsexual,unlabeled1,unlabeled2,pangender,pangender.contrast,gendernonconforming1,gendernonconforming2,femboy,tomboy,gynesexual,androsexual,gendervoid,voidgirl,voidboy,nonhuman\-unity,caninekin,plural,fraysexual,bear,butch,leather,otter,twink,kenochoric,veldian,solian,lunian,polyam,sapphic,androgyne,interprogress,progress,intersex,old\-polyam,equal\-rights,drag,pronounfluid,pronounflux,exipronoun,neopronoun,neofluid,genderqueer,cisgender,baker,beiyang,burger,throatlozenges,band,random}
Use preset or comma\-separated color list or comma\-separated hex colors
(e.g., "#ff0000,#00ff00,#0000ff"). Comma\-separated preset names will
pick one randomly.
PRESET={rainbow,transgender,nonbinary,xenogender,agender,queer,genderfluid,bisexual,pansexual,polysexual,omnisexual,omniromantic,gay\-men,lesbian,abrosexual,asexual,aromantic,fictosexual,aroace1,aroace2,aroace3,autosexual,intergender,greygender,akiosexual,bigender,demigender,demiboy,demigirl,transmasculine,transfeminine,genderfaun,demifaun,genderfae,demifae,neutrois,biromantic1,biromantic2,autoromantic,boyflux2,girlflux,genderflux,nullflux,hypergender,hyperboy,hypergirl,hyperandrogyne,hyperneutrois,finsexual,unlabeled1,unlabeled2,pangender,pangender.contrast,gendernonconforming1,gendernonconforming2,femboy,tomboy,gynesexual,androsexual,gendervoid,voidgirl,voidboy,nonhuman\-unity,plural,fraysexual,bear,butch,femme,leather,otter,twink,adipophilia,kenochoric,veldian,solian,lunian,polyam,sapphic,androgyne,interprogress,progress,intersex,old\-polyam,equal\-rights,drag,pronounfluid,pronounflux,exipronoun,neopronoun,neofluid,genderqueer,cisgender,baker,caninekin,libragender,librafeminine,libramasculine,libraandrogyne,libranonbinary,fluidflux1,fluidflux2,transbian,autism,cenelian,transneutral,beiyang,burger,throatlozenges,band,petergriffin,rubber,haruhi,random}
.TP
\fB\-m\fR, \fB\-\-mode\fR=\fI\,MODE\/\fR
Color mode MODE={8bit,rgb}
+23 -21
View File
@@ -1,7 +1,7 @@
.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.49.3.
.TH NEOFETCH "1" "August 2025" "Neofetch 8.0.1" "User Commands"
.TH NEOFETCH "1" "April 2026" "Neofetch 8.1.0" "User Commands"
.SH NAME
Neofetch \- manual page for Neofetch 8.0.1
Neofetch \- manual page for Neofetch 8.1.0
.SH SYNOPSIS
.B neofetch
\fI\,func_name --option "value" --option "value"\/\fR
@@ -326,13 +326,13 @@ BigLinux_large, Bitrig, BlackArch, BlackMesa, blackPanther, BLAG,
BlankOn, BlueLight, Bodhi, bonsai, BSD, BunsenLabs, CachyOS,
Calculate, CalinixOS, Carbs, CBL\-Mariner, CelOS, Center, CentOS,
Chakra, ChaletOS, Chapeau, Chimera, ChonkySealOS, Chrom, Cleanjaro,
Clear Linux OS, ClearOS, Clover, Cobalt, Condres, Container Linux by
CoreOS, CRUX, Crystal Linux, Cucumber, CutefishOS, CuteOS, CyberOS,
dahlia, DarkOs, Darwin, Debian, Deepin, DesaOS, Devuan, DietPi,
digital UNIX, DracOS, DragonFly, Drauger, Droidian, Elementary,
Elive, EncryptOS, EndeavourOS, Endless, Enso, EuroLinux,
EvolutionOS, eweOS, Exherbo, Exodia Predator OS, Fedora, Fedora
Kinoite, Fedora Sericea, Fedora Silverblue, Fedora_unicode,
Clear Linux OS, ClearOS, Clover, Cobalt, Codex Linux, Condres,
Container Linux by CoreOS, CRUX, Crystal Linux, Cucumber,
CutefishOS, CuteOS, CyberOS, dahlia, DarkOs, Darwin, Debian, Deepin,
DesaOS, Devuan, DietPi, digital UNIX, DracOS, DragonFly, Drauger,
Droidian, Elementary, Elive, EncryptOS, EndeavourOS, Endless, Enso,
EuroLinux, EvolutionOS, eweOS, Exherbo, Exodia Predator OS, Fedora,
Fedora Kinoite, Fedora Sericea, Fedora Silverblue, Fedora_unicode,
FemboyOS, Feren, Finnix, Floflis, FreeBSD, FreeMiNT, Frugalware,
Funtoo, Furreto, GalliumOS, Garuda, Gentoo, GhostBSD, glaucus,
Gloire, gNewSense, GNOME, GNU, GoboLinux, GrapheneOS, Grombyang,
@@ -352,22 +352,24 @@ Tumbleweed, openSUSE Tumbleweed\-Slowroll, OPNsense, Oracle, orchid,
OS Elbrus, PacBSD, Panwah, Parabola, parch, Pardus, Parrot, Parsix,
PCBSD, PCLinuxOS, pearOS, Pengwin, Pentoo, Peppermint, Peropesis,
phyOS, PikaOS, Pisi, PNM Linux, Pop!_OS, Porteus, PostMarketOS,
Profelis SambaBOX, Proxmox, PuffOS, Puppy, PureOS, Q4OS, Qubes,
Profelis SambaBOX, Proxmox, PuffOS, Puppy, PureOS, Q4OS, QNX, Qubes,
Qubyt, Quibian, Radix, Raspbian, ravynOS, Reborn OS, Red Star,
Redcore, Redhat, Refracted Devuan, Regata, Regolith, RhaymOS, Rhino
Linux, rocky, Rosa, Sabayon, sabotage, Sailfish, SalentOS, Salient
OS, Salix, Sasanqua, Scientific, semc, Septor, Serene, SharkLinux,
ShastraOS, Siduction, SkiffOS, Slackel, Slackware, SliTaz, SmartOS,
Soda, Solus, Source Mage, Sparky, Star, SteamOS, Stock Linux, Sulin,
SunOS, SwagArch, t2, Tails, Tatra, TeArch, TorizonCore, Trisquel,
Twister, Ubuntu, Ubuntu Budgie, Ubuntu Cinnamon, Ubuntu Kylin,
Ubuntu MATE, Ubuntu Studio, Ubuntu Sway, Ubuntu Touch, Ubuntu\-GNOME,
ubuntu_old02, Ultramarine Linux, unicodearch, Univalent, Univention,
Uos, UrukOS, uwuntu, Vanilla, Venom, VNux, Void, VzLinux, wii\-linuxngx, Windows, Windows 10, Windows 11, Windows95, Wrt, Xenia, Xenia2,
XFerience, Xray_OS, Xubuntu, yiffOS, Zorin have ascii logos.
OS, Salix, Sasanqua, Scientific, secureblue, semc, Septor, Serene,
SharkLinux, ShastraOS, Siduction, SkiffOS, Slackel, Slackware,
SliTaz, SmartOS, Soda, Solus, Source Mage, Sparky, Star, SteamOS,
Stock Linux, Sulin, SunOS, SwagArch, t2, Tails, Tatra, TeArch,
TorizonCore, Trisquel, Twister, Ubuntu, Ubuntu Budgie, Ubuntu
Cinnamon, Ubuntu Kylin, Ubuntu MATE, Ubuntu Studio, Ubuntu Sway,
Ubuntu Touch, Ubuntu\-GNOME, ubuntu_old02, Ultramarine Linux,
unicodearch, Univalent, Univention, Uos, UrukOS, uwuntu, Vanilla,
Venom, VNux, Void, VzLinux, wii\-linux\-ngx, Windows, Windows 10,
Windows 11, Windows95, Wrt, Xenia, Xenia2, XFerience, Xray_OS,
Xubuntu, yiffOS, Zirconium, Zorin have ascii logos.
.TP
NOTE: arch, dragonfly, Fedora, LangitKetujuh, nixos, redhat, Ubuntu
have 'old' logo variants, use {distro}_old to use them.
NOTE: arch, dragonfly, Fedora, LangitKetujuh, nixos, redhat, Ubuntu,
void have 'old' logo variants, use {distro}_old to use them.
.TP
NOTE: alpine, android, arch, arcolinux, artix, CalinixOS, centos,
cleanjaro, crux, debian, dragonfly, elementary, endeavouros, fedora,
+9
View File
@@ -1,8 +1,17 @@
from __future__ import annotations
import os
from .py import run_py
from .rs import run_rust
def run_neofetch():
from .neofetch_util import run_neofetch_cmd
import sys
run_neofetch_cmd(sys.argv[1:])
if __name__ == '__main__':
if os.environ.get('HYFETCH_PY', False):
run_py()
+3 -1
View File
@@ -1 +1,3 @@
VERSION = '2.0.1'
from __future__ import annotations
VERSION = '2.1.0'
+11 -3
View File
@@ -135,9 +135,17 @@ class RGB:
:return: RGB object
"""
hex = hex.lstrip("#")
r = int(hex[0:2], 16)
g = int(hex[2:4], 16)
b = int(hex[4:6], 16)
if len(hex) == 6:
r = int(hex[0:2], 16)
g = int(hex[2:4], 16)
b = int(hex[4:6], 16)
elif len(hex) == 3:
r = int(hex[0] * 2, 16)
g = int(hex[1] * 2, 16)
b = int(hex[2] * 2, 16)
else:
raise ValueError(f"Error: invalid hex length")
return cls(r, g, b)
def to_ansi_rgb(self, foreground: bool = True) -> str:
+1
View File
@@ -9,6 +9,7 @@ from .types import LightDark
from .__version__ import VERSION
CONFIG_PATH = Path.home() / '.config/hyfetch.json'
SRC = Path(__file__).parent
TEST_ASCII = r"""
@@ -1,8 +1,4 @@
# This file is automatically generated. Please do not modify.
from . import AsciiArt
adelie = AsciiArt(match=r'''"Adélie"* | "Adelie"*''', color='4 7 6', ascii=r"""
{"match": "\"Ad\u00e9lie\"* | \"Adelie\"*", "color": "4 7 6"}
${c1} ${c3} ,-^-___
${c3} /\\\///
${c2}refined.${c1} /\\\\//
@@ -18,6 +14,4 @@ ${c1} ///////${c3}\\\\\\\\\\//
/\\\/${c1}\\/
/\\\\//
//////
/// ${c3}\\\\\
""")
/// ${c3}\\\\\
+15
View File
@@ -0,0 +1,15 @@
{"match": "\"Aeon\"*", "color": "38;5;36 38;5;36"}
⣾⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣷
⣿⡇ ⢸⣿
⣿⡇ ⢀⣀ ⣀⡀ ⢸⣿
⣿⣇ ⠸⣿⣄ ⣠⣿⠇ ⣸⣿
⢹⣿⡄ ⠙⠻⠿⠿⠟⠋ ⢠⣿⡏
⠹⣿⣦⡀ ⢀⣴⣿⠏
⠈⠛⢿⣶⣤⣄ ⣠⣤⣶⡿⠛⠁
${c2} ⣠⣴⡿⠿⠛ ⠛⠿⢿⣦⣄
⣠⣾⠟⠉ ⠉⠻⣷⣄
⢰⣿⠏ ⢀⣤⣶⣶⣤⡀ ⠹⣿⡆
⣿⡟ ⢰⣿⠏⠁⠈⠹⣿⡆ ⢿⣿
⣿⡇ ⠈⠋ ⠙⠁ ⢸⣿
⣿⡇ ⢸⣿
⣿⣷⣶⣶⣶⣶⣶⣶⣶⣶⣶⣶⣶⣶⣶⣶⣾⣿
@@ -1,8 +1,4 @@
# This file is automatically generated. Please do not modify.
from . import AsciiArt
aeros = AsciiArt(match=r'''"aerOS"*''', color='fg 0 0 0', ascii=r"""
{"match": "\"aerOS\"*", "color": "fg 0 0 0"}
${c1}
ooo OOO OOO ooo
oOO OOo
@@ -24,6 +20,4 @@ ${c1}
oO OOo
oOO OOo
oOO OOo
ooo OOO OOO ooo
""")
ooo OOO OOO ooo
+17
View File
@@ -0,0 +1,17 @@
{"match": "\"AerynOS\"*", "color": "7 5"}
;llll.
0MMMMMM:
NMMMMMMMMd
.@ .cccccccccoWMMMMMMMMMM0
@@ .MMMMMMMMMMMMMMMMMMMMMMMN
OMMMMMMMMMMMMMMMW.
.@ .MMMMMMMMMMMMMMMMMMM.
.@ dMMMMMMMMMMMMMMMMMMl OMMMMMMMMk
.OWMMMMM; dMMMMMMMMMk
.MMMMMMMMMk
@@ ooooooooooooooooooo .MMMMMMMMMN
.@ oooooMMMMMMMMMMMMP NMMMMMMMMW.
KMMMMMMMMMM. 0MMMMMMMMM:
NMMMMMMMMM. dMMMMMMMMMd
.WMMMMMMMW. XMMMMMMMMO
.MMMMMMMk. xMMMMMMMMX
@@ -1,8 +1,4 @@
# This file is automatically generated. Please do not modify.
from . import AsciiArt
afterglow = AsciiArt(match=r'''"Afterglow"*''', color='5 1 3 4', ascii=r"""
{"match": "\"Afterglow\"*", "color": "5 1 3 4"}
${c2} .
${c1}. ${c2}.{!
${c1}.L! ${c2}J@||*
@@ -17,6 +13,4 @@ ${c2} .
${c3}.@FJJJF`${c4},@LFFFF`
${c3}_@FFFFF ${c4}VLLLP`
${c3}J@@LL@" ${c4}`"
${c3}V@@"
""")
${c3}V@@"
@@ -1,8 +1,4 @@
# This file is automatically generated. Please do not modify.
from . import AsciiArt
aix = AsciiArt(match=r'''"AIX"*''', color='2 7', ascii=r"""
{"match": "\"AIX\"*", "color": "2 7"}
${c1} `:+ssssossossss+-`
.oys///oyhddddhyo///sy+.
/yo:+hNNNNNNNNNNNNNNNNh+:oy/
@@ -22,6 +18,4 @@ h//NNNNh ossss` +h md- .hm/ `sNNNNN:+y
:h+-yNNNNNNNNNNNNNNNNNNNNNNs-oh-
:ys:/yNNNNNNNNNNNNNNNmy/:sy:
.+ys///osyhhhhys+///sy+.
-/osssossossso/-
""")
-/osssossossso/-
@@ -1,8 +1,4 @@
# This file is automatically generated. Please do not modify.
from . import AsciiArt
almalinux = AsciiArt(match=r'''"AlmaLinux"*''', color='1 3 4 2 6', ascii=r"""
{"match": "\"AlmaLinux\"*", "color": "1 3 4 2 6"}
${c1} 'c:.
${c1} lkkkx, .. ${c2}.. ,cc,
${c1} okkkk:ckkx' ${c2}.lxkkx.okkkkd
@@ -22,6 +18,4 @@ ${c3} ..... ${c5}.;dk:. ${c5}lkk. ${c4}:;,
,c,,;;;:xkkd.
;kkkkl...
;kkkkl
,od;
""")
,od;
@@ -1,8 +1,4 @@
# This file is automatically generated. Please do not modify.
from . import AsciiArt
alpine = AsciiArt(match=r'''"Alpine"*''', color='4 5 7 6', ascii=r"""
{"match": "\"Alpine\"*", "color": "4 5 7 6"}
${c1} .hddddddddddddddddddddddh.
:dddddddddddddddddddddddddd:
/dddddddddddddddddddddddddddd/
@@ -22,6 +18,4 @@ hdddyo+ohddyosdddddddddho+oydddy++ohdddh
+dddddddddddddddddddddddddddddd+
/dddddddddddddddddddddddddddd/
:dddddddddddddddddddddddddd:
.hddddddddddddddddddddddh.
""")
.hddddddddddddddddddddddh.
+18
View File
@@ -0,0 +1,18 @@
{"match": "\"Alpine2\"*", "color": "4 7"}
.:::::::::::::::::::::.
.:::::::::::::::::::::::.
.:::::::::::::::::::::::::.
.:::::::::::::::::::::::::::.
.:::::::::${c2},db,${c1}::::::::::::::::.
.::::::::${c2},d%%%%b,${c1}::${c2},db,${c1}:::::::::.
.:::::::${c2},%%%%P'%%%b,d%%%b,${c1}::::::::.
.::::::${c2},%%%%P,${c1}:::${c2}`%%%b'^q%%b,${c1}:::::::.
'::::${c2},%%%%P,d|${c1}:::::${c2}`%%%b:'^%%b,${c1}:::::'
'::${c2}`%%%'${c1}:${c2}'q$|${c1}:::::::${c2}'q%%b'`q%%b'${c1}::'
':::::::::::::::::::::::::::::::'
':::::::::::::::::::::::::::::'
':::::::::::::::::::::::::::'
':::::::::::::::::::::::::'
':::::::::::::::::::::::'
':::::::::::::::::::::'
+7
View File
@@ -0,0 +1,7 @@
{"match": "\"alpine2_small\"*", "color": "4 7"}
${c1} /\ /\
/${c2}/ ${c1}\ \
/${c2}// ${c1}\ \
/${c2}// ${c1}\ \
${c2}// ${c1}\ \
\
+8
View File
@@ -0,0 +1,8 @@
{"match": "\"alpine3_small\"*", "color": "7"}
,db,
,d%%%%b, ,db,
,%%%%P'%%%b,d%%%b,
,%%%%P, `%%%b'^q%%b,
,%%%%P,d| `%%%b '^%%b,
`%%%' 'q$| 'q%%b'`q%%b
+7
View File
@@ -0,0 +1,7 @@
{"match": "\"alpine_small\"", "color": "4 7"}
${c1} /\ /\
/${c2}/ ${c1}\ \
/${c2}/ ${c1}\ \
/${c2}// ${c1}\ \
${c2}// ${c1}\ \
\
@@ -1,8 +1,4 @@
# This file is automatically generated. Please do not modify.
from . import AsciiArt
alter = AsciiArt(match=r'''"Alter"*''', color='6 6', ascii=r"""
{"match": "\"Alter\"*", "color": "6 6"}
${c1} %,
^WWWw
'wwwwww
@@ -22,6 +18,4 @@ ${c1} %,
@~:~~: ~:~~:~:(zltlltlO a,wwwwww
8~~:~~:~~~~:~~~~_1ltltu ,www
5~~:~~:~~:~~:~~:~~~_1ltq N,,
g~:~~:~~~:~~:~~:~:~~~~1q N,
""")
g~:~~:~~~:~~:~~:~:~~~~1q N,
+23
View File
@@ -0,0 +1,23 @@
{"match": "\"ALTLinux\"*", "color": "3 8 7"}
##############
######################
##########################
##+${c2}####${c1}#######################
#####${c2}#${c1}*${c2}###%+${c1}######################
########${c2}%${c1}*#${c2}%#####${c1}###################
##########${c2}##${c1}*#*${c2}#######%+${c1}##############
#############${c2}%#############%${c1}############
#############${c2}+################${c1}##########
##############${c2}################*${c1}#########
##############${c2}+################+${c1}########
###############${c2}##########${c1}###${c2}+##%${c1}########
###############${c2}+########${c1}######${c2}###${c1}#######
#############${c2}*####${c1}############${c2}%#+${c1}#######
############${c2}+###${c3}####${c1}##########${c2}%#*${c1}#######
##########${c2}###*${c3}######${c2}+#+${c1}#####${c2}+##*${c1}######
#########${c2}##%${c3}#####${c2}:%#####${c1}###${c2}###*${c1}#####
########${c2}%#+${c3}######${c2}#############${c1}####
#####${c2}##%:${c3}######${c2}:############${c1}##
##${c2}+##*${c3}########${c2}############${c1}
${c2}###${c3}#########${c2}##########${c1}
${c3}########${c2}######
@@ -1,8 +1,4 @@
# This file is automatically generated. Please do not modify.
from . import AsciiArt
amazon = AsciiArt(match=r'''"Amazon"*''', color='3 7', ascii=r"""
{"match": "\"Amazon\"*", "color": "3 7"}
${c1} `-/oydNNdyo:.`
`.:+shmMMMMMMMMMMMMMMmhs+:.`
-+hNNMMMMMMMMMMMMMMMMMMMMMMNNho-
@@ -21,6 +17,4 @@ dMMMMMMMMMMMMMMMMh yMMMMMMMMMMMMMMMMd
dMMMMMMMMMMMMMMMMh yMMMMMMMMMMMMMMMMd
.:+ydNMMMMMMMMMMMh yMMMMMMMMMMMNdy+:.
`.:+shNMMMMMh yMMMMMNhs+:``
`-+shy shs+:`
""")
`-+shy shs+:`
+11
View File
@@ -0,0 +1,11 @@
{"match": "\"Amazon Linux\"*|\"amzn\"*", "color": "7 38;5;178"}
, ${c2}#_${c1}
~\_ ${c2}####_${c1}
~~ \_${c2}#####\${c1}
~~ \${c2}###|${c1}
~~ \${c2}#/${c1} ___
~~ V~' '->
~~~ /
~~._. _/
_/ _/
_/m/'
+15
View File
@@ -0,0 +1,15 @@
{"match": "\"Amiga\"*", "color": "1 1 3 4 6 3 2"}
----.---
:-==.-==-
${c2} -=== ===:
===-:===.
${c3} -+++:=++=
=+++ +++.
${c6} .+++-=++=
${c4}.::. ::: ${c6} :**+ +**-
${c4} :--:.---. ${c6} .+**=-***.
${c5} :--- ---::${c6}***:***+
${c5} .---::-${c6}=##*.*##-
${c7} ----+${c6}##=:##*.
${c7} :-${c6}###-*##+
@@ -1,8 +1,4 @@
# This file is automatically generated. Please do not modify.
from . import AsciiArt
amogos = AsciiArt(match=r'''"AmogOS"*''', color='15 6', ascii=r"""
{"match": "\"AmogOS\"*", "color": "15 6"}
${c1} ___________
/ \
/ ${c2}______${c1} \
@@ -21,6 +17,4 @@ ${c1} ___________
| / ____/ |
\_________/ / |
\ __/
\_______/
""")
\_______/
@@ -1,8 +1,4 @@
# This file is automatically generated. Please do not modify.
from . import AsciiArt
anarchy = AsciiArt(match=r'''"Anarchy"*''', color='7 4', ascii=r"""
{"match": "\"Anarchy\"*", "color": "7 4", "foreground": [2]}
${c2}..${c1}
${c2}..${c1}
${c2}:..${c1}
@@ -30,6 +26,4 @@ anarchy = AsciiArt(match=r'''"Anarchy"*''', color='7 4', ascii=r"""
${c2}.${c1} ${c2}.:+++${c1}.
${c2}.:${c1}:
${c2}..${c1}
${c2}..${c1}
""")
${c2}..${c1}
@@ -1,8 +1,4 @@
# This file is automatically generated. Please do not modify.
from . import AsciiArt
android = AsciiArt(match=r'''"Android"*''', color='2 7', ascii=r"""
{"match": "\"Android\"*", "color": "2 7", "foreground": [2]}
${c1} -o o-
+hydNNNNdyh+
+mMMMMMMMMMMMMm+
@@ -20,6 +16,4 @@ ${c1} -o o-
`/++MMMMh++hMMMM++/`
MMMMo oMMMM
MMMMo oMMMM
oNMm- -mMNs
""")
oNMm- -mMNs
+7
View File
@@ -0,0 +1,7 @@
{"match": "\"android_small\"*", "color": "2 7"}
${c1} ;, ,;
';,.-----.,;'
,' ',
/ O O \
| |
'-----------------'
+21
View File
@@ -0,0 +1,21 @@
{"match": "\"anduinos\"*", "color": "6 4"}
${c1}+++++++++++
+++++++++++++++++++++
+++++++++++++++++++++++++++++++
=+++++++++++++++++++++++++++++++++++++++=
+++++++++++++++++++++++++++++++++++++++++++++
=++++++++++++++++++++++++++++++++++++++++++++
==+++++++++++++++++++++++++++++++++==
+++++++++++++++++++++++++++
${c2}**** ${c1}++=+++++++++++=++ ${c2}****
********** ${c1}+++++++ ${c2}**********
************** **************
**************** ****************
***********************
****** ************* ******
*********** *** ***********
*************** ***************
*************** ***************
*********************
***********
@@ -1,8 +1,4 @@
# This file is automatically generated. Please do not modify.
from . import AsciiArt
antergos = AsciiArt(match=r'''"Antergos"*''', color='4 6', ascii=r"""
{"match": "\"Antergos\"*", "color": "4 6", "foreground": [1]}
${c2} `.-/::/-``
.-/osssssssso/.
:osyysssssssyyys+-
@@ -21,6 +17,4 @@ dmmmdddddddhhhyso${c1}++++++${c2}shhhhhddddddmmmmh
-dmmmdddddddhhys${c1}o++++o${c2}shhhhdddddddmmmmd-
.smmmmddddddddhhhhhhhhhdddddddddmmmms.
`+ydmmmdddddddddddddddddddmmmmdy/.
`.:+ooyyddddddddddddyyso+:.`
""")
`.:+ooyyddddddddddddyyso+:.`
@@ -1,8 +1,4 @@
# This file is automatically generated. Please do not modify.
from . import AsciiArt
antix = AsciiArt(match=r'''"antiX"*''', color='1 7 3', ascii=r"""
{"match": "\"antiX\"*", "color": "1 7 3"}
${c1}
\
, - ~ ^ ~ - \ /
@@ -15,6 +11,4 @@ ${c1}
\,_/\_/ | |_/|_/|_/_/ \,
, / ,\
, / , ' \
' - , _ _ _ , '
""")
' - , _ _ _ , '
+22
View File
@@ -0,0 +1,22 @@
{"match": "\"AnushOS\"*", "color": "7 8 3 6 1"}
${c4}#######################
${c4}# ${c2}##### ${c4}#
${c4}# ${c2}####### ${c4}#
${c4}# ${c2}##${c5}O${c2}#${c5}O${c2}## ${c4}#
${c4}# ${c2}#${c3}#####${c2}# ${c4}#
${c4}# ${c2}##${c1}##${c3}###${c1}##${c2}## ${c4}#
${c4}# ${c2}#${c1}##########${c2}## ${c4}#
${c4}# ${c2}#${c1}############${c2}## ${c4}#
${c4}# ${c2}#${c1}######${c5}A_O${c1}####${c2}### ${c4}#
${c4}# ${c3}##${c2}#${c1}############${c2}##${c3}## ${c4}#
${c4}#${c3}######${c2}#${c1}#######${c2}#${c3}######${c4}#
${c4}#${c3}#######${c2}#${c1}#####${c2}#${c3}#######${c4}#
${c4}# ${c3}#####${c2}#######${c3}##### ${c4}#
${c4}#######################
${c4}#${c5}╔═╗╔╗╔╦ ╦╔═╗╦ ╦╔═╗╔═╗${c4}#
${c4}#${c5}╠═╣║║║║ ║╚═╗╠═╣║ ║╚═╗${c4}#
${c4}#${c5}╩ ╩╝╚╝╚═╝╚═╝╩ ╩╚═╝╚═╝${c4}#
${c4}#######################
${c4}# ${c3}WWW.ANUSHOS.ORG ${c4}#
${c4}#######################
@@ -1,8 +1,4 @@
# This file is automatically generated. Please do not modify.
from . import AsciiArt
aosc_os = AsciiArt(match=r'''"AOSC OS"*''', color='4 0 1 3', ascii=r'''
{"match": "\"AOSC OS\"*", "color": "4 0 1 3"}
${c2} __
${c2}gpBBBBBBBBBP
${c2}_gBBBBBBBBBRP
@@ -19,6 +15,4 @@ ${c2} __
${c3}_gBNNNNNNNNNNNNNNNNNP"
${c3}_wNNNNNNNNNNNNNNNNNNNM^
${c3}""Y^^MNNNNNNNNNNNNP`
${c3}`"""""""
''')
${c3}`"""""""
+21
View File
@@ -0,0 +1,21 @@
{"match": "\"Aosc OS_old\"*|\"aoscos_old\"*", "color": "7"}
.:+syhhhhys+:.
.ohNMMMMMMMMMMMMMMNho.
`+mMMMMMMMMMMmdmNMMMMMMMMm+`
+NMMMMMMMMMMMM/ `./smMMMMMN+
.mMMMMMMMMMMMMMMo -yMMMMMm.
:NMMMMMMMMMMMMMMMs .hMMMMN:
.NMMMMhmMMMMMMMMMMm+/- oMMMMN.
dMMMMs ./ymMMMMMMMMMMNy. sMMMMd
-MMMMN` oMMMMMMMMMMMN: `NMMMM-
/MMMMh NMMMMMMMMMMMMm hMMMM/
/MMMMh NMMMMMMMMMMMMm hMMMM/
-MMMMN` :MMMMMMMMMMMMy. `NMMMM-
dMMMMs .yNMMMMMMMMMMMNy/. sMMMMd
.NMMMMo -/+sMMMMMMMMMMMmMMMMN.
:NMMMMh. .MMMMMMMMMMMMMMMN:
.mMMMMMy- NMMMMMMMMMMMMMm.
+NMMMMMms/.` mMMMMMMMMMMMN+
`+mMMMMMMMMNmddMMMMMMMMMMm+`
.ohNMMMMMMMMMMMMMMNho.
.:+syhhhhys+:.
+19
View File
@@ -0,0 +1,19 @@
{"match": "\"Aosc OS/Retro\"*|\"aoscosretro\"*", "color": "4 7"}
${c2} .........
...................
.....................${c1}################${c2}
.............. ....${c1}################${c2}
.............. ...${c1}################${c2}
............. ..${c1}****************${c2}
............ . .${c1}****************${c2}
........... ... ${c1}................${c2}
.......... ..... ${c1}...............${c2}
......... ....... ...
.${c3}...... ${c2}.
${c3}..... .....${c2}.... ${c4}...........
${c3}.... ......${c2}. ${c4}...........
${c3}... ....... ${c4}...........
${c3}................ ${c4}***********
${c3}................ ${c4}###########
${c3}****************
${c3}################
@@ -0,0 +1,10 @@
{"match": "\"Aosc OS/Retro_small\"*|\"aoscosretro_small\"*", "color": "4 7"}
${c2} _____ ${c1}_____${c2}
-' '-${c1}| |${c2}
/ ___ ${c1}| |${c2}
| / _ \${c1}|_____|${c2}
' / /_\ \
\ / _____ \${c4}___
${c3}|${c2}/_/ ${c3}| ${c4}| |
${c3}| | ${c4}|___|
${c3}|_____|
@@ -0,0 +1,5 @@
{"match": "\"Aperio GNU/Linux\"*", "color": "255"}
${c2}
_.._ _ ._.. _
(_][_)(/,[ |(_)
| GNU/Linux
@@ -1,8 +1,4 @@
# This file is automatically generated. Please do not modify.
from . import AsciiArt
aperture = AsciiArt(match=r'''"Aperture"*''', color='6 6 7 1', ascii=r"""
{"match": "\"Aperture\"*", "color": "6 6 7 1"}
${c1} .,-:;//;:=,
. :H@@@MM@M#H/.,+%;,
,/X+ +M@@M@MM%=,-%HMMM@X/,
@@ -22,6 +18,4 @@ ${c1} .,-:;//;:=,
=XMMM@MM@MM#H;,-+HMM@M+ /MMMX=
=%@M@M#@$-.=$@MM@@@M; %M%=
,:+$+-,/H#MMMMMMM@= =,
=++%%%%+/:-.
""")
=++%%%%+/:-.
+18
View File
@@ -0,0 +1,18 @@
{"match": "\"Apple\"*", "color": "2 3 1 1 5 4"}
..'
,xNMM.
.OMMMMo
lMM"
.;loddo:. .olloddol;.
cKMMMMMMMMMMNWMMMMMMMMMM0:
${c2}.KMMMMMMMMMMMMMMMMMMMMMMMWd.
XMMMMMMMMMMMMMMMMMMMMMMMX.
${c3};MMMMMMMMMMMMMMMMMMMMMMMM:
:MMMMMMMMMMMMMMMMMMMMMMMM:
${c4}.MMMMMMMMMMMMMMMMMMMMMMMMX.
kMMMMMMMMMMMMMMMMMMMMMMMMWd.
${c5}'XMMMMMMMMMMMMMMMMMMMMMMMMMMk
'XMMMMMMMMMMMMMMMMMMMMMMMMK.
${c6}kMMMMMMMMMMMMMMMMMMMMMMd
;KMMMMMMMWXXWMMMMMMMk.
"cooc*" "*coo'"
+8
View File
@@ -0,0 +1,8 @@
{"match": "\"Apple_small\"*", "color": "2 3 1 5 4"}
${c1} .:'
__ :'__
${c2} .'`__`-'__``.
${c3}:__________.-'
${c4}:_________:
:_________`-;
${c5} `.__.-.__.'
@@ -1,8 +1,4 @@
# This file is automatically generated. Please do not modify.
from . import AsciiArt
apricity = AsciiArt(match=r'''"Apricity"*''', color='4 7 1', ascii=r"""
{"match": "\"Apricity\"*", "color": "4 7 1"}
${c2} ./o-
``...`` `:. -/:
`-+ymNMMMMMNmho-` :sdNNm/
@@ -20,6 +16,4 @@ MMMMMM/`.-/ohmNMMMMMMy-
MMMMMMNmNNMMMMMMMMmo.
MMMMMMMMMMMMMMMms:`
MMMMMMMMMMNds/.
dhhyys+/-`
""")
dhhyys+/-`
@@ -1,8 +1,4 @@
# This file is automatically generated. Please do not modify.
from . import AsciiArt
arch = AsciiArt(match=r'''"Arch"*''', color='6 6 7 1', ascii=r"""
{"match": "\"Arch\"*", "color": "6 6 7 1"}
${c1} -`
.o+`
`ooo/
@@ -21,6 +17,4 @@ ${c2} .oossssso-````/ossssss+`
`/ossssso+/:- -:/+osssso+-
`+sso+:-` `.-/+oso:
`++:. `-/+/
.` `/
""")
.` `/
+20
View File
@@ -0,0 +1,20 @@
{"match": "\"arch2\"*", "color": "6 6"}
▟█▙
▟███▙
▟█████▙
▟███████▙
▂▔▀▜██████▙
▟██▅▂▝▜█████▙
▟█████████████▙
▟███████████████▙
▟█████████████████▙
▟███████████████████▙
${c2} ▟█████████▛▀▀▜████████▙
▟████████▛ ▜███████▙
▟█████████ ████████▙
▟██████████ █████▆▅▄▃▂
▟██████████▛ ▜█████████▙
▟██████▀▀▀ ▀▀██████▙
▟███▀▘ ▝▀███▙
▟▛▀ ▀▜▙
+20
View File
@@ -0,0 +1,20 @@
{"match": "\"arch3\"*", "color": "6 6"}
.
/ \
/ \
/ \
/ \
/>, \
/ `*. \
/ ` \
/ \
/ \
${c2} / ,.-+-.. \
/ ,/' `\. \
/ .|' `|. _ \
/ :|. ,|; `+.\
/ .\: ;/, "<\
/ __,--+" "+--.__ \
/ _,+'" "'+._ \
/,-' `-.\
' '
@@ -1,8 +1,4 @@
# This file is automatically generated. Please do not modify.
from . import AsciiArt
arch_old = AsciiArt(match=r'''"arch_old"''', color='6 7 1', ascii=r"""
{"match": "\"arch_old\"", "color": "6 7 1"}
${c1} __
_=(SDGJT=_
_GTDJHGGFCVS)
@@ -18,6 +14,4 @@ ${c1}JSNRVW'${c2} __+MNAEC${c1}\IOI,${c2}\BN'
${c1}HELK['${c2} __,=OFFXCBGHC${c1}\FD)
${c1}?KGHE ${c2}\_-#DASDFLSV='${c1} 'EF
'EHTI !H
`0F' '!
""")
`0F' '!
+8
View File
@@ -0,0 +1,8 @@
{"match": "\"arch_small\"", "color": "6 7 1"}
${c1} /\
/ \
/\ \
${c2} / \
/ ,, \
/ | | -\
/_-'' ''-_\
@@ -1,8 +1,4 @@
# This file is automatically generated. Please do not modify.
from . import AsciiArt
archbox = AsciiArt(match=r'''"ArchBox"*''', color='2 7 1', ascii=r"""
{"match": "\"ArchBox\"*", "color": "2 7 1"}
${c1} ...:+oh/:::..
..-/oshhhhhh` `::::-.
.:/ohhhhhhhhhhhh` `-::::.
@@ -21,6 +17,4 @@ ${c1} ...:+oh/:::..
/:::+`hhhhoos` `hhhhhhhhhhhhhhhhhs+`
`--/:` /: `hhhhhhhhhhhho/-
-/:. `hhhhhhs+:-`
::::/ho/-`
""")
::::/ho/-`
@@ -1,8 +1,4 @@
# This file is automatically generated. Please do not modify.
from . import AsciiArt
archcraft = AsciiArt(match=r'''"Archcraft"*''', color='6 1 2 3 4 5', ascii=r"""
{"match": "\"Archcraft\"*", "color": "6 1 2 3 4 5"}
${c1}⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄${c1}⢰⡆${c1}⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄
${c2}⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄${c1}⢠⣿⣿⡄${c2}⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄
${c3}⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄${c1}⢀⣾⣿⣿⣿⡀${c3}⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄
@@ -22,6 +18,4 @@ ${c4}⠄⠄⠄⠄${c1}⢀⣾⣿⣿⣿⣿⣿⣿⣷⣤⡀${c4}⠄⠄⠄${c1}⠻⣿
${c5}⠄⠄⠄${c1}⢠⣾⣿⣿⣿⣿⣿⣿⣿⣿⣿⠏${c5}⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄${c1}⢿⣿⣿⣿⣿⣿⣿⣿⣿⣦⡀${c5}⠄⠄⠄
${c6}⠄⠄${c1}⢠⣿⣿⣿⣿⣿⣿⣿⡿⠟⠋⠁${c6}⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄${c1}⠙⠻⣿⣿⣿⣿⣿⣿⣿⣿⡄${c6}⠄⠄
${c1}⠄${c1}⣠⣿⣿⣿⣿⠿⠛⠋⠁${c1}⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄${c1}⠉⠙⠻⢿⣿⣿⣿⣿⣆${c1}⠄
${c1}⡰⠟⠛⠉⠁${c2}⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄${c1}⠉⠙⠛⠿⢆
""")
${c1}⡰⠟⠛⠉⠁${c2}⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄${c1}⠉⠙⠛⠿⢆
@@ -1,9 +1,5 @@
# This file is automatically generated. Please do not modify.
from . import AsciiArt
archcraft_ascii = AsciiArt(match=r'''"archcraft_ascii"*''', color='6 1 2 3 4 5', ascii=r"""
${c1} -o\
{"match": "\"Archcraft2\"*", "color": "6"}
-o\
:ooo:
.ooooo.
ooooooo.
@@ -23,5 +19,3 @@ ${c1} -o\
.+osossos+-` `-+osososs+.
:sss+=-:` `:-=+ssss:
:=-:` `-=+:
""")
@@ -0,0 +1,21 @@
{"match": "\"archcraft_ascii\"*", "color": "6 1 2 3 4 5"}
${c1} -o\
:ooo:
.ooooo.
ooooooo.
+oooooooo.
-oooooooooo.
--:-+oooooooo.
yooo+=+sooooooo.
yoooooosooooooooo.
y+ooooooooooooooooo.
yoooooooooooooooooooo`
yoooooo+oo= :oo++ooooo`
:oooooo. +ooooo-
-ooooooo. .::. +ooosoo=
-oooooo` .oooo` +os-=o=
=ooooooo=: `oo+ :=ooo=--`.
+ooooooooos. .=sooooooo+-
.+osossos+-` `-+osososs+.
:sss+=-:` `:-=+ssss:
:=-:` `-=+:
@@ -1,8 +1,4 @@
# This file is automatically generated. Please do not modify.
from . import AsciiArt
archcraft_minimal = AsciiArt(match=r'''"archcraft_minimal"*''', color='6 1 2 3 4 5', ascii=r"""
{"match": "\"archcraft_minimal\"*", "color": "6 1 2 3 4 5"}
${c1} ⢰⡆
⢠⣿⣿⡄
⢀⣾⣿⣿⣿⡀
@@ -22,6 +18,4 @@ ${c1} ⢰⡆
⢠⣾⣿⣿⣿⣿⣿⣿⣿⣿⣿⠏ ⢿⣿⣿⣿⣿⣿⣿⣿⣿⣦⡀
⢠⣿⣿⣿⣿⣿⣿⣿⡿⠟⠋⠁ ⠙⠻⣿⣿⣿⣿⣿⣿⣿⣿⡄
⣠⣿⣿⣿⣿⠿⠛⠋⠁ ⠉⠙⠻⢿⣿⣿⣿⣿⣆
⡰⠟⠛⠉⠁ ⠉⠙⠛⠿⢆
""")
⡰⠟⠛⠉⠁ ⠉⠙⠛⠿⢆
@@ -1,8 +1,4 @@
# This file is automatically generated. Please do not modify.
from . import AsciiArt
archlabs = AsciiArt(match=r'''"ARCHlabs"*''', color='6 6 7 1', ascii=r"""
{"match": "\"ARCHlabs\"*", "color": "6 6 7 1"}
${c1} 'c'
'kKk,
.dKKKx.
@@ -23,6 +19,4 @@ ${c1} 'c'
'xKXXXXK0kdl:. ${c4}.ok; ${c1}.cdk0KKXXXKx'
'xKK0koc,.. ${c4}'c, ${c1} ..,cok0KKk,
,xko:'. ${c4}.. ${c1} .':okx;
.,'. .',.
""")
.,'. .',.
@@ -1,8 +1,4 @@
# This file is automatically generated. Please do not modify.
from . import AsciiArt
archmerge = AsciiArt(match=r'''"ArchMerge"*''', color='6 6 7 1', ascii=r"""
{"match": "\"ArchMerge\"*", "color": "6 6 7 1"}
${c1} y:
sMN-
+MMMm`
@@ -22,6 +18,4 @@ ${c1} y:
-NMMMMMMMMMh `mNMMMMMMMMd`
/NMMMNds+:.` `-/oymMMMm.
+Mmy/. `:smN:
/+. -o.
""")
/+. -o.
@@ -1,8 +1,4 @@
# This file is automatically generated. Please do not modify.
from . import AsciiArt
archstrike = AsciiArt(match=r'''"ArchStrike"*''', color='8 6', ascii=r"""
{"match": "\"ArchStrike\"*", "color": "8 6", "foreground": [2]}
${c1} *
**.
****
@@ -19,6 +15,4 @@ ${c1} *
****${c2}/${c1}**** ${c2}/////${c1}***${c2}/${c1}****
******${c2}/${c1}*** ${c2}//// ${c1}**${c2}/${c1}******
********${c2}/${c1}* ${c2}/// ${c1}*${c2}/${c1}********
,****** ${c2}// ______ / ${c1}******,
""")
,****** ${c2}// ______ / ${c1}******,
+21
View File
@@ -0,0 +1,21 @@
{"match": "\"arco\"*|\"arcolinux\"*", "color": "4 7"}
/-
ooo:
yoooo/
yooooooo
yooooooooo
yooooooooooo
.yooooooooooooo
.oooooooooooooooo
.oooooooarcoooooooo
.ooooooooo-oooooooooo
.ooooooooo- oooooooooo
:ooooooooo. :ooooooooo
:ooooooooo. :ooooooooo
:oooarcooo .oooarcooo
:ooooooooy .ooooooooo
${c1}:ooooooooo ${c2}/ooooooooooooooooooo
${c1}:ooooooooo ${c2}.-ooooooooooooooooo.
${c1}ooooooooo- ${c2}-ooooooooooooo.
${c1}ooooooooo- ${c2}.-oooooooooo.
${c1}ooooooooo. ${c2}-ooooooooo
+12
View File
@@ -0,0 +1,12 @@
{"match": "\"arco_small\"*|\"arcolinux_small\"*", "color": "4 7"}
A
ooo
ooooo
ooooooo
ooooooooo
ooooo ooooo
ooooo ooooo
ooooo ooooo
ooooo ${c2}<oooooooo>${c1}
ooooo ${c2}<oooooo>${c1}
ooooo ${c2}<oooo>
@@ -1,8 +1,4 @@
# This file is automatically generated. Please do not modify.
from . import AsciiArt
arcolinux = AsciiArt(match=r'''"ArcoLinux"*''', color='7 4', ascii=r"""
{"match": "\"ArcoLinux\"*", "color": "7 4"}
${c2} /-
ooo:
yoooo/
@@ -22,6 +18,4 @@ ${c2} /-
:ooooooooo ${c1}.-ooooooooooooooooo.${c2}
ooooooooo- ${c1}-ooooooooooooo.${c2}
ooooooooo- ${c1}.-oooooooooo.${c2}
ooooooooo. ${c1}-ooooooooo${c2}
""")
ooooooooo. ${c1}-ooooooooo${c2}
@@ -0,0 +1,12 @@
{"match": "\"arcolinux_small\"*", "color": "7 4"}
${c2} A
ooo
ooooo
ooooooo
ooooooooo
ooooo ooooo
ooooo ooooo
ooooo ooooo
ooooo ${c1}<oooooooo>${c2}
ooooo ${c1}<oooooo>${c2}
ooooo ${c1}<oooo>${c2}
@@ -1,8 +1,4 @@
# This file is automatically generated. Please do not modify.
from . import AsciiArt
arkane = AsciiArt(match=r'''"Arkane"*''', color='7 130 237', ascii=r"""
{"match": "\"Arkane\"*", "color": "7 130 237", "foreground": [1]}
${c3} .:..
..:::......
${c2}.${c3} .${c2}.${c3}.....
@@ -25,6 +21,4 @@ ${c2}.-==+++***++*${c1}*#########${c3}=:::.
${c2}.-=++++*++++**${c1}#######%%###${c3}=
${c2}.:==++++++**${c1}#############${c3}:
${c2}.${c3}-+*++*+++==${c1}###${c3}+
-${c1}*+${c3}:
""")
-${c1}*+${c3}:
+12
View File
@@ -0,0 +1,12 @@
{"match": "\"Armbian\"*", "color": "7 1"}
..
`:]x**j-,'
.,+t***********z\<"
?******************;
'*n` .'`^,;;,^`'. ,cc.
-<. .[l
// ^^ ^^ \
!^ ${c2}^^${c1} ":
'tt}` ${c2}!~]rj_${c1} ")t/.
Itttt?' ${c2}~~]rr]${c1} `{tttt,
\tttttt!""I${c2}_]r(${c1}
+15
View File
@@ -0,0 +1,15 @@
{"match": "\"Armbian2\"*", "color": "1"}
█ █ █ █ █ █ █ █ █ █ █
███████████████████████
▄▄██ ██▄▄
▄▄██ ███████████ ██▄▄
▄▄██ ██ ██ ██▄▄
▄▄██ ██ ██ ██▄▄
▄▄██ ██ ██ ██▄▄
▄▄██ █████████████ ██▄▄
▄▄██ ██ ██ ██▄▄
▄▄██ ██ ██ ██▄▄
▄▄██ ██ ██ ██▄▄
▄▄██ ██▄▄
███████████████████████
█ █ █ █ █ █ █ █ █ █ █
+16
View File
@@ -0,0 +1,16 @@
{"match": "\"arse\"*|\"arselinux\"*|\"arse-linux\"*", "color": "4 7"}
⣀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⣶⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸⣿⠀⠀⠀⠀⠀⠀⣴⣶⠀⠀⠀⠀⠀
⢸⣿⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸⣿⣄⠀⠀⠀⠀⣼⠟⠁⠀⠀⢀⣀⠀
⢸⣿⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⡀⠀⢀⣤⡀⠀⠀⠀⠉⢻⣷⡄⠀⠀⠁⠀⢀⣤⣾⡿⠟⠀
⢸⣿⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠙⢿⣷⣿⠏⠀⠀⠀⠀⠀⠀⠹⣿⡄⠀⠀⠀⠙⠉⠁⠀⠀⠀
⢸⣿⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠹⣿⡄⠀⠀⠀⠀⠀⠀⠀⢹⣿⠀⠀⠀⠀⠠⣶⣶⣶⡶
⢸⣿⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢹⣿⠀⠀⠀⠀⠀⠀⠀⠀⣿⡇⠀⠀⠀⠀⠀⠀⠀⠀
⢸⣿⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸⣿⠀⠀⠀⠀⠀⠀⠀⢠⣿⠁⠀⠀⠀⠀⠀⠀⠀⠀
⢸⣿⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸⣿⠂⠀⠀⠀⠀⠀⢀⣾⡏⠀⠀⠀⠀⠀⠀⠀⠀⠀
⢸⣿⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢠⣿⠇⠀⠀⠀⠀⠀⣠⣾⠟⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⢸⣿⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣠⣴⣿⣇⣀⣀⣀⣠⣴⣾⣿⡏⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⢸⣿⠀⠀⠀⠀⠀⣤⣤⣴⣶⣾⠿⠟⣿⡏⠙⠛⠛⠛⠋⠉⢀⣿⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⣿⡄⠀⠀⠀⠀⠈⠉⠉⠀⠀⠀⠀⣿⡇⠀⠀⠀⠀⠀⠀⢸⣿⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⣿⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢿⠇⠀⠀⠀⠀⠀⠀⠘⠿⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠈⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
@@ -1,8 +1,4 @@
# This file is automatically generated. Please do not modify.
from . import AsciiArt
arselinux = AsciiArt(match=r'''"ArseLinux"*''', color='4 7', ascii=r"""
{"match": "\"ArseLinux\"*", "color": "4 7"}
${c1}
⣀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⣶⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸⣿⠀⠀⠀⠀⠀⠀⣴⣶⠀⠀⠀⠀⠀
@@ -18,6 +14,4 @@ ${c1}
⢸⣿⠀⠀⠀⠀⠀⣤⣤⣴⣶⣾⠿⠟⣿⡏⠙⠛⠛⠛⠋⠉⢀⣿⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⣿⡄⠀⠀⠀⠀⠈⠉⠉⠀⠀⠀⠀⣿⡇⠀⠀⠀⠀⠀⠀⢸⣿⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⣿⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢿⠇⠀⠀⠀⠀⠀⠀⠘⠿⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠈⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
""")
⠀⠈⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
@@ -1,8 +1,4 @@
# This file is automatically generated. Please do not modify.
from . import AsciiArt
artix = AsciiArt(match=r'''"Artix"*''', color='6 6 7 1', ascii=r"""
{"match": "\"Artix\"*", "color": "6 6 7 1"}
${c1} '
'o'
'ooo'
@@ -22,6 +18,4 @@ ${c1} '
'ooooxooi::'` .:iiixkxxo'
'ooooi:'` `'';ioxxo'
'i:'` '':io'
'` `'
""")
'` `'
+9
View File
@@ -0,0 +1,9 @@
{"match": "\"artix2_small\"*", "color": "6"}
/\
/ \
/`'.,\
/ ',
/ ,`\
/ ,.'`. \
/.,'` `'.\
@@ -1,8 +1,4 @@
# This file is automatically generated. Please do not modify.
from . import AsciiArt
artix_small = AsciiArt(match=r'''"artix_small"*''', color='6 6 7 1', ascii=r"""
{"match": "\"artix_small\"*", "color": "6 6 7 1"}
${c1} '
'A'
'ooo'
@@ -15,6 +11,4 @@ ${c1} '
'ookxxkoo'` .'oo'
'ooxoo'` .:ooxxo'
'io'` `'oo'
'` `'
""")
'` `'
@@ -1,8 +1,4 @@
# This file is automatically generated. Please do not modify.
from . import AsciiArt
arya = AsciiArt(match=r'''"Arya"*''', color='2 1', ascii=r"""
{"match": "\"Arya\"*", "color": "2 1"}
${c1} `oyyy/${c2}-yyyyyy+
${c1} -syyyy/${c2}-yyyyyy+
${c1} .syyyyy/${c2}-yyyyyy+
@@ -17,6 +13,4 @@ ${c1} +yyyyyys :yyyyyy/${c2}-yyyyyy+
${c1} .oyyyyyyo. :yyyyyy/${c2}-yyyyyy+ ---------
${c1} .syyyyyy+` :yyyyyy/${c2}-yyyyy+-+syyyyyyyy
${c1} -syyyyyy/ :yyyyyy/${c2}-yyys:.syyyyyyyyyy
${c1}:syyyyyy/ :yyyyyy/${c2}-yyo.:syyyyyyyyyyy
""")
${c1}:syyyyyy/ :yyyyyy/${c2}-yyo.:syyyyyyyyyyy
@@ -1,8 +1,4 @@
# This file is automatically generated. Please do not modify.
from . import AsciiArt
asahi = AsciiArt(match=r'''"Asahi"*''', color='3 2 1 8 7 6 4', ascii=r"""
{"match": "\"Asahi\"*", "color": "3 2 1 8 7 6 4", "foreground": [5]}
${c1} ## ${c2}**
${c1}*####${c2}****.
${c1}###${c2},
@@ -20,6 +16,4 @@ ${c3}(((((((((((((((((((((${c5}@@@${c6}&%&${c5}@@@%${c4},..........
${c3}/((((((((((((${c5}@@@@@@/${c4}.../&&
${c3}.(((((((((${c5}@@@@(${c4}....
${c3}/(((((${c5}@@#${c4}...
${c3}.((${c4}&,
""")
${c3}.((${c4}&,
+19
View File
@@ -0,0 +1,19 @@
{"match": "\"asahi2\"*|\"asahi-linux2\"*", "color": "3 6 1 1 7 8 6"}
${c1}_wwM ${c2}_ww
${c1}MMM${c2}MMMM
${c1}MM
${c3}_ww##############yy_
${c4}wMMMMM${c3}###########${c4}MMMMm
${c4},MMMMMMMMM${c3}######${c4}MMMMMMMM0_
${c4}wMMMMMMMMMMMMM${c5}MM${c6}0MMMMMMMMMMm
${c4},MMMMMMMMMMMMMMM${c5}MMMM${c6}0MMMMMMMMM0,
${c4}wMMMMMMMMMMMMMMMM${c5}MMMMM0${c6}MMMMMMMMMMb
${c4}_MMMMMMMMMMMMMMMMMM${c5}MMMMMMM0${c6}MMMMMMMMM0,
${c4}_MMMMMMMMMMMMMMMMMMM${c5}MMMM${c7}M${c5}MMMW${c6}MMMMMMMMMM_
${c4}_MMMMMMMMMMMMMMMMMMMM${c5}MMMM${c7}M0${c5}MMMW${c6}MMMMMMMMMM_
${c4}~MMMMMMMMMMMMMMMMM${c5}MMMM${c7}M${c5}MMMW${c6}MMMMM00~
${c4}~MMMMMMMMMMMMM${c5}MMMWMMM${c6}0MM${c5}MMM${c6}~
${c4}~MMMMMMMMMM${c5}MMMMM${c6}0MMM~~
${c4}~MMMMMM${c5}MMM${c6}0MM~
${c4}~MM${c5}M${c6}@~
${c4}M
+19
View File
@@ -0,0 +1,19 @@
{"match": "\"aster\"*", "color": "6"}
...''...
.;oOXWMWNXXXNMMN0d:.
.oXMWOo;.. ..:oO;
;KMWx, co,
'KMNl dMMW.
oMMx xMMMMk
xMM: dMMMMMM;
cMMl dMMMMMMMW
NMK xMMMx::dXMx
,MMl xMMN' .o.
cMM; dMMW'
;MMc oMMW,
WMK dMMW, ccccccc.
lMMl oMMM; ooooooo.
OMMc ...
xMMx
;XMN:
,.
@@ -1,8 +1,4 @@
# This file is automatically generated. Please do not modify.
from . import AsciiArt
asteroidos = AsciiArt(match=r'''"AsteroidOS"*''', color='160 208 202 214', ascii=r"""
{"match": "\"AsteroidOS\"*", "color": "160 208 202 214"}
${c1} ***
${c1} *****
${c1} **********
@@ -19,6 +15,4 @@ ${c3} /######## ########
${c4} #######%#######
${c4} (#%%%%%%%#
${c4} %%%%%
${c4} %%%
""")
${c4} %%%
@@ -1,8 +1,4 @@
# This file is automatically generated. Please do not modify.
from . import AsciiArt
astos = AsciiArt(match=r'''"astOS"*''', color='8', ascii=r"""
{"match": "\"astOS\"*", "color": "8"}
${c1} oQA#$%UMn
H 9
G #
@@ -25,6 +21,4 @@ uURF$##Bv nKWB$%ABc aM@3R@D@b
8 M @ O # %
% & G U @ @
& @ # % % #
!HGN@MNCf t&$9#%HQr ?@G#6S@QP
""")
!HGN@MNCf t&$9#%HQr ?@G#6S@QP
+23
View File
@@ -0,0 +1,23 @@
{"match": "\"Astra\"*|\"Astra Linux\"*|\"astralinux\"*", "color": "1 7"}
AA
AaaA
Aa${c2}/\${c1}aA
${c1} Aa${c2}/${c1}aa${c2}\${c1}aA
${c1} Aa${c2}/${c1}aAAa${c2}\${c1}aA
${c1} aA${c2}/${c1}aaAAaa${c2}\${c1}Aa
${c1} aA${c2}/${c1}aaAAAAaa${c2}\${c1}Aa
${c1} aaaaaaAAAAa${c2}/${c1}aaAAAAAAaa${c2}\${c1}aAAAAaaaaa
${c1}aAAa${c2}-----${c1}aaaaaAAAAAAAAAAaaaaa${c2}-----${c1}aAAa
${c1} aAA${c2}\ ${c1}aAAAAAAAAAAAAAAAAAAAAAAa${c2} /${c1}AAa
${c1} aAa${c2}\${c1}aAAA${c2}\${c1}AAAA${c2}\${c1}AAAA${c2}\${c1}AAA${c2}\${c1}AAa${c2}/${c1}aAa
${c1} aAa${c2}\${c1}aA${c2}\${c1}AAA${c2}\${c1}AAA${c2}\${c1}AA${c2}\/${c1}aAa
${c1} aAA${c2}\${c1}aA${c2}\${c1}AAA${c2}\${c1}AAA${c2}\${c1}Aa${c2}/${c1}AAa
${c1} aA${c2}\${c1}aA${c2}\${c1}AAA${c2}\${c1}AAA${c2}\/${c1}Aa
${c1} aA${c2}/${c1}AA${c2}\\${c1}AA${c2}\\${c1}AA${c2}\\${c1}Aa
${c1} aA${c2}/\${c1}AAa${c2}\\${c1}Aa${c2}\\${c1}Aa${c2}\\${c1}Aa
${c1} aA${c2}/\${c1}AAa${c2}\/\${c1}a${c2}\\${c1}Aa${c2}\${c1}Aa
${c1} aA${c2}/${c1}a${c2}\\${c1}Aa${c2}\/${c1}AA${c2}\\\${c1}Aa${c2}\${c1}Aa
${c1} aA${c2}/${c1}aA${c2}\/${c1}aAa aAa${c2}\\${c1}Aa${c2}\${c1}Aa
${c1} aA${c2}/\${c1}A${c2}\/${c1}Aa aA${c2}\${c1}A${c2}\${c1}Aa
${c1} A${c2}|/${c1}aaAa aAaa${c2}\|${c1}A
${c1} aAaa aaAa
@@ -1,8 +1,4 @@
# This file is automatically generated. Please do not modify.
from . import AsciiArt
astra_linux = AsciiArt(match=r'''"Astra Linux"*''', color='160 231', ascii=r"""
{"match": "\"Astra Linux\"*", "color": "160 231", "foreground": [2]}
${c1} AA
${c1} AaaA
${c1} Aa${c2}/\${c1}aA
@@ -24,6 +20,4 @@ ${c1} aA${c2}/${c1}a${c2}\\\${c1}Aa${c2}\/${c1}AA${c2}\\\\\${c1}Aa${c2}\\
${c1} aA${c2}/${c1}aA${c2}\\/${c1}aAa aAa${c2}\\\${c1}Aa${c2}\${c1}Aa
${c1} aA${c2}/\${c1}A${c2}\/${c1}Aa aA${c2}\\${c1}A${c2}\\${c1}Aa
${c1} A${c2}|/${c1}aaAa aAaa${c2}\|${c1}A
${c1} aAaa aaAa
""")
${c1} aAaa aaAa
@@ -1,9 +1,5 @@
# This file is automatically generated. Please do not modify.
from . import AsciiArt
januslinux = AsciiArt(match=r'''"januslinux"*|"janus"*|"Ataraxia Linux"*|"Ataraxia"*''', color='4 5 6 2', ascii=r"""
${c1} 'l:
{"match": "\"Ataraxia Linux\"*|\"Ataraxia\"*", "color": "4 5"}
'l:
loooooo
loooo coooool
looooooooooooooooooool
@@ -27,5 +23,3 @@ ${c1} cooo: ${c2}coooooooooooooooooool
:oooool, coool:, looool:,
looool: ooooooooooooooo:
cooolc .ooooooooooool
""")
+25
View File
@@ -0,0 +1,25 @@
{"match": "\"Athena\"*", "color": "7 3"}
${c1} . ..
${c1} :####: ####.
${c1} .################
${c1} :##################
${c1}.###################.
${c1}######## #######
${c1}####### ${c2}####${c1} #####
${c1}:#######. ####
${c1} ######### ${c2}#${c1} ## #
${c1} ####### ${c2}##${c1} ####
${c1}######## ${c2}####${c1} #######
${c1}######## ${c2}#####${c1} ########
${c1}######## ${c2}#######${c1} #######
${c1} ####### ${c2}########${c1} #######
${c1} ######## ${c2}#########${c1} ######
${c1} ######## ${c2}#########${c1} #####
${c1} ####### ${c2}#########${c1} ####
${c1} ####### ${c2}#########${c1} ##
${c1} ####### ${c2}########${c1} ##
${c1} ###### ${c2}########${c1} #
${c1} ### ${c2}#######${c1}
${c1} ${c2}######${c1}
${c1} ${c2}####${c1}
${c1} ${c2}##${c1}
+30
View File
@@ -0,0 +1,30 @@
{"match": "\"AthenaOS\"*", "color": "4 4"}
u.
..:Y
.Y..1
..::i::.. .br7S.
.::::...::::. 5dDr:
..:::.. .:i::.. Y7:
..:::::.. ..::::.
...:i:i:i:.. ${c2}... ${c1}:.:..:i:::...
::i:. ${c2}.USL Yr ${c1}..i::.
.:::. ${c2}:K :u. ${c1}.::.
:... ${c2}jB. .:vUi: 77 KB: ${c1}..::
...: ${c2}iBR vP::5X5PgSKXvLjS. iBB ${c1}.::.
:i:: ${c2}BBQr jgDIuj1UuJjXbbi 2BBP ${c1}:::;
'i:: ${c2}sQBg: i2S55121XSSU. YBQZ: ${c1}.:::
r::: ${c2}r:JgBMu. Q :BqEqZEB: Q :qBBK7i: ${c1}:i:i
.rir. ${c2}IBqPDgQBDr P rB :q 1QBRgEqgB ${c1}.::i.
:i:i ${c2}:JsXPDDRQQPBL P qQXBQRDDPIYY ${c1}rir:
:iii ${c2}5qvLUDDMgMgBB5 :DBQZRgMDdJ7Ygi ${c1}iir:
iri: ${c2}MBRgdZZggQgRBMIBQQRRggdZdMBBr ${c1}riri
irii ${c2}IBQgdZbDDRRRgQgQQMZDdZdgBB. ${c1}iiri
i7rr ${c2}.BBQZZbEEMQQDBQMEZdDDBBP ${c1}.rir:
:7ir. ${c2}7BBQMDMQSbB5ZBggQBBQ. ${c1}ivr7.
:r7r. ${c2}7BBBB:rBbQ.1BBBM. ${c1}:r7vi
::rLrr. ${c2}.b:rBQ7QB uU. ${c1}:7vLi.
.BB .iLYv: ${c1}idL B1 ${c1}:r77r.
LBB :vrvvr rvu7r:
ZB. ':7v177Lsvurr:'
.d2 ''::r:''
:'
@@ -1,9 +1,5 @@
# This file is automatically generated. Please do not modify.
from . import AsciiArt
athena = AsciiArt(match=r'''"Athena"*''', color='7 3', ascii=r"""
${c1} . ..
{"match": "\"AthenaOS_old\"*", "color": "7 3"}
. ..
${c1} :####: ####.
${c1} .################
${c1} :##################
@@ -27,5 +23,3 @@ ${c1} ### ${c2}#######${c1}
${c1} ${c2}######${c1}
${c1} ${c2}####${c1}
${c1} ${c2}##${c1}
""")
+29
View File
@@ -0,0 +1,29 @@
{"match": "\"Aurora\"*", "color": "4 5 1 7"}
+++++++++
+++++${c4}+${c1}++++++${c4}+${c1}++
++++++${c4}+${c1}+++ +++++++++++
+++++++++++ ${c2}+${c1} +++++${c4}+${c1}+++++
++++++${c4}+${c1}++++ ${c4}+++${c1} +++++++++++
++++++++++${c4} + +++++ ++ ${c2}+++++${c4}+${c2}++++
+++${c4}+${c1}++++${c4} + + + +++++++ + + ${c2}+++++${c4}+${c2}++
++++++${c4} ${c2}+${c4} +++ +++++++++ +++ ${c2}++++++++
+++${c4}+${c1}++${c4} + +++++ +++++ +
++++++${c4} ${c2}+${c4} +++++ +++++ +++++
++${c4}+${c2}+++${c4} + +++++ ++++++ ++++++++++
++++++${c4} +++++ +++++ + +++++++++++++++++++
++++++${c4} + +++++ + +++++++++++++++
+++${c4}++${c2}+${c4} ++++++ +++++++++++++
++++++${c4} + ++++++ +++++++++++++ ${c2}+++ ${c4}++
++++++${c4} ++++++++++++++++ ${c2}++${c4}+${c2}+ ${c4}++ ${c1}+
++++++${c4} ++++++++++++++ ${c3}+ ${c2}++++
++++++${c4} +++++++++++ + ${c4}+ ${c3}++++++
++${c4}+${c3}+++${c4} ++++++++++ +++ ${c3}+++++++++++++
+++++ ${c4}+++++++++ + ${c3}+++++++++++++
+++ ${c4}++++++++ ${c2}++${c4} + ${c3}++++++++++++++ ++++
++ ${c4}++++++++ ${c3}+ ++++++++++++++ +++++++
${c4}++++++ ${c2}+ ${c3}+++++++++++++ +++++++${c2}++
${c4}++++ ${c3}+++++++++++++ ++++++${c2}+++
+++++++++++ ++++++${c2}+++
+++++ ++++++${c2}+++
++++++${c2}++
+++++
+17
View File
@@ -0,0 +1,17 @@
{"match": "\"AxOS\"*", "color": "38;2;222;6;255 38;2;222;6;255"}
▂🬭𜴧⎻𜷗𜴗𜴦𜵎⎻𜴧🬭▂
▁▂𜴧━𜵼𜵶𜶮▂🬭🬭𜴐🭗 🬁𜴜🬭🬭▂𜶮▁𜵁━𜴧▂▁
𜷓𜵐🬂🬂🮂𜶮𜴸𜴪━𜴆🮂▔ ▔🮂𜴆━𜴩𜵳𜴸🮂🬂🬂𜶚🬿
🭄🬨▍ 🬜🮂▔ ▁▂▂🬭🬭▂▂▁ ▔🮂🬪 🮈🬕𜶿
🭄🭙▐▎𜵫 🭃██████████🭎 🭢𜶡🮇▌🭤𜶿
🭄🭙 ▐🭄🭙 🭋█████🭜𜴦█████🭀 🭤🭏▌ 🭤🭏
𜵫🭗 🮉🭛 🭃███🭝🭙 🭥🭒███🭎 🭦▋ 🭢𜶡
▟🬮𜴧━🭷🭘 🭋████▄▂ ▂▄████🭀 🭣𜴇━𜴧🬯🭏
🭕𜴸𜴆╾🭺🬽 🭃██🭡 🭖██🭐 🭈𜵡╼𜴆🬡🭠
𜴤🬼 🮉🭀 🭋███΄ 🭤███🭀 🭋▊ 🭇𜵐
𜴠🬾 ▐𜴢🬾▁▁ 🭃██𜴍 𜶘██🭐 ▁▁🭉🭫▌ 🭉🭠
𜴠🬾🮈▎𜶚 ▔🮂🬂▀🬎🬎 🮅🬎▀🬂🮂▔ 𜵐🮇▌🭉𜴏
𜴢🭿▍ 𜴬▂▁ ▁▂🬜΄🮈🬲𜴏
🭥𜶡🬭🬭▂𜶭▁𜵁━𜴧▂▁ ▁▂𜴧━𜶷𜶭𜶮▂🬭🬭𜵫🭚
▔⎺𜴆━𜴩▔𜶮🮂🬂🬂𜴜🬼 🭇𜴐🬂🬂🮂𜶮▔𜴨━𜴆⎺▔
⠈🮂🭷𜴆╾𜶦𜷞🭄𜴬╼𜴆🬂🮂΄
@@ -1,8 +1,4 @@
# This file is automatically generated. Please do not modify.
from . import AsciiArt
azos = AsciiArt(match=r'''"azos"*''', color='6 1', ascii=r"""
{"match": "\"azos\"*", "color": "6 1"}
${c1} ////. ${c2} (((((
${c1} //////// ${c2} @((((((((
${c1} //////// ${c2} @((((((((
@@ -19,6 +15,4 @@ ${c1} //////// ///////// ${c2} &(((((((( @((((((((
${c1} //////// ////// ${c2} @(((( @((((((((
${c1} //////// ${c2} @((((((((
${c1} //////// ${c2} @((((((((
${c1} ///// ${c2} (((((
""")
${c1} ///// ${c2} (((((
@@ -1,8 +1,4 @@
# This file is automatically generated. Please do not modify.
from . import AsciiArt
bazzite = AsciiArt(match=r'''"Bazzite"*''', color='5 5', ascii=r"""
{"match": "\"Bazzite\"*", "color": "5 5"}
${c1} %%%%%%====%%%%%%%%%%
%%%%%%%% %%%%%%%%%%%%%%
%%%%%%%%% %%%%%%%%%%%%%%%%
@@ -21,6 +17,4 @@ ${c1} %%%%%%====%%%%%%%%%%
%#######==========#########
#######################
###################
###########
""")
###########
@@ -1,8 +1,4 @@
# This file is automatically generated. Please do not modify.
from . import AsciiArt
bedrock = AsciiArt(match=r'''"Bedrock"*''', color='8 7', ascii=r"""
{"match": "\"Bedrock\"*", "color": "8 7"}
${c1}--------------------------------------
--------------------------------------
--------------------------------------
@@ -19,6 +15,4 @@ ${c1}--------------------------------------
-------------${c2}\\\////////////////${c1}------
--------------------------------------
--------------------------------------
--------------------------------------
""")
--------------------------------------

Some files were not shown because too many files have changed in this diff Show More