My personal website and Gemini capsule

Start fresh

Changed files
+7015
gemini
gemlog
http
archetypes
content
posts
static
themes
scripts
+13
.gitignore
···
+
# ---> Hugo
+
# Generated files by hugo
+
http/public/
+
http/resources/_gen/
+
http/assets/jsconfig.json
+
http/hugo_stats.json
+
+
# Temporary lock file while building
+
.hugo_build.lock
+
+
# ---> Python
+
scripts/.mypy_cache
+
scripts/venv
+170
LICENSE
···
+
Creative Commons Attribution-ShareAlike 4.0 International
+
+
Creative Commons Corporation (“Creative Commons”) is not a law firm and does not provide legal services or legal advice. Distribution of Creative Commons public licenses does not create a lawyer-client or other relationship. Creative Commons makes its licenses and related information available on an “as-is” basis. Creative Commons gives no warranties regarding its licenses, any material licensed under their terms and conditions, or any related information. Creative Commons disclaims all liability for damages resulting from their use to the fullest extent possible.
+
+
Using Creative Commons Public Licenses
+
+
Creative Commons public licenses provide a standard set of terms and conditions that creators and other rights holders may use to share original works of authorship and other material subject to copyright and certain other rights specified in the public license below. The following considerations are for informational purposes only, are not exhaustive, and do not form part of our licenses.
+
+
Considerations for licensors: Our public licenses are intended for use by those authorized to give the public permission to use material in ways otherwise restricted by copyright and certain other rights. Our licenses are irrevocable. Licensors should read and understand the terms and conditions of the license they choose before applying it. Licensors should also secure all rights necessary before applying our licenses so that the public can reuse the material as expected. Licensors should clearly mark any material not subject to the license. This includes other CC-licensed material, or material used under an exception or limitation to copyright. More considerations for licensors.
+
+
Considerations for the public: By using one of our public licenses, a licensor grants the public permission to use the licensed material under specified terms and conditions. If the licensor’s permission is not necessary for any reason–for example, because of any applicable exception or limitation to copyright–then that use is not regulated by the license. Our licenses grant only permissions under copyright and certain other rights that a licensor has authority to grant. Use of the licensed material may still be restricted for other reasons, including because others have copyright or other rights in the material. A licensor may make special requests, such as asking that all changes be marked or described.
+
+
Although not required by our licenses, you are encouraged to respect those requests where reasonable. More considerations for the public.
+
+
Creative Commons Attribution-ShareAlike 4.0 International Public License
+
+
By exercising the Licensed Rights (defined below), You accept and agree to be bound by the terms and conditions of this Creative Commons Attribution-ShareAlike 4.0 International Public License ("Public License"). To the extent this Public License may be interpreted as a contract, You are granted the Licensed Rights in consideration of Your acceptance of these terms and conditions, and the Licensor grants You such rights in consideration of benefits the Licensor receives from making the Licensed Material available under these terms and conditions.
+
+
Section 1 – Definitions.
+
+
a. Adapted Material means material subject to Copyright and Similar Rights that is derived from or based upon the Licensed Material and in which the Licensed Material is translated, altered, arranged, transformed, or otherwise modified in a manner requiring permission under the Copyright and Similar Rights held by the Licensor. For purposes of this Public License, where the Licensed Material is a musical work, performance, or sound recording, Adapted Material is always produced where the Licensed Material is synched in timed relation with a moving image.
+
+
b. Adapter's License means the license You apply to Your Copyright and Similar Rights in Your contributions to Adapted Material in accordance with the terms and conditions of this Public License.
+
+
c. BY-SA Compatible License means a license listed at creativecommons.org/compatiblelicenses, approved by Creative Commons as essentially the equivalent of this Public License.
+
+
d. Copyright and Similar Rights means copyright and/or similar rights closely related to copyright including, without limitation, performance, broadcast, sound recording, and Sui Generis Database Rights, without regard to how the rights are labeled or categorized. For purposes of this Public License, the rights specified in Section 2(b)(1)-(2) are not Copyright and Similar Rights.
+
+
e. Effective Technological Measures means those measures that, in the absence of proper authority, may not be circumvented under laws fulfilling obligations under Article 11 of the WIPO Copyright Treaty adopted on December 20, 1996, and/or similar international agreements.
+
+
f. Exceptions and Limitations means fair use, fair dealing, and/or any other exception or limitation to Copyright and Similar Rights that applies to Your use of the Licensed Material.
+
+
g. License Elements means the license attributes listed in the name of a Creative Commons Public License. The License Elements of this Public License are Attribution and ShareAlike.
+
+
h. Licensed Material means the artistic or literary work, database, or other material to which the Licensor applied this Public License.
+
+
i. Licensed Rights means the rights granted to You subject to the terms and conditions of this Public License, which are limited to all Copyright and Similar Rights that apply to Your use of the Licensed Material and that the Licensor has authority to license.
+
+
j. Licensor means the individual(s) or entity(ies) granting rights under this Public License.
+
+
k. Share means to provide material to the public by any means or process that requires permission under the Licensed Rights, such as reproduction, public display, public performance, distribution, dissemination, communication, or importation, and to make material available to the public including in ways that members of the public may access the material from a place and at a time individually chosen by them.
+
+
l. Sui Generis Database Rights means rights other than copyright resulting from Directive 96/9/EC of the European Parliament and of the Council of 11 March 1996 on the legal protection of databases, as amended and/or succeeded, as well as other essentially equivalent rights anywhere in the world.
+
+
m. You means the individual or entity exercising the Licensed Rights under this Public License. Your has a corresponding meaning.
+
+
Section 2 – Scope.
+
+
a. License grant.
+
+
1. Subject to the terms and conditions of this Public License, the Licensor hereby grants You a worldwide, royalty-free, non-sublicensable, non-exclusive, irrevocable license to exercise the Licensed Rights in the Licensed Material to:
+
+
A. reproduce and Share the Licensed Material, in whole or in part; and
+
+
B. produce, reproduce, and Share Adapted Material.
+
+
2. Exceptions and Limitations. For the avoidance of doubt, where Exceptions and Limitations apply to Your use, this Public License does not apply, and You do not need to comply with its terms and conditions.
+
+
3. Term. The term of this Public License is specified in Section 6(a).
+
+
4. Media and formats; technical modifications allowed. The Licensor authorizes You to exercise the Licensed Rights in all media and formats whether now known or hereafter created, and to make technical modifications necessary to do so. The Licensor waives and/or agrees not to assert any right or authority to forbid You from making technical modifications necessary to exercise the Licensed Rights, including technical modifications necessary to circumvent Effective Technological Measures. For purposes of this Public License, simply making modifications authorized by this Section 2(a)(4) never produces Adapted Material.
+
+
5. Downstream recipients.
+
+
A. Offer from the Licensor – Licensed Material. Every recipient of the Licensed Material automatically receives an offer from the Licensor to exercise the Licensed Rights under the terms and conditions of this Public License.
+
+
B. Additional offer from the Licensor – Adapted Material. Every recipient of Adapted Material from You automatically receives an offer from the Licensor to exercise the Licensed Rights in the Adapted Material under the conditions of the Adapter’s License You apply.
+
+
C. No downstream restrictions. You may not offer or impose any additional or different terms or conditions on, or apply any Effective Technological Measures to, the Licensed Material if doing so restricts exercise of the Licensed Rights by any recipient of the Licensed Material.
+
+
6. No endorsement. Nothing in this Public License constitutes or may be construed as permission to assert or imply that You are, or that Your use of the Licensed Material is, connected with, or sponsored, endorsed, or granted official status by, the Licensor or others designated to receive attribution as provided in Section 3(a)(1)(A)(i).
+
+
b. Other rights.
+
+
1. Moral rights, such as the right of integrity, are not licensed under this Public License, nor are publicity, privacy, and/or other similar personality rights; however, to the extent possible, the Licensor waives and/or agrees not to assert any such rights held by the Licensor to the limited extent necessary to allow You to exercise the Licensed Rights, but not otherwise.
+
+
2. Patent and trademark rights are not licensed under this Public License.
+
+
3. To the extent possible, the Licensor waives any right to collect royalties from You for the exercise of the Licensed Rights, whether directly or through a collecting society under any voluntary or waivable statutory or compulsory licensing scheme. In all other cases the Licensor expressly reserves any right to collect such royalties.
+
+
Section 3 – License Conditions.
+
+
Your exercise of the Licensed Rights is expressly made subject to the following conditions.
+
+
a. Attribution.
+
+
1. If You Share the Licensed Material (including in modified form), You must:
+
+
A. retain the following if it is supplied by the Licensor with the Licensed Material:
+
+
i. identification of the creator(s) of the Licensed Material and any others designated to receive attribution, in any reasonable manner requested by the Licensor (including by pseudonym if designated);
+
+
ii. a copyright notice;
+
+
iii. a notice that refers to this Public License;
+
+
iv. a notice that refers to the disclaimer of warranties;
+
+
v. a URI or hyperlink to the Licensed Material to the extent reasonably practicable;
+
+
B. indicate if You modified the Licensed Material and retain an indication of any previous modifications; and
+
+
C. indicate the Licensed Material is licensed under this Public License, and include the text of, or the URI or hyperlink to, this Public License.
+
+
2. You may satisfy the conditions in Section 3(a)(1) in any reasonable manner based on the medium, means, and context in which You Share the Licensed Material. For example, it may be reasonable to satisfy the conditions by providing a URI or hyperlink to a resource that includes the required information.
+
+
3. If requested by the Licensor, You must remove any of the information required by Section 3(a)(1)(A) to the extent reasonably practicable.
+
+
b. ShareAlike.In addition to the conditions in Section 3(a), if You Share Adapted Material You produce, the following conditions also apply.
+
+
1. The Adapter’s License You apply must be a Creative Commons license with the same License Elements, this version or later, or a BY-SA Compatible License.
+
+
2. You must include the text of, or the URI or hyperlink to, the Adapter's License You apply. You may satisfy this condition in any reasonable manner based on the medium, means, and context in which You Share Adapted Material.
+
+
3. You may not offer or impose any additional or different terms or conditions on, or apply any Effective Technological Measures to, Adapted Material that restrict exercise of the rights granted under the Adapter's License You apply.
+
+
Section 4 – Sui Generis Database Rights.
+
+
Where the Licensed Rights include Sui Generis Database Rights that apply to Your use of the Licensed Material:
+
+
a. for the avoidance of doubt, Section 2(a)(1) grants You the right to extract, reuse, reproduce, and Share all or a substantial portion of the contents of the database;
+
+
b. if You include all or a substantial portion of the database contents in a database in which You have Sui Generis Database Rights, then the database in which You have Sui Generis Database Rights (but not its individual contents) is Adapted Material, including for purposes of Section 3(b); and
+
+
c. You must comply with the conditions in Section 3(a) if You Share all or a substantial portion of the contents of the database.
+
For the avoidance of doubt, this Section 4 supplements and does not replace Your obligations under this Public License where the Licensed Rights include other Copyright and Similar Rights.
+
+
Section 5 – Disclaimer of Warranties and Limitation of Liability.
+
+
a. Unless otherwise separately undertaken by the Licensor, to the extent possible, the Licensor offers the Licensed Material as-is and as-available, and makes no representations or warranties of any kind concerning the Licensed Material, whether express, implied, statutory, or other. This includes, without limitation, warranties of title, merchantability, fitness for a particular purpose, non-infringement, absence of latent or other defects, accuracy, or the presence or absence of errors, whether or not known or discoverable. Where disclaimers of warranties are not allowed in full or in part, this disclaimer may not apply to You.
+
+
b. To the extent possible, in no event will the Licensor be liable to You on any legal theory (including, without limitation, negligence) or otherwise for any direct, special, indirect, incidental, consequential, punitive, exemplary, or other losses, costs, expenses, or damages arising out of this Public License or use of the Licensed Material, even if the Licensor has been advised of the possibility of such losses, costs, expenses, or damages. Where a limitation of liability is not allowed in full or in part, this limitation may not apply to You.
+
+
c. The disclaimer of warranties and limitation of liability provided above shall be interpreted in a manner that, to the extent possible, most closely approximates an absolute disclaimer and waiver of all liability.
+
+
Section 6 – Term and Termination.
+
+
a. This Public License applies for the term of the Copyright and Similar Rights licensed here. However, if You fail to comply with this Public License, then Your rights under this Public License terminate automatically.
+
+
b. Where Your right to use the Licensed Material has terminated under Section 6(a), it reinstates:
+
+
1. automatically as of the date the violation is cured, provided it is cured within 30 days of Your discovery of the violation; or
+
+
2. upon express reinstatement by the Licensor.
+
+
c. For the avoidance of doubt, this Section 6(b) does not affect any right the Licensor may have to seek remedies for Your violations of this Public License.
+
+
d. For the avoidance of doubt, the Licensor may also offer the Licensed Material under separate terms or conditions or stop distributing the Licensed Material at any time; however, doing so will not terminate this Public License.
+
+
e. Sections 1, 5, 6, 7, and 8 survive termination of this Public License.
+
+
Section 7 – Other Terms and Conditions.
+
+
a. The Licensor shall not be bound by any additional or different terms or conditions communicated by You unless expressly agreed.
+
+
b. Any arrangements, understandings, or agreements regarding the Licensed Material not stated herein are separate from and independent of the terms and conditions of this Public License.
+
+
Section 8 – Interpretation.
+
+
a. For the avoidance of doubt, this Public License does not, and shall not be interpreted to, reduce, limit, restrict, or impose conditions on any use of the Licensed Material that could lawfully be made without permission under this Public License.
+
+
b. To the extent possible, if any provision of this Public License is deemed unenforceable, it shall be automatically reformed to the minimum extent necessary to make it enforceable. If the provision cannot be reformed, it shall be severed from this Public License without affecting the enforceability of the remaining terms and conditions.
+
+
c. No term or condition of this Public License will be waived and no failure to comply consented to unless expressly agreed to by the Licensor.
+
+
d. Nothing in this Public License constitutes or may be interpreted as a limitation upon, or waiver of, any privileges and immunities that apply to the Licensor or You, including from the legal processes of any jurisdiction or authority.
+
+
Creative Commons is not a party to its public licenses. Notwithstanding, Creative Commons may elect to apply one of its public licenses to material it publishes and in those instances will be considered the “Licensor.” Except for the limited purpose of indicating that material is shared under a Creative Commons public license or as otherwise permitted by the Creative Commons policies published at creativecommons.org/policies, Creative Commons does not authorize the use of the trademark “Creative Commons” or any other trademark or logo of Creative Commons without its prior written consent including, without limitation, in connection with any unauthorized modifications to any of its public licenses or any other arrangements, understandings, or agreements concerning use of licensed material. For the avoidance of doubt, this paragraph does not form part of the public licenses.
+
+
Creative Commons may be contacted at creativecommons.org.
+49
README.md
···
+
# hyperreal.coffee
+
+
* Website: <https://hyperreal.coffee>
+
* Gemini: <gemini://hyperreal.coffee>
+
+
Workflows use [just](https://just.systems). The justfile I use that contains the commands below can be found in my [justfiles](https://tildegit.org/hyperreal/justfiles) repo, in the `blogging.just` file.
+
+
## Workflow: Create new blog/gemlog entry
+
+
Open new blog entry template in Neovim:
+
+
```shell
+
newblog "slug"
+
```
+
+
Convert blog entry to gemlog entry:
+
+
```shell
+
blog2gmi /path/to/post.md "Title"
+
```
+
+
Push changes to git and deploy website and capsule:
+
+
```shell
+
push-deploy
+
```
+
+
## Workflow: Edit pages on website/capsule
+
+
Edit the page with Neovim:
+
+
```shell
+
nvim /path/to/page.md
+
```
+
+
Convert website page changes to gemtext and send to capsule:
+
+
```shell
+
board-capsule
+
```
+
+
Push and deploy changes
+
+
```shell
+
push-deploy
+
```
+
+
Kinda neat, huh?
+
No? Well then... eat an apple. Or something. If you want more excitement. 😒
+89
gemini/about.gmi
···
+
## About me
+
+
* Based in the Chicago area.
+
* Born on March 15th, 1988.
+
* I'm shy and might come across as reserved and standoffish at first, but I open up when I get more comfortable with people.
+
* I have a Bachelor of Science in Computer Science from University of Illinois-Springfield.
+
* I'm a mental illness and mental health advocate.
+
* Some of my favorite things include: free and open source software/culture/content/access, diversity, automation, programming, logic, video games, role-playing games, language, and coffee.
+
* I dislike monocultures, non-consensual power structures, and closed-mindedness.
+
* My pronouns are he/him/his or they/them/their.
+
* I'm autistic.
+
* I'm genderfluid. More specifically, I'm a demi-gendered man, which means I identify as mostly masculine and have some feminine markers.
+
* I have schizoaffective disorder and OCD. I was diagnosed in September of 2007 and have been taking medication since 2006. Secondary symptoms that stem from these, and which overlap with my neurodivergence, include agoraphobia, social phobia, selective mutism, and alogia/speech articulation issues.
+
* I'm an atheist, naturalist, and secular humanist.
+
* Politically, I'm a libertarian socialist.
+
+
### Links
+
+
=> https://autisticadvocacy.org/about-asan/about-autism/ Autism
+
+
=> https://en.wikipedia.org/wiki/Schizoaffective_disorder Schizoaffective disorder
+
+
=> https://en.wikipedia.org/wiki/Obsessive%E2%80%93compulsive_disorder OCD
+
+
=> https://en.wikipedia.org/wiki/Agoraphobia Agoraphobia
+
+
=> https://en.wikipedia.org/wiki/Social_anxiety_disorder Social phobia
+
+
=> https://en.wikipedia.org/wiki/Selective_mutism Selective mutism
+
+
=> https://en.wikipedia.org/wiki/Alogia Alogia
+
+
=> https://en.wikipedia.org/wiki/Atheism Atheism
+
+
=> https://en.wikipedia.org/wiki/Naturalism_%5C%28philosophy%5C%29 Naturalism
+
+
=> https://en.wikipedia.org/wiki/Secular_humanism Secular humanism
+
+
=> https://en.wikipedia.org/wiki/Libertarian_socialism Libertarian socialism
+
+
=> https://files.hyperreal.coffee/Jeffrey_Serio_-_System_Administrator__DevOps.pdf Resume
+
+
=> https://hyperreal.coffee/about/facts/ More info about me
+
+
## Interests
+
+
Below is an outline of things I'm interested in and would like to learn more about.
+
+
* Python and Go
+
* Unix/Linux system administration
+
* computer networks
+
* infosec / cybersecurity
+
* shell scripting with bash, zsh, and Nushell
+
* self-hosting
+
* digital homemaking
+
* digital archiving and preservation
+
* retro-computing
+
* decentralized internet
+
* privacy and digital rights
+
* free and open source software / culture/ content / access
+
* Wikipedia and other Wikimedia projects
+
* mental illness and mental health awareness
+
* neurodivergence
+
* minimalism
+
* history
+
* psychology
+
* anthropology
+
* philosophy
+
* language and linguistics
+
* mythology and folklore
+
* Hacker culture and Hacker ethic
+
* high fantasy and science fiction
+
* role-playing games. Only video games for now, but One Of These Days™ I will get into table-top gaming.
+
+
### Links
+
+
=> https://en.wikipedia.org/wiki/Free_and_open-source_software Free and open-source software
+
+
=> https://en.wikipedia.org/wiki/Free-culture_movement Free-culture movement
+
+
=> https://en.wikipedia.org/wiki/Free_content Free content
+
+
=> https://en.wikipedia.org/wiki/Open_access Open access
+
+
=> https://en.wikipedia.org/wiki/Neurodiversity Neurodiversity
+
+
=> https://en.wikipedia.org/wiki/Hacker_culture Hacker culture
+
+
=> https://en.wikipedia.org/wiki/Hacker_ethic Hacker ethic
+49
gemini/beef-and-red-lentil-chili.gmi
···
+
## Ingredients
+
+
> Note that the kosher salt and black pepper are listed twice, because each portion is added to the pot at different times during the cooking process. I keep them in separate containers to make it easier to add.
+
+
* 2 tbsp olive oil
+
* 1 tbsp unsalted butter (or plant-based alternative for vegan)
+
* 1 cup chopped white onion
+
* 3 garlic cloves, chopped
+
* 1 serrano chile, seeded and minced
+
* 0.75 tsp kosher salt
+
* 1.25 tsp kosher salt
+
* 0.5 tsp ground black pepper
+
* 0.5 tsp ground black pepper
+
* 1 large zucchini
+
* 1 large yellow squash
+
* 1 lb ground beef (optional for vegan)
+
* 3 tbsp chili powder
+
* 1 tsp ground cumin
+
* 1 tsp garlic powder
+
* 4 cups (32 oz) chicken stock (or vegan-friendly vegetable stock)
+
* 1 (15 oz) can red kidney beans
+
* 1 cup uncooked red lentils, rinsed
+
* 1 (28 oz) can whole peeled plum tomatoes, crushed by hand
+
* 1 bunch of kale, chopped
+
+
## Utensils
+
+
* 1 large pot
+
* 1 container to hold 1 cup of chopped onion, 3 cloves of chopped garlic, minced serrano pepper, 0.75 tsp of salt, and 0.5 tsp of black pepper.
+
* 1 container to hold chopped zucchini and yellow squash.
+
* 1 smaller container to hold chili powder, cumin, garlic powder, 1.25 tsp of salt, and 0.5 tsp of black pepper.
+
+
## Instructions
+
+
> Note: If you have raw skin or open sore on your fingers, beware when seeding and mincing the serrano chile pepper (trust me). Wear rubber gloves or use another form of protection.
+
+
* Chop onion, zucchini, yellow squash, and kale. Seed and mince serrano pepper.
+
* Place chopped onion, garlic, serrano pepper, 0.75 tsp of salt, and 0.5 tsp of black pepper in a single container.
+
* Place chopped zucchini and yellow squash in another single container.
+
* Place chili powder, cumin, garlic powder, 1.25 tsp of salt, and 0.5 tsp of black pepper in another, smaller container.
+
* Heat olive oil and butter in covered pot over medium heat, until butter melts. ~1 minute.
+
* Add onion, garlic, serrano, salt, and pepper to pot. Cook, stirring occasionally until onion is softened. ~3 minutes.
+
* Stir in zucchini and yellow squash. Cook, stirring often, until softened. ~3 minutes.
+
* Add ground beef, chili powder, cumin, garlic powder, salt, and black pepper. Stir to crumble beef. ~1-2 minutes.
+
* Cover pot and cook, stirring occasionally until beef is cooked through. ~3-5 minutes.
+
* Stir in chicken stock, beans, and lentils. Increase heat to high and bring to boil.
+
* Reduce heat to low; cover and cook, stirring occasionally until lentils are softened. ~25-30 minutes.
+
* Stir in crushed tomatoes; cover and simmer on low, stirring occasionally. ~20 minutes.
+
* Stir in kale until wilted. Cook, stirring occasionally. ~25 minutes.
+65
gemini/community-driven-distros.gmi
···
+
I've.com)piled a list of.com)munity-driven, non-corporate FOSS operating systems. What I mean by .com)munity-driven" is distributions that are self-governed, where decisions regarding the direction of the distribution are ultimately made by the.com)munity itself and its leadership. This is in contrast to distributions that are beholden to corporations like IBM/Red Hat, Canonical, and Novell.
+
+
## Linux
+
+
=> https://almalinux.org AlmaLinux
+
+
=> https://alpinelinux.org Alpine Linux
+
+
=> https://archlinux.org Arch Linux
+
+
=> https://artixlinux.org Artix Linux
+
+
=> https://cachyos.org CachyOS
+
+
=> https://chimera-linux.org Chimera Linux
+
+
=> https://www.debian.org Debian GNU/Linux
+
+
=> https://www.devuan.org Devuan GNU+Linux
+
+
=> https://guix.gnu.org/en GNU Guix System
+
+
=> https://gentoo.org Gentoo Linux
+
+
=> https://hyperbola.info Hyperbola GNU/Linux-libre
+
+
=> https://linuxmint.com Linux Mint
+
+
=> https://mxlinux.org MX Linux
+
+
=> https://parabola.nu Parabola GNU/Linux-libre
+
+
=> https://qubes-os.org Qubes OS
+
+
=> https://rockylinux.org Rocky Linux
+
+
=> https://slackware.com Slackware
+
+
=> https://tails.net Tails
+
+
=> https://voidlinux.org Void Linux
+
+
=> https://antixlinux.com antiX Linux
+
+
=> https://postmarketos.org postmarketOS
+
+
## BSD
+
+
=> https://dragonflybsd.org DragonFly BSD
+
+
=> https://freebsd.org FreeBSD
+
+
=> https://hardenedbsd.org HardenedBSD
+
+
=> https://netbsd.org NetBSD
+
+
=> https://openbsdfoundation.org OpenBSD
+
+
## Android
+
+
=> https://e.foundation/e-os/ /e/OS
+
+
=> https://calyxos.org CalyxOS
+
+
=> https://grapheneos.org GrapheneOS
+85
gemini/computing.gmi
···
+
## Hardware
+
+
=> homelab.gmi Homelab
+
+
=> vps-cloud-servers.gmi VPS and cloud servers
+
+
## Software
+
+
These are my daily drivers.
+
+
=> https://github.com/makew0rld/amfora Amfora
+
+
=> https://www.gnu.org/software/bash/ Bash
+
+
=> https://www.borgbackup.org/ Borgbackup
+
+
=> https://torsion.org/borgmatic/ Borgmatic
+
+
=> https://btrfs.readthedocs.io/en/latest/ Btrfs
+
+
=> https://cachyos.org CachyOS
+
+
=> https://calibre-ebook.com/ Calibre
+
+
=> https://git.causal.agency/catgirl/about/ Catgirl
+
+
=> https://www.debian.org/ Debian stable
+
+
=> https://discordapp.com Discord
+
+
=> https://www.freebsd.org/ FreeBSD
+
+
=> https://gnome.org/ GNOME
+
+
=> https://grafana.com/ Grafana
+
+
=> https://jellyfin.org/ Jellyfin
+
+
=> https://just.systems Just
+
+
=> https://kde.org/plasma-desktop/ KDE Plasma
+
+
=> https://kdeconnect.kde.org/ KDEConnect
+
+
=> https://apps.kde.org/konsole/ Konsole
+
+
=> https://gmi.skyjake.fi/lagrange/ Lagrange
+
+
=> https://librewolf.net/ LibreWolf
+
+
=> https://miniflux.app/ Miniflux
+
+
=> https://doc.e.foundation/what-s-e Murena /e/os
+
+
=> https://neovim.io/ Neovim
+
+
=> https://newsboat.org/ Newsboat
+
+
=> https://nextcloud.com/ Nextcloud
+
/
+
=> https://murena.com/workspace/ Murena Workspace
+
+
=> https://www.nushell.sh/ Nushell
+
+
=> https://prometheus.io/ Prometheus
+
+
=> https://signal.org/ Signal
+
+
=> https://tailscale.com/ Tailscale
+
+
=> https://github.com/tmuxinator/tmuxinator Tmuxinator
+
+
=> https://www.zsh.org/ Z shell
+
+
=> https://openzfs.org/wiki/Main_Page ZFS
+
+
=> https://zellij.dev/ Zellij
+
+
=> https://zen-browser.app/ Zen Browser
+
+
=> https://firewalld.org/ firewalld
+
+
=> https://www.qbittorrent.org/ qBittorrent
+
+
=> https://starship.rs/ starship.rs
+25
gemini/facts.gmi
···
+
* I only drink filtered black coffee, and it has to be sufficiently dark roast.
+
* I've never worn jeans. I can't tolerate the denim material.
+
* I can't tolerate tight- or snug-fitting clothing generally. In the winter I wear stretchy, baggy sweatpants. In the summer I wear stretchy athletic shorts. If I absolutely have to dress up, I would find slacks that are baggy and have an elastic waistband.
+
* I'm <i>super</i> picky when it comes to eating meat. I tend to prefer meat that is lean, dry, and well-done; not bloody, juicy, and fatty. I won't eat pork chops, but I like the cut of pork used in pulled pork sandwiches. If I eat bacon it has to be crispy. Steaks and beef tenderloin that are barely cooked are disgusting to me. The only kind of beef I tend to eat is the kind used in Italian beef sandwiches, the arrachera skirt steak in Mexican tacos (even this is sometimes gross to me, depending on how well it's cooked and its fat content), and ground beef like in chili recipes. I'll eat corned beef and pastrami depending on how non-fatty they are -- I'll often peel the fat off when I have a corned beef sandwich.
+
* I smoke tobacco cigarettes, but I can't stand any menthol flavor.
+
* I don't drink alcohol. I just don't care for it taste-wise, and I prefer to be sober-minded and in control of myself. There were some beers that I used to enjoy in moderation, like Guiness and dark craft brews, but I no longer see the point of being buzzed at all. I never liked hard alcohol either.
+
* I'm 37 years old at the time of this writing, and I'm still a virgin, if that means anything. I don't see losing my virginity as a sort of accomplishment, and I think the concept of losing virginity as a rite of passage is sexist and patriarchal. However, I do hope to eventually experience sex someday if I meet the right person. I'm also not against casual sex or going to a brothel as long as it's consensual and legal.
+
* My favorite pop (soda) is Dr. Pepper and Pepsi.
+
* I don't like bell peppers or plain uncooked tomatoes. The latter makes me gag.
+
* I'm kind of a mysophobe. It's not at a clinical OCD level.
+
* I can be super fussy about things to the point of decision paralysis. I do tend to eventually resolve the issue, though.
+
* I'm monotropic, which means I can only focus on one stream of activity or sensory input at a time. This is part of my autism. Regarding sensory input, I find that I can focus on one main activity with a few other non-intense sensory inputs. I can't have a conversation while driving. It's also hard to drive while listening to others talking. If there is just me in the car then I can drive with the radio on or listen to a podcast; otherwise, it's hard to focus on driving with other sensory distractions.
+
* I find that I'm quite sensory-averse, in that I have a hard preference for low-key, quiet, and non-chaotic environments.
+
* As per sensory aversion, I'm prone to misophonia with certain sounds. This depends on various other factors, such as my mood.
+
* I prefer the cooler fall and winter months to the warmer months. I <i>hate</i> the summer heat. I also take medication that makes me prone to overheating.
+
* My favorite holidays and seasons are Halloween, Thanksgiving (United States), and Christmas. I'm not religious, so I only celebrate the cultural aspects of Christmas. I don't celebrate Thanksgiving as a colonial heritage; I just love the food lol. Halloween will always have a special place in my heart. I love the "spooky" culture and folklore. I don't describe myself as a horror geek, but my older brother is, so I've been exposed to the horror classics for most of my life and I enjoy them as an integral part of the Halloween culture.
+
* My favorite pizza toppings are mushrooms, olives, spinach, and garlic. I'll take any or all. There is an Italian restaurant in Chicago called Pompei, and they have this Sicilian style baked clam pizza that is super good.
+
* I'm of Italian and German heritage. Both my parents are half Italian and half German. Culturally we're more Italian, though. I don't know much about the ancestry of my German relatives. My paternal great-great-grandfather, Cosimo Serio, immigrated from Cefalù, Sicily. Apparently the Serio surname is most common there. Serio means <i>serious</i> in Italian. It also means <i>serious</i> in Spanish, and the French version is <i>serieux</i>.
+
* I have an affinity for Latin and Greek words and their derivatives. I excelled in two years of Spanish in high school and one semester in college. I have a "peripheral goal" to learn the Italian and German languages, or at least a significant amount of them.
+
* I hope to travel someday. I'd like to see Canada and most of Europe, especially Italy. I'd also like to see Australia and Japan, but they are less of a priority. I think I would need a travel partner, like a significant other.
+
* I have an extreme fear of insects, especially spiders and centipedes.
+
* I'm not a water person. I never cared for swimming pools. I would describe myself as "hydrophobic" in the sense that I have a strong sensory aversion to getting wet, not that I'm irrationally afraid of water.
+
* I'm not as funny as I think I am. That's okay. It's valid.
+
* I tend to be routinized, but I try not to be too rigid. I'm not a fan of major changes. I get cranky when my routine is disrupted unexpectedly. I generally need a lot of time to process routine changes, so I appreciate notices a few to several days in advance.
+
* I am prone to irritability spells. This involves me being cranky, not wanting to interact with anyone, and not taking kindly to demands on my time.
+32
gemini/gem-bookmarks.gmi
···
+
# Bookmarks
+
+
You have 24 bookmarks.
+
+
Save this page to export them, or you can copy them to the clipboard.
+
+
=> gemini://warmedal.se/~antenna/ Antenna
+
=> gemini://envs.net/ envs.net
+
=> gemini://typed-hole.org/ Flight Journal - typed-hole.org
+
=> gemini://hyperreal.coffee/ hyperreal.coffee
+
=> gemini://moddedbear.xyz/ JP's home on gemini
+
=> gemini://kwiecien.us/ Kwiecien.us
+
=> gemini://gemini.lottalinuxlinks.com/ lottalinuxlinks
+
=> gemini://makeworld.space/ makeworld.space
+
=> gemini://nytpu.com nytpu's place
+
=> gemini://perma.computer/ PERMACOMPUTER
+
=> gemini://xosc.org/ Ramblings about stuff I do or did
+
=> gemini://seirdy.one/ Seirdy's Home
+
=> gemini://gemini.rlamacraft.uk/ rlamacraft
+
=> gemini://skyjake.fi/ skyjake's Capsule
+
=> gemini://tilde.pink/~slondr/ slondrlog — slondr
+
=> gemini://rawtext.club/~sloum/ sloum's capsule — sloum
+
=> gemini://gemini.cyberbot.space/smolzine/ smolZINE
+
=> gemini://snowymouse.com/ Snowy's Thoughts
+
=> gemini://gemini.bortzmeyer.org/ Stéphane Bortzmeyer's Gemini server
+
=> gemini://tilde.team/~khuxkm/ sup — khuxkm
+
=> gemini://tobykurien.com/ Toby Kurien
+
=> gemini://smol.pub/ Your journal on the small net
+
=> gemini://gemi.dev/ 🏭 Gemi.dev Heavy Industries
+
=> gemini://gemini.dimakrasner.com/ dimkr
+
+
Each link represents a bookmark. Folder structure is defined by level 2/3 headings. Bullet lines and quotes are reserved for additional information about the preceding bookmark. Text lines and preformatted text are considered comments and should be ignored.
+45
gemini/gemlog/2021-01-16-my-guess-on-tes6-clue.gmi
···
+
# My guess on the TES VI clue
+
+
> Epistemic status: EXTREMELY SPECULATIVE
+
+
WARNING: Spoilers for TES V: Skyrim
+
+
The Elder Scrolls official Twitter account posted the image below, saying: "Transcribe the past and map the future." The three lights placed on the map are supposed to be clues as to the setting of TES VI. The hint is pretty obviously pointing to Hammerfell, but the other clues I think warrant a deeper investigation for their own sake, which might reveal points of a narrative consistent with currently-known lore.
+
+
=> ../media/tes6-clue.jpg "Transcribe the past and map the future."
+
+
The top left light is right at the location of the Katariah, the Emperor’s flagship moored in the Solitude inlet during the events of TES V: Skyrim, where the Emperor is assassinated by the Dark Brotherhood. This could symbolize the death of the Empire.
+
+
The bottom-most light is clearly indicating Hammerfell. I’m not sure if the compass needle has any relevance to the clue, or whether the tall cliff structure in the upper left corner is significant.
+
+
The top right light is more obscure to me, but it would seem to have something to do with the coins next to it. The coins used throughout the Empire are called "Septims", after Tiber Septim, the founder of the Third Empire. The Septim bloodline died out after Martin Septim sacrificed himself with the Amulet of Kings in order to end the Oblivion Crisis that plagued Tamriel in 3E 433.
+
+
The coin in top of the pile depicts the Wolf of Solitude, and the coin directly beneath it appears to depict the two moons, Masser and Secunda. The inscription on the latter coin reads "The two..." but is cut off at the top. I'll attempt to explain why the engravings on these coins are significant to the clue.
+
+
In 4E 98 (102 years before the events of TES V: Skyrim), the moons Masser and Secunda vanished from the sky until mysteriously reappearing two years later. The Thalmor took credit for the return of the moons. The two moons are an integral part of Khajiit culture and religion, so this gave the Aldmeri Dominion considerable influence over the Khajiit. While the Empire's influence in Elsweyr declined, the Elsweyr Confederacy split into the two kingdoms of Anequina and Pellitine and became client states of the Aldmeri Dominion.
+
+
In 4E 175 (25 years before TES V: Skyrim), the Empire signed the White-Gold Concordat, a peace treaty with the Aldmeri Dominion, which ended the Great War. The conditions of the treaty included banning the worship of Talos throughout the Empire, disbanding of the Blades, and giving a large portion of southern Hammerfell to the Aldmeri Dominion. Talos worship is important to Nord culture, so these conditions were unacceptable to many Nords and consequently provoked a rebellion. Ulfric Stormcloak incited the rebellion when he murdered High-King Torygg at the Blue Palace in Solitude. During the events of TES V: Skyrim, Ulfric and the Stormcloaks engage in a civil war against General Tullius and the Empire. Regardless of whether the player sides with the Empire or the Stormcloaks, the civil war considerably weakens both Skyrim and the Empire.
+
+
It's interesting to note that, among the conditions of the White-Gold Concordat, the Aldmeri Dominion specifically demands the disbanding of the Blades. The Blades are sworn to protect the Dragonborn Emperors of Tamriel. With the Septim bloodline passed on and the Amulet of Kings destroyed, it seems the Thalmor seek to sever the remaining ties between the Empire and the dragon-god Akatosh to gain a strategic advantage against the Empire.
+
+
The Wolf of Solitude and Two Moons coins could symbolize the Empire and the two kingdoms of Elsweyr are in the pocket of the Aldmeri Dominion. It's hard to make out what the coins underneath these depict, but maybe a starting point to narrow it down could be to check the history with regard to which nations the Aldmeri Dominion has "in their pocket" by the end of TES V.
+
+
So, starting from the top east-most coin and going south-westward, a narrative of the clue could be something like: The Empire and Elsweyr are in the pocket of the Aldmeri Dominion, which leads to the death of the Empire. The south-western light, then, could indicate that the next plot point in the war against the Aldmeri Dominion is in Hammerfell.
+
+
Assuming this is even remotely correct, it makes me wonder whether the person who hired the Dark Brotherhood to assassinate Emperor Titus Mede II was an agent of the Thalmor. His name is Amaund Motierre, and all that we currently know about him is that he is part of a powerful Breton family established in Cyrodiil, and he paid the Dark Brotherhood in advance with an amulet that is given exclusively to members of the Elder Council.
+
+
## References
+
=> https://en.uesp.net/wiki/Lore:Tiber_Septim [UESP] Lore: Tiber Septim
+
=> https://en.uesp.net/wiki/Lore:Third_Empire [UESP] Lore: Third Empire
+
=> https://en.uesp.net/wiki/Lore:Septim_Dynasty [UESP] Lore: Septim Dynasty
+
=> https://en.uesp.net/wiki/Lore:Solitude [UESP] Lore: Solitude
+
=> https://en.uesp.net/wiki/Lore:White-Gold_Concordat [UESP] Lore: White-Gold Concordat
+
=> https://en.uesp.net/wiki/Lore:Great_War [UESP] Lore: Great War
+
=> https://en.uesp.net/wiki/Lore:Blades [UESP] Lore: Blades
+
=> https://en.uesp.net/wiki/Skyrim:Amaund_Motierre [UESP] Skyrim: Amaund Motierre
+
+
## END
+
Last updated: 2021-11-18
+
+
=> ../gemlog/ Gemlog archive
+
=> ../ Back to hyperreal.coffee
+30
gemini/gemlog/2021-05-10-gtfm.gmi
···
+
# GTFM (Generate the Friendly Manual)
+
+
The Zsh Manual is already friendly; I just decided to make it more hospitable by publishing an mdBook version. I endeavored to automate this with a script and deploy the mdBook via Netlify. The result can be viewed here: https://zsh-manual.netlify.app
+
+
I started out writing a Python script, but after some progress I realized that the task could be done more efficiently with my homies Bash, Sed, and Find, though I kept the bit of Python code that generates the SUMMARY.md file.
+
+
The script does the following 8 tasks:
+
+
* Downloads and extracts the tar.gz archive of the Zsh Manual from their website
+
* Removes some unneeded files
+
* Removes some HTML noise using Sed
+
* Renames the file extensions from .html to .md
+
* Converts html to GitHub-flavored Markdown using Pandoc
+
* Moves the resulting markdown files to the temporary mdBook src directory
+
* Generates a table of contents for each file using DocToc.
+
* Calls a Python script to generate the SUMMARY.md by scraping the original Zsh Manual’s table of contents.
+
+
There are probably some minor issues that could be found by perusing the mdBook but all in all the content seems to have transferred over nicely. The only parts that are missing are the indexes from the original Zsh Manual–their HTML structure doesn’t lend itself well to Markdown–but I reckon there is little need for them now with mdBook’s search feature.
+
+
UPDATE: I now use a Perl script to do all of these tasks.
+
+
=> http://zsh.sourceforge.net/Doc/ Original Zsh Manual
+
=> https://zsh-manual.netlify.app/ Modernized Zsh Manual
+
=> https://github.com/hyperreal64/zsh-manual-mdBook
+
+
## END
+
Last updated: 2021-11-18
+
+
=> ../gemlog/ Gemlog archive
+
=> ../ Back to hyperreal.coffee
+26
gemini/gemlog/2021-07-05-adventures-in-parsimonious-computing.gmi
···
+
# Adventures in parsimonious computing
+
+
=> ../media/occam.jpg Occam's Razor: A Parsimonious Shave Every Time!
+
+
I find myself increasingly drawn toward static, minimal, immutable, and lightweight software with low resource footprint. I have made some changes to my computing activity flows, which I describe below:
+
+
* Migrated my blog and website back to Hugo, a static web site generator written in Go, which is now hosted at my new domain that points to a VPS running Nginx.
+
* Am in the process of migrating my Git projects to my own server, with cgit as a browsable front-end. My cgit instance is hosted on the VPS at git.unixc.at. A few of my projects are there now. I will still keep them on GitHub but most of them will be archived. My mdBook Zsh Manual will not be archived because it is part of a CI/CD workflow on Netlify, and I would like to keep it open to potential pull requests or suggestions from the Zsh community.
+
* I have started using NixOS as my daily driver and am enjoying it thus far. It is everything an automatist could want in an operating system.
+
* I’m currently tinkering with an Openbox + tint2 + sxhkd + rofi + Alacritty + picom + tmux computing environment. I will also use Xfce’s power management, polkit, and authentication agent.
+
* Techne, my personal reference base, will no longer be hosted as a website. Nobody but me really uses it anyway. I’m going to migrate it to VimWiki and use it locally, but I will store the contents in a Git repository. Migrating all the markdown files to VimWiki should be pretty trivial. I will also be cleaning it up a bit and removing content that I no longer have use for.
+
+
Some concepts and philosophical ideals that I aim toward:
+
=> gemini://vault.transjovian.org/full/en/Minimalism%20(computing) Minimalism (computing)
+
=> gemini://vault.transjovian.org/full/en/Unix%20philosophy Unix philosophy
+
=> gemini://vault.transjovian.org/full/en/Occam's%20razor Occam's razor
+
=> gemini://vault.transjovian.org/full/en/Marie%20Kondo Marie Kondo
+
=> https://suckless.org/philosophy Suckless philosophy
+
+
This makes me happy 😊
+
+
## END
+
Last updated: 2021-11-19
+
+
=> ../gemlog/ Gemlog archive
+
=> ../ Back to hyperreal.coffee
+28
gemini/gemlog/2021-11-12-connecting-usb-devices-to-wsl.gmi
···
+
# Comments on using EmulationStation in WSL2
+
+
=> https://devblogs.microsoft.com/commandline/connecting-usb-devices-to-wsl/ Connecting USB devices to WSL
+
+
This might allow me to use EmulationStation with the RetroPie script in WSL2. I was able to get it running, but it couldn't detect my Xbox gamepad because there is no USB passthrough yet in WSL2.
+
+
These are the constraints of my personal scenario:
+
+
* I dual-boot Windows 11 and Fedora 35.
+
* EmulationStation is a pain to configure natively on any system, so the RetroPie script is super convenient.
+
* RetroPie setup script only works well on Raspberry Pi OS or Debian/Ubuntu-based armhf, armv8, or x86/64 PCs. This would be fine if I used Debian or Ubuntu as my main Linux OS, because then I can just run it natively. But my setup is already kind of entrenched in the Fedora ecosystem, and I enjoy using Fedora.
+
* Modifying the script for Fedora is non-trivial.
+
* Certain emulators I want to use with EmulationStation are only available for x64, so running it on my armv8 Raspberry Pi is not preferable.
+
* I'd prefer to keep my gaming stuff in one place, i.e. Windows 11.
+
+
WSL2 allows running graphical GNU/Linux applications. Ubuntu and Debian are both available as WSL distros, and the architecture would be x64. This means the RetroPie script would work, I could run EmulationStation with less overhead** than in a full virtual machine, I can keep my gaming in one place, and I don't have to triple-boot Windows 11, Fedora, and Debian/Ubuntu. So my constraints are satisfied.
+
+
** Less overhead in terms of computing ergonomics -- a combination of physical comfort and efficient use of computing resources. It just has more of an out-of-the-box sort of efficiency-feeling, I guess.
+
+
UPDATE 2021-11-12: I tried this out last night, and I was able to get the Xbox gamepad available to WSL and see it in the output of lsusb, but for some reason EmulationStation doesn't pick it up.
+
+
UPDATE 2021-11-18: I'm very much considering taking up the task of porting the RetroPie setup scripts to Fedora. At the time of this writing, the scripts require Debian, because many of the emulation pacakges depend on Debian tooling, systemd init scripts, Debian-specific filesystem paths, and so forth.
+
+
## END
+
Last updated: 2021-11-19
+
+
=> ../gemlog/ Gemlog archive
+
=> ../ Back to hyperreal.coffee
+15
gemini/gemlog/2021-11-12-privilege.gmi
···
+
# My blood boils when people misunderstand the concept of privilege
+
+
When someone tells you to check your white privilege, male privilege, able privilege, or financial privilege, it does not mean that your life hasn't been difficult, nor that you haven't worked hard for what you've got.
+
+
It means that your perceived race, perceived gender, non-disability, and wealth aren't one of the factors making your life difficult.
+
+
The reason anyone would say this to you is because you've expressed opinions or thoughts that overlook the difficulties those factors present to non-white, non-male, disabled, or poor people.
+
+
Sometimes this overlooking is unintentional -- in which case you may be less /culpable/ -- and sometimes it is willful -- in which case you are entirely culpable. In both cases, you are entirely /responsible/ for educating yourself and making a conscious effort to avoid letting that privilege affect opportunities and outcomes for people without it.
+
+
## END
+
Last updated: 2021-11-18
+
+
=> ../gemlog/ Gemlog archive
+
=> ../ Back to hyperreal.coffee
+24
gemini/gemlog/2021-11-14-re1-how-you-were-using-the-internet.gmi
···
+
# Re Part 1: How you were using the Internet in the 1991-1995 and 1995-2005?
+
+
I was born in 1988, so I was too young during 1991-1995. My first time using the Internet was in 1998. We had the AOL suite on a dial-up modem that used our landline. My screenname was BBJeff10 -- BB for baseball, my favorite sport, and 10 because that was my age at the time. My mom set up our screennames, and her user was the master account on our AOL instance. I don't quite recall what I did on the Internet exactly, but I didn't use it a whole lot. I think I mostly just chatted with my friends on AOL and looked up video game stuff on GameFAQs and Cheat.cc.
+
+
## 2000-2001
+
I was really into professional wrestling entertainment, like WWF (now WWE), WCW, and ECW. I found these fantasy wrestling communities called e-federations or e-wrestling leagues. These were communities of users who create their own original characters and roleplay various scenes, challenging other wrestlers in the league. The roleplays were written out and posted on the league's message board. Feuds between wrestlers would take place, and if there was a match between them, the wrestler with the best roleplay would win, as judged by the league owner/CEO who was usually the webmaster and did not take part in roleplays. The matches were simulated using wrestling simulation software. One such program in particular was called Zeus Pro.
+
+
The league that I was part of was called ACWL (Action Championship Wrestling League) and the owner, who was called Jim Rooster, wrote his own wrestling simulator software. My character had a caustic and cocky personality and his wrestling style was a mix of lightweight/high-flying and hardcore/roughneck. My character was inspired by the urban grunge/gothic aesthetic of the wrestler Raven, the hardcore dare-devil-ish Cactus Jack/Mankind, and the martial arts of Steve Blackman. He had some crazy high-flying moves too, like shooting star press and moonsaults.
+
+
I made one online friend within my first week of roleplaying; one user liked my roleplays and my character and asked me if I wanted to team up with their character. Their character was named Rune, and we formed a group called the Renegades of Funk. Our theme song was something by Rage Against the Machine (it might have been Guerilla Radio, but I can't say for sure. Or that might have been my own character's theme song.) Our partnership didn't last very long but I don't remember why, I think we just decided to go separate ways.
+
+
The owner/CEO of the league deemed me the most creative trash-talker in roleplays; my character won the ACWL North American title belt and held onto it for two matches before losing it to a character named Cyborg, with whom my character feuded for a time. Some users' roleplays were kind of perfunctory and simplistic; mine were among the more detailed ones.
+
+
Anyway, during this time I became more computer/Internet savvy because I spent a lot more time with it. I made my AOL username the master account, so I was able to view websites for wrestling news and M-rated video game stuff that was restricted by PG-13 AOL parental controls. HTML was often used for roleplaying on the message boards, and eventually I realized I could use HTML to design a whole website. At one time I had my own e-federation with a website I designed that was hosted on Angelfire. My e-fed didn't get very big, there were maybe 10 or so people, most of whom were online friends I made from the other league.
+
+
During this time also was when Napster was really popular. I thought it was amazing that I could look up any individual song and download it, for free, to my computer.
+
+
I will follow up on this post and share my Internet experience from the years 2002-2005.
+
+
## END
+
Last updated: 2021-11-19
+
+
=> ../gemlog/ Gemlog archive
+
=> ../ Back to hyperreal.coffee
+30
gemini/gemlog/2021-11-28-switch-from-gnome-to-xfce.gmi
···
+
# Switching from GNOME to Xfce
+
+
## Context
+
I've been using GNOME consistently for a few years now. It's a great desktop environment, but I want something more lightweight with less of a memory footprint. The main obstacle I've consistently run into with choosing a desktop environmnent or window manager is my HiDPI screen. Window managers like Openbox do not have very good HiDPI support -- even when you configure Xresources to use 120 DPI scaling, the result is horrendous, at least in my experience. Apps don't scale right, fonts don't scale right, the cursor is too big and the window buttons and title bar are too small. There are no themes I like that cater to HiDPI screens. If I had a "normal" DPI screen this wouldn't be an issue at all.
+
+
HiDPI + Nvidia + Intel + dual-monitor setup + Linux is an effing shit show, which complicates things. (In fact, this is the main reason my next PC is going to have an AMD CPU and GPU). These are my constraints:
+
* I need 125% fractional scaling for everything to look satisfactory on HiDPI.
+
* Wayland allows fractional scaling as an experimental feature, but I have an NVidia graphics card, which doesn't play nicely with Wayland yet, so I have to use Xorg.
+
* Xorg upstream no longer supports fractional scaling. Ubuntu developers have made patches to Xorg that enable fractional scaling. Fedora does not have these patches, and I don't wanna use Ubuntu, so I'll have to tweak Fedora.
+
* I don't want to spend a lot of time tweaking Fedora and trying to make tweaks reproducible in automation scripts.
+
+
GNOME has just been the easiest to satisfy these constraints. On Fedora, I need to enable the RPMFusion repos to install the proprietary NVidia driver, and then set the font scaling to 1.25 in gnome-tweak-tool. This has been enough for me for the past few years. Lately, in addition to wanting something lightweight, I've been wanting a reprieve from the bugginess and version incompatibilities of GNOME Shell Extensions. I'd rather not spend time fiddling around with things to make them "just right", or finding alternatives to things that aren't yet supported in the current version of GNOME.
+
+
## Enter Xfce
+
Tangent: I've been pronouncing it as "ex-fice" since I started using Linux and that pronunciation is pretty much soldered into my neural circuitry. Anyway...
+
+
I haven't used Xfce in a few years. For a time, I had been running Xubuntu as my daily driver, then Xfce on Arch Linux, and then MATE on Arch Linux, but this was back when I had a "normal" DPI screen. I think I tried Xfce once on my current screen and hastily decided it was more trouble than it was worth, and I had been so used to GNOME that anything else felt weird.
+
+
The other day I decided to give Fedora's Xfce edition a more thorough trial, and I'm glad I did. Xfce's custom DPI setting in the Appearance menu is a real treat. The panel profiles feature is also really great -- IIRC, this wasn't available the last time I used Xfce regularly. Xfce's panel has plenty of nice plugins that satisfy all my preferences as far as a panel is concerned. The Xfce Terminal has a nice dropdown feature that can be used with a keyboard shortcut. I also use Rofi for quick fuzzy app opening, file opening, emoji selecting, and keyboard shortcut searching. I am happy with this setup 😊
+
+
See screenshots below:
+
=> ../media/xfce-screenshot00.png Xfce desktop showing dropdown terminal
+
=> ../media/xfce-screenshot01.png Xfce desktop showing file manager and context menu
+
+
+
## END
+
Last updated: 2021-11-28
+
+
=> ./ Gemlog archive
+
=> ../ Back to hyperreal.coffee
+15
gemini/gemlog/2021-12-22-quick-note-on-glamorizing-mental-illness.gmi
···
+
# Quick note on "glamorizing" mental illness
+
+
=> https://youtu.be/R9il2-bfAp8 Its Cool To Have A Mental Illness - @SchizophrenicNYC
+
+
I don't associate "coolness" with something I wish I didn't have. When I make dark humor jokes about my mental health issues, the intent is not to glamorize the mental illness.
+
+
The social goal I have in mind when I do that is two-fold:
+
* It highlights an experience that I think is worth sharing, because sharing it promotes de-stigmatization and acceptance, which helps other people who might relate with it.
+
* It's a coping mechanism for me, a way to "pwn" my mental illness, so to speak. In other words, it's being like, "these are the sub-optimal coffee beans I've been dealt, and I'd have preferred to have been dealt better ones, but I might as well roast them dark and make them more palatable."
+
+
## END
+
Last updated: 2021-12-22
+
+
=> ../gemlog/ Gemlog archive
+
=> ../ Back to hyperreal.coffee
+23
gemini/gemlog/2021-12-26-how-do-i-pick-something-and-stick-with-it.gmi
···
+
# How do I pick something and stick with it?
+
+
Every day, my productivity consists of haphazardly going from one thing to the other. I'm too exhausted at the moment to describe it eloquently and humorously in a meme format.
+
+
Basically, within a span of thirty minutes, it's like: I'll work on the course on A Cloud Guru. But my Golang project, though. Perl, Raku. C++ problems on Exercism. Reading about init systems and why Systemd is bad. Perusing the runit documentation. Oh, I should probably update my VPS. I should write a gemlog post about my current thoughts on Systemd and my new computing setup with Void Linux musl, and why I enjoy using Void Linux. But I should really just focus on the A Cloud Guru course. I should scroll my Facebook feed and see what's happening. I'm going to respond to that comment. I'm going to comment on that other post. Now on to Twitter. Oh this Very Cool Person on Twitter posted a C++ tutorial, I should read that and then work on C++ problems on Exercism.
+
+
What the literal fuck.
+
+
I need to somehow prioritize and setup a sort of schedule that I'll follow weekly. Like Mondays and Wednesdays I can dedicate to A Cloud Guru lessons. Tuesdays and Thursdays are coding days, which would include working on my coding project or solving problems on Exercism. For this I'd have to make an informed choice about what programming languages I want to focus on. This choice must involve practical considerations, like what language is in demand for the type of job I want. And Fridays I can focus on reading, which would include technical material.
+
+
I need to pace myself and set time aside at the end of each day, like after dinner, for purely fun activites, such as light fiction reading and video-games. I would include socializing as a purely fun activity, but I'm not very good at socializing so it isn't as enjoyable as I'd like it to be. Nevertheless, I guess I can casually participate on IRC, Matrix, and Discord.
+
+
As far as programming languages go, Python is used almost everywhere, so I basically can't go wrong with Python. Forget Perl and Raku. C++? Idk.
+
+
I'm glad tomorrow is Monday so I can start this schedule on the proper beginning of the week.
+
+
I'm caregiving for my grandpa, which is mostly a 24/7 thing, so aside from these activities I have to sort of be basically on-call when my grandpa needs me in the other room, and also do these things around /his/ schedule.
+
+
## END
+
Last updated: 2021-12-26
+
+
=> ../gemlog/ Gemlog archive
+
=> ../ Back to hyperreal.coffee
+18
gemini/gemlog/2022-01-03-normalize-bidets.gmi
···
+
# Normalize bidets
+
+
Why they aren't already normalized is beyond me. I've never used one before -- I've never even seen one in person before -- but from what I've gathered, the benefits compared to traditional means make it a no-brainer.
+
+
* Easier to sanitize yourself
+
* Not abrasive to your skin back there
+
* Virtually no clogging of toilets
+
* No wet-wipes clogging up sewers
+
* Save money on toilet paper and wet-wipes
+
* Hands are less involved, so there is less cross-contamination
+
+
Someone on my Facebook also commented that "'feels like you're living in the future' is non-zero good in and of itself".
+
+
## END
+
Last updated: 2022-01-03
+
+
=> ../gemlog/ Gemlog archive
+
=> ../ Back to hyperreal.coffee
+12
gemini/gemlog/2022-01-06-re-is-there-a-word-for-nightmares-while-awake.gmi
···
+
# re: Is There a Word For Nightmares While Awake?
+
+
Responding to ew0k's post:
+
=> gemini://warmedal.se/~bjorn/posts/2022-01-06-is-there-a-word-for-nightmares-while-awake.gmi
+
+
I've used the term 'daymare' before, to refer to daydreams that aren't pleasant. This may be a different experience to what you have described, though. Sleep deprivation /may/ have something to do with the frequency of daymares, but I've always attributed them to my mental illness or even just the way my mind works fundamentally, at least as a common denominator. These are distinguished from flashbacks in that they don't seem to be necessarily triggered by anything external, nor do they involve reliving /specific/ past events. They might occur during my mental replaying of a given social event where I "extrapolate" or catastrophize the meaning of a social cue or something someone said. They also aren't the same as the images I experience from certain kinds of intrusive thoughts, but those do occur during daymares as well.
+
+
## END
+
Last updated: 2022-01-06
+
+
=> ../gemlog/ Gemlog archive
+
=> ../ Back to hyperreal.coffee
+13
gemini/gemlog/2022-01-17-something-that-bothers-me-about-conversations.gmi
···
+
# Something that bothers me about conversations generally
+
+
Something that bothers me about conversations generally, and especially on Twitter: When making claims, statements, or hot-takes on a given topic, and someone responds with a counter-point, there is often not enough feasible/appropriate room/time to really respond to the counter-point in an epistemically-sufficient way.
+
+
In in-person conversations, like say at a coffee shop or social gathering, this results in epistemic progress on the topic being stunted, unless each participant is willing to engage in a monologue and listen to the other participants' monologues. And this is assuming each participant has the working memory and experience to adequately convey the points they want to make and recall and respond to the other participants' points. But our social norms make this manner of dialogue inappropriate anyway.
+
+
At least on blogs, some social media, and forums, you can share links to references, give long-winded monologues on things, you have the time to gather your thoughts on the topic, and it's more socially appropriate to do that there than it is in-person. But that's not usually how people want to discuss things on social media, least of all on Twitter.
+
+
## END
+
Last updated: 2022-01-17
+
+
=> ../gemlog/ Gemlog archive
+
=> ../ Back to hyperreal.coffee
+21
gemini/gemlog/2022-01-29-editing-wikipedia-with-firejail.gmi
···
+
# Editing Wikipedia with Firejail
+
+
=> https://firejail.wordpress.com/ Firejail | security sandbox
+
+
I'm trying to get back into editing Wikipedia. Wikipedia has a policy that editors are not allowed to use VPNs or anything that hides their IP address, but makes an exception for users behind the Great Firewall of China and other countries that censor Internet access.
+
+
I didn't want to give up using my VPN -- currently Mullvad VPN, whose service I've been quite pleased with -- so I had to find a way to edit Wikipedia using the IP address from my ISP. On the Mullvad GUI app, there is a split tunneling feature that allows one to exclude certain apps from the VPN tunnel. Since I'm on Void Linux, which doesn't have a GUI app for Mullvad, I've been using Mullvad's Wireguard configuration files, so I've had to find another way to split the VPN tunnel per application.
+
+
Someone in the Wireguard IRC channel suggested I use Firejail, which turned out to be a great solution to this problem. I haven't really dived into Firejail documentation yet, but from what I understand, Firejail utilizes the Linux kernel's namespaces to create a new network stack within the sandbox that is isolated from the host's main network stack, which allows me to have applications in the sandbox that do not use the Wireguard interface of the VPN. So I've created a sandbox for the LibreWolf browser that I will use to edit Wikipedia. I've changed the Exec directive in LibreWolf's .desktop file to this command:
+
+
```
+
firejail --net=wlp3s0 --noprofile --dns=1.1.1.1 /home/jas/Applications/LibreWolf.x86_64_817ca3fd38e2c1623d580bee3afe36cc.AppImage
+
```
+
+
It works awesomely!
+
+
## END
+
Last updated: 2022-01-29
+
+
=> ../gemlog/ Gemlog archive
+
=> ../ Back to hyperreal.coffee
+33
gemini/gemlog/2022-05-27-sci-fi-plans-for-this-weekend.gmi
···
+
# Sci-fi plans for this weekend
+
+
For the next three days, my life is going to consist of reading Shadowrun books, (re)playing the Shadowrun trilogy on PC, and watching Stranger Things 4.
+
+
The Google Play Store has a sale for $4 off any ebook over $4. I bought Shadowrun Legends: Secrets of Power, which consists of three novels by Robert N. Charrette:
+
* Never Deal With A Dragon (1990)
+
* Choose Your Enemies Carefully (1991)
+
* Find Your Own Truth (1991)
+
+
I also got Shadowrun: Spells and Chrome, edited by John Helfers, which is an anthology of short fiction set in the Shadowrun universe.
+
+
Stranger Things 4 just released on Netflix today (2022-05-27).
+
+
I'm also starting a reading list for sci-fi, fantasy, and cyberpunk:
+
* Ender's Game and subsequent stories (Orson Scott Card)
+
* The Neuromancer and subsequent stories (William Gibson)
+
* Open for more suggestions!
+
+
Am also gonna have BBQ and bacon pizza for dinner tonight 😊
+
+
Oh, and it looks like we're in for some decent weathers here!
+
```bash
+
curl wttr.in/Chicago
+
```
+
+
=> https://en.wikipedia.org/wiki/List_of_Shadowrun_books#Novels Wikipedia - List of Shadowrun books
+
=> https://store.catalystgamelabs.com/products/shadowrun-anthology-vol-1-spells-chrome-digital Shadowrun Anthology: Spells and Chrome
+
+
## END
+
Last updated: 2022-05-27
+
+
=> ../gemlog/ Gemlog archive
+
=> ../ Back to hyperreal.coffee
+9
gemini/gemlog/2022-05-31-am-nervous-about-getting-into-dnd.gmi
···
+
# Am nervous about getting into DnD
+
+
Someday, I hope to have a page on my website and gemlog dedicated to my RPG OCs and RPGing generally. I'm still dreadfully nervous about finding a table-top gaming group to play with online. I've found a Discord server but the idea of talking to new people is daunting. I have severe social anxiety and speech issues, among other things, so in order for me to feel comfortable gaming, I'd have to be able to not use video or voice chat. Writing is my preferred communication style, but I'm just not sure if it is even feasible to play table-top RPGs without using video or voice. I've never played before.
+
+
## END
+
Last updated: 2022-05-31
+
+
=> ../gemlog/ Gemlog archive
+
=> ../ Back to hyperreal.coffee
+21
gemini/gemlog/2022-06-15-chat-app-overload.gmi
···
+
# Chat App Overload
+
+
So, instead of having three separate chat apps running on my desktop, cluttering up the taskbar and system tray, I just installed the Flatpak version of Ungoogled Chromium and am using the web versions of those apps. I keep my regular web browsing in Firefox. I've found this to be optimal. The chat apps I use are Cinny (Matrix client), Discord, Android Messages for Web, Slack, and The Lounge (IRC client).
+
+
* I don't have to use a clunky all-in-one chat app.
+
* I can use the Catppuccin theme for Discord with the Stylus extension.
+
* Cinny just works better in a browser.
+
* I don't have to open three Electron apps when I login to my desktop.
+
* I can run Android Messages and The Lounge in Ungoogled Chromium tabs and keep all my communication stuff in one place.
+
+
Yay!
+
+
=> https://github.com/catppuccin/catppuccin Catppuccin: Soothing pastel theme for the high-spirited!
+
+
## END
+
Last updated: 2022-06-15
+
+
=> ../gemlog/ Gemlog archive
+
=> ../ hyperreal.coffee
+
+
+44
gemini/gemlog/2022-07-07-comments-on-elder-scrolls-online-high-isle-spoilers.gmi
···
+
# Comments on The Elder Scrolls Online: High Isle (SPOILERS)
+
+
The new High Isle chapter was released on 2022-06-06. The chapter takes place on the Systres archipelago, which is located in Eltheric Ocean, north of Summerset Isles and west of Stros M'Kai. The Systres archipelago consists of three islands: High Isle, Amenos, and Y'ffelon.
+
+
## The Systres Archipelago
+
* High Isle: Most of the civilization resides here. The vibes I get are like a cross between High Rock and Summerset with a sort of Pacific volcanic landscape. The main city on High Isle is Gonfalon Bay. Most of the residents on High Isle are Breton nobles, but there are also tribes of Druids out in the surrounding wilderness.
+
* Amenos: North-east of High Isle. It's a tropical jungle. The main town is Amenos Station, which consists of a stockade where prisoners are sent. The surrounding jungle is inhospitable and people aren't expected to survive among the beasts and carnivorous plants. When the prisoners of Amenos Station go through "processing", they are released from the stockade and sent out to the jungle, and there are magical enchantments placed on them that prevent them from leaving the island. Some of these prisoners have formed a band called the Green Serpents, and are hostile to anyone who encounters them.
+
* Y'ffelon: A smaller island to the north, consisting of a semi-dormant volcano called Firesong mountain. This may be part of the zone in the next Q4 DLC.
+
+
## Noble houses
+
The Systres are led by two noble Breton houses: House Dufort and House Mornard.
+
+
* House Dufort: Led by Duchess Elea Dufort, they control most of Systres. Before their rise to nobility, the Duforts were a prosperous merchant family and reknown shipbuilders. Dufort and Mornard worked together to make High Isle a prosperous settlement, and eventually High Rock decided to elevate both families to nobility. Dufort were previously subordinate to House Mornard, but when Mornard lent support to Ranser in Ranser's War, they fell out of favor in Wayrest, and High King Emeric then seized many of Mornard's holdings and gave control of the Systres to House Dufort.
+
* House Mornard: Like the Duforts, the Mornards were a mercantile family when they settled on High Isle. As they worked with the Duforts to make High Isle prosperous, both houses were elevated to nobility, with Mornard granted a dukedom and Dufort granted a barony. Duke Mornard gave his house exclusive control over the mines and prison facilities on Amenos, which sparked a rivalry between the two families. Duke Avrippe Mornard's response to the Knahaten Flu in 2E 562 weakened the house's influence, and his support for Ranser in 2E 566 prompted the end to their reign as dukes. High King Emeric reduced their rank to count and, led by the Count Leonard Mornard, they now control only the mines and prisons on Amenos.
+
+
## New companions
+
The chapter introduces two new companions, Isobel and Ember. When you first meet Isobel, she is a Knight Aspirant, and her introduction quest involves winning a tournament held by the Knight Commander Jourvel. The Knight Commander offers her daughter Aurelia's hand in marriage to the winner of the Sapphire Tourney. Isobel and Aurelia are childhood friends, but some rumors around Castle Navire indicate that they may have been more than friends at one point. Isobel wishes to win the tournament in order to free her friend Aurelia from an unhappy marriage to any of the other Aspirants. You help Isobel on a quest to gain the favor of the three main Knightly Orders of High Isle: The Oaken Order, the Order of the Albatross, and the Order of the Iron Knot. Upon winning the tournament, Isobel is granted a favor from the Knight Commander, which she uses to free Aurelia from betrothal to allow her to make her own decisions. Isobel is then awarded a full Knighthood from Knight Commander Jourvel, and from this point the player is allowed to call on Isobel as a companion. Isobel's personality is similar to what one might expect from a Knight trope: honor, courage, and justice are her core values. Her moral alignment is more 'lawful good', and the player's rapport with Isobel will depend on whether the player makes 'lawful good' decisions.
+
+
Ember is introduced during the quest Tower Full of Trouble at Tor Draioch. A spell she was using went awry, and now she needs help cleaning up the mess before Magister Irin returns. Ember is a protege of Master Irin, and due to her impulsivity, Magister Irin has forbidden her from entering his Arcane Library. What I find refreshing to see is Ember's mixed skill set and her personality. She is very adept with magic, but is hyperactive and learns better by doing rather than by studying books. Consequently, she often finds herself cleaning up messes she makes from not thinking things through. She is also very adept at lockpicking, a skill she learned out of necessity from growing up on the streets. When you complete Ember's quest, Magister Irin returns and explains that he is not a suitable mentor for Ember, because her personality makes it difficult for her to take instruction in a traditional academic style. He hopes the player will allow Ember to accompany them so that she can develop her skills more efficiently. Ember is more of a 'chaotic good' alignment and does not mind the player getting their hands dirty.
+
+
## New creatures
+
As far as I've encountered, there are several new creatures introduced in this chapter:
+
+
* Fauns: Humanoids with the head and hooves of a deer. They are hostile, territorial, and live in tribes. They have an intelligence similar to goblins.
+
* Hadolids: Humanoids with crustacean-like features. Their upper body is reminiscent of dreughs. Also hostile and territorial. One quest on Amenos involves quelling a hadolid takeover of a House Mornard-run mine.
+
* Vulk'esh: Wamasu-like creatures that emerge from the volcanic vents scattered across the isles. They have a molten rock exterior and spew fire from their mouths.
+
* Coral haj mota: These are effectively the same as the haj mota you encounter elsewhere in Tamriel (e.g., in Blackmarsh, Hew's Bane, and some parts of Elseweyr), except the main difference is that their exterior is made of coral.
+
* Soulrazer knights: Undead knights about the size of frost atronachs. The Sable Knight world boss is a soulrazer knight and is said to be the first of its kind.
+
* Ornaugs: UESP Wiki describes them as fish-like canines. They are caninoid and have scales and fins. They are kind of similar to durzogs.
+
* Coraldrift bear: These are bears with coral exteriors. I've only encountered these in the Coral Cliffs delve located at the topmost point of Amenos.
+
+
## Druids
+
Druids are introduced in this chapter. They live in druidic circles out in the wilderness of the Systres. Their philosophy and nature magic is similar to that of the Wyrd covens of Glenumbra and Bangkorai. They worship Y'ffre and practice the True Way, which involves living a life connecting with and valuing the natural world. Unlike the Wyrd, they accept male members into their circles. The foremost philosophical difference between Druid and Wyrd is that Druids believe in living in harmony with non-Druid civilization while the Wyrd seek isolation from it. Each druidic circle interprets Y'ffre's will differently, and they also vary amongst one in other in their attitudes toward non-druids.
+
+
There are three known druidic circles in the Systres:
+
* Stonelore: Welcoming and cooperative with non-druids. They help investigate and soothe volcanic fissures throughout the Systres.
+
* Eldertide: Hostile to non-druids and even other druidic circles. They were involved in the capture of High King Emeric and Prince Irnskar, seeking to turn them over to the Ascendent Order. One group of Eldertide druids were responsible for raising coral out of the sea to wreck a ship carrying Maormer prisoners to Amenos Station.
+
* Firesong: Not much is known about these druids apart from the fact that they live primarily on the island of Y'ffelon and tend to the volcano called Firesong mountain.
+
+
## END
+
Last updated: 2022-07-15
+
+
=> ../gemlog/ Gemlog archive
+
=> ../ hyperreal.coffee
+23
gemini/gemlog/2022-07-15-glad-to-see-ocd-stereotypes-being-broken-up.gmi
···
+
# Glad to see OCD stereotypes being broken up
+
+
=> https://latitudes.org/forums/topic/19706-contamination-obsessions-and-poor-self-grooming/ Contamination obsessions and poor self-grooming
+
+
The first response is right on point: OCD is, by definition, not rational.
+
+
I can relate with the OP's son in that I have contamination obsessions and wash my hands probably more than the average person, and definitely way more than necessary. These obsessions aren't as bad as they used to be, but they're still there. Yet I can go days without showering.
+
+
One possible explanation I've had, and which might be the case for others, is that some instances of contamination obsessions are--for lack of a better term--self-serving. What I mean is that it's about keeping yourself quarantined from anything external, and you're not /quite/ as keen about not contaminating others. (I've personally been making an effort to be more considerate about this.) Since I'm mostly reclusive, not showering isn't putting up any "contamination!" red flags in my brain, at least not until I start to feel and smell gross enough.
+
+
That is to emphasize that /some instances of/ contamination obsessions are self-serving. Other instances are more general, or even specific to certain people in the sufferer's life. For example, I recall reading a post from a mother who suffered from post-partum OCD and had contamination obsessions that centered on her newborn daughter. She wasn't as much concerned about herself or her husband getting contaminated as she was about the health of her daughter.
+
+
Also, I've observed that the feeling of "feel and smell gross enough" is subjective and relative. Some people feel gross by the end of the day, and they shower at least once a day. Nose-blindness is a related but somewhat different phenomenon. When you rationalize not showering, you alter your frame of reference and set a new "standard".
+
+
The difference is that nose-blindness is more of a temporary/non-internalized thing. Like when your teenage son is playing video games online with his friends, blissfully unaware of the festering laundry smell permeating his bedroom. All he needs to do is leave the room for an hour or so and come back and notice the difference. On the other hand, this rationalizing not showering/altering frame of reference is more of an internalized belief that, if the person wants to change, requires restructuring daily habits -- in other words, behavioral intervention. It's more of an addiction-ish thing, and is still as much a part of the OCD process as cleaning compulsions.
+
+
**** I should note that I make no endorsement whatsoever of the site in the link above nor of the organization that sponsors it. I briefly just went through some of their treatment philosophy and I got the impression that they are largely supportive of the medical model of disability. The only thing I'm supporting is the experiences of the OP and various commenters on the forum.
+
+
## END
+
Last updated: 2022-07-15
+
+
=> ../gemlog/ Gemlog archive
+
=> ../ hyperreal.coffee
+21
gemini/gemlog/2022-07-28-wish-I-could-taper-off-meds.gmi
···
+
# I wish I could taper off my meds
+
+
> Content warning: mental health and medication
+
+
What I really wish I could do is taper off my meds as a sort of experiment. Sometimes I doubt whether I really need them.
+
+
What that would look like is that I'd need to be 100% sequestered for the duration of the tapering plus 6 months after the final dose. No responsibilities other than self-care. Sort of like a controlled rehab type thing.
+
+
I'd also need something like a benzodiazepine to help with the surge in anxiety and paranoia, but I'm not sure if that would be good because I don't want to become dependent on them.
+
+
No stimulants other than cigarettes and a drastic reduction in coffee intake (like to one cup a day). Cigarettes do make life more tolerable in the moment, and I can't imagine going through medication withdrawal without them. I could try to reduce the quantity I smoke. Without the medication balancing out my anxiety level, I'd probably end up reducing my intake of stimulants anyway due to operant conditioning, pairing the behavior (using the stimulant) with the unpleasantness of the uptick in anxiety.
+
+
I'd need to have all the comforts of home to help cope with withdrawal. It probably would be a good idea to somehow block social media so that I'm not tempted to let the monkeys run wild. Or maybe just keep it limited to posting feeling emojis and requesting support, as an Exposure Response Prevention sort of thing.
+
+
All this is probably unrealistic, but a guy can dream, I guess. If I had to bargain for it, I'd settle with tapering off of the current meds and trying out new ones that don't have the side effects, or where the side effects are less common.
+
+
## END
+
Last updated: 2022-07-28
+
+
=> ../gemlog/ Gemlog archive
+
=> ../ hyperreal.coffee
+25
gemini/gemlog/2022-09-09-what-i-look-forward-to-in-fall.gmi
···
+
# What I look forward to in the fall
+
+
Here are some things I'm stoked about for the upcoming fall season:
+
+
* Leaves changing into beautiful reds, oranges, browns, and yellows.
+
* The smell and feel of cool, crisp fall air.
+
* Hot apple cider
+
* Cold fizzy apple cider
+
* Pumpkin spice
+
* Halloween culture
+
* Thanksgiving
+
* Fedora 37 release. I'm looking forward to official Raspberry Pi 4 support.
+
* Elder Scrolls Online Q4 zone DLC (usually the first week of November on PC).
+
* Every year around November, I do a fresh install of the Windows operating system. It's kind of a yearly ritual.
+
* Playing through spooky survival horror games from my childhood (not really a yearly ritual but I have an itch to do it this year)
+
* Playing through the Dishonored series. This is also a yearly ritual since 2015. I feel that the aesthetic of the game pairs well with fall and spooky season.
+
* Homemade vegetable soup
+
* Chili
+
* Using my Halloween name on Twitter, Jeffrey Scary-o.
+
+
## END
+
Last updated: 2022-09-09
+
+
=> ../gemlog/ Gemlog archive
+
=> ../ hyperreal.coffee
+23
gemini/gemlog/2022-09-17-considering-using-ipfs-for-content-hosting.gmi
···
+
# Considering using IPFS for content hosting
+
+
=> https://ipfs.tech/ IPFS Powers the Distributed Web
+
+
I like the concept of IPFS. I'm considering using it to host my homepage and possibly my Gemini capsule, and to pin some resources pertaining to FOSS, mental health, and digital rights. I'm just not sure about its adjacency to the NFT/Web3 scene.
+
+
In theory, I would setup an IPFS node on my Digital Ocean VPS, and use DNSLink to link my domain to an IPFS content address that points to the latest version of my homepage. The IPFS node would also contain pinned web resources that I'd like to keep available through IPFS.
+
+
One could use IPFS for its decentralization aand p2p features without ever using Protocol Lab's Filecoin-based NFT and Web3 storage. At least Filecoin uses proof-of-storage cryptocurrency algorithms that are greener and fairer than the computation-based proof-of-work algorithm of Bitcoin, so that kind of eases my conscience a bit.
+
+
From what I've gathered, Filecoin uses proof-of-replication and proof-of-spacetime consensus algorithms. Proof-of-replication is a kind of proof-of-storage that ensures that a user is dedicating a unique physical storage location to a piece of data and does not have replicas of the data in the same location. This prevents servers from creating multiple "Sybil" identities that can provide valid proofs-of-storage for each replica, selling those replicas to the same user, and then deduplicating them to their original unique copy which would render the sold replicas invalid. Proof-of-spacetime ensures that a user is using a certain amount of storage space over a period of time.
+
+
=> https://filecoin.io/proof-of-replication.pdf Proof-of-Replication.pdf
+
+
Still, though, I don't like the idea of being complicit in the NFT/Web3 hype. Aside from the environmental hazards involved in minting NFTs and mining cryptocurrency, it's a Ponzi scheme that deceives people into investing monetary value into something that is inherently valueless and thrives off the delusion that they own the thing.
+
+
=> https://web3isgoinggreat.com/ Web3 is going just great
+
+
## END
+
Last updated: 2022-09-18
+
+
=> ../gemlog/ Gemlog archive
+
=> ../ hyperreal.coffee
+15
gemini/gemlog/2023-02-01-re-i-got-a-new-tablet.gmi
···
+
# RE: StackSmith: I got a new tablet
+
+
=> gemini://gemini.ctrl-c.club/~stack/gemlog/2023-01-31.tablet.gmi Original post: StackSmith: I got a new tablet
+
+
I currently own a Pine64 RockPro64 and a Quartz64. I recently bought the 7 inch LCD display with the Playbox enclosure and Wifi/Bluetooth module. This would enable me to turn either the RockPro64 or Quartz64 into a tablet. The current OS options available for RockPro64 are a stock Android 9 rom, postmarketOS with various UI options, or I could run Manjaro ARM and install Plasma Mobile. For the Quartz64, the only OS options currently available are a development version of an Android 11 ROM or Manjaro ARM.
+
+
It would be really nice if LineageOS supported these devices but that does not appear to be in their future plans. I ran LineageOS on my previous tablet, which was a Samsung Galaxy Tab S2 (Wifi version), but it died abou a year ago.
+
+
The LineageOS version I used on my old tablet had Open GApps installed, which provided replacments for the standard Google Apps typically installed by default on Android. Instead of the Play Store, there was the Aurora Store, which had some hack that allowed you to login anonymously with your Google credentials, and this circumvented Google tracking the apps you install. So it might be worth looking into a custom ROM that offers Open GApps.
+
+
## END
+
Last updated: 2023-02-01
+
+
=> ../gemlog Gemlog archive
+
=> ../ hyperreal.coffee
+15
gemini/gemlog/2023-03-12-morality-in-dream-content.gmi
···
+
# Morality in dream content
+
+
The dreams that I can remember the next day are rarely concrete enough to describe in words, but last night I had an odd one. It's amusing how, as far as I can recall, the dreams just, like, seamlessly place you into a certain context that makes sense in the dream.
+
+
> I ordered a pizza, and for some reason which made sense in the dream, it was supposed to be delivered to the southeast corner of an intersection four blocks from where I live. It was delivered and left on the ground at the intersection. I avoided interacting with the delivery driver because I didn't want to give him a tip, it seems because I just didn't want to pay extra money, so I stayed in my car. My car was parked about (roughly, seemingly) 20 feet from the southeast corner of the intersection, but facing south, and in the U.S. this means it was on the wrong side of the road. But weirdly it seems like the road was a one-way street going south, even though in reality it is a two-way street running north-south. The delivery person left without a tip. Someone was sitting in a car parked across the street, near the southwest corner of the intersection. They saw that I didn't leave a tip for the delivery driver and reproached me for it.
+
+
What stands out to me about this dream is that I violated an ethic that I've internalized as good to follow such that not following it is selfish, rude, or entitled. I occasionally have similar ethic-violation dreams that involve common everyday things, such as being pulled over by the police and getting a ticket, or forgetting a deadline for some important event and getting in trouble, or situations in which I made a selfish decision.
+
+
I'm not into deep, abstract dream interpretation. I don't think there is some hidden message or any kind of deep symbolism or metaphor, at least from my perspective and in my experience. I do think, like in the dreams I described above, there is some moral quality to some of them, and that it's like, your brain takes your moral anxiety as an input and cobbles some mostly random sequence of events together as some kind of...I don't know, warning, maybe? Like, I'd bet these kinds of dreams are especially common in morally scrupulous people, respective to their moral values.
+
+
## END
+
Last updated: 2023-03-12
+
+
=> ../gemlog Gemlog archive
+
=> ../ hyperreal.coffee
+25
gemini/gemlog/2023-05-14-migration-to-truenas.gmi
···
+
# Migration to TrueNAS
+
+
My homelab now runs TrueNAS. I have FreeBSD jails for my Gemini server and Mastodon instance, Transmission instance, and Borg backup repositories. Each jail has its own ZFS dataset within the main storage pool.
+
+
TrueNAS offers automatic snapshot scheduling and replication. With this, I've replaced three Borg backup tasks that were carried out over SSH and were rather slow. I have a separate jail and ZFS dataset that contains a Borg repository that my Fedora PC backs up to over SSH.
+
+
I find it somewhat refreshing doing things the old-fashioned BSD UNIX way without Systemd. In some way, it feels simpler, more flexible, and less cumbersome. Running a script on a schedule consists of adding a single-line crontab entry instead of writing a Systemd service and timer for it and making sure it's allowed by SELinux. There are some security trade-offs with this approach, as not having SELinux doing access control increases the attack surface. Net traffic to the services running in the jail has to pass through a Suricata gateway first, so hopefully this would sufficiently mitigate any threats.
+
+
FreeBSD has a Tailscale package in their repository. I have a tailnet setup between a Linode VPS, where my domain points to and which runs Rocky Linux 9, and the FreeBSD jail that runs my Mastodon instance and Gemini server. Suricata is integrated with Firewalld on the VPS, and it mediates traffic that is forwarded to the tailnet node in the FreeBSD jail.
+
+
Setting up and migrating my Mastodon instance to FreeBSD was probably the hardest thing to do here. I ran into some compatibility issues with Ruby 3.1 and the version of Rails that Mastodon recommends, so I had to edit the Gemfile by hand to ensure a specific version of the 'psych' gem is installed by bundler. Installing Mastodon on Linux involves using rbenv to manage the Ruby version; on FreeBSD, the recommended way is to use the latest Mastodon version available in the ports tree, which has Ruby 3.1 as a hard dependency. I suppose it's technically possible to install Mastodon from source via Git and use rbenv to manage the Ruby version, but the Mastodon in the FreeBSD ports tree has instructions that setup FreeBSD-appropriate users, groups, filesystem paths, init services, and permissions.
+
+
I've never felt quite satisfied with any homelab setup I've done. There was always something or other that didn't sit right with me and would make me want to re-think the whole setup. I definitely want a next-generation filesystem like Btrfs or ZFS to store all the data with compression and snapshot/rollback capabilities. I want to maintain some extent of security-by-isolation, either with containers or virtual machines, but I've found both of those methods cumbersome on Proxmox or even when using Fedora Server as a sort of hypervisor.
+
+
I'd prefer to avoid Ubuntu because of practical and philosophical opinions I have about how they do things; namely, insisting on Snapcraft.io packages over regular DEB packages, Canonical's decision to exclude and discourage Flatpaks in Ubuntu and its flavors, basically forcing the flavors into accepting Snapcraft snaps.
+
+
Fedora Server is great and I prefer the Fedora/RHEL ecosystem over anything, but I also prefer to maximize service uptime and minimize reboots, as core system libraries and kernels are updated frequently -- not that this is an altogether *bad* thing, but it's just a lot of upkeep and disruption. I still use Fedora as my daily driver OS. Rocky Linux, Almalinux, or CentOS Stream are stable, long-term enterprise server distributions, so that would minimize frequent service disruption; however, none of them support Btrfs for the root filesystem, and their package repositories are heavily geared toward enterprise computing which means some of the tools that make life easier on the command-line aren't available even with EPEL enabled.
+
+
FreeBSD's Jails and BSD UNIX approach to system administration with things like init and task scheduling, along with native ZFS support, seems to be working out pretty well for the time being. FreeBSD's package repositories are pretty up-to-date, and there's also the ports tree. TrueNAS's documentation includes a primer for ZFS among other useful resources, and the FreeBSD Handbook is indispensible as well. I still have a lot to learn about how Jails work and specifically how their features differ from LXC containers (aside from the fact that they don't use cgroups that are specific to the Linux kernel). So, until I happen upon something better, TrueNAS will be my setup for now.
+
+
## END
+
Last updated: 2023-05-14
+
+
=> ../gemlog Gemlog archive
+
=> ../ hyperreal.coffee
+186
gemini/gemlog/2023-06-11-yet-another-homelab-setup.gmi
···
+
# Yet Another Homelab Setup
+
+
I have a new homelab setup. I've been homelab-hopping for the past year or so, and with each new setup, something or other just never sat right with me. It always felt like there was something that could be made better or more effcient with the resources I had. I recently discovered the wonderful world of LXD, and I was excited over how robust the technology is, so I endeavored to make my homelab setup with it.
+
+
My homelab consists of two physical machines: a System76 Thelio Major, and an ASUS mini PC.
+
+
## Specs
+
+
Thelio Major:
+
* OS: Ubuntu Server 22.04 LTS
+
* CPU: AMD Ryzen 7 7700X, 8 cores, 16 threads @ 4.5 GHz
+
* GPU: AMD ATI Radeon RX 6600 XT/6600M
+
* RAM: 32 GB
+
* Internal HD: 1 TB NVMe
+
* External HD: two 5 TB SSD, formatted as a ZFS mirror pool
+
+
ASUS Mini PC:
+
* OS: TrueNAS CORE
+
* CPU: AMD Ryzen 7 5700U, 8 cores, 16 threads @ 1.8 GHz
+
* GPU: AMD Radeon
+
* RAM: 16 GB
+
* Internal HD: 500 GB NVMe
+
* External HD: 5 TB SSD, used as the main storage pool
+
+
## Main "control center"
+
+
> I may rename this machine and set its hostname to "nexus.local", because it seems fitting given its purpose, and I happen to like the word "nexus". :-)
+
+
The bulk of my homelab activity resides on the Thelio Major. The web services that my homelab runs are separated into LXD containers. I'm using LXD as a more resource-friendly alternative to virtual machines. I have two 5 TB external SSDs that make up a ZFS mirror pool. I have a dataset on my ZFS mirror being used for an LXD storage pool, with LXD's ZFS storage driver. My LXD setup consists of the following containers:
+
+
* debian-archive
+
* debian-serv
+
* fedora-transmission
+
* ubuntu-mastodon
+
+
I have a Linode VPS running HAproxy on Rocky Linux 9. My domain, hyperreal.coffee, and subdomains mastodon.hyperreal.coffee, irc.hyperreal.coffee, and rss.hyperreal.coffee all point to this VPS, and HAproxy takes care of routing traffic to them to their respective backends. Tailscale is installed on the VPS as well as in my debian-serv and ubuntu-mastodon LXD containers. The LXD containers' Tailnet IP addresses are used for the backends that HAproxy routes requests to. It's roughly this:
+
+
* hyperreal.coffee -> debian-serv
+
* irc.hyperreal.coffee -> debian-serv
+
* rss.hyperreal.coffee -> debian-serv
+
* mastodon.hyperreal.coffee -> ubuntu-mastodon
+
+
+
### Creating the containers
+
+
To create the LXD containers, I run the lxc init command and supply it with an image, the name of the container, and the storage pool I want the container to use:
+
+
```
+
lxc init images:debian/12/cloud debian-archive --storage lxd-pool
+
```
+
+
I need to use images suffixed with /cloud in order to use cloud-init to initialize the containers. With the container created, I then supply it with a cloud-init configuration as shown below:
+
+
```
+
lxc config set debian-archive cloud-init.user-data - <<- EOF
+
#cloud-config
+
users:
+
- name: debian
+
ssh_authorized_keys:
+
- ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIIOmibToJQ8JZpSFLH3482oxvpD56QAfu4ndoofbew5t jas@si.local
+
sudo: 'ALL=(ALL) NOPASSWD: ALL'
+
shell: /bin/bash
+
lock_passwd: true
+
apt:
+
sources_list: |
+
deb http://deb.debian.org/debian $RELEASE main
+
deb http://deb.debian.org/debian $RELEASE-updates main
+
deb http://deb.debian.org/debian-security/ $RELEASE-security main
+
deb http://deb.debian.org/debian $RELEASE-backports
+
package_update: true
+
package_upgrade: true
+
packages:
+
- curl
+
- debian-keyring
+
- debsig-verify
+
- git
+
- nodejs
+
- npm
+
- notmuch
+
- offlineimap3
+
- pass
+
- python3-dev
+
- python3-pip
+
- ripgrep
+
- ssh
+
- wget
+
- xauth
+
- youtube-dl
+
rsyslog:
+
configs:
+
- content: "*.* @10.0.0.41:514"
+
filename: 99-forward.conf
+
remotes:
+
moonshadow: 10.0.0.41
+
timezone: America/Chicago
+
EOF
+
```
+
+
After setting the cloud-init configuration, I then start the container and monitor the progress of cloud-init:
+
+
```
+
lxc start debian-archive
+
lxc exec debian-archive -- cloud-init status --wait
+
```
+
+
When this finishes, the container is ready to go. I have Ansible roles for setting up my homelab services. These roles can be viewed at the Codeberg repository below.
+
+
=> https://codeberg.org/hyperreal/ansible-homelab
+
+
### Snapshots
+
+
Each of my LXD containers except for fedora-transmission are on daily snapshot schedules. This is configured with the lxc command as shown below:
+
+
```
+
lxc config set debian-archive snapshots.schedule "0 23 * * *"
+
```
+
+
I can also set the snapshot naming pattern:
+
+
```
+
lxc config set debian-archive snapshots.pattern "{{ creation_date|date:'2006-01-02_15-04-05' }}"
+
```
+
+
A cool thing about these snapshots is that they are easily pluggable. If the container instance fails for whatever reason, I can rollback to a previous working state using the lxc command:
+
+
```
+
lxc restore debian-archive 2023-06-08_22-59-17
+
```
+
+
The snapshots can also include running state information like process memory state and TCP connections by passing the --stateful flag when creating the snapshot:
+
+
```
+
lxc snapshot debian-archive snapshot0 --stateful
+
```
+
+
Because I'm not lacking for storage space, I set the expiry date for 1 week, which keeps a week's worth of snapshots on disk:
+
+
```
+
lxc config set debian-archive snapshots.expiry "1w"
+
```
+
+
LXD uses the ZFS storage driver and creates ZFS snapshots. I have a task on my TrueNAS server that replicates these snapshots daily into an offsite dataset.
+
+
### debian-archive
+
+
A Debian container that runs my ArchiveBox instance and stores my mail offline. I have the Proton Mail bridge running in a fake tty to keep the connection open locally, and offlineimap runs daily to download my mail from my Proton Mail account. The mail is then indexed by notmuch. This container is not accessible from the public Internet, so only I have access to it from my workstation machine.
+
+
### debian-serv
+
+
A Debian container that runs Caddy web server and Molly Brown Gemini server; these serve my HTTP website, Gemini server, The Lounge IRC instance, and FreshRSS instance. These are accessible from the public Internet, but FreshRSS and The Lounge are only used by me.
+
+
* hyperreal.coffee -> web and Gemini
+
* irc.hyperreal.coffee -> The Lounge IRC
+
* rss.hyperreal.coffee -> FreshRSS
+
+
Because HAproxy doesn't deal with the Gemini protocol, I have a firewalld rule on the VPS that forwards port 1965 to port 1965 in the debian-serv LXD container via the Tailnet. Currently, I have ~/public on my workstation as a sort of mirror for ~/public on debian-serv. When I edit my web site or Gemini caspule, I edit the files in ~/public on my workstation and just rsync the directory to debian-serv. I have port 4444 on the LXD host mapped to port 22 (SSH) in debian-serv, so when I rsync the files I have to use the -e 'ssh -p 4444' as an rsync argument. I'm looking for a way to keep those directories constantly in sync, and lsyncd seems to be the way to go. NixOS doesn't install a systemd service for lsyncd, so I'd have to write my own.
+
+
### fedora-transmission
+
+
A Fedora container that runs transmission-daemon. I chose Fedora because, unlike Debian and Ubuntu, Fedora has Transmission version 4. Not that my use-case specifically relies on version 4, but I just prefer to use the latest stable versions of things wherever feasible. I learned that Alpine Linux has Transmission version 4 in their repositories, so I'll eventually use an Alpine LXD container for the transmission-daemon. This LXD container is not accessible from the public Internet; I have port 9091 forwarded from the LXD host to port 9091 in the container, so I access the Transmission web interface from my local subnet. I also use the Transmission RPC API client for Go to manage torrents programmatically.
+
+
=> https://github.com/hekmon/transmissionrpc
+
+
> Side note: I've updated hekmon/transmissionrpc to support Transmission version 4, which uses RPC v17. My pull request can be seen by following the link below. It works on my machine for the tasks I use it for, but it still needs testers so that hekmon can merge it into main.
+
> => https://github.com/hekmon/transmissionrpc/pull/21
+
+
### ubuntu-mastodon
+
+
An Ubuntu container that runs my Mastodon instance. I chose Ubuntu because it's easier to setup Mastodon than it is on Fedora, but it was mostly done as a sort of proof-of-concept when I was initially learning about LXD, so I may migrate it to Fedora eventually. I prefer Fedora's package and tooling ecosystem and the security benefits of SELinux. My Mastodon instance is available from the public Internet (it has to be), so this LXD container forms a part of my Tailnet, and receives HTTP/S requests to mastodon.hyperreal.coffee from HAproxy upstream on the VPS.
+
+
+
## TrueNAS server
+
+
My TrueNAS server is used solely as a NAS. It currently only has one 5 TB external HD that it uses as the main storage pool, but I may eventually get another one to create a ZFS mirror. It has a replication task that runs once a day and pulls LXD snapshots from the main nexus server. I also have a dataset on here that receives daily snapshots from my NixOS workstation machine via znapzend. I recently ordered a new laptop, a Lenovo Thinkpad X1 Carbon Gen 10 Intel (14") with Linux pre-installed -- though, of course, I'll install my own OS when I receive it. I intend to install NixOS on ZFS root on it, which I will configure to send daily snapshots to my TrueNAS server. The ZFS on root setup for NixOS is based on the repository below, which is geared toward setting up multiple hosts:
+
+
=> https://github.com/ne9z/dotfiles-nixos
+
+
## Closing
+
+
As I mentioned above, and as anyone who's been following me on here or other places on the Internet can tell, I've been super indecisive when it comes to my homelab setup. I've hopped between several different setups over the past year, never feeling quite satisfied with any. I can't say whether I will change my setup again in the future (it's possible, and given my track record, pretty likely)... but, with my current hardware, LXD containers, and TrueNAS CORE, I can honestly say that I've never been more satisifed with a homelab setup.
+
+
## END
+
Last updated: 2023-06-11
+
+
=> ./ Gemlog archive
+
=> ../ hyperreal.coffee
+23
gemini/gemlog/2023-08-29-invega-withdrawal-day-24.gmi
···
+
# Invega withdrawal and other things
+
+
It has been 24 days that I've been on 4.5 mg of Invega. No noticeable withdrawal effects today.
+
+
Other than the "benign" paranoia that is constantly present in my mind and which I don't think will ever go away, I haven't had any episodes of the panicky paranoia aside from that one day last week. My cognition feels basically the same as it did on the higher dose. I had panicky paranoia episodes on that too.
+
+
My mood seems stable today.
+
+
I have been feeling sad and lonely/socially alienated intermittently. This seems to be an outcome of social anxiety and rejection sensitivity. The other day I made a minor mistake on a public GitHub repository and felt stupid/terrible about it, and my brain probably made a bigger deal out of it than it actually was (catastrophizing).
+
+
I did a lot of manual labor today. I cut the grass early this morning. Then my new sleeping recliner arrived via FedEx, so I had to unbox it, move the old one out of my room, bring the pieces of the new one into my room, and assemble the new one. I feel physically taxed.
+
+
I didn't do any significant tech-related things today. I just did routine checking on my homelab servers.
+
+
Someone on Twitter mentioned that they were taking a break from Twitter and focusing on developing their skills without needing to continually post about it or do a play-by-play of their progress. I think this is a good idea. So tomorrow and for the rest of the week, I'm going to continue working on Hack the Box Academy modules as my main task during the day.
+
+
Right now, it is almost 4:30 pm, and I feel content with taking advantage of an Invega-withdrawal-free day by relaxing and playing Baldur's Gate 3.
+
+
## END
+
Last updated: 2023-08-29
+
+
=> ../gemlog/ Gemlog archive
+
=> ../ hyperreal.coffee
+29
gemini/gemlog/2024-01-11-home-networking-madness.gmi
···
+
# Home Networking Madness
+
+
I'd like to setup some sort of network segmentation on my home network. The following is just a rough brainstorming before I do any in-depth research, but I'd like to publish it here in case anyone with experience can offer suggestions, and it also helps me sort out my thoughts.
+
+
## Reasons for wanting network segmentation
+
* I can eliminate the need for a VPS. My current setup involves pointing my domain name to the VPS using Linode's nameservers in my domain registrar. The VPS then uses firewalld to forward all traffic to relevant ports to my homelab (which is currently behind a NAT) through a Tailscale network. Having my domain pointing directly to my homelab machine would reduce any overhead such a setup creates, and it would simplify things like HTTP redirection for reverse-proxied services.
+
+
* Eliminating the need for a VPS would also save me $5 a month. $5 a month isn't really a big deal, but the less I have to spend, the better.
+
+
* The reason I have this setup to begin with is so that I don't have to use port forwarding on my home router and open up my network to malicious traffic and cyberattacks. With network segmentation, I can keep the public-facing homelab servers isolated from my personal devices, which would keep potential cyberattacks confined to the public-facing server and away from my private data.
+
+
## Technical constraints
+
* I have a 5 Gbps fiber Internet connection from my ISP. Whatever OS or networking software I use to setup network segmentation must be used on my main homelab machine, because none of my other devices (save for my desktop PC) are 5GbE-capable. If I can do this with just firewalld alone, that would be perfect, but I feel like I might need more specialized networking software/tools. I'll configure IP passthrough on my ISP router to make the homelab machine receive the public IP address.
+
+
* Would OpenVSwitch be useful for a situation like this? Does it allow the creation of VLANs? I've never used it before so I'm completely clueless about it.
+
+
* If I have to run something like OpenWrt or OPNsense in a virtual machine on the main homelab machine, that would be fine, but I have to find out if the virtual network interfaces of the hypervisor (libvirt/QEMU) inherit the link speed of the host interface. If they don't, then I might need to buy another (relatively inexpensive) machine that is 5GbE-capable, which I'd prefer not to do.
+
+
* I'd obviously need a good free and open source SIEM solution.
+
+
* I might also need DDoS protection, which I might have to pay for, but I'd like to avoid using Cloudflare. Another alternative would just be to let Linode manage my domain and DNS entries and have the records point to my homelab's public IP address. Though I don't know if I'd still get DDoS protection from Linode if I don't have a Linode VPS, which is another thing I'd have to look into (but I'm leaning toward probably not).
+
+
I would have been able to use another machine for firewall/routing purposes, because I bought a dual 10GbE to Thunderbolt 3 adapter, which is about the size of a standard masonry brick. It turns out the USB-C connector on the machine I inteded to plug the adapter into is not in fact a Thunderbolt 3-capable port, even though the port is a USB-C connector. I thought they were the same thing, but apparently not (the more I know). So I ended up returning the Thunderbolt brick and getting my money back. Honestly good riddance, because the brick was pricey and would have consumed extra power (it had a power cord and fan built in, but I suppose the extra power is needed for the Thunderbolt conversion). I might as well just get a machine with dual 10GbE or 5GbE ports for about relatively the same price.
+
+
On the other hand, for the 5 Gbps fiber connection, I'm currently locked into a 12-month contract with Earthlink. Next November I think I'll just downgrade to 2.5 Gbps. I'm not sure there is any noticeable practical benefit to 5 Gbps over 2.5 Gbps for my Internet usage. Most things on the Internet are <= 2.5 Gbps anyway and it's not like 2.5 Gbps isn't ultra-fast enough.
+
+
Of course, I could have, and should have, done more research before agreeing to the 5 Gbps 12-month contract. Live and learn, I guess.
+
+
I can technically downgrade before the 12-month contract is up, but I'd have to pay a fee. If downgrading to 2.5 Gbps saves me money every month, and if the sum total amount I save by November is more than the fee they'd charge me for breaking the contract, then it would be worth it.
+32
gemini/gemlog/2024-07-20-i-finally-sorted-out-my-self-hosting-stuff.gmi
···
+
# I finally sorted out my self-hosting stuff
+
+
I think. Infodump commencing...
+
+
## My previous setup
+
My previous setup included running nirn.quest services on a $30/month SeedHost.eu dedicated server, and my hyperreal.coffee services in a virtual machine in my homelab. For the latter, I had Linode managing the DNS for my hyperreal.coffee domain, and the domain itself pointed to a $5/month Linode VPS, which used Tailscale to forward HTTP and port 1965 traffic to the virtual machine in my homelab.
+
+
I originally got the $30/month SeedHost.eu dedicated server with 8T of storage to use as a seedbox for Sci Hub torrents. I later decided to get a dedicated app hosting package for $173/month, which included 72T of storage and a 10Gbps network throughput speed. I figured this was better for torrenting Sci Hub. I then repurposed the $30/month dedicated server and started running nirn.quest services on it.
+
+
With this previous setup, I would be spending $30 + $173 + $5 = $208/month.
+
+
## My current setup
+
The previous setup was fine until I found a $18/month dedicated server on netcup.de, which has better specs minus the 8T storage space. I don't really need the 8T anymore, since I now have a dedicated app hosting package on SeedHost that can store the entire Sci Hub collection. This netcup.de dedicated server has 256G storage which is plenty for my use-case. On this new dedicated server from netcup.de, I can host everything I had on hyperreal.coffee as well as nirn.quest. So I decided to start using only my hyperreal.coffee domain, which simplifies things like DNS and web server configuration. The nirn.quest domain will expire in a few months, and it was super cheap--like $3 if I recall correctly--so I'm not too sore about leaving it but for the cool domain name. The netcup.de dedicated server is located in Manassas, Virginia, US. Now that everything is being hosted there, I no longer need Linode to manage my hyperreal.coffee domain, nor do I need a Linode VPS to act as a relay between the Internet and my homelab virtual machine. My monthly expenditure will now be $18 + $173 = $191/month.
+
+
My Mastodon instance uses ElasticSearch for full-text search. When the ElasticSearch daemon runs, it automatically allocates half of the available RAM on the host. To conserve the total available 16G of RAM on my remote server, I have a Tailscale connection between a virtual machine on my homelab running ElasticSearch and my new remote netcup.de server where my Mastodon instance is running. On my homelab virtual machine, Firewalld is configured to only accept connections to port 9200 from the remote server's Tailnet IP address.
+
+
## Backups
+
I'm using Wasabi object storage for backups of Mastodon and important files on the remote server. I've written a backup script that utilizes rclone to sync and copy the files to the configured Wasabi remote. I'm currently trying to figure out how to properly setup using a Wasabi bucket for Mastodon S3 object storage. I'm pretty sure I have everything configured as it should be, but when I set `S3_ENABLED=true` and reload Mastodon, the avatars and attachments are blank, and I get S3 XML AccessDenied error messages when attempting to view resources in their own tab. According to the guide 'Getting Mastodon working with Amazon S3 file-hosting', this means the permissions on either the files or the bucket are not set correctly. When using `awscli` to sync the `public/system/` folder over to the bucket, I made sure to use the `--acl public-read` option, but this didn't seem to work. I wondered if it is because Wasabi does not enable public access to the buckets by default, so I emailed Wasabi support, and they suggested a more secure work-around that doesn't seem to git with my Mastodon use-case. So, until I can get this sorted out, I'm using local filesystem storage on my instance.
+
+
Wasabi costs $6.99/TB/month, which isn't too bad when I have less than 1T of data. Eventually, I'm going to ask SeedHost.eu if they can offer MinIO as an app option for dedicated app hosting. Then I would be able to use some of the 72T for S3-compatible object storage and not have to pay extra for Wasabi.
+
+
## Sci Hub torrents
+
I'm going to peruse the awesome-libgen repository for things I can use to help Sci Hub and the broader open access movement. I had an idea to write a Python script that (1) checks for which Sci Hub torrents need seeders and (2) configure my qBittorrent instance to prioritize those torrents.
+
+
## Other notes
+
Since I don't pay the electric bill, I've been making it a point not to use too much energy with my computers and homelab equipment. I'm not currently using my OPNsense device, and my homelab is now basically just my TrueNAS machine + my remote dedicated server. My Orange Pi 5+'s and Pine64 devices are currently out of commission. Someday soon when I get a job, move to a place of my own, and pay my own electric bill, I will start using them again. My daily driver setup right now includes my workstation PC, my gaming PC, my laptop, my smartphone, my ISP router, a 2.5Gbps Ethernet switch, and my TrueNAS machine. The gaming PC and laptop go into sleep mode to conserve energy when I'm not using them.
+
+
## END
+
Last updated: 2024-07-20
+
+
=> ../gemlog Gemlog archive
+
=> ../ Back to hyperreal.coffee
+19
gemini/gemlog/2024-07-26-thoughts-on-tilde-hosting.gmi
···
+
# Thoughts on tilde hosting
+
+
I had considered running my own tilde, but like...
+
+
1. It's a lot of work for one person. Having to manage /other/ users adds an order of complexity to the administration load. I think I'm fine hosting various web services and privacy front-ends.
+
+
2. There are already plenty of great tildes out there. It would be better if I just contribute to those.
+
+
I've been out-sourcing my RSS aggregation to (previously) envs.net and (now) vern.cc. envs.net offers TinyTinyRSS, and I find the UI/UX rather cumbersome and annoying. vern.cc offers FreshRSS and Miniflux. I've come to prefer the minimalism of Miniflux. It has just what I want and nothing more. I can also use it with elfeed on Emacs. I signed up to use vern.cc's Soju IRC bouncer. I'm currently running my own instance of The Lounge, but I like Soju's features, and the senpai IRC client seems to suck less than the other options.
+
+
=> gemini://vern.cc vern.cc
+
=> gemini://envs.net envs.net
+
=> https://soju.im soju
+
+
## END
+
Last updated: 2024-07-26
+
+
=> ../gemlog gemlog index
+
=> ../ hyperreal.coffee
+18
gemini/gemlog/2024-08-20-listening-to-podcasts-while-driving.gmi
···
+
# Listening to podcasts while driving
+
+
I've become frustrated constantly switching through our local radio stations to find something I want to listen to while driving, especially when more than one of those stations plays ads for like 10 minutes between songs. For a while I had been just turning off the radio and driving in silence, or with whatever entertainment or chaotic discontent my brain afforded to me.
+
+
I solved this problem by buying a USB-C to 3.5 audio aux jack so that I can connect my Google Pixel 6 (running GrapheneOS) to the aux port in my car. This enables me to listen to podcasts or run a music playlist on my phone through the car's speakers when I drive.
+
+
The podcasts I've been enjoying lately include the Self-Hosted Show and LINUX Unplugged, both from Jupiter Broadcasting. It's so refreshing to listen to stuff I want to listen to and not what radio stations impose on me. Driving is now somewhat more tolerable.
+
+
I look forward to the day when I can afford a car that is capable of running an open source operating system where I can install a podcast app. Like GrapheneOS for auto-mobile devices, or something.
+
+
=> https://linuxunplugged.com/ LINUX Unplugged
+
=> https://selfhosted.show/ Self-Hosted Show
+
+
## END
+
Last updated: 2024-08-20
+
+
=> ../gemlog/ Gemlog archive
+
=> ../ hyperreal.coffee
+27
gemini/gemlog/2024-08-30-reducing-social-media-cross-posting-complexity.gmi
···
+
# Reducing social media cross-posting complexity
+
+
## Resources
+
=> https://github.com/charmbracelet/gum gum: A tool for glamorous shell scripts
+
=> https://github.com/charmbracelet/bubbletea bubbletea: A powerful little TUI framework
+
=> https://github.com/charmbracelet/huh huh: Build terminal forms and prompts
+
+
What could be useful for me to minimize the complexity of cross-posting to Facebook, Twitter, Bsky, and Mastodon: a Python or Go program that does the following:
+
+
* Connects to my accounts via API.
+
* Uses gum, bubbletea, or huh to prompt the user for the post content.
+
* Editing, replying, and/or delete functionality would be seamless with the exception of Bsky and Twitter, in which case I'd have to delete the post and redo it.
+
* Command-line flags for --facebook, --twitter, --bsky, and --mastodon to control which accounts to make the post to. If no account flags are supplied, then assume all. If Bsky, Twitter, and Mastodon are explicitly or implicitly passed, provide visual feedback to the user about the number of characters. The complements of each flag could also be supplied to exclude accounts, e.g. --no-twitter. Accounts can also be configured in a JSON file to avoid using command-line flags.
+
* Can post photos by providing the absolute path to the file(s) on the local filesystem.
+
* Allows using content warnings Mastodon-style at the top of the post. On Mastodon it would use the content warning feature. On Twitter, Bsky, and Facebook it would place "CW: <text>" at the top of the post.
+
* Allows using sensitive content shields for photos.
+
* Allows adding alt-text.
+
* Allows tagging accounts by parsing a tag format like "%twitter:@account", "%bsky:@account". Tagged accounts on one platform would only apply to that platform. The tag format syntax would otherwise not show up in the post. Account tags and hashtags would not be used inline; they would be added to the end of the post and based on user input from optional account tag and hashtag prompts.
+
* Possibly an option for some hacky string gymnastics to prevent URLs from creating link previews. I dunno if this is feasible unless there is a way to opt out of them that is built in to the API methods, e.g. by adding a specific boolean parameter to the API request or something. It seems this would even benefit the platforms by reducing the load on the servers from resolving the links. I haven't looked at the APIs yet, though. But also there might be a reason there isn't, namely so that the platforms can validate the legitimacy of the links.
+
+
I'm eager, but not quite ready to get started on this yet, as I have other coding projects to refine and other entropy to clean up.
+
+
## END
+
Last updated: 2024-08-30
+
+
=> ../gemlog/ Gemlog archive
+
=> ../ hyperreal.coffee
+19
gemini/gemlog/2024-09-19-experimenting-with-freebsd-fate-of-invidious.gmi
···
+
# Experimenting with FreeBSD and comments on the future of Invidious
+
+
## Experimenting with FreeBSD
+
I've always admired the BSD family of operating systems even though I mostly use Linux. I currently run a Debian Linux server that hosts a bunch of alternative services like PrivateBin, Invidious, RedLib, etc. Most of these require the use of Docker and/or systemd. Docker doesn't seem to be a hard requirement, though, because inside the Dockerfile there has got to be a Unixy way to setup and run the services. So I'm planning on spinning up a temporary FreeBSD VPS on Vultr and experimenting with getting those services running without Docker. If all goes well, I will convert my main Debian server to FreeBSD. One thing I would miss, however, is FirewallD. BSD's PF (Packet Filter) firewall doesn't have a command-line interface to interact with firewall policies. As far as I know, everything goes into a /etc/pf.conf configuration file. I'd have to look into PF configuration options that are effectively the same as the ones I use with FirewallD.
+
+
UPDATE: Someone in the fediverse mentioned the pfctl command. I don't know how much functionality this command has compared to something like firewall-cmd, but I'll peruse the man page regardless. Maybe I can even write some Bash functions that make managing PF easier from the command line.
+
+
## Comments on the future of the Invidious project
+
It's currently broken on my instance because of Google blocking the use of the API to by-pass the ads. From what I understand, it's a bit of an arms race between the Invidious developers circumventing the Google blocks and Google catching on and imposing more restrictions. I'm not sure about the future of the project. Hosting an Invidious instance, and keeping in line with the requirements to remain an official instance recommended by the project in their instances liste, heavily relies on Docker workflows, so it might not be feasible for me to get it running on FreeBSD and continue to satisfy those requirements. I don't think it's worth running an instance until a more permanent solution to the Google blocking problem is found, anyway.
+
+
See the first link below, which is an issue reported on the Invidious GitHub repo, for more information on what's going on with it. Every time there is a fix, a new problem pops up that breaks Invidious instances. The final comment by unixfox (Invidious developer) on the aforementioned GitHub issue was the last straw for me. Previous fixes require using and depending on a bunch of hacky tools from the developers that aren't guaranteed to be long-term solutions. I very much appreciate the time the devs have put into the project. I really, really hate Google's unrelenting mission to break the fixes in order to maintain their ad-driven monopoly on video content. YouTube is just too popular to fail at this point, and Google will never let it fail. The only way forward that I can see from here is just to promote PeerTube in the fediverse or other FOSS video hosting alternatives.
+
+
=> https://github.com/iv-org/invidious/issues/4734# [Bug] "This helps protect our community." #4734
+
+
## END
+
Last updated: 2024-09-19
+
+
=> ../gemlog gemlog archive
+
=> ../ hyperreal.coffee
+24
gemini/gemlog/2024-09-20-i-want-to-tell-google-to-eff-off.gmi
···
+
# I want to tell Google to eff off
+
+
I'm thinking of deleting my Google account. I've downloaded all my Gmail data. I know I have some services that use my old Gmail address. I need to think about how this might affect my interconnected system of Internet services that have dependencies on my Google account. Changing my email on services still using my Gmail is mostly trivial. I just have to remember/find out what all those services are. I can peruse through my Gmail archive that is mostly spam or unwanted email and see if there are any critical services I'd have to change my email address for. I figure going back about six months through my Gmail archive would suffice. Any entity that doesn't contact me during a six month period likely doesn't have any important tendrils attached, and I probably don't want anything to do with them, either.
+
+
I would also lose access to my YouTube account, which is fine, because I don't mind using it without logging in. If need be, I can use Invidious during times when the Invidious devs have the upper hand in the arms race. I can also use it with youtube-dl + VLC or something.
+
+
I've been able to download my ebooks from Google Play Books and put them into a Calibre library. If I want new ebooks in the future, I'd like to find a non-big-tech service to download them from via the Calibre interface. However, since I have and frequently use an Amazon account, I suppose Amazon will become my new ebook supplier for the time being. I also don't know if any non-big-tech ebook services I might find would have the ebooks that I want available in their catalog.
+
+
I'm also trying to have just one email address. I currently have four, besides the Gmail one, that are in use by various services. Three of them are all part of my Proton Mail account, so they all go to the same inbox.
+
+
* verandis@protonmail.com: permanent, main Proton Mail account.
+
* hyperreal64@pm.me: part of my Proton Mail account, but I've been trying to phase it out.
+
* hyperreal@moonshadow.dev: permanent, in use as a custom domain for my Proton Mail account. I'm trying to make this my main one.
+
* hyperreal@fedoraproject.org: an alias from the Fedora Project that is provided to Fedora contributors. It forwards to my Proton Mail account. It was mostly just for bling to represent my involvement with the Fedora Project. I still consider myself very much part of the Fedora community, but my personality/neurodivergence/what-not is such that I can't make a monogamous for-life commitment to any one distro. I feel more comfortable making a for-life commitment to the broader free and open source movement.
+
+
I now use GrapheneOS on my Google Pixel 6, so in some sense there are still some minor Googly tendrils stuck in me. The Google Pixel 6 is getting old, but it still works tolerably well. Perhaps soon I will get a PinePhone or some other non-big-tech device to run GrapheneOS or PostmarketOS. It's a matter of whether my cellular carrier supports it.
+
+
I'm sure there are some other things I'm mising here in my personal tech ecosystem bubble that depend on me having a Google account.
+
+
## END
+
Last updated: 2024-09-20
+
+
=> ../gemlog gemlog archive
+
=> ../ hyperreal.coffee
+34
gemini/gemlog/2024-09-30-rubber-duck-helps-me-debug-my-daily-driver-issues.gmi
···
+
# Rubber duck helps me debug my daily driver issues
+
+
ME
+
>I love Fedora, but I don't like having to do updates and reboot more than once a week. If only there was a Debian-like LTS for Fedora ...
+
+
RUBBER DUCK
+
>There kinda is. You could install Rocky Linux, AlmaLinux, or CentOS Stream and use one of those as your daily driver. I mean, you use Nix as a package manager anyway, so it's not like you'll miss anything from the Fedora repos.
+
+
ME
+
>Oh, uh, you might actually be onto something there, Rubber duck. But the idea of using an enterprise server-oriented distro as my daily driver? That ... that doesn't quite sit right with me.
+
+
RUBBER DUCK
+
>Well, you could also try Fedora Kinoite. It's rock-solid, and you would only have to run `rpm-ostree update` once a week. You could setup a basic toolbox container with Distrobox and install the Nix package manager via the daemon-less single-user method. The toolbox container could even be Debian stable.
+
+
ME
+
>Yeah 🤔. That does sound very appealing. And I wouldn't mind using the latest Fedora as a toolbox container; it's mostly when running updates requires a reboot because the kernel and core system libraries were updated. With the toolbox container, at most I would just have to restart the container. For other graphical applications, I could either use flatpaks or install them with Nix and configure `update-desktop-database` to search for them in my Nix profile. There is really no hard reason I need to do anything important outside the mutable parts of the filesystem. Aside from the /home directory, /etc and /usr/local are also mutable.
+
+
RUBBER DUCK
+
>Yep. Also, if you're going the immutable-ish route, you might as well just use NixOS, then, no?
+
+
ME
+
>Yeah, I've tried that before, but the filesystem and userspace just felt ... I dunno ... /weird/. And using the Nix language for anything other than development environments and home directory configuration feels rather ... I dunno ... /weird/. And I'd rather not get lost in the labyrinth of a Nix flakes rabbit hole. It just seems needlessly complicated for little benefit, to me. My goal is to find something and stick with it consistently, and have it be my daily driver, the same way my physical desk is just here, and reliable, and low maintenance. I want to avoid wasting time fussing about with my NixOS configuration.
+
+
RUBBER DUCK
+
>Fair enough, I hear you.
+
+
ME
+
>Anyway, I think I know what I want now. Thanks for the chat, Rubber duck!
+
+
## END
+
Last updated: 2024-09-30
+
+
=> ../gemlog gemlog archive
+
=> ../ hyperreal.coffee
+49
gemini/gemlog/2024-11-24-home-networking-and-preventing-dns-leaks.gmi
···
+
# Home networking and preventing DNS leaks
+
+
> Originally posted on my weblog on 2024-10-13
+
+
I'm thinking of getting my OPNsense device back up again. At my previous place of residence, I had AT&T internet, and AT&T had all sorts of configurable options in their modem that played well with my OPNsense device. At my current place of residence, I have Xfinity Comcast, and the only option I can configure on their modem that would allow me to use my OPNsense device is "Enable/disable bridge mode". When I first moved in here, I tried doing that, but for some reason the IPv4 gateway on my OPNsense device wasn't picking up anything. I believe I had everything configured correctly, the Xfinity modem was in Bridge mode, and the OPNsense router was assigned the public IP address from my Xfinity account. This was four months ago, and it's very likely I missed something in the configuration, so it can't hurt to try again. The worst-case scenario is that I reset my Xfinity modem to factory defaults and continue to use that. But it would sure be nice if I could have more control over that portion of my internet.
+
+
I think I've figured out how to prevent my Fedora Linux desktop from leaking DNS to Xfinity. My Linux desktop is part of a Tailscale network that uses Mullvad's ad-blocking and malware blocking public DNS server, but I still have DNS laks because my main network interface is using the Xfinity DNS servers from its DHCP connection via the Xfinity modem. Below are the steps I took to prevent DNS leaks to Xfinity.
+
+
## systemd-networkd
+
+
NetworkManager is the default on Fedora 40. I disabled NetworkManager and enabled systemd-networkd with the following configuration:
+
+
```
+
[Match]
+
Name=eno1
+
+
[Network]
+
DHCP=yes
+
DNS=100.100.100.100
+
DNSSEC=allow-downgrade
+
+
[DHCPv4]
+
UseDNS=no
+
```
+
+
In the `[DHCPv4]` section, `UseDNS=no` ensures that you're not using the DNS servers provided by the DHCP connection. In my case, my DHCP connection via my Xfinity modem was setting the DNS to the Xfinity DNS servers. So that is no longer the case now. For good measure, I added my tailnet's DNS as a static DNS server in the `[Network]` section.
+
+
`resolvectl status` now shows that my primary network interface `eno1` uses only the DNS from my Tailscale network, which is `100.100.100.100`.
+
+
## Disable IPv6
+
+
Another possible source of DNS leaks is IPv6. On Fedora 40, the way to disable IPv6 is by adding a kernel argument to the GRUB bootloader configuration. This can be done with the following command:
+
+
```
+
sudo grubby --args=ipv6.disable=1 --update-kernel=ALL
+
sudo grub2-mkconfig -o /boot/grub2/grub.cfg
+
```
+
+
Reboot the system for the change to take effect.
+
+
## Ensure Firefox or LibreWolf are not using DNS over HTTPS
+
+
In most cases Firefox/LibreWolf are configured to use the system DNS resolver by default, but if you have it configured to use one of the "protection" settings for DNS over HTTPS, this could be a source of DNS leaks. Setting it to "Off - Use your default DNS resolver" fixes this issue.
+
+
## END
+
Last updated: 2024-11-24
+
+
=> ../gemlog gemlog archive
+
=> ../ back to hyperreal.coffee
+19
gemini/gemlog/2024-11-24-invega-mental-health-and-hygiene.gmi
···
+
# Invega, mental health, and hygiene
+
+
> Originally posted on my weblog on 2024-10-11
+
+
Since I've been on a lower dose of Invega, I've noticed that I've had more spoons for maintaining my hygiene. This may be coincidental, or it may be causative.
+
+
In retrospect, during my adult years, my poor hygiene correlates with increases in my Invega dose. 2011-2019 were probably the most unhygienic years for me, and that coincides with being on 9-12 mg of Invega. Invega causes me to be fatigued and drowsy during the day, which means I have less spoons for maintaining my hygiene. Also, it's one thing to not have energy for maintaining my hygiene, but it's another to simply not care about it. Whatever Invega does to my brain chemistry that reduces positive symptoms of psychosis somehow also makes me care less about my hygiene. Barring other possible reasons, if it is the case that Invega causes me to care less about hygiene, then I would expect to get my "normal" pre-Invega hygiene habits back if I were weened off completely. It's almost like Invega decreased positive symptoms of psychosis and traded them off for an increase in negative symptoms.
+
+
Before Invega, I cared a lot about my hygiene, sometimes even irrationally so. 2003-2006 me would never let me go a day without shower or cleaning my teeth. But, maybe this reflects more my values regarding hygiene back then compared to my values from 2011-2019. And the uptick in hygiene-consciousness today could be related to my general mental health improvement, which in turn could be related to natural changes in my brain as I've aged. Another possibility is that my reclusiveness could affect whether I consider taking care of my hygiene to be worth it. But if that were the case, then it wouldn't explain why I'm more hygiene-conscious today, because I'm still just as reclusive. I want to be and feel clean for my own comfort and peace of mind.
+
+
I haven't noticed any significant uptick in positive symptoms of psychosis since I've been on 4.5 mg of Invega (since early September). My general anxiety and social anxiety have remained about the same, with better and worse days, as usual. I've been more talkative, more energy to vocally and verbally express what's on my mind. In fact, I feel like I've had more "content" available on my mind to express. The relation between energy levels, verbal/vocal expression/articulation, and thought content is not clear to me. Paranoia-related intrusive thoughts as not as prominent today, or they are more easily dispelled by reason.
+
+
Someone on Twitter a while back asked if I've ever been hospitalized. I never really needed to be. My personality made me more withdrawn and wanting to isolate. I've had times of paranoia-influenced quarrelsome behavior with other people, but it was never to the point of being a danger to myself or others. I also had other more intense moments, but if I describe those here then I would be airing my dirty laundry, so I won't do that. For the most part, I've felt in control of my behavior. To qualify the previous statement: I'm more outspoken and comfortable expressing my thoughts and feelings in text on the Internet, so my social inhibitions are lower for what I consider appropriate to express verbally. If I feel paranoid and suspicious of people on the Internet, I'm more likely to express it verbally and confront them, whereas in person I'm more likely to escape, withdraw, and avoid confrontation.
+
+
## END
+
Last updated: 2024-10-11
+
+
=> ./gemlog gemlog archive
+
=> ../ back to hyperreal.coffee
+31
gemini/gemlog/2024-11-24-on-using-reproducible-python-development-environments.gmi
···
+
# On using reproducible Python development environments
+
+
> Originally posted on my weblog on 2024-11-05
+
+
One of the things I find annoying about using Python is that there are so many ways of making the development environment of a package or set of scripts reproducible. I have a repository that contains several Python scripts that help me with various tasks, mostly related to qBittorrent. Maybe one or two of these scripts can be separated out into a distinct, individual package, but it's generally more convenient for me to have a directory-level development environment activated with direnv where I can run the other scripts too. I've been using `nix-shell` with a shell.nix file, but this tends to require that I learn the Nix expression language in order to configure shell.nix. I don't like using tools I don't fully understand, and I'm not willing to prioritize learning Nix. It would be nice if I could just use a TOML file to declare everything I need, similar to pyproject.toml, and `nix-shell` would read this instead of shell.nix. As far as I know, the Nix language doesn't have a way to map the TOML structure to Nix expressions. I've tried devenv.sh, but this adds extra files and cruft that I don't want polluting my development environment. If I use a plain requirements.txt file with a virtualenv, it can't pull in the Python tools I use, like black, isort, bpython, and pyright.
+
+
One solution I'm leaning toward is to install these tools with pipx, where they'd be available to my shell environment relative to my home directory at `~/.local/bin`, and use something like
+
+
```
+
uv venv
+
source .venv/bin/activate
+
uv pip install -r requirements.txt
+
echo "layout python3" > .envrc
+
direnv allow
+
printf ".venv\n.direnv\n" | tee -a .gitignore
+
```
+
+
direnv would activate the virtualenv, which in turn would be relative to that git repository directory.
+
+
I'm open to suggestions and am curious how others might have solved this problem. Feel free to reach out to me in the Fediverse at @hyperreal@fedi.hyperreal.coffee.
+
+
## Links
+
+
=> https://codeberg.org/hyperreal/admin-scripts codeberg.org/hyperreal/admin-scripts
+
=> https://devenv.sh/ devenv.sh
+
+
## END
+
Last updated: 2024-11-05
+
+
=> ../gemlog gemlog archive
+
=> ../ back to hyperreal.coffee
+22
gemini/gemlog/2024-12-08-my-speech-language-enhancing-technology-wishes.gmi
···
+
# My speech/language-enhancing technology wishes
+
+
I wish there was a speech/language technology that could:
+
+
1. Interface with my brain, somehow.
+
2. Instantaneously (like milliseconds) create a rough model of /the ideas I want to express verbally/ at any given moment.
+
3. Find words, phrases, and social scripts that are as close to a 1:1 correspondence with /the ideas I want to express verbally/ as our language permits, and present these to my brain for me to choose on my own volition.
+
+
Could we hypothetically leverage LLM technology to do this? I feel like this would be super practical for me specifically because of my speech issues.
+
+
I feel like it would also enhance my language skills, because:
+
+
1. More information/options would be presented to my brain that would enable me to use my best human judgment in choosing appropriate words, phrases, and social scripts for a given social situation.
+
2. After some amount of repetition of these patterns, I would eventually /learn/ better ways to express ideas for a given social situation, and gradually become less reliant on the technology.
+
+
Though, there would still be times when I just don't have the cognitive spoons to articulate things myself, and in these instances I wouldn't mind the technology doing it for me, and all I would have to do is the physical act of vocalizing it.
+
+
## END
+
Last updated: 2024-12-08
+
+
=> ../gemlog Gemlog archive
+
=> ../ hyperreal.coffee
+47
gemini/gemlog/2024-12-09-my-tentative-file-syncing-solution.gmi
···
+
# My tentative file-syncing solution
+
+
The devices I want to keep certain files in sync between are my Linux desktop, Linux laptop, gaming PC, and Android phone. The gaming PC and Android phone are not strictly necessary to keep in sync with the others, but it's moderately convenient to have certain files synced and available on them.
+
+
For my Linux desktop and laptop, I will continue to use rsync. I have a justfile that contains commands that sync between them using their tailnet FQDNs.
+
+
```shell
+
.justfile
+
+
to-laptop:
+
rsync -aAXP /home/jas/sync/ jas@laptop.tailnet.ts.net:/home/jas/sync
+
+
to-desktop:
+
rsync -aAXP /home/jas/sync/ jas@desktop.tailnet.ts.net:/home/jas/sync
+
```
+
+
I only use my laptop when I leave the house to a location where I have enough time and convenient space to set it up and use for a while. I also use it while still at the house if I'm on my desk treadmill or sitting out on the deck in the backyard. Before leaving the desktop and using the laptop, I would run `just to-laptop`, and vice versa before leaving the laptop and going back to the desktop.
+
+
For my gaming PC and Android phone, there is a Proton Drive client for both Windows and Android, so I have it installed on those devices. I could then use rclone from my Linux desktop or laptop to sync the contents of the `/home/jas/sync` directory to Proton Drive. I would add the following to my justfile:
+
+
```shell
+
.justfile
+
+
to-protondrive:
+
rclone sync --transfers 16 -P /home/jas/sync/ protondrive:/
+
+
from-protondrive:
+
rclone sync --transfers 16 -P protondrive:/ /home/jas/sync
+
```
+
+
I usually tend to know ahead of time whether I will need to use any of the above commands -- rarely is there a time when I'm using one device and find myself in need of a file that exists on another device. So this will suffice until Proton Technologies develops a Proton Drive client for Linux.
+
+
Regarding Proton Technologies developing a Proton Drive client for Linux: I'm starting to wonder if it's a matter of /if/ rather than /when/. It doesn't seem to be a priority for them at this time, which I find kind of baffling. It makes sense from an economic standpoint to only support macOS, iOS, Windows, and Android, since the majority of devices in the world run one of those. I'm just surprised that they don't make the Linux desktop a priority out of principle because they otherwise seem dedicated to privacy and FOSS.
+
+
I was using MEGA sync for a while, and maybe I'll just go back to using that. They have clients for Linux, and they also seem dedicated to privacy and FOSS. It's just that...I have 500 GB of storage on Proton Drive with my Proton Plus account and it irks me that I can't use it the way I want to.
+
+
I'm aware of the Celeste app, which is supposedd to be a Dropbox-like GUI solution that allows syncing with multiple cloud services, including Proton Drive. I've tried it twice, and it always kind of froze when syncing with Proton Drive. The Celeste app is still under development so there are many rough edges to smooth out, but I believe it uses rclone for Proton Drive anyway.
+
+
=> https://just.systems/ just - just a command runner
+
=> https://mega.io/ MEGA Sync
+
=> https://github.com/hwittenborn/celeste Celeste
+
+
## END
+
Last updated: 2024-12-09
+
+
=> ../gemlog Gemlog archive
+
=> ../ hyperreal.coffee
+21
gemini/gemlog/2024-12-11-20-years-of-mental-illness.gmi
···
+
# 20 years of mental illness
+
+
20 years ago (autumn of 2004) I experienced the full onset of schizoaffective disorder. In retrospect, I would say the prodromal phase began around the spring of 2004, because that's when things started to feel different, and when I started having ideations of a delusional quality.
+
+
In the autumn of 2004, I had a panic attack** after work one night, and I believe this marked the onset of my condition, because I instantly became more acutely paranoid and socially withdrawn. I'd go entire days at school avoiding everyone I didn't have to interact with. I didn't socialize for fun, because I was paranoid and highly suspicious of almost everyone except close family members. I thought there was some huge conspiracy, and my parents, siblings, and other family members weren't in on it, and that this was by design ofthe conspirators. The conspirators I believed were people at school and work. I didn't have any concept of exactly what the conspiracy was about; I just keenly felt that there as /something/ going on, and that there was some hidden line of communication between school and work.
+
+
At this point, whoever I was before that, my entire self-concept, disintegrated, melted away into nothing. In retrospect, I think about how I thought of myself back then, and I can't pick out anything that I identified with. I was like a robot that was programmed to show up to school, and then go to work. Weirdly, I was able to work well at my job as a bus boy and dishwasher at a restaurant, because apparently robots are diligent and don't waste time socializing with other coworkers. When I had to speak to customers and the wait staff, I was extremely passive, my voice was monotonous and lacking any personal quality. As a bus boy, I had compulsions to clean off the dirty tables a certain way after the customers had left, and stack dishes on the bussing cart a certain way. I had figured this way was efficient, predictable, and added structure to a mostly unpredictable workflow.
+
+
This is just a snippet/snapshot of my experience back then -- there are many layers I can unfold about symptoms I experienced during this period, like body dysmorphia, social phobia, and perceptual abnormalities that I recognize in retrospect. I'm not willing to spend time unfolding those here, but I would be willing if anyone asked about it.
+
+
Three years later in September of 2007, after realizing that /something is not quite right/ with my brain and seeking professional help, I was diagnosed with schizoaffective disorder (depressive type) and OCD. I don't know what the diagnostic process consisted of, or what information they had about me, but I don't think they based the entire diagnosis on a single one-on-one interview with me describing my symptoms. I would imagine they got records and information from my school and my guidance counselor and from the psychiatrist I was seeing at the time. I'm not sure if they would bother my previous employer or coworkers to ask about my behavior -- maybe there is a legal reason they wouldn't.
+
+
I don't know how else to end this blog post. Someone on Facebook shared an old photo of themself from 2004, and it got me thinking of what I was doing in 2004. It reminded me of the fact that it's been 20 years now. I just wanted to relate a snapshot of what it was like back then. I'm doing better today, and I think I have a more solid self-concept.
+
+
** What I mean by /panic attack/ here is that I started hyperventiliating, my vision got blurry, I felt like I was in slow-motion, and I collapsed to the ground. People sometimes describe non-panic attack anxiety as "butterflies in the stomach", but I would describe the abdominal feeling I experienced at that moment to have been more like a swarm of vampire bats. I don't think I blacked out. I got up after about a minute and got my bearings, but things were very not okay afterward. I don't think I slept at all that night. I went to school the next day probably looking like I saw a ghost. If anyone was paying attention to my body language, they would have seen that something was wrong. I think this is around the time I went to see my guidance counselor and I just started balling, I couldn't hold back the crying. I think I went to see my guidance counselor to ask if I can switch out of a class with a teacher I was paranoid about.
+
+
## END
+
Last updated: 2024-12-09
+
+
=> ../gemlog Gemlog archive
+
=> ../ hyperreal.coffee
+52
gemini/gemlog/2024-12-12-my-nas-solution-and-other-homelab-projects.gmi
···
+
# My NAS solution and other homelab projects
+
+
Back in April (2024), I built a NAS machine with the following components:
+
* CPU: 12th Gen Intel i5-12600K 10-core (16 threads) at 4.9GHz with integrated graphics (Alderlake-S GT1)
+
* RAM: 64 GB (4x16GB) Corsair Vengeance LPX DDR4
+
* Silverstone Technology CS382 8-bay SAS-12G/SATA-6G hot-swappable Micro ATX NAS chassis
+
* four Seagate Exos X22 20TB SATA 6Gb/s 7200RPM 3.5-inch Enterprise HDDs
+
* Corsair SF850L fully modular low-noise SFX power supply
+
* MSI PRO B760M-A WiFi DDR4 ProSeries motherboard, 2.5Gbps LAN
+
+
## Network-attached storage solution
+
+
When I moved back in with my parents in June, I had this machine running for a couple months. My parents, who pay the electric bill, are strict about conserving energy and saving money, so they yell at me for leaving lights on and such. (But they have their own "parent math", such that they get mad when lights are needlessly left on but they justify other expenditures that seem needless to me. But it's their money, so.) I figured having this NAS machine running 24/7 was probably contributing to a good portion of the electric bill. So I decided to buy a 4-bay external NAS hard drive enclosure that supports up to 80 TB, and connect this to my laptop to use as a NAS solution. I used this for a while until last week, when I decided to get the NAS machine I built back up and running again. I told my parents that I will pay them $50 a month toward the electric bill. They are fine with this deal.
+
+
I didn't bother taking the hard drives out of the 4-bay external NAS enclosure, and I just connected itto a USB port on the back of the NAS machine. The NAS chassis I bought is built to hold up to 8 HDDs, but the motherboard only has 4 SATA connector ports, so the machine can only support 4 HDDs. If I ever want to expand from 80 TB up to 160 TB, I can do that, but 80 TB is plenty, at least for now.
+
+
I previously used TrueNAS SCALE on the NAS machine when I first got it back in April and until I shelved it. Now it runs regular Debian, which gives me more granular control over the system than the sort of locked-down approach of TrueNAS. The four 20 TB enterprise HDDs are part of a RAID0 ZFS pool. Perhaps if I want redundancy in the future I can get four more 20 TB HDDs and make them mirror the other four, but redundancy is not really a priority for the type of data I store on them. I only really want redundancy for personal data, not public archive data. On my Linux desktop, I have a 5 TB Btrfs RAID1 mirror that consists of three 5 TB external HDDs, and on this 5 TB RAID1 mirror I have my personal data in an encrypted Borgbackup repository. For additional redundancy and separation I also have this Borgbackup repository mirrored on my Linux desktop's 1 TB local hard drive.
+
+
My NAS machine also runs some local services, like Invidious, Grafana, Prometheus, Loki, Promtail, Linkding, qBittorrent, and two qBittorrent Prometheus exporters. One of those qBittorrent exporters is for my local qBittorrent instance where I torrent Linux distribution ISOs and other stuff that is legal in the U.S. The other qBittorrent exporter is for my remote qBittorrent instance on SeedHost that resides in Amsterdam, which I use for public digital archive stuff.
+
+
## Kubernetes cluster
+
+
I have three Orange Pi 5 Plus devices that are currently doing nothing right now. I came across an article[1] for setting up a K3s cluster on Orange Pi 5 Plus running Armbian. I'm considering doing this. I also came across another article[2] for setting up Ollama in a Kubernetes cluster, and there's also a way to set it up with TrueCharts. Ollama is about as ethical as LLM use can get at this time. It allows you to download open source LLMs and run them locally. I came across another article[3] that discusses generating alt-text from images with LLaVA. Most of the time my brain deadlocks when I want to describe an image for alt-text, so I've tended to avoid doing it. This causes friction with my belief that content on the Internet should be accessible to visually-impaired users. Lately I've been trying to get into the habit of adding alt-text to the best of my ability, but it takes a lot, and I fear that even the little I can do at a given time is inadequate, which isn't fair to visually-impaired users. So I find this to be an acceptable use-case for LLMs. I generally believe LLMs have a ton of potential for accessibility.
+
+
Other things I'm considering running on the Orange Pi 5 Plus Kubernetes cluster:
+
+
=> https://truecharts.org/charts/incubator/semaphore Semaphore : An open source alternative to Ansible Tower, which allows you to create, manage, and monitor Ansible projects, playbooks, and roles.
+
=> https://truecharts.org/charts/premium/blocky blocky : DNS proxy, DNS enhancer, and ad-blocker for the LAN written in Go.
+
=> https://truecharts.org/charts/premium/vaultwarden Vaultwarden : Unofficial Bitwarden compatible server written in Rust. I wouldn't use this as a replacement for Bitwarden, but I would use it to mirror my Bitwarden vault locally.
+
=> https://truecharts.org/charts/stable/apt-cacher-ng apt-cacher-ng : Caching proxy for Debian packages, but apparently not limited to Debian.
+
=> https://github.com/atuinsh/atuin Atuin : magical shell history. It replaces existing shell history with a SQLite database and records additional context for your commands. Can also sync shell history across devices.
+
=> https://truecharts.org/charts/stable/calibre/ calibre : An open source e-book manager. I currently use the desktop version of calibre, but I think it's worth seeing how running it in a K3s cluster would work out. Additionally, calibre-web.
+
=> https://truecharts.org/charts/stable/ciao/ ciao : Checks HTTP(S) URL endpoints for a status code and sends notification on change via email or webhooks. I might also just deploy this on my NAS machine.
+
=> https://truecharts.org/charts/stable/netbootxyz netboot.xyz : PXE boot for any type of operating system or utility disk. Could be highly useful for me.
+
=> https://truecharts.org/charts/stable/pihole Pihole : If not blocky, then Pihole.
+
=> https://truecharts.org/charts/stable/protonmail-bridge protonmail-bridge : This could be highly useful for me to have available on my LAN.
+
=> https://truecharts.org/charts/stable/seafile Seafile : File-sync solution. Maybe?
+
=> https://truecharts.org/charts/stable/tailscale Tailscale : Obviously need to have these services accessible on my tailnet somehow.
+
+
I might also run Invidious, Grafana, Prometheus, Loki, Promtail, and rsyslog on the K3s cluster, though I'd prefer not to mess with their current installation on my NAS machine. I doubt I will have every one of the above services setup on the cluster, but they are definitely good candidates. I would also need to find a way to make my NAS storage available to the cluster.
+
+
## Links
+
+
=> https://jobcespedes.dev/2023/11/building-a-k3s-cluster-with-armbian-on-orange-pi-5-plus/ Building a K3s Cluster with Armbian on Orange Pi 5 Plus
+
=> https://md.vern.cc/@yuxiaojian/host-your-own-ollama-service-in-a-cloud-kubernetes-k8s-cluster-c818ca84a055 Host Your Own Ollama Service in a Cloud Kubernetes (K8s) Cluster
+
=> https://notes.unindented.org/notes/note_image_to_text_with_llava_and_ollama/ Image to text with LLaVA and Ollama
+
+
## END
+
Last updated: 2024-12-12
+
+
=> ../gemlog Gemlog archive
+
=> ../ hyperreal.coffee
+22
gemini/gemlog/2024-12-16-update-on-homelab-projects.gmi
···
+
# Update on homelab projects
+
+
On December 14, 2024, I made the following post on Mastodon:
+
+
> Homelab projects for this weekend:
+
> - Try out Guix as a daily driver
+
> - Take off the Doom Emacs training wheels and setup a custom Emacs config
+
> - Setup K3s cluster on my three Orange Pi 5 Plus devices
+
+
Guix is a no-go, because KDE Plasma is not an officially supported desktop environment on Guix yet. Nor does Tailscale have a reliable way to install and manage on Guix. Maybe when the Non-Guix maintainers decide toport Tailscale to their channel.
+
+
I've decided to keep using Doom Emacs for now. Once I get my K3s cluster up and running and in working order, I will take time to pick apart my Doom Emacs config. This would involve finding the packages and configuration that are builtin to Doom Emacs, which I mostly take for granted -- aside from the ones I have defined in `packages.el`. I would have to find a way to conveniently manage packages without the `doom sync` and `doom upgrade` commands. But, for now, everything just works, and I'd like to keep it that way as I'm working on the K3s cluster.
+
+
I have my three Orange Pi 5 Plus's ready to be plugged in. I have Armbian on a microSD card, ready to be installed to each of the eMMCs. I have ethernet cables running between my unmanaged switch and each of the Pi's. Once Armbian is installed and configured on them, I will run an Ansible playbook that bootstrap the K3s cluster. I have a `.org` file as a reference. All I have to do now is cut the ribbon. Am kinda nervous about it, tho, so I've been kinda procrastinating. But, I've got this.
+
+
About two years ago I bought a PoE (Power-over-Ethernet) switch that supports gigabit ethernet. I stopped using it when I got 5Gbps Internet from AT&T when I will still living with my grandfather about a little over a year ago. Now that I live back with my parents, I have 2.5Gbps Internet from Comcast Xfinity. Since I've had no luck finding a 2.5Gbps PoE to USB-C splitter, I'll have to make do with what I've got. There's no reason for me to be a spoiled snob about utilizing my network's full throughput capacity for this use-case -- gigabit ethernet is ample, and I don't need to spend more money on a 2.5Gbps PoE switch. I bought three 1Gbps PoE to USB-C splitters. When they are delivered, I will unplug the power cords of the three Orange Pi 5 Plus's, plugin the gigabit PoE switch, run an ethernet cable from my unmanaged switch to the PoE switch, run three ethernet cables to each of the PoE to USB-C splitters, and plug the USB-C connectors into the power sockets of the three Pi's.
+
+
## END
+
Last updated: 2024-12-16
+
+
=> ../gemlog Gemlog archive
+
=> ../ hyperreal.coffee
+21
gemini/gemlog/2024-12-18-my-disillusionment-and-aspirations.gmi
···
+
# My disillusionment and aspirations
+
+
I'm having a hard time articulating things right now, so please bear with me. I'm recovering from being triggered earlier today when I heard Trump claim that pesticides are responsible for the "rise" in autism cases. I feel like I'm sufficiently cooled off, but some of my anger might still be lingering in the background, which may affect my ability to be objective here.
+
+
Anyway.
+
+
My failure to wrap my head around Kubernetes today as I tried to setup a three-node cluster has made me realize that I don't particularly like all this containerization and catering to corporate infrastructure needs in the tech industry. I'm not dunking on the merits of the technology -- it undoubtedly solves a great many problems. It's just that those problems are not something I'm personally interested in solving.
+
+
I'm feeling more of an affinity toward minimalism, the Unix philosophy, and suckless.org principles.
+
+
Since I've graduated from uni with a Bachelor's degree in computer science, I've felt this anxiety regarding finding a job, and this kind of spurred me toward thinking I need to learn DevOps technologies like Docker, Kubernetes, AWS, and other cloud-based services. I no longer want to feel that anxiety. It has prevented me from following my curiosity in learning things I've wanted to learn when I first became interested in computer science, because I've always felt like I needed to prioritize those job skill requirements.
+
+
I'm 36 years old, and I'm starting to worry that I might never find a career doing something I love and have a deep appreciation for. $400 a month on disability benefits is not sustainable. If it wasn't for my family, I'd probably be homeless and/or working at a job that doesn't pay a living wage anyway, let alone making enough to pay off my student debt. I'm disillusioned by this university education culture that promised a better life outcome if I earned a degree. This feels like such a scam when I realize the skills I learned as a computer science major could have been learned on my own, without putting myself into $70k student debt. I know this is a unique-to-me situation, and other C.S. graduates have gotten jobs and are making good money. But I'd bet that few if any of them have had to deal with debilitating mental illness for their entire adult life. I'd also bet that the majority of them are working at corporate offices, in service to the American capitalist GDP machine.
+
+
My ideal job would be something that helps a community and is centered around my values regarding digital freedom, privacy, anti-Big corporate, information freedom, and free and open source software. Those are the societal problems I am interested in solving.
+
+
## END
+
Last updated: 2024-12-18
+
+
=> ../gemlog Gemlog archive
+
=> ../ hyperreal.coffee
+76
gemini/gemlog/2025-01-05-my-network-wide-bullshit-blocking-setup.gmi
···
+
# My network-wide bullshit-blocking setup
+
+
## Orange Pi 5 Plus
+
* Unbound for recursive DNS resolver on 127.0.0.1:5335.
+
* Blocky for DNS proxy, ad-blocking, and malware-blocking on 0.0.0.0:53. Uses Unbound on 127.0.0.1:5335 as upstream resolver.
+
* Tailscale with `--accept-dns=false`.
+
* unbound-resolvconf.service is disabled, and /etc/resolv.conf is not managed by any service, so I just put nameserver 9.9.9.9 in it for local DNS resolution.
+
+
I intend on eventually making this fault-tolerant by using another device as a failover with keepalived. Where and what that other device will be is to be determined. I have Blocky configured to use the strict strategy for the upstreams setting, so after a timeout of the topmost server it will fallback to the next one, which is Quad9. An idea I have is to setup a cheap VPS on Vultr and run a public DNS resolver on it, but Quad9 is fine for now. Using a completely self-hosted recursive DNS resolver is fairly important to me, but as long as it's not going through Google or my ISP it is fine.
+
+
I have the Orange Pi 5 Plus Tailnet IP address configured to be my Tailnet's global nameserver. So every device on my Tailnet that uses MagicDNS will be using Blocky and Unbound.
+
+
## Blocky configuration
+
+
```yaml
+
upstreams:
+
strategy: strict
+
groups:
+
default:
+
- 127.0.0.1:5335
+
- 9.9.9.9
+
- 149.112.112.112
+
+
blocking:
+
denylists:
+
ads:
+
- https://raw.githubusercontent.com/StevenBlack/hosts/master/hosts
+
- https://adaway.org/hosts.txt
+
- https://v.firebog.net/hosts/AdguardDNS.txt
+
suspicious:
+
- https://v.firebog.net/hosts/static/w3kbl.txt
+
tracking:
+
- https://gitlab.com/quidsup/notrack-blocklists/raw/master/notrack-blocklist.txt
+
- https://v.firebog.net/hosts/Easyprivacy.txt
+
- https://v.firebog.net/hosts/Prigent-Ads.txt
+
malicious:
+
- http://phishing.mailscanner.info/phishing.bad.sites.conf
+
- https://v.firebog.net/hosts/Prigent-Crypto.txt
+
- https://raw.githubusercontent.com/StevenBlack/hosts/master/alternates/fakenews/hosts
+
+
clientGroupsBlock:
+
default:
+
- ads
+
- suspicious
+
- tracking
+
- malicious
+
+
ports:
+
dns: 53
+
http: 4000
+
+
prometheus:
+
enable: yes
+
+
caching:
+
minTime: 60s
+
maxItemsCount: 10000
+
prefetching: yes
+
prefetchMaxItemsCount: 2000
+
+
queryLog:
+
type: csv-client
+
target: /home/jas/dns-query-logs
+
logRetentionDays: 5
+
+
clientLookup:
+
upstream: 10.0.0.1
+
singleNameOrder:
+
- 1
+
```
+
+
## END
+
Last updated: 2025-01-05
+
+
=> ../gemlog Gemlog archive
+
=> ../ hyperreal.coffee
+105
gemini/gemlog/2025-01-12-my-comcast-home-isp-proof-qbittorrent-setup.gmi
···
+
# My Comcast/home ISP-proof qBittorrent setup
+
+
This setup consists of two Orange Pi 5 Plus devices. One of them I use as my NAS server, which we'll call nas-node. The other is an auxiliary that runs the qBittorrent Docker container, which we'll call aux-node.
+
+
## nas-node
+
+
My NAS server uses Tailscale so that I can conveniently access it from any device on my tailnet. I have an external NAS hard drive enclosure connected to it via USB 3.0, and this NAS enclosure contains four 20 TB enterprise HDDs, so I have a total of roughly 80 TB of storage space that comprises a "RAID0" ZFS pool. My goal is to use some of this storage space for open access data, such as Anna's Archive. The problem is if I start bittorrenting those archives, it's possible my Comcast ISP will complain or block, or I'll get legal scare letters, or some such nonsense. A solution, or a way to circumvent detection by Comcast, would be to use a VPN for the qBittorrent connection. I could use ProtonVPN from my Proton Unlimited account, but this would interfere with the Tailscale VPN. A solution to this, in turn, is to use one of my other Orange Pi 5 Plus devices as an auxiliary node to run the qBittorrent Docker container, and have qBittorrent configured to save downloaded data to the NAS node via an NFS share on the nas-node. In order to ensure a consistent and fast connection to the nas-node, I decided to use the second ethernet ports on the Orange Pi 5 Plus devices. So I have a 12-inch ethernet cable connecting both Orange Pi 5 Plus devices to their second ethernet ports. I configured this with systemd-networkd by setting up a subnet between the two devices.
+
+
For the sake of this post, eth0 refers to the primary ethernet port that receives Internet, and eth1 refers to the second ethernet port that connects to the subnet.
+
+
On nas-node, I created a network file for systemd at /etc/systemd/network/eth1.network:
+
+
```systemd
+
[Match]
+
Name=eth1
+
+
[Network]
+
Address=10.0.4.1/24
+
```
+
+
On aux-node, I created a network file for systemd at /etc/systemd/network/eth1.network:
+
+
```systemd
+
[Match]
+
Name=eth1
+
+
[Network]
+
Address=10.0.4.2/24
+
```
+
+
Bot nas-node and aux-node are running Ubuntu 24.04, which uses netplan.io to configure the network interfaces. I had to disable netplan.io by removing its package, enable systemd-networkd, and reboot in order to use systemd-networkd.
+
+
```shell
+
sudo apt purge netplan.io
+
sudo apt autoremove
+
sudo systemctl enable systemd-networkd
+
sudo systemctl reboot
+
```
+
+
Now that I have a li'l subnet for nas-node and aux-node, I configured the NFS share on nas-node to allow connection from the aux-node IP address 10.0.4.2. First, I had to create a ZFS dataset to store the torrent data, and then configure that dataset to be an NFS share.
+
+
```shell
+
sudo zfs create naspool/torrents
+
sudo zfs set sharenfs="rw=@10.0.4.0/24" naspool/torrents
+
sudo chown -R jas:jas /naspool/torrents
+
```
+
+
In /etc/exports:
+
+
```shell
+
/naspool/torrents 10.0.4.2(rw,sync,no_subtree_check)
+
```
+
+
I set the ownership of the naspool/torrents dataset to the jas user, so that the jas user on both the nas-node and aux-node can access it.
+
+
## aux-node
+
+
I configured /etc/fstab to mount the NFS share from nas-node automatically on boot.
+
+
```shell
+
10.0.4.1:/naspool/torrents /mnt/torrents nfs4 rw,relatime,vers=4.2,rsize=1048576,wsize=1048576,namlen=255,hard,proto=tcp,timeo=600,retrans=2,sec=sys,clientaddr=10.0.4.2,local_lock=none,addr=10.0.4.1 0 0
+
```
+
+
I installed Docker and the wireguard-tools packages on aux-node. I created and downloaded a ProtonVPN Wireguard configuration file and saved it to /etc/wireguard/wg0.conf. I actually have several of these from various geographic locations in case on stop working for whatever reason. When creating the Wireguard configurations for ProtonVPN, I made sure to select NAT port-forwarding for peer-to-peer filesharing.
+
+
For the qBittorrent Docker container, I used docker compose with the following compose.yml file:
+
+
```yaml
+
---
+
services:
+
qbittorrent:
+
image: lscr.io/linuxserver/qbittorrent:latest
+
container_name: qbittorrent
+
environment:
+
- PUID=1000
+
- PGID=1000
+
- TZ=Etc/UTC
+
- WEBUI_PORT=8080
+
- TORRENTING_PORT=6881
+
volumes:
+
- /mnt/torrents/downloads:/downloads
+
- qbittorrent-config:/config
+
ports:
+
- 8080:8080
+
- 6881:6881
+
- 6881:6881/udp
+
- 9000:9000
+
- 9000:9000/udp
+
restart: unless-stopped
+
+
volumes:
+
qbittorrent-config:
+
```
+
+
Note that /mnt/torrents on aux-node is the NFS share from nas-node via the subnet I created for nas-node and aux-node. Port 8080 is so that I can access the qBittorrent web UI. Port 6881 for TCP and UDP are the torrenting ports that will be forwarded through the ProtonVPN connection. Port 9000 for TCP and UDP is to allow port-forwarding for the embedded tracker in qBittorrent. The qBittorrent Docker container automatically uses the ProtonVPN connection on the host. I checked this by entering the qBittorrent container's shell environment and running curl ipinfo.io to check its public IP address, which was indeed the ProtonVPN IP address.
+
+
## Closing
+
+
So, with this setup, I am able to use some of my ~80 TB NAS storage to help out the open access community, with my Comcast ISP being none the wiser. Though, to be epistemically thorough, it's possible there is some hole in this setup that Comcast can hypothetically circumvent. At the very least, they are able to tell I'm using a VPN.
+
+
## END
+
Last updated: 2025-01-16
+
+
=> ../gemlog Gemlog archive
+
=> ../ hyperreal.coffee
+23
gemini/gemlog/2025-02-09-mental-health-improvement-or-something.gmi
···
+
# Mental health improvement or something
+
+
On February 8th, 2024, I made the following Fediverse post:
+
+
> Paranoid/self-focused: X claims to be a body positivity advocate and presents a veneer of social liberalism but this instance in which they subtly mock my weight issues exposes their hypocrisy and shows that even so-called "champions" of justice will succumb to selfish motives like status-seeking at my expense.
+
>
+
> Bayesian: X is demonstrably a body positivity advocate; they have a track record of fighting bigotry online, and have never been seen making petty criticisms of others' personal issues. It's not likely that they were subtly mocking my weight issues in this instance. Whatever I picked out as mockery is likely coincidence, and they probably have better priorities than to make fun of me.
+
>
+
> I often find myself trapped in a twilight zone between these two possible worlds.
+
+
Over the past year, I've found myself less frequently trapped in this sort of twilight zone. The paranoid possible world is more easily dismissed and I don't tend to go down its rabbit hole.
+
+
The reasons for this improvement (if that's what it is) are not obvious to me, especially considering that I've been on a lower dose of Invega since September of 2024. I don't know really how to explain it. Maybe I'm less insecure about things in general, and the Invega maybe never really had any bearing on my insecurity, as my insecurities might be separate from the thing that Invega treats. Maybe I'm less insecure about my weight issues in particular, due to losing weight on Wegovy. It's also possible that I've just surrounded myself with less shitty people (shrug).
+
+
What I mean by "this sort of twilight zone" is that such paranoid thought processes are not only limited to personal issues like my obesity. They could be about other personal issues or just things about me in general that I feel insecure about.
+
+
One thing I can say with confidence is that this improvement is, at the very least, applicable to my current baseline, which is my sequestered, reclusive, and extremely online lifestyle. It's likely that the insecurities increase in contexts where they tend to be more triggered, such as around a lot of people or in public places. Hence, it's also likely that the paranoia would increase and I would find myself in the sort of twilight zone described above if I were to put myself in those contexts. Any therapist worth their co-pay would likely tell me that the more I put myself in those contexts, the more I get used to it, and I could eventually reach a point where my insecurities don't bother me in those contexts. However, I'm almost 37, and at this point, I have priorities and obligations that make putting myself in triggering situations extremely inconvenient. In the context of autonomy and personal freedom, I think I have a right not to put myself in extremely uncomfortable situations if I can help it. I see a path in my future where I can survive just fine in this lifestyle. Of course I will miss many other opportunities, but at the moment this is acceptable to me.
+
+
## END
+
Last updated: 2025-02-09
+
+
=> ../gemlog/ Gemlog archive
+
=> ../ hyperreal.coffee
+17
gemini/gemlog/2025-02-21-the-foreseeable-future.gmi
···
+
# The foreseeable future
+
+
Me: I don't know. Maybe I'm just meant to be a sort of starving FOSS community volunteer who lives with his parents for the foreseeable future.
+
+
Rubber duck: Perhaps. You also have aspirations to become a Debian developer, which could open doors for future job opportunities, including sysadmin.
+
+
Me: Yeah. But I'd be middle-aged by then, and companies tend to want younger folks.
+
+
Rubber duck: Not necessarily. If you've got skills and experience with FOSS projects that companies covet, you're more likely to be hired.
+
+
Me: What worries me about that is that jobs aren't guaranteed for life, even if you have skills and experience. Comapnies lay people off, and if that happens to me, then that would be a big change I'd have to adjust to, with no guaranteed safety net to cover my medical and living expenses.
+
+
## END
+
Last updated: 2025-02-21
+
+
=> ../gemlog Gemlog archive
+
=> ../ hyperreal.coffee
+17
gemini/gemlog/2025-04-05-i-really-dislike-computers-sometimes.gmi
···
+
# I really dislike computers sometimes
+
+
I've got to figure something out with the arrangement of my bedroom/office. Right now, I have two desks in the shape of an L in the corner. This corner is necessary because that's where the outlets are. One of the desks holds my gaming PC, and the other desk holds my main Linux workstation along with my NAS and homelab machines. I'd rather have: (1) one desk for my gaming PC and Linux workstation, and (2) the other desk for my homelab equipment.
+
+
The problem with (1) is that I'd like to be able to have one set of peripheral devices that can connect to both my gaming PC and Linux workstation, and conveniently switch between them when I want to. One way this is possible is just by unplugging and plugging in each peripheral device (keyboard, mouse, monitor) into the desired machine. But this would be a pain in the fundament, because my gaming PC doesn't have any ports conveniently on the front of the machine, so I'd have to crawl down under the desk and reach into the back of the machine every time. I could also use USB hubs for this and save myself from having to crawl under the desk. I can have a USB hub for each machine. This would at least cover the keyboard and mouse. As for the monitor, my current monitor only has one DisplayPort port, so I'd have to keep unplugging and plugging in DisplayPort cables for both machines. Maybe I can find a monitor that has more than one DisplayPort, and use the monitor's buttons to toggle between them. Or some kind of splitter/switch hub thingy that has a button that I can just press to toggle which machine uses the monitor (if such a thing exists?). Another way would be Bluetooth peripheral devices that I'd have to keep charged and paired constantly – but that idea can go straight the fuck to Hell where it belongs.
+
+
What's wrong with using the Windows 11 gaming PC as my main workstation like a normie instead of having a separate Linux workstation? Honestly, I've seriously considered this, as it would sure make all this easier. But the answer ought to be obvious to anyone who cares about digital rights[1]. Why don't I just dual boot on the gaming PC, then? Because reasons.
+
+
[1] Maybe there is a way I can isolate some things similar to Qubes OS, and try to keep personal data off the Windows host OS as much as possible. Maybe I can leverage WSL for this somehow. I can look into making Windows less privacy-invasive without breaking certain functionality, if that's even possible these days.
+
+
Of course, none of this would be a problem if I had more space in my bedroom/office with outlets at convenient locations, but that's not possible for the foreseeable future, so I have to work with what I've got. I think any arrangement I come up with is going to have an entropistic Cyberpunk 2077 look, and, uh, that's supposed to be a dystopia best avoided. (Ironically, my Secret Lab Magnus Pro desk has a Cyberpunk 2077 theme lol.)
+
+
## END
+
Last updated: 2025-04-05
+
+
=> ../gemlog Gemlog archive
+
=> ../ hyperreal.coffee
+22
gemini/gemlog/2025-11-06-homelab-update-v20251028.gmi
···
+
# Homelab update v20251028
+
+
My homelab previously consisted of the following machines:
+
+
* Orange Pi 5+ running Ubuntu 24.04, serving as a centralized monitoring station with Prometheus, Grafana, Prometheus exporters for qbittorrent and my Tapo TP-Link smartplugs, and syslog-ng forwarding.
+
* Orange Pi 5+ running DietPi, serving FreshRSS, Nextcloud, Blocky DNS proxy with Unbound recursive DNS resolver.
+
* System76 Meerkat (meer9) running Debian 13, serving my public web content, including my website and other public-facing web services. I had port forwarding enabled in my router to this machine.
+
* System76 Thelio Major running FreeBSD 14.3, serving as a NAS.
+
+
I've rearranged, cleaned up, simplified, and repurposed the first three. I'm no longer port forwarding through my router.
+
+
My public stuff is on a Debian 13 VPS from netcup.de that resides in Manassas, Virginia, USA. From there, it can benefit from higher availability and uptime, easier snapshotting and backup of the entire VPS, IPv6, and it closes off an attack vector on my home network.
+
+
Since I use Murena Workspace[1] for my Nextcloud and other cloud stuff, which integrates nicely with /e/os on my phone, I no longer need to self-host Nextcloud. It is therefore superfluous to have the DietPi machine running. I can just consolidate the Blocky DNS proxy and FreshRSS into the centralized monitoring machine. However, since my System76 Meerkat is now free, I'd prefer to use it for these tasks instead, as it is far more powerful. This means I can reduce four machines into two, namely the Orange Pi 5+ machines will be laid off and the Meerkat will replace them. Sad for the Orange Pi 5+ devices, but they're just machines without feelings, families, or survival needs, so they'll be fine if a bit dusty.
+
+
As it turns out, Fedora 43 was just released today. So I'm going to install Fedora 43 Server on the Meerkat.
+
+
## END
+
Last updated: "2025-11-06"
+
+
=> ../gemlog Gemlog archive
+
=> ../ hyperreal.coffee
+21
gemini/gemlog/2025-11-06-homelab-update-v20251030.gmi
···
+
# Homelab update v20251030
+
+
Thelio Major is now running bazzite:nvidia. Just regular Bazzite; no custom modifications or builds. I don't intend to use it as a regular workstation, so no personalized software is installed. Just Steam, Lutris, MangoJuice, and a few flatpaks. I'm using the Firefox flatpak with sync enabled for minimally viable browsing. So it's basically like a glorified gaming console. I'm using the GSYNC monitor for this machine. It is configured to go to sleep after 60 minutes of idleness.
+
+
Meerkat (meer9) is now my main workstation, with CachyOS KDE Plasma. I've also decided to run homelab monitoring stuff like Ntfy, Prometheus, Grafana, Loki, and Promtail with syslog-ng forwarding on it. I don't quite see a sufficient reason to keep this monitoring stack separate from my workstation. I do everything there anyway, so the services might as well run on localhost. I can still connect to the Grafana dashboard over Tailscale from my laptop.
+
+
I played Prey for a couple hours on Bazzite, and somehow the performance of the game felt more efficient than it did on CachyOS. I don't know why, but it's alright by me.
+
+
On Bazzite, I also have my Nextcloud via Murena Workspace account accessible on it with the Nextcloud desktop client flatpak. Most of my Steam games store saved games in the Steam Cloud, but GOG stores everything under `~/Gaming/gog/`. Lutris allows using the native system paths for some games. Like Dishonored stores saved games and settings under `~\Documents\My Games` on Windows. The Linux XDG equivalent would be `~/Documents`, which for me is a symbolic link to `~/Nextcloud/Documents`, so that stuff is synced with Nextcloud. In contrast, Prey stores saved games under `~/Games/gog/prey/drive_c/Users/jas/Saved Games/Arkane Studios/...`. For now I just rsynced the saved games there, but I have to figure out an efficient way to sync that directory on Nextcloud. Maybe if I keep the actual files under `~/Nextcloud/Documents/Saved Games` and create a symlink to that directory from `~/Games/gog/prey/drive_c/Users/jas/Saved Games`. Now that I think of it, I recall there being a program on GitHub called GameImage that might provide a more efficient way to keep gaming stuff synced on Linux. I can't just sync `~/Games` on Nextcloud because Lutris downloads and stores the entire game files there, roughly more than 100 GB of data with the games I currently have installed. Not something I want to sync over Nextcloud lol.
+
+
Anyway I'm pretty satisfied with this setup.
+
+
In other news, my NAS has to remain shut down until we figure out what is wrong with our house's electrical wiring. My NAS is the most consistently power-hungry machine in my homelab, so it will be good to keep it off until we fix whatever needs fixing. My parents' electrician friend is coming this weekend to see what's wrong. Last week a circuit breaker shorted out, which powers stuff in our garage and outside the house. The wiring in our house is pretty old, and probably wasn't setup to handle digital age power demands. I'd like for my parents to consider getting solar panels, but that's too liberal-coded for them and they hastily dismiss the idea without a second thought. /We don't need no goddamn hippie solar panels./
+
+
My bedroom is pretty quiet now.
+
+
## END
+
Last updated: "2025-11-06"
+
+
=> ../gemlog Gemlog archive
+
=> ../ hyperreal.coffee
+19
gemini/gemlog/2025-11-27-hot-take-on-vivaldi-browser.gmi
···
+
# Hot take on Vivaldi browser
+
+
So I installed Vivaldi to use Netflix for Stranger Things 5, and holy crap. It's like the KDE of browsers in terms of appearance and configurability.
+
+
It's such a shame that it's partly proprietary. But I don't know. It's tempting for me to be open-minded about using it.
+
+
* 92% of the code base is open source from Chromium.
+
* 3% is open source from Vivaldi.
+
* 5% is proprietary from Vivaldi, which is mostly the UI stuff.
+
+
They've also made a public commitment to not integrating AI into their browser. This gives them points for trustworthiness and putting the user above AI hype and profit.
+
+
So... I'm not usually in the habit of giving hot takes on software, but I'm kind of thinking that despite its 5% proprietary code, and in light of Mozilla's terribleness lately, it's ethically and technically superior to Firefox.
+
+
## END
+
Last updated: 2025-11-27
+
+
=> ../gemlog Gemlog archive
+
=> ../ hyperreal.coffee
+15
gemini/gemlog/2025-11-27-interesting-episode-of-late-night-linux-podcast.gmi
···
+
# Interesting episode of Late Night Linux podcast
+
+
Yesterday I listened to Late Night Linux podcast episode 358, where the hosts were at a recent Ubuntu summit and they got to interview Mark Shuttleworth.
+
+
A lot of what Shuttleworth said resonated with me -- he mentioned he's fascinated by the small things self-hosting and IoT stuff. He also discussed the merits of Snap packages, which made me less hostile to the fact that Ubuntu prioritizes them over regular .deb packages.
+
+
Shuttleworth seems like a pretty cool guy. Hopefully he stays that way.
+
+
Another thing that resonated with me in the podcast is that the hosts talk about how the big players in the FOSS ecosystem -- Ubuntu/Canonical, Fedora/Red Hat, Suse/Novell -- all raise the tide for the smaller community-oriented distros and projects. So it's like a symbiotic relationship in that regard. It's not so much a zero-sum game for distros, even though there is some nominal level of competition among them.
+
+
## END
+
Last updated: 2025-11-27
+
+
=> ../gemlog Gemlog archive
+
=> ../ hyperreal.coffee
+60
gemini/gemlog/2025-11-27-unexpected-legacy-of-timothy-leary.gmi
···
+
# Unexpected legacy of Timothy Leary
+
+
I don't condone the use of psychedelics. I've never tried them myself either. But it's difficult for me not to be in awe of the life Timothy Leary led.
+
+
I never knew much about him other than that he developed LSD, and I suspect that's what most people think of when they hear his name. There is quite a legacy behind the person.
+
+
The following text is quoted from the Facebook page This Day in History, with my own paragraph spacing added.
+
+
=> https://www.facebook.com/share/p/16jkn5KcEP/ https://www.facebook.com/share/p/16jkn5KcEP/
+
+
> Timothy Leary arrived at California Men's Colony prison in 1970 facing twenty years behind bars. He was fifty years old, a former Harvard psychologist turned counterculture icon, sentenced for marijuana possession in an era when the establishment treated drug advocacy as existential threat. Prison officials processed him like any other inmate: fingerprints, prison blues, a psychological evaluation to determine security placement.
+
+
Then they handed him the test.
+
+
> Leary looked at the questions and recognized his own work. Years earlier, during his respectable academic career, he'd developed the Leary Interpersonal Behavior Inventory—a personality assessment designed to evaluate how people relate to authority, handle stress, and respond to institutional control. Now the same system he'd created was being used to classify him.
+
+
> He filled out the questionnaire in under ten minutes, deliberately shaping his answers to present exactly what the evaluators wanted to see: a middle-aged man with no fight left, interested in gardening and forestry, compliant, unlikely to cause trouble. The results placed him in minimum security with an assignment tending the prison gardens.
+
+
Leary had just manipulated his own psychological test to engineer the conditions for his escape.
+
+
> He wasn't always a rebel. Timothy Leary started as an establishment academic, exactly the kind of psychologist Harvard hired in 1959 expecting orderly research and publishable papers. He'd earned his PhD from Berkeley, directed psychiatric research at Kaiser Foundation Hospital, published respected work on personality assessment. His career trajectory pointed toward tenure and professional respectability.
+
+
> Then he went to Mexico in the summer of 1960 and tried psilocybin mushrooms.
+
+
> The experience didn't just alter his consciousness—it altered his understanding of what psychology could be. He returned to Harvard convinced that psychedelic compounds offered therapeutic potential that traditional psychiatry couldn't match. He started the Harvard Psilocybin Project, conducting research with graduate students, prisoners, and intellectuals. Subjects included Allen Ginsberg, Jack Kerouac, and religious scholars. They took controlled doses, wrote detailed reports, participated in therapeutic sessions.
+
> The research was legitimate. The methodology was sound. But the implications terrified administrators who saw a professor encouraging students to chemically alter their perception of reality. Colleagues whispered about loss of scientific objectivity. Newspapers sensationalized the experiments. By 1963, Harvard decided Leary had become a liability. They fired him, officially for leaving campus during the semester without authorization, but everyone understood the real reason: he'd stopped being a respectable psychologist and become something the institution couldn't control.
+
> Leary saw the dismissal as liberation. Freed from academic constraints, he became the public face of psychedelic exploration. He traveled, lectured, founded research centers first in Mexico then in Millbrook, New York. He coined phrases that became counterculture mantras: "Turn on, tune in, drop out." Critics heard nihilism. Followers heard permission to question inherited assumptions about consciousness, authority, identity.
+
+
> The establishment heard threat.
+
+
> In 1965, authorities arrested him at the Texas-Mexico border for marijuana possession. Prosecutors pushed for harsh sentencing, treating him as a symbol of cultural decay that needed crushing. Leary fought back through the legal system. He appealed all the way to the Supreme Court and won—not through cultural arguments about drug policy, but through constitutional law. The Court ruled in Leary v. United States that the marijuana tax law he'd been charged under violated the Fifth Amendment's protection against self-incrimination.
+
+
> But victories in court didn't stop the targeting. In 1968, police arrested him again in Laguna Beach. Combined with his previous offense, he now faced twenty years in prison. This time, there would be no Supreme Court rescue.
+
+
> Once transferred to the minimum-security facility at California Men's Colony, Leary began planning the impossible. The Weather Underground, a radical leftist organization, agreed to help for $25,000 paid by The Brotherhood of Eternal Love, a group of psychedelic advocates. They smuggled him tools and coordinated logistics for a nighttime escape.
+
+
> On September 13, 1970, Leary climbed onto a prison rooftop, pulled himself up a telephone pole, and moved hand-over-hand along a cable spanning the prison yard—over barbed wire, over security perimeter, beyond what guards thought anyone would attempt. He dropped to the road outside where Weather Underground operatives waited.
+
+
> He left behind his prison clothes and a note that reportedly read: "I declare myself free."
+
> The escape became international news. Prison officials found themselves explaining how one of America's most recognizable prisoners had simply climbed out while they watched. Leary fled to Algeria, where he stayed briefly with Black Panther Eldridge Cleaver's government-in-exile. Then Switzerland. Then Afghanistan. He traveled under assumed names, gave lectures in disguise, wrote manifestos. Intelligence agencies tracked him across continents. He became a fugitive philosophy professor.
+
+
> The chase ended in 1973 when Afghan authorities, working with American intelligence, arrested him in Kabul. He returned to the United States in handcuffs. Newspapers framed it as law finally catching up with chaos. Leary framed it differently. In interviews, he emphasized that the real threat wasn't psychedelics—it was the questions they made people ask about who controlled their consciousness and why.
+
+
> He served additional years in prison, during which he wrote extensively about neurology, consciousness, and human potential. When finally released in 1976, he didn't retreat into quiet obscurity. Instead, he evolved. He lectured on cyberculture before most people understood what the internet would become. He talked about space colonization, artificial intelligence, consciousness expansion through technology. He refused to become a museum piece from the 1960s, choosing instead to adapt his message to new frontiers.
+
+
> Critics dismissed him as a relic trying to stay relevant. But Leary understood something fundamental: the questions he'd been asking—about autonomy, consciousness, institutional control, who decides what's acceptable to think and feel—didn't stop being important just because the decade changed.
+
+
> Near the end of his life in the 1990s, still lecturing and writing, someone asked why he'd spent decades provoking institutions that imprisoned him, surveilled him, tried to silence him. Why keep pushing when the cost had been so high?
+
+
> Leary's answer captured everything about his approach to authority, consciousness, and control: "The moment you stop questioning, somebody else starts answering for you."
+
+
> Because that was the real story of Timothy Leary—not the drugs, not the slogans, not the escapes. It was his refusal to let anyone else define the boundaries of acceptable thought. He'd figured out how to game a psychological test because he understood how institutions try to categorize and control people. He'd escaped from prison because he understood that the only real prison is the one you accept. He'd kept questioning authority because he understood that the alternative wasn't safety—it was surrender.
+
+
> The establishment called him dangerous. Leary called them predictable. And in 1970, when they handed him his own test thinking they'd finally contained him, he proved exactly how predictable they were.
+
+
## END
+
Last updated: 2025-11-27
+
+
=> ../gemlog Gemlog archive
+
=> ../ hyperreal.coffee
+330
gemini/gemlog/atom.xml
···
+
<?xml version='1.0' encoding='UTF-8'?>
+
<feed xmlns="http://www.w3.org/2005/Atom">
+
<id>gemini://hyperreal.coffee/gemlog/</id>
+
<title>hyperreal's gemlog</title>
+
<updated>2025-11-06T22:32:10-06:00</updated>
+
<link href="gemini://hyperreal.coffee/gemlog/atom.xml" rel="self" type="application/atom+xml"/>
+
<link href="gemini://hyperreal.coffee/gemlog/" rel="alternate" type="text/gemini"/>
+
<generator uri="https://lkiesow.github.io/python-feedgen" version="1.0.0">python-feedgen</generator>
+
<entry>
+
<id>gemini://hyperreal.coffee/gemlog/2025-11-27-unexpected-legacy-of-timothy-leary.gmi</id>
+
<title>Unexpected legacy of Timothy Leary</title>
+
<updated>2025-11-27T18:14:38-06:00</updated>
+
<link href="gemini://hyperreal.coffee/gemlog/2025-11-27-unexpected-legacy-of-timothy-leary.gmi"/>
+
</entry>
+
<entry>
+
<id>gemini://hyperreal.coffee/gemlog/2025-11-27-hot-take-on-vivaldi-browser.gmi</id>
+
<title>Hot take on Vivaldi browser</title>
+
<updated>2025-11-27T18:06:54-06:00</updated>
+
<link href="gemini://hyperreal.coffee/gemlog/2025-11-27-hot-take-on-vivaldi-browser.gmi"/>
+
</entry>
+
<entry>
+
<id>gemini://hyperreal.coffee/gemlog/2025-11-27-interesting-episode-of-late-night-linux-podcast.gmi</id>
+
<title>Interesting episode of Late Night Linux podcast</title>
+
<updated>2025-11-27T17:57:35-06:00</updated>
+
<link href="gemini://hyperreal.coffee/gemlog/2025-11-27-interesting-episode-of-late-night-linux-podcast.gmi"/>
+
</entry>
+
<entry>
+
<id>gemini://hyperreal.coffee/gemlog/2025-11-06-homelab-update-v20251030.gmi</id>
+
<title>Homelab update v20251030</title>
+
<updated>2025-11-06T22:32:10-06:00</updated>
+
<link href="gemini://hyperreal.coffee/gemlog/2025-11-06-homelab-update-v20251030.gmi"/>
+
</entry>
+
<entry>
+
<id>gemini://hyperreal.coffee/gemlog/2025-11-06-homelab-update-v20251028.gmi</id>
+
<title>Homelab update v20251028</title>
+
<updated>2025-11-06T22:18:52-06:00</updated>
+
<link href="gemini://hyperreal.coffee/gemlog/2025-11-06-homelab-update-v20251028.gmi"/>
+
</entry>
+
<entry>
+
<id>gemini://hyperreal.coffee/gemlog/2025-04-05-i-really-dislike-computers-sometimes.gmi</id>
+
<title>I really dislike computers sometimes</title>
+
<updated>2025-04-10T06:29:04-05:00</updated>
+
<link href="gemini://hyperreal.coffee/gemlog/2025-04-05-i-really-dislike-computers-sometimes.gmi"/>
+
</entry>
+
<entry>
+
<id>gemini://hyperreal.coffee/gemlog/2025-02-21-the-foreseeable-future.gmi</id>
+
<title>The foreseeable future</title>
+
<updated>2025-02-21T01:26:42-06:00</updated>
+
<link href="gemini://hyperreal.coffee/gemlog/2025-02-21-the-foreseeable-future.gmi"/>
+
</entry>
+
<entry>
+
<id>gemini://hyperreal.coffee/gemlog/2025-02-09-mental-health-improvement-or-something.gmi</id>
+
<title>Mental health improvement or something</title>
+
<updated>2025-02-09T17:50:08-06:00</updated>
+
<link href="gemini://hyperreal.coffee/gemlog/2025-02-09-mental-health-improvement-or-something.gmi"/>
+
</entry>
+
<entry>
+
<id>gemini://hyperreal.coffee/gemlog/2025-01-12-my-comcast-home-isp-proof-qbittorrent-setup.gmi</id>
+
<title>My Comcast/home ISP-proof qBittorrent setup</title>
+
<updated>2025-01-12T17:29:08-06:00</updated>
+
<link href="gemini://hyperreal.coffee/gemlog/2025-01-12-my-comcast-home-isp-proof-qbittorrent-setup.gmi"/>
+
</entry>
+
<entry>
+
<id>gemini://hyperreal.coffee/gemlog/2025-01-05-my-network-wide-bullshit-blocking-setup.gmi</id>
+
<title>My network-wide bullshit-blocking setup</title>
+
<updated>2025-01-05T16:00:13-06:00</updated>
+
<link href="gemini://hyperreal.coffee/gemlog/2025-01-05-my-network-wide-bullshit-blocking-setup.gmi"/>
+
</entry>
+
<entry>
+
<id>gemini://hyperreal.coffee/gemlog/2024-12-18-my-disillusionment-and-aspirations.gmi</id>
+
<title>My disillusionment and aspirations</title>
+
<updated>2024-12-18T09:20:36-06:00</updated>
+
<link href="gemini://hyperreal.coffee/gemlog/2024-12-18-my-disillusionment-and-aspirations.gmi"/>
+
</entry>
+
<entry>
+
<id>gemini://hyperreal.coffee/gemlog/2024-12-16-update-on-homelab-projects.gmi</id>
+
<title>Update on homelab projects</title>
+
<updated>2024-12-16T12:13:17-06:00</updated>
+
<link href="gemini://hyperreal.coffee/gemlog/2024-12-16-update-on-homelab-projects.gmi"/>
+
</entry>
+
<entry>
+
<id>gemini://hyperreal.coffee/gemlog/2024-12-12-my-nas-solution-and-other-homelab-projects.gmi</id>
+
<title>My NAS solution and other homelab projects</title>
+
<updated>2024-12-12T04:10:02-06:00</updated>
+
<link href="gemini://hyperreal.coffee/gemlog/2024-12-12-my-nas-solution-and-other-homelab-projects.gmi"/>
+
</entry>
+
<entry>
+
<id>gemini://hyperreal.coffee/gemlog/2024-12-11-20-years-of-mental-illness.gmi</id>
+
<title>20 years of mental illness</title>
+
<updated>2024-12-11T13:25:10-06:00</updated>
+
<link href="gemini://hyperreal.coffee/gemlog/2024-12-11-20-years-of-mental-illness.gmi"/>
+
</entry>
+
<entry>
+
<id>gemini://hyperreal.coffee/gemlog/2024-12-09-my-tentative-file-syncing-solution.gmi</id>
+
<title>My tentative file-syncing solution</title>
+
<updated>2024-12-09T14:41:09-06:00</updated>
+
<link href="gemini://hyperreal.coffee/gemlog/2024-12-09-my-tentative-file-syncing-solution.gmi"/>
+
</entry>
+
<entry>
+
<id>gemini://hyperreal.coffee/gemlog/2024-12-08-my-speech-language-enhancing-technology-wishes.gmi</id>
+
<title>My speech/language-enhancing technology wishes</title>
+
<updated>2024-12-09T14:41:09-06:00</updated>
+
<link href="gemini://hyperreal.coffee/gemlog/2024-12-08-my-speech-language-enhancing-technology-wishes.gmi"/>
+
</entry>
+
<entry>
+
<id>gemini://hyperreal.coffee/gemlog/2024-11-24-on-using-reproducible-python-development-environments.gmi</id>
+
<title>On using reproducible Python development environments</title>
+
<updated>2024-11-27T14:41:18-06:00</updated>
+
<link href="gemini://hyperreal.coffee/gemlog/2024-11-24-on-using-reproducible-python-development-environments.gmi"/>
+
</entry>
+
<entry>
+
<id>gemini://hyperreal.coffee/gemlog/2024-11-24-home-networking-and-preventing-dns-leaks.gmi</id>
+
<title>Home networking and preventing DNS leaks</title>
+
<updated>2024-11-27T14:41:18-06:00</updated>
+
<link href="gemini://hyperreal.coffee/gemlog/2024-11-24-home-networking-and-preventing-dns-leaks.gmi"/>
+
</entry>
+
<entry>
+
<id>gemini://hyperreal.coffee/gemlog/2024-11-24-invega-mental-health-and-hygiene.gmi</id>
+
<title>Invega, mental health, and hygiene</title>
+
<updated>2024-11-27T14:41:18-06:00</updated>
+
<link href="gemini://hyperreal.coffee/gemlog/2024-11-24-invega-mental-health-and-hygiene.gmi"/>
+
</entry>
+
<entry>
+
<id>gemini://hyperreal.coffee/gemlog/2024-09-30-rubber-duck-helps-me-debug-my-daily-driver-issues.gmi</id>
+
<title>Rubber duck helps me debug my daily driver issues</title>
+
<updated>2024-09-30T23:16:31-05:00</updated>
+
<link href="gemini://hyperreal.coffee/gemlog/2024-09-30-rubber-duck-helps-me-debug-my-daily-driver-issues.gmi"/>
+
</entry>
+
<entry>
+
<id>gemini://hyperreal.coffee/gemlog/2024-09-20-i-want-to-tell-google-to-eff-off.gmi</id>
+
<title>I want to tell Google to eff off</title>
+
<updated>2024-09-20T23:55:52-05:00</updated>
+
<link href="gemini://hyperreal.coffee/gemlog/2024-09-20-i-want-to-tell-google-to-eff-off.gmi"/>
+
</entry>
+
<entry>
+
<id>gemini://hyperreal.coffee/gemlog/2024-09-19-experimenting-with-freebsd-fate-of-invidious.gmi</id>
+
<title>Experimenting with FreeBSD, and comments on the future of Invidious</title>
+
<updated>2024-09-19T01:58:16-05:00</updated>
+
<link href="gemini://hyperreal.coffee/gemlog/2024-09-19-experimenting-with-freebsd-fate-of-invidious.gmi"/>
+
</entry>
+
<entry>
+
<id>gemini://hyperreal.coffee/gemlog/2024-08-30-reducing-social-media-cross-posting-complexity.gmi</id>
+
<title>Reducing social media cross-posting complexity</title>
+
<updated>2024-08-30T20:23:28-05:00</updated>
+
<link href="gemini://hyperreal.coffee/gemlog/2024-08-30-reducing-social-media-cross-posting-complexity.gmi"/>
+
</entry>
+
<entry>
+
<id>gemini://hyperreal.coffee/gemlog/2024-08-20-listening-to-podcasts-while-driving.gmi</id>
+
<title>Listening to podcasts while driving</title>
+
<updated>2024-08-20T23:22:23-05:00</updated>
+
<link href="gemini://hyperreal.coffee/gemlog/2024-08-20-listening-to-podcasts-while-driving.gmi"/>
+
</entry>
+
<entry>
+
<id>gemini://hyperreal.coffee/gemlog/2024-07-26-thoughts-on-tilde-hosting.gmi</id>
+
<title>Thoughts on tilde hosting</title>
+
<updated>2024-07-26T03:58:15-05:00</updated>
+
<link href="gemini://hyperreal.coffee/gemlog/2024-07-26-thoughts-on-tilde-hosting.gmi"/>
+
</entry>
+
<entry>
+
<id>gemini://hyperreal.coffee/gemlog/2024-07-20-i-finally-sorted-out-my-self-hosting-stuff.gmi</id>
+
<title>I finally sorted out my self-hosting stuff</title>
+
<updated>2024-07-20T20:39:15-05:00</updated>
+
<link href="gemini://hyperreal.coffee/gemlog/2024-07-20-i-finally-sorted-out-my-self-hosting-stuff.gmi"/>
+
</entry>
+
<entry>
+
<id>gemini://hyperreal.coffee/gemlog/2024-01-11-home-networking-madness.gmi</id>
+
<title>Home Networking Madness</title>
+
<updated>2024-01-11T17:06:19-06:00</updated>
+
<link href="gemini://hyperreal.coffee/gemlog/2024-01-11-home-networking-madness.gmi"/>
+
</entry>
+
<entry>
+
<id>gemini://hyperreal.coffee/gemlog/2023-08-29-invega-withdrawal-day-24.gmi</id>
+
<title>Invega withdrawal and other things</title>
+
<updated>2023-08-29T16:55:10-05:00</updated>
+
<link href="gemini://hyperreal.coffee/gemlog/2023-08-29-invega-withdrawal-day-24.gmi"/>
+
</entry>
+
<entry>
+
<id>gemini://hyperreal.coffee/gemlog/2023-06-11-yet-another-homelab-setup.gmi</id>
+
<title>Yet Another Homelab Setup</title>
+
<updated>2023-06-11T21:39:15-05:00</updated>
+
<link href="gemini://hyperreal.coffee/gemlog/2023-06-11-yet-another-homelab-setup.gmi"/>
+
</entry>
+
<entry>
+
<id>gemini://hyperreal.coffee/gemlog/2023-05-14-migration-to-truenas.gmi</id>
+
<title>Migration to TrueNAS CORE</title>
+
<updated>2023-05-14T21:59:19-05:00</updated>
+
<link href="gemini://hyperreal.coffee/gemlog/2023-05-14-migration-to-truenas.gmi"/>
+
</entry>
+
<entry>
+
<id>gemini://hyperreal.coffee/gemlog/2023-03-12-morality-in-dream-content.gmi</id>
+
<title>Morality in dream content</title>
+
<updated>2023-03-12T23:56:41-05:00</updated>
+
<link href="gemini://hyperreal.coffee/gemlog/2023-03-12-morality-in-dream-content.gmi"/>
+
</entry>
+
<entry>
+
<id>gemini://hyperreal.coffee/gemlog/2023-02-01-re-i-got-a-new-tablet.gmi</id>
+
<title>RE: StackSmith: I got a new tablet</title>
+
<updated>2023-02-01T22:57:44-06:00</updated>
+
<link href="gemini://hyperreal.coffee/gemlog/2023-02-01-re-i-got-a-new-tablet.gmi"/>
+
</entry>
+
<entry>
+
<id>gemini://hyperreal.coffee/gemlog/2022-09-17-considering-using-ipfs-for-content-hosting.gmi</id>
+
<title>Considering using IPFS for content hosting</title>
+
<updated>2022-09-17T20:17:19+00:00</updated>
+
<link href="gemini://hyperreal.coffee/gemlog/2022-09-17-considering-using-ipfs-for-content-hosting.gmi"/>
+
</entry>
+
<entry>
+
<id>gemini://hyperreal.coffee/gemlog/2022-09-09-what-i-look-forward-to-in-fall.gmi</id>
+
<title>What I look forward to in the fall</title>
+
<updated>2022-09-09T21:47:43+00:00</updated>
+
<link href="gemini://hyperreal.coffee/gemlog/2022-09-09-what-i-look-forward-to-in-fall.gmi"/>
+
</entry>
+
<entry>
+
<id>gemini://hyperreal.coffee/gemlog/2022-07-28-wish-I-could-taper-off-meds.gmi</id>
+
<title>I wish I could taper off my meds</title>
+
<updated>2022-07-28T22:40:09+00:00</updated>
+
<link href="gemini://hyperreal.coffee/gemlog/2022-07-28-wish-I-could-taper-off-meds.gmi"/>
+
</entry>
+
<entry>
+
<id>gemini://hyperreal.coffee/gemlog/2022-07-15-glad-to-see-ocd-stereotypes-being-broken-up.gmi</id>
+
<title>Glad to see OCD stereotypes being broken up</title>
+
<updated>2022-07-15T22:27:35+00:00</updated>
+
<link href="gemini://hyperreal.coffee/gemlog/2022-07-15-glad-to-see-ocd-stereotypes-being-broken-up.gmi"/>
+
</entry>
+
<entry>
+
<id>gemini://hyperreal.coffee/gemlog/2022-07-07-comments-on-elder-scrolls-online-high-isle-spoilers.gmi</id>
+
<title>Comments on The Elder Scrolls Online: High Isle (SPOILERS)</title>
+
<updated>2022-07-07T08:20:00+00:00</updated>
+
<link href="gemini://hyperreal.coffee/gemlog/2022-07-07-comments-on-elder-scrolls-online-high-isle-spoilers.gmi"/>
+
</entry>
+
<entry>
+
<id>gemini://hyperreal.coffee/gemlog/2022-06-15-chat-app-overload.gmi</id>
+
<title>Chat App Overload</title>
+
<updated>2022-06-15T20:21:00+00:00</updated>
+
<link href="gemini://hyperreal.coffee/gemlog/2022-06-15-chat-app-overload.gmi"/>
+
</entry>
+
<entry>
+
<id>gemini://hyperreal.coffee/gemlog/2022-05-31-am-nervous-about-getting-into-dnd.gmi</id>
+
<title>Am nervous about getting into DnD</title>
+
<updated>2022-05-31T23:09:00+00:00</updated>
+
<link href="gemini://hyperreal.coffee/gemlog/2022-05-31-am-nervous-about-getting-into-dnd.gmi"/>
+
</entry>
+
<entry>
+
<id>gemini://hyperreal.coffee/gemlog/2022-05-27-sci-fi-plans-for-this-weekend.gmi</id>
+
<title>Sci-fi plans for this weekend</title>
+
<updated>2022-05-27T15:17:00+00:00</updated>
+
<link href="gemini://hyperreal.coffee/gemlog/2022-05-27-sci-fi-plans-for-this-weekend.gmi"/>
+
</entry>
+
<entry>
+
<id>gemini://hyperreal.coffee/gemlog/2022-01-29-editing-wikipedia-with-firejail.gmi</id>
+
<title>Editing Wikipedia with Firejail</title>
+
<updated>2022-01-29T11:10:00+00:00</updated>
+
<link href="gemini://hyperreal.coffee/gemlog/2022-01-29-editing-wikipedia-with-firejail.gmi"/>
+
</entry>
+
<entry>
+
<id>gemini://hyperreal.coffee/gemlog/2022-01-17-something-that-bothers-me-about-conversations.gmi</id>
+
<title>Something that bothers me about conversations
+
generally</title>
+
<updated>2022-01-17T19:43:00+00:00</updated>
+
<link href="gemini://hyperreal.coffee/gemlog/2022-01-17-something-that-bothers-me-about-conversations.gmi"/>
+
</entry>
+
<entry>
+
<id>gemini://hyperreal.coffee/gemlog/2022-01-06-re-is-there-a-word-for-nightmares-while-awake.gmi</id>
+
<title>re: Is There a Word For Nightmares While Awake?</title>
+
<updated>2022-01-06T23:36:00+00:00</updated>
+
<link href="gemini://hyperreal.coffee/gemlog/2022-01-06-re-is-there-a-word-for-nightmares-while-awake.gmi"/>
+
</entry>
+
<entry>
+
<id>gemini://hyperreal.coffee/gemlog/2022-01-03-normalize-bidets.gmi</id>
+
<title>Normalize bidets</title>
+
<updated>2022-01-03T17:36:00+00:00</updated>
+
<link href="gemini://hyperreal.coffee/gemlog/2022-01-03-normalize-bidets.gmi"/>
+
</entry>
+
<entry>
+
<id>gemini://hyperreal.coffee/gemlog/2021-12-26-how-do-i-pick-something-and-stick-with-it.gmi</id>
+
<title>How do I pick something and stick with it?</title>
+
<updated>2021-12-26T22:31:00+00:00</updated>
+
<link href="gemini://hyperreal.coffee/gemlog/2021-12-26-how-do-i-pick-something-and-stick-with-it.gmi"/>
+
</entry>
+
<entry>
+
<id>gemini://hyperreal.coffee/gemlog/2021-12-22-quick-note-on-glamorizing-mental-illness.gmi</id>
+
<title>A quick note on "glamorizing" mental illness</title>
+
<updated>2021-12-22T20:40:00+00:00</updated>
+
<link href="gemini://hyperreal.coffee/gemlog/2021-12-22-quick-note-on-glamorizing-mental-illness.gmi"/>
+
</entry>
+
<entry>
+
<id>gemini://hyperreal.coffee/gemlog/2021-11-28-switch-from-gnome-to-xfce.gmi</id>
+
<title>Switching from GNOME to Xfce</title>
+
<updated>2021-11-28T21:27:00+00:00</updated>
+
<link href="gemini://hyperreal.coffee/gemlog/2021-11-28-switch-from-gnome-to-xfce.gmi"/>
+
</entry>
+
<entry>
+
<id>gemini://hyperreal.coffee/gemlog/2021-11-14-re1-how-you-were-using-the-internet.gmi</id>
+
<title>Re Part 1: How you were using the Internet in the
+
1991-1995 and 1995-2005?</title>
+
<updated>2021-11-14T00:00:00+00:00</updated>
+
<link href="gemini://hyperreal.coffee/gemlog/2021-11-14-re1-how-you-were-using-the-internet.gmi"/>
+
</entry>
+
<entry>
+
<id>gemini://hyperreal.coffee/gemlog/2021-11-12-privilege.gmi</id>
+
<title>My blood boils when people misunderstand the concept of
+
privilege</title>
+
<updated>2021-11-12T00:00:00+00:00</updated>
+
<link href="gemini://hyperreal.coffee/gemlog/2021-11-12-privilege.gmi"/>
+
</entry>
+
<entry>
+
<id>gemini://hyperreal.coffee/gemlog/2021-11-12-connecting-usb-devices-to-wsl.gmi</id>
+
<title>Comments on using EmulationStation in WSL2</title>
+
<updated>2021-11-12T00:00:00+00:00</updated>
+
<link href="gemini://hyperreal.coffee/gemlog/2021-11-12-connecting-usb-devices-to-wsl.gmi"/>
+
</entry>
+
<entry>
+
<id>gemini://hyperreal.coffee/gemlog/2021-07-05-adventures-in-parsimonious-computing.gmi</id>
+
<title>Adventures in parsimonious computing</title>
+
<updated>2021-07-05T00:00:00+00:00</updated>
+
<link href="gemini://hyperreal.coffee/gemlog/2021-07-05-adventures-in-parsimonious-computing.gmi"/>
+
</entry>
+
<entry>
+
<id>gemini://hyperreal.coffee/gemlog/2021-05-10-gtfm.gmi</id>
+
<title>GTFM (Generate the Friendly Manual)</title>
+
<updated>2021-05-10T00:00:00+00:00</updated>
+
<link href="gemini://hyperreal.coffee/gemlog/2021-05-10-gtfm.gmi"/>
+
</entry>
+
<entry>
+
<id>gemini://hyperreal.coffee/gemlog/2021-01-16-my-guess-on-tes6-clue.gmi</id>
+
<title>My guess on the TES VI clue</title>
+
<updated>2021-01-16T00:00:00+00:00</updated>
+
<link href="gemini://hyperreal.coffee/gemlog/2021-01-16-my-guess-on-tes6-clue.gmi"/>
+
</entry>
+
</feed>
+60
gemini/gemlog/index.gmi
···
+
+
# hyperreal's gemlog
+
+
=> ./atom.xml Atom feed for this page
+
+
=> ./2025-11-27-unexpected-legacy-of-timothy-leary.gmi 2025-11-27 Unexpected legacy of Timothy Leary
+
=> ./2025-11-27-hot-take-on-vivaldi-browser.gmi 2025-11-27 Hot take on Vivaldi browser
+
=> ./2025-11-27-interesting-episode-of-late-night-linux-podcast.gmi 2025-11-27 Interesting episode of Late Night Linux podcast
+
=> ./2025-11-06-homelab-update-v20251030.gmi 2025-11-06 Homelab update v20251030
+
=> ./2025-11-06-homelab-update-v20251028.gmi 2025-11-06 Homelab update v20251028
+
=> ./2025-04-05-i-really-dislike-computers-sometimes.gmi 2025-04-05 I really dislike computers sometimes
+
=> ./2025-02-21-the-foreseeable-future.gmi 2025-02-21 The foreseeable future
+
=> ./2025-02-09-mental-health-improvement-or-something.gmi 2025-02-09 Mental health improvement or something
+
=> ./2025-01-12-my-comcast-home-isp-proof-qbittorrent-setup.gmi 2025-01-12 My Comcast/home ISP-proof qBittorrent setup
+
=> ./2025-01-05-my-network-wide-bullshit-blocking-setup.gmi 2025-01-05 My network-wide bullshit-blocking setup
+
=> ./2024-12-18-my-disillusionment-and-aspirations.gmi 2024-12-18 My disillusionment and aspirations
+
=> ./2024-12-16-update-on-homelab-projects.gmi 2024-12-16 Update on homelab projects
+
=> ./2024-12-12-my-nas-solution-and-other-homelab-projects.gmi 2024-12-12 My NAS solution and other homelab projects
+
=> ./2024-12-11-20-years-of-mental-illness.gmi 2024-12-11 20 years of mental illness
+
=> ./2024-12-09-my-tentative-file-syncing-solution.gmi 2024-12-09 My tentative file-syncing solution
+
=> ./2024-12-08-my-speech-language-enhancing-technology-wishes.gmi 2024-12-08 My speech/language-enhancing technology wishes
+
=> ./2024-11-24-on-using-reproducible-python-development-environments.gmi 2024-11-24 On using reproducible Python development environments
+
=> ./2024-11-24-home-networking-and-preventing-dns-leaks.gmi 2024-11-24 Home networking and preventing DNS leaks
+
=> ./2024-11-24-invega-mental-health-and-hygiene.gmi 2024-11-24 Invega, mental health, and hygiene
+
=> ./2024-09-30-rubber-duck-helps-me-debug-my-daily-driver-issues.gmi 2024-09-30 Rubber duck helps me debug my daily driver issues
+
=> ./2024-09-20-i-want-to-tell-google-to-eff-off.gmi 2024-09-20 I want to tell Google to eff off
+
=> ./2024-09-19-experimenting-with-freebsd-fate-of-invidious.gmi 2024-09-19 Experimenting with FreeBSD, and comments on the future of Invidious
+
=> ./2024-08-30-reducing-social-media-cross-posting-complexity.gmi 2024-08-30 Reducing social media cross-posting complexity
+
=> ./2024-08-20-listening-to-podcasts-while-driving.gmi 2024-08-20 Listening to podcasts while driving
+
=> ./2024-07-26-thoughts-on-tilde-hosting.gmi 2024-07-26 Thoughts on tilde hosting
+
=> ./2024-07-20-i-finally-sorted-out-my-self-hosting-stuff.gmi 2024-07-20 I finally sorted out my self-hosting stuff
+
=> ./2024-01-11-home-networking-madness.gmi 2024-01-11 Home Networking Madness
+
=> ./2023-08-29-invega-withdrawal-day-24.gmi 2023-08-29 Invega withdrawal and other things
+
=> ./2023-06-11-yet-another-homelab-setup.gmi 2023-06-11 Yet Another Homelab Setup
+
=> ./2023-05-14-migration-to-truenas.gmi 2023-05-14 Migration to TrueNAS CORE
+
=> ./2023-03-12-morality-in-dream-content.gmi 2023-03-12 Morality in dream content
+
=> ./2023-02-01-re-i-got-a-new-tablet.gmi 2023-02-01 RE: StackSmith: I got a new tablet
+
=> ./2022-09-17-considering-using-ipfs-for-content-hosting.gmi 2022-09-17 Considering using IPFS for content hosting
+
=> ./2022-09-09-what-i-look-forward-to-in-fall.gmi 2022-09-09 What I look forward to in the fall
+
=> ./2022-07-28-wish-I-could-taper-off-meds.gmi 2022-07-28 I wish I could taper off my meds
+
=> ./2022-07-15-glad-to-see-ocd-stereotypes-being-broken-up.gmi 2022-07-15 Glad to see OCD stereotypes being broken up
+
=> ./2022-07-07-comments-on-elder-scrolls-online-high-isle-spoilers.gmi 2022-07-07 Comments on The Elder Scrolls Online: High Isle (SPOILERS)
+
=> ./2022-06-15-chat-app-overload.gmi 2022-06-15 Chat App Overload
+
=> ./2022-05-31-am-nervous-about-getting-into-dnd.gmi 2022-05-31 Am nervous about getting into DnD
+
=> ./2022-05-27-sci-fi-plans-for-this-weekend.gmi 2022-05-27 Sci-fi plans for the weekend
+
=> ./2022-01-29-editing-wikipedia-with-firejail.gmi 2022-01-29 Editing Wikipedia with Firejail
+
=> ./2022-01-17-something-that-bothers-me-about-conversations.gmi 2022-01-17 Something that bothers me about conversations generally
+
=> ./2022-01-06-re-is-there-a-word-for-nightmares-while-awake.gmi 2022-01-06 re: Is There a Word For Nightmares While Awake?
+
=> ./2022-01-03-normalize-bidets.gmi 2022-01-03 Normalize bidets
+
=> ./2021-12-26-how-do-i-pick-something-and-stick-with-it.gmi 2021-12-26 How do I pick something and stick with it?
+
=> ./2021-12-22-quick-note-on-glamorizing-mental-illness.gmi 2021-12-22 A quick note on "glamorizing" mental illness
+
=> ./2021-11-28-switch-from-gnome-to-xfce.gmi 2021-11-28 Switching from GNOME to Xfce
+
=> ./2021-11-14-re1-how-you-were-using-the-internet.gmi 2021-11-14 Re: How you were using the Internet in 1991-1995 and 1995-2005
+
=> ./2021-11-12-connecting-usb-devices-to-wsl.gmi 2021-11-12 Connecting USB devices to WSL
+
=> ./2021-11-12-privilege.gmi 2021-11-12 My blood boils when people misunderstand privilege
+
=> ./2021-07-05-adventures-in-parsimonious-computing.gmi 2021-07-05 Adventures in parsimonious computing
+
=> ./2021-05-10-gtfm.gmi 2021-05-10 GTFM (Generate the Friendly Manual)
+
=> ./2021-01-16-my-guess-on-tes6-clue.gmi 2021-01-16 My guess on the TES VI clue
+
+
=> ../ Back to hyperreal.coffee
+31
gemini/ground-beef-vegetable-soup-with-gnocchi.gmi
···
+
Source:
+
=> https://www.southernliving.com/recipes/ground-beef-vegetable-soup-gnocchi https://www.southernliving.com/recipes/ground-beef-vegetable-soup-gnocchi
+
+
=> /images/ground-beef-vegetable-soup-with-gnocchi.jpg Ground beef vegetable soup with gnocchi [IMG]
+
+
## Ingredients
+
+
* 2 tsp of olive oil
+
* 1 pound of ground chuck
+
* 1 large yellow onion, chopped (about 3 cups)
+
* 4 celery ribs, thinly sliced (about 2 cups)
+
* 3 garlic cloves, finely chopped (about 4 tsp)
+
* 1 (28 oz) can of whole, peeled plum tomatoes, drained
+
* 2 tsp of dried oregano
+
* 8 cups of low-sodium chicken broth
+
* 1 (12 oz) package of gnocchi
+
* 1 (6 oz) package of fresh spinach
+
* 3 tsp of kosher salt
+
* 1/8 tsp of black pepper
+
* grated Parmesan cheese, for serving
+
+
## Instructions
+
+
* Heat oil in a large saucepan over high heat. Add beef and coo, stirring occasionally, until browned. (~8 minutes)
+
* Add onion, celery, and garlic. Cook, stirring often, until vegetables are softened. (~8 minutes)
+
* Stir in tomatoes and oregano, breaking up tomatoes with wooden spoon.
+
* Stir in broth and bring to a boil.
+
* Reduce heat to medium-low, and gently boil until the vegetables are tender. (~8 minutes)
+
* Add gnocchi, and cook until just tender. (~3 minutes)
+
* Remove from heat. Stir in spinach, salt, and black pepper.
+
* Sprinkle each serving with grated Parmesan.
+59
gemini/homelab.gmi
···
+
## Desktop / Gaming
+
+
* Machine: System76 Thelio Major (r4)
+
* CPU: AMD Ryzen 7 7700X (8 cores, 16 threads) @ 5.6 GHz
+
* GPU: NVIDIA GeForce RTX 4090 (discrete), 24 GB with 16384 CUDA Cores
+
* RAM: 64 GB Dual Channel DDR5 (4x16 GB), 4800 MHz
+
* HDD: 2 TB PCIe Gen4, Read: 7000 MB/s, Write: 5100 MB/s
+
* Networking: 2.5 GB/s Ethernet, Built-in Intel WiFi 6E + Bluetooth 5.3
+
* OS: CachyOS with GNOME
+
+
## Laptop
+
+
* Machine: Lenovo Thinkpad X1 Carbon (11th gen)
+
* CPU: 12th Gen Intel Core i7-1260Pz (8 cores, 16 threads) @ 4.70 GHz
+
* GPU: Intel Iris Xe Graphics @ 1.40 GHz (integrated)
+
* RAM: 16 GB LPDDR5 6000 MHz
+
* HDD: 476.9 GB NVMe
+
* Networking: Built-in Intel WiFi 6E + Bluetooth 5.3
+
* OS: CachyOS with KDE Plasma
+
+
## NAS
+
+
* Machine: System76 Meerkat (meer9)
+
* CPU: Intel Core Ultra 7 155H, (16 cores, 22 threads) @ 4.8 GHz
+
* GPU: Intel Arc Graphics @ 2.25 GHz (integrated)
+
* RAM: 64 GB Dual Channel DDR5 5600 MHz
+
* HDD: 500 GB M.2 PCIe Gen4 NVMe
+
* Networking: 2.5 GB/s Ethernet, Built-in Intel WiFi 6E + Bluetooth 5.3
+
* OS: FreeBSD
+
+
### Notes
+
+
In addition to the internal hard drive, I have a NAS enclosure that contains 8x22 TB Enterprise HDDs. The NAS enclosure I use is Syba 8-bay hot swappable 2.5" 3.5" SATA non-RAID external USB 3.0.
+
+
=> https://www.amazon.com/dp/B07MD2LNYX Syba 8-Bay, Hot Swappable 2.5" 3.5" SATA Non RAID External USB 3.0 Enclosure
+
+
I use the NAS for digital archiving. It runs the following services:
+
+
* ArchiveBox
+
* Jellyfin
+
* qBittorrent in a dedicated thick VNET jail over ProtonVPN/WireGuard
+
+
=> https://archivebox.io ArchiveBox
+
+
=> https://techne.hyperreal.coffee/torrenting.html Techne: Dedicated thick VNET jail
+
+
For all the machines from which I want to backup data, each machine runs borgmatic to backup data to borgbackup repositories located on the NAS.
+
+
The 8x22 TB Enterprise HDDs comprise a 176 TB ZFS pool. I have separate ZFS datasets for various categories of data.
+
+
## Phone
+
+
* Machine: Motorola Edge 2025
+
* CPU: Octa-core (4x2.6 GHz Cortex-A78 & 4x2.0 GHz Cortex-A55)
+
* GPU: Mali-G615 MC2
+
* RAM: 8 GB
+
* HDD: 256 GB
+
* Networking: GSM / HSPA / LTE / 5G
+
* OS: stock Android 15 (for now, until a ROM becomes available for Murena /e/OS)
+92
gemini/hyperreal.pgp.asc
···
+
-----BEGIN PGP PUBLIC KEY BLOCK-----
+
+
mDMEZ5gVQBYJKwYBBAHaRw8BAQdAhbX7GOQsr3ncsCxsZT7IDUmsbSb6JJGiYoHf
+
szyrxwm0KEplZmZyZXkgU2VyaW8gPGh5cGVycmVhbEBtb29uc2hhZG93LmRldj6J
+
A5QEExYIAzwCGwMFCQPCZwAFCwkIBwIGFQoJCAsCBBYCAwECHgECF4AWIQTmqurJ
+
uvA6vgsIYfb9vrfSFNW77wUCaNnHbU0UgAAAAAAQADRwcm9vZkBhcmlhZG5lLmlk
+
b3BlbnBncDRmcHI6RTZBQUVBQzlCQUYwM0FCRTBCMDg2MUY2RkRCRUI3RDIxNEQ1
+
QkJFRjYUgAAAAAAQAB1wcm9vZkBhcmlhZG5lLmlkaHR0cHM6Ly90aWxkZS56b25l
+
L0BoeXBlcnJlYWw2FIAAAAAAEAAdcHJvb2ZAYXJpYWRuZS5pZGh0dHBzOi8vZGlz
+
Y29yZC5nZy9EVmQ0ZWFZeUdmXRSAAAAAABAARHByb29mQGFyaWFkbmUuaWRodHRw
+
czovL2dpc3QuZ2l0aHViLmNvbS9oeXBlcnJlYWw2NC9kOGIxM2Q2NDFkNzg3NGVm
+
Y2E3MjExYTE3NzEwZDgxMTQUgAAAAAAQABtwcm9vZkBhcmlhZG5lLmlkZG5zOm1v
+
b25zaGFkb3cuZGV2P3R5cGU9VFhUNhSAAAAAABAAHXByb29mQGFyaWFkbmUuaWRk
+
bnM6aHlwZXJyZWFsLmNvZmZlZT90eXBlPVRYVEYUgAAAAAAQAC1wcm9vZkBhcmlh
+
ZG5lLmlkaHR0cHM6Ly9jb2RlYmVyZy5vcmcvaHlwZXJyZWFsL2tleW94aWRlX3By
+
b29mNxSAAAAAABAAHnByb29mQGFyaWFkbmUuaWRodHRwczovL2xlbW15Lm1sL3Uv
+
aHlwZXJyZWFsNjRlFIAAAAAAEABMcHJvb2ZAYXJpYWRuZS5pZGh0dHBzOi8vYnNr
+
eS5hcHAvcHJvZmlsZS9kaWQ6cGxjOm51YzMzdGhuc2lxemh5dGtsZXlyNWplay9w
+
b3N0LzNsd3dmZ3FhN2xjMnhLFIAAAAAAEAAycHJvb2ZAYXJpYWRuZS5pZGh0dHBz
+
Oi8vdW5pdmVyc2FsLWJsdWUuZGlzY291cnNlLmdyb3VwL3UvaHlwZXJyZWFsRhSA
+
AAAAABAALXByb29mQGFyaWFkbmUuaWRodHRwczovL3RpbGRlZ2l0Lm9yZy9oeXBl
+
cnJlYWwva2V5b3hpZGVfcHJvb2YACgkQ/b630hTVu+/QgAD/bwX17Nuqpj6C9meJ
+
4uT3YiVF+NEEJPjfGfoy5ysrwdMBAKVSAH6n2ZsTH6jZ5BFS+a3jXlsCxP1Zxcj6
+
mMv1pj8HiQNPBBMWCAL3AhsDBQkDwmcABQsJCAcCBhUKCQgLAgQWAgMBAh4BAheA
+
FiEE5qrqybrwOr4LCGH2/b630hTVu+8FAminT95LFIAAAAAAEAAycHJvb2ZAYXJp
+
YWRuZS5pZGh0dHBzOi8vdW5pdmVyc2FsLWJsdWUuZGlzY291cnNlLmdyb3VwL3Uv
+
aHlwZXJyZWFsZRSAAAAAABAATHByb29mQGFyaWFkbmUuaWRodHRwczovL2Jza3ku
+
YXBwL3Byb2ZpbGUvZGlkOnBsYzpudWMzM3RobnNpcXpoeXRrbGV5cjVqZWsvcG9z
+
dC8zbHd3ZmdxYTdsYzJ4NxSAAAAAABAAHnByb29mQGFyaWFkbmUuaWRodHRwczov
+
L2xlbW15Lm1sL3UvaHlwZXJyZWFsNjRGFIAAAAAAEAAtcHJvb2ZAYXJpYWRuZS5p
+
ZGh0dHBzOi8vY29kZWJlcmcub3JnL2h5cGVycmVhbC9rZXlveGlkZV9wcm9vZjYU
+
gAAAAAAQAB1wcm9vZkBhcmlhZG5lLmlkZG5zOmh5cGVycmVhbC5jb2ZmZWU/dHlw
+
ZT1UWFQ0FIAAAAAAEAAbcHJvb2ZAYXJpYWRuZS5pZGRuczptb29uc2hhZG93LmRl
+
dj90eXBlPVRYVF0UgAAAAAAQAERwcm9vZkBhcmlhZG5lLmlkaHR0cHM6Ly9naXN0
+
LmdpdGh1Yi5jb20vaHlwZXJyZWFsNjQvZDhiMTNkNjQxZDc4NzRlZmNhNzIxMWEx
+
NzcxMGQ4MTE2FIAAAAAAEAAdcHJvb2ZAYXJpYWRuZS5pZGh0dHBzOi8vZGlzY29y
+
ZC5nZy9EVmQ0ZWFZeUdmNhSAAAAAABAAHXByb29mQGFyaWFkbmUuaWRodHRwczov
+
L3RpbGRlLnpvbmUvQGh5cGVycmVhbE8UgAAAAAAQADZwcm9vZkBhcmlhZG5lLmlk
+
aHR0cHM6Ly9naXRsYWIuaHlwZXJyZWFsLmNvZmZlZS9oeXBlcnJlYWwvZ2l0bGFi
+
X3Byb29mAAoJEP2+t9IU1bvv9YoA+QHKxpa5HNyuXm5sKpV7oHWRovYRzqV4tu83
+
+Le9K+NnAP9Y+CuQi2V9OdpF4hiP0BGqhAWUkUmcBH4d5eJU+bGABIkDAwQTFggC
+
qwIbAwUJA8JnAAULCQgHAgYVCgkICwIEFgIDAQIeAQIXgBYhBOaq6sm68Dq+Cwhh
+
9v2+t9IU1bvvBQJop06STxSAAAAAABAANnByb29mQGFyaWFkbmUuaWRodHRwczov
+
L2dpdGxhYi5oeXBlcnJlYWwuY29mZmVlL2h5cGVycmVhbC9naXRsYWJfcHJvb2Y2
+
FIAAAAAAEAAdcHJvb2ZAYXJpYWRuZS5pZGh0dHBzOi8vdGlsZGUuem9uZS9AaHlw
+
ZXJyZWFsNhSAAAAAABAAHXByb29mQGFyaWFkbmUuaWRodHRwczovL2Rpc2NvcmQu
+
Z2cvRFZkNGVhWXlHZl0UgAAAAAAQAERwcm9vZkBhcmlhZG5lLmlkaHR0cHM6Ly9n
+
aXN0LmdpdGh1Yi5jb20vaHlwZXJyZWFsNjQvZDhiMTNkNjQxZDc4NzRlZmNhNzIx
+
MWExNzcxMGQ4MTE0FIAAAAAAEAAbcHJvb2ZAYXJpYWRuZS5pZGRuczptb29uc2hh
+
ZG93LmRldj90eXBlPVRYVDYUgAAAAAAQAB1wcm9vZkBhcmlhZG5lLmlkZG5zOmh5
+
cGVycmVhbC5jb2ZmZWU/dHlwZT1UWFRGFIAAAAAAEAAtcHJvb2ZAYXJpYWRuZS5p
+
ZGh0dHBzOi8vY29kZWJlcmcub3JnL2h5cGVycmVhbC9rZXlveGlkZV9wcm9vZjcU
+
gAAAAAAQAB5wcm9vZkBhcmlhZG5lLmlkaHR0cHM6Ly9sZW1teS5tbC91L2h5cGVy
+
cmVhbDY0ZRSAAAAAABAATHByb29mQGFyaWFkbmUuaWRodHRwczovL2Jza3kuYXBw
+
L3Byb2ZpbGUvZGlkOnBsYzpudWMzM3RobnNpcXpoeXRrbGV5cjVqZWsvcG9zdC8z
+
bHd3ZmdxYTdsYzJ4AAoJEP2+t9IU1bvva0kA/2aXND9cX3QKRfVGyAg62lWkNHUr
+
fw4W+kuH8lbd8nsIAP9UaoQG0gtji6xHrxqgtRhEoRrm7EeLU4WXrXI9HnWNA4kC
+
4AQTFggCiAIbAwUJA8JnAAULCQgHAgYVCgkICwIEFgIDAQIeAQIXgBYhBOaq6sm6
+
8Dq+Cwhh9v2+t9IU1bvvBQJop00jTxSAAAAAABAANnByb29mQGFyaWFkbmUuaWRo
+
dHRwczovL2dpdGxhYi5oeXBlcnJlYWwuY29mZmVlL2h5cGVycmVhbC9naXRsYWJf
+
cHJvb2Y2FIAAAAAAEAAdcHJvb2ZAYXJpYWRuZS5pZGh0dHBzOi8vdGlsZGUuem9u
+
ZS9AaHlwZXJyZWFsNhSAAAAAABAAHXByb29mQGFyaWFkbmUuaWRodHRwczovL2Rp
+
c2NvcmQuZ2cvRFZkNGVhWXlHZl0UgAAAAAAQAERwcm9vZkBhcmlhZG5lLmlkaHR0
+
cHM6Ly9naXN0LmdpdGh1Yi5jb20vaHlwZXJyZWFsNjQvZDhiMTNkNjQxZDc4NzRl
+
ZmNhNzIxMWExNzcxMGQ4MTE0FIAAAAAAEAAbcHJvb2ZAYXJpYWRuZS5pZGRuczpt
+
b29uc2hhZG93LmRldj90eXBlPVRYVEIUgAAAAAAQAClwcm9vZkBhcmlhZG5lLmlk
+
aHR0cHM6Ly9ic2t5LmFwcC9wcm9maWxlL2h5cGVycmVhbC5jb2ZmZWU2FIAAAAAA
+
EAAdcHJvb2ZAYXJpYWRuZS5pZGRuczpoeXBlcnJlYWwuY29mZmVlP3R5cGU9VFhU
+
RhSAAAAAABAALXByb29mQGFyaWFkbmUuaWRodHRwczovL2NvZGViZXJnLm9yZy9o
+
eXBlcnJlYWwva2V5b3hpZGVfcHJvb2Y3FIAAAAAAEAAecHJvb2ZAYXJpYWRuZS5p
+
ZGh0dHBzOi8vbGVtbXkubWwvdS9oeXBlcnJlYWw2NAAKCRD9vrfSFNW778xLAP41
+
rYG16Y12UiKpSX+Kja/eKPf0QVStT7sbw0mPgn6LMQEAi0lKcr4PdTi5zUQcg/wr
+
gm9jdSawGsb9J+GOX40R1QOJApAEExYIAjgCGwMFCQPCZwAFCwkIBwIGFQoJCAsC
+
BBYCAwECHgECF4AWIQTmqurJuvA6vgsIYfb9vrfSFNW77wUCaKdL+zcUgAAAAAAQ
+
AB5wcm9vZkBhcmlhZG5lLmlkaHR0cHM6Ly9sZW1teS5tbC91L2h5cGVycmVhbDY0
+
RhSAAAAAABAALXByb29mQGFyaWFkbmUuaWRodHRwczovL2NvZGViZXJnLm9yZy9o
+
eXBlcnJlYWwva2V5b3hpZGVfcHJvb2Y2FIAAAAAAEAAdcHJvb2ZAYXJpYWRuZS5p
+
ZGRuczpoeXBlcnJlYWwuY29mZmVlP3R5cGU9VFhUQhSAAAAAABAAKXByb29mQGFy
+
aWFkbmUuaWRodHRwczovL2Jza3kuYXBwL3Byb2ZpbGUvaHlwZXJyZWFsLmNvZmZl
+
ZTQUgAAAAAAQABtwcm9vZkBhcmlhZG5lLmlkZG5zOm1vb25zaGFkb3cuZGV2P3R5
+
cGU9VFhUXRSAAAAAABAARHByb29mQGFyaWFkbmUuaWRodHRwczovL2dpc3QuZ2l0
+
aHViLmNvbS9oeXBlcnJlYWw2NC9kOGIxM2Q2NDFkNzg3NGVmY2E3MjExYTE3NzEw
+
ZDgxMTYUgAAAAAAQAB1wcm9vZkBhcmlhZG5lLmlkaHR0cHM6Ly9kaXNjb3JkLmdn
+
L0RWZDRlYVl5R2Y2FIAAAAAAEAAdcHJvb2ZAYXJpYWRuZS5pZGh0dHBzOi8vdGls
+
ZGUuem9uZS9AaHlwZXJyZWFsAAoJEP2+t9IU1bvvo60BAJ4z1vYEBjKimvq//qFb
+
lcB9VSnlge8g7zc/0SfO7q+iAQDa4YXtY5FrLvJHXpUCs8OadENLamUhOf7sqSWl
+
OYpIB7g4BGeYFUASCisGAQQBl1UBBQEBB0BheBN/VeHBFksgFUT0knizvK63Zvzl
+
Kc4wTcvu1xnIXAMBCAeIfgQYFggAJhYhBOaq6sm68Dq+Cwhh9v2+t9IU1bvvBQJn
+
mBVAAhsMBQkDwmcAAAoJEP2+t9IU1bvv0IcBAKD2t+NpE9CdZplTuVv1Bd5EwTk6
+
JiSSDsQPzfm6V1p+AQD/OiHZac1PddqNTRpMv+rL9g+ZPXXWaTj0K64XyWZSCw==
+
=DGS2
+
-----END PGP PUBLIC KEY BLOCK-----
+44
gemini/index.gmi
···
+
```
+
+
8 8
+
8 8
+
8oPYo. o o .oPYo. .oPYo. oPYo. oPYo. .oPYo. .oPYo. 8
+
8 8 8 8 8 8 8oooo8 8 `' 8 `' 8oooo8 .oooo8 8
+
8 8 8 8 8 8 8. 8 8 8. 8 8 8
+
8 8 `YooP8 8YooP' `Yooo' 8 8 `Yooo' `YooP8 8
+
..:::..:....8 8 ....::.....:..::::..:::::.....::.....:..
+
:::::::::ooP'.8 ::::::::::::::::::::::::::::::::::::::::
+
:::::::::...::..::::::::::::::::::::::::::::::::::::::::
+
```
+
+
Hi, I'm hyperreal. Welcome to my capsule in Geminispace.
+
+
I'm a FOSS geek, privacy advocate, digital archivist, mental illness advocate, RPG enthusiast, coffee lover.
+
+
=> ./hyperreal.pgp.asc PGP Key: E6AAEAC9BAF03ABE0B0861F6FDBEB7D214D5BBEF
+
=> https://keyoxide.org/hyperreal%40moonshadow.dev Keyoxide profile
+
+
## Navigation
+
=> ./gemlog/ Gemlog
+
=> ./about.gmi About
+
=> ./computing.gmi Computing
+
=> ./recipes.gmi Recipes
+
=> ./resources.gmi Resources
+
=> ./gem-bookmarks.gmi Gemini bookmarks
+
=> https://hyperreal.coffee My HTTP website
+
+
I am not affiliated with Techdirt in any way. I'm just running an hourly script that converts their RSS feed to gemtext.
+
=> ./techdirt.gmi Techdirt feed
+
+
If you have any questions about the content here, feel free to contact me on any of the below things:
+
=> https://tilde.zone/@hyperreal Fediverse
+
=> https://bsky.app/profile/hyperreal.bsky.moonshadow.dev Bluesky
+
=> https://discordapp.com/users/263927928595808257 Discord
+
=> https://signal.me/#eu/UEc0iZQ4f_2sCKN0JPz7DkP48QpdHcU2LENa0dLmbnx4D1XENahJp7q-oaP_gsNS Signal
+
+
You can also find me as `hyperreal` on any of the below IRC networks:
+
* irc.libera.chat
+
* irc.tilde.chat
+
* irc.oftc.net
+
+
Last updated: 2025-11-22
+28
gemini/italian-pastina-soup.gmi
···
+
Source:
+
=> https://allrecipes.com/classic-italian-pastina-soup-recipe-7971739 https://allrecipes.com/classic-italian-pastina-soup-recipe-7971739
+
+
=> /images/italian-pastina-soup.jpg Italian pastina soup [IMG]
+
+
## Ingredients
+
+
* 1 3-4 lb. whole chicken, neck and insides removed
+
* 10-12 cups cold water
+
* 3 stalks of celery, divided
+
* 2 medium white or yellow onions, peeled, divided
+
* 3 large carrots, peeled, divided
+
* 1 tbsp kosher salt, plus more to taste, divided
+
* 2 tsp black pepper, divided
+
* 2 tbsp of olive oil
+
* 2 cloves of garlic, minced
+
* 1 tbsp of reduced sodium chicken base, such as Better Than Bouillon
+
* 1 cup of pastina or other tiny pasta, such as stars
+
* 1 tbsp of finely chopped parsley, or to taste (optional)
+
* 2 tbsp of freshly grated Parmesan cheese, or to taste (optional)
+
+
## Instructions
+
+
* Place chicken in large pot and pour water over to cover.
+
* Roughly chop 2 ribs of celery, 1.5 onions, and 2 carrots. Add to pot with chicken. Season with 2 teaspoons of salt and 1 teaspoon of black pepper. Bring pot to a boil over high heat. Reduce the heat to medium-low and allow the chicken to simmer 1 hour, covered.
+
* Remove chicken from the pot and allow to cool before removing and shredding the meat. Strain the stock and discard the solids. Reserve liquid and add water if necessary to measure 12 cups of liquid. Wipe pot clean.
+
* Finely chop remaining celery, onion, and carrot. Place pot over medium-high heat and add oil. Add chopped vegetables, remaining salt, black pepper, and garlic, and cook frequently until vegetables are tender and onion is translucent (the veggies should not be browned). Add reserved stock and chicken base and stir to combine. Bring mixture to a boil and reduce it to simmer. Allow soup to simmer 10 minutes.
+
* Increase heat to high and bring to a boil. Add pasta and cook, stirring occasionally 15 minutes or until pasta is tender. Reduce heat to low and add chicken and season if desired. Cook 5 additional minutes. Stir in chopped parsley and serve with grated Parmesan cheese.
+21
gemini/keto-no-noodle-chicken-cabbage-soup.gmi
···
+
## Ingredients
+
+
* 4 oz butter
+
* 2 tbsp dried minced onion
+
* 2 (2.75 oz) celery ribs, chopped
+
* 6 oz mushrooms, sliced
+
* 2 minced garlic cloves
+
* 8 cups of chicken broth
+
* 2 oz (7 tbsp) carrots, sliced
+
* 2 tsp dried parsley
+
* 1 tsp salt
+
* 1/4 tsp ground black pepper
+
* 1.5 (2.66 lbs) rotisserie chicken, shredded
+
* 5 oz. green cabbage, sliced into strips
+
+
## Instructions
+
+
* Melt butter in large pot, over medium heat.
+
* Add dried onion, chopped celery, sliced mushrooms, and garlic into the pot and cook. ~3-4 minutes.
+
* Add broth, sliced carrots, parsley, salt, and pepper. Simmer until vegetables are tender.
+
* Add cooked chicken and cabbage. Simmer for an additional 8-12 minutes until the cabbage is tender.
+9
gemini/recipes.gmi
···
+
=> beef-and-red-lentil-chili.gmi Beef and red lentil chili
+
+
=> ground-beef-vegetable-soup-with-gnocchi.gmi Ground beef vegetable soup with gnocchi
+
+
=> italian-pastina-soup.gmi Italian pastina soup
+
+
=> keto-no-noodle-chicken-cabbage-soup.gmi Keto no-noodle chicken cabbage soup
+
+
=> white-bean-soup-with-pasta.gmi White bean soup with pasta
+45
gemini/resources.gmi
···
+
=> community-driven-distros.gmi Community-driven FOSS distros
+
+
=> https://asciinema.org/~hyperreal My Asciinema profile
+
+
=> https://bookmarks.hyperreal.coffee My Bookmarks
+
+
=> https://github.com/hyperreal64 My GitHub profile
+
+
=> https://keyoxide.org/hyperreal%40moonshadow.dev My Keyoxide profile
+
+
=> https://tildegit.org/hyperreal My code on Tildegit.org
+
+
=> https://archives.hyperreal.coffee My digital archive collection
+
+
## Podcasts I listen to
+
+
=> https://www.bsdnow.tv/ BSD Now
+
+
=> https://tuxdigital.com/podcasts/destination-linux/ Destination Linux
+
+
=> https://dlnxtend.com/ Linux Out Loud
+
+
=> https://podcast.thelinuxexp.com/@tlenewspodcast Linux & Open Source News
+
+
=> https://twit.tv/shows/security-now Security Now
+
+
## Public web services I host
+
+
These are mainly alternative, FOSS, ad-free, minimalistic front-ends to various websites and services.
+
+
=> https://anonoverflow.hyperreal.coffee AnonymousOverflow
+
+
=> https://breezewiki.hyperreal.coffee BreezeWiki
+
+
=> https://dumb.hyperreal.coffee Dumb
+
+
=> https://lingva.hyperreal.coffee Lingva Translate
+
+
=> https://annas-archive.hyperreal.coffee Mirror of Anna's Archive torrents
+
+
=> https://pb.hyperreal.coffee PrivateBin
+
+
=> https://searxng.hyperreal.coffee SearXNG
+
+
=> https://txtdot.hyperreal.coffee txtdot
+23
gemini/vps-cloud-servers.gmi
···
+
## netcup.de: hyperreal
+
+
* Machine: VPS 1000 G11 iv 12M MNZ
+
* CPU: AMD EPYC-Genoa (4-core) @ 2.25 GHz
+
* RAM: 8 GB
+
* HDD: 256 GB SSD
+
* Networking: 2.5 GB/s uplink
+
* Monthly traffic: 2 TB per 24 hours, otherwise 200 MB/s
+
* OS: Debian 13
+
* Price: €5.75 = $6.65 per month
+
+
### Notes
+
+
This is my main public-facing server. It hosts my website, blog, and Gemini capsule. Additionally, it hosts the following alternative front-end web services:
+
+
* Anonymous Overflow : alternative front-end to Stack Overflow)
+
* BreezeWiki : alternative front-end to Fandom.com wikis
+
* Dumb : alternative front-end to Genius lyrics
+
* Lingva Translate : language translation service
+
* PrivateBin : Private pastebin
+
* SearXNG : privacy-focused meta-search engine
+
* txtdot : render web pages as text
+
* Anna's Archive torrent mirror : A mirror site for Anna's Archive .torrent files.
+31
gemini/white-bean-soup-with-pasta.gmi
···
+
Source:
+
=> https://www.eatingwell.com/recipe/7923697/white-bean-soup-with-pasta/ https://www.eatingwell.com/recipe/7923697/white-bean-soup-with-pasta/
+
+
=> /images/white-bean-soup-with-pasta.jpg White bean soup with pasta [IMG]
+
+
## Ingredients
+
+
* 1 tbsp of extra-virgin olive oil
+
* 1.5 cups of frozen mirepoix (diced onion, celery, and carrot)
+
* 2 cloves of garlic, minced
+
* 1 tsp of Italian seasoning
+
* 1 tsp of salt
+
* 0.25 tsp of crushed red pepper
+
* 0.25 tsp of ground black pepper
+
* 1 (28 oz) can of no-salt-added diced tomatoes
+
* 2 cups of low-sodium chicken broth
+
* 1 (15 oz) can of low-sodium cannellini beans, rinsed
+
* 8 ounces of small whole-wheat pasta, such as elbows
+
* 1.5 cups of frozen cut-leaf spinach
+
* 4 tbsp of grated Parmesan cheese
+
+
## Instructions
+
+
* Put a large saucepan of water on to boil.
+
* Heat 1 tbsp of olive oil in a a large pot over medium-high heat. Add 1.5 cups of frozen mirepoix and cook, stirring until softened. (~3 minutes)
+
* Add 2 cloves of minced garlic, 1 tsp of Italian seasoning, 1 tsp of salt, 0.25 tsp of crushed red pepper, and 0.25 tsp of ground black pepper, and cook, stirring until fragrant. (~1 minute)
+
* Add 1 can of diced tomatoes and their juices, 2 cups of chicken broth, and 1 can of beans. Bring to a boil.
+
* Reduce heat to maintain a lively simmer. Cover and cook, stirring occasionally, until tomatoes begin to break down. (~10 minutes)
+
* Meanwhile, cook 8 ounces of pasta in the boiling water for 1 minute less than the package directions. Drain pasta.
+
* Stir 1.5 cups of spinach into the soup. Stir in the pasta just before serving.
+
* Serve topped with 4 tbsp of Parmesan cheese.
+4
http/archetypes/default.md
···
+
+++
+
title = '{{ replace .File.ContentBaseName "-" " " | title }}'
+
draft = true
+
+++
+15
http/content/_index.md
···
+
I'm hyperreal. Welcome to my nook of the interwebz.
+
+
* PGP Key: [E6AAEAC9BAF03ABE0B0861F6FDBEB7D214D5BBEF](https://hyperreal.coffee/hyperreal.pgp.asc)
+
* Keyoxide: <https://keyoxide.org/hyperreal%40moonshadow.dev>
+
+
If you have any questions about the content here, feel free to find me on any of the below things:
+
+
[Fediverse](https://tilde.zone/@hyperreal)
+
[Bluesky](https://bsky.app/profile/hyperreal.bsky.moonshadow.dev)
+
[Discord](https://discordapp.com/users/263927928595808257)
+
[Signal](https://signal.me/#eu/UEc0iZQ4f_2sCKN0JPz7DkP48QpdHcU2LENa0dLmbnx4D1XENahJp7q-oaP_gsNS)
+
+
*This site is intentionally simple to improve accessibility.*
+
+
<a href="https://moule.world"><img src="/88x31/MOULEWORLD.gif" loading="lazy" alt="MOULE WORLD"></a> <a href="https://32bit.cafe" target="_blank" rel="noopener"><img src="/88x31/32BitCafe.PNG" loading="lazy" alt="32-Bit Cafe"></a> <a href="https://peertube2.cpy.re/w/04af977f-4201-4697-be67-a8d8cae6fa7a" target="_blank" rel="noopener"><img src="/88x31/AaronSwartz.png" loading="lazy" alt="Aaron Swartz: 1986 - 2013"></a> <a href="https://yesterweb.org/no-to-web3/" target="_blank" rel="noopener"><img src="/88x31/AntiNFT.gif" loading="lazy" alt="This is an Anti-NFT site."></a> <a href="https://stimpunks.org/2023/04/01/how-to-be-an-ally-during-autism-acceptance-month/" target="_blank" rel="noopener"><img src="/88x31/Autism.jpg" loading="lazy" alt="Autism Acceptance NOW!"></a> <a href="https://autisticprideday.org/" target="_blank" rel="noopener"><img src="/88x31/AutisticPride.png" loading="lazy" alt="Autistic Pride"></a> <a href="https://blacklivesmatter.com" target="_blank" rel="noopener"><img src="/88x31/BLM.png" loading="lazy" alt="Black Lives Matter"></a> <img src="/88x31/Coffee.gif" loading="lazy" alt="Fueled by Coffee"> <img src="/88x31/ComeAsYouAre.GIF" loading="lazy" alt="Come As You Are"> <a href="https://resistcovideugenics.carrd.co/" target="_blank" rel="noopener"><img src="/88x31/COVIDNotOver.png" loading="lazy" alt="Hey, COVID is still not over!"></a> <a href="https://www.debian.org" target="_blank" rel="noopener"><img src="/88x31/Debian.gif" loading="lazy" alt="Powered by Debian"></a> <a href="https://defectivebydesign.org" target="_blank" rel="noopener"><img src="/88x31/DBD.gif" loading="lazy" alt="Defective by Design: Eliminate DRM NOW!"></a> <a href="https://www.webnots.com/4-ways-to-block-ai-bots-accessing-your-site/" target="_blank" rel="noopener"><img src="/88x31/AI.GIF" loading="lazy" alt="Don't feed the AI! Link to how to block AI scrapers."></a> <img src="/88x31/Ducks.png" loading="lazy" alt="Powered by DUCKS"> <a href="https://github.com/DerekTurtleRoe/awesome-emulators" target="_blank" rel="noopener noreferrer"><img src="/88x31/Emulate.png" loading="lazy" alt="Emulate NOW!"></a> <img src="/88x31/Encrypt.GIF" loading="lazy" alt="Encrypt your Shit!!"> <a href="https://fediring.net/" target="_blank" rel="noopener"><img src="/88x31/FediRing.gif" loading="lazy" alt="FediRing"></a> <a href="https://jointhefediverse.net" target="_blank" rel="noopener"><img src="/88x31/Fediverse.png" loading="lazy" alt="Join the Fediverse"></a> <img src="/88x31/Fight.gif" loading="lazy" alt="Fight for open web standards, for online privacy, against monopolistic practises. Stand up to Google!"> <a href="https://en.wikipedia.org/wiki/Right_to_repair" target="_blank" rel="noopener"><img src="/88x31/Repair.gif" loading="lazy" alt="I support right to repair"></a> <a href="https://archive.org" target="_blank" rel="noopener"><img src="/88x31/IA.png" loading="lazy" alt="Preserve the internet, games, film, TV, software, photos, books, HISTORY! Internet Archive"></a> <a href="https://indiepocalypse.social" target="_blank" rel="noopener"><img src="/88x31/IndiePocalypse.png" loading="lazy" alt="IndiePocalypse.Social Mastodon"></a> <a href="https://indieweb.org" target="_blank" rel="noopener"><img src="/88x31/IndieWeb.gif" loading="lazy" alt="IWC Now! IndieWeb.org"></a> <a href="https://w3.org/Promotion/WIP/" target="_blank" rel="noopener"><img src="/88x31/Interop.gif" loading="lazy" alt="Web Interoperability Pledge"></a> <img src="/88x31/ISIProgressPride.png" loading="lazy" alt="Intersex-Inclusive Progress Pride Flag"> <a href="https://yesterweb.org/no-to-web3/" target="_blank" rel="noopener"><img src="/88x31/NoWeb3.gif" loading="lazy" alt="Keep the Web Free, Say No to Web3"></a> <a href="https://join-lemmy.org" target="_blank" rel="noopener"><img src="/88x31/Lemmy.png" loading="lazy" alt="Lemmy: join-lemmy.org"></a> <a href="https://joinmastodon.org" target="_blank" rel="noopener"><img src="/88x31/LTJM.gif" loading="lazy" alt="Leave Twitter, Join Mastodon"></a> <a href="https://www.libreoffice.org/discover/what-is-opendocument/" target="_blank" rel="noopener"><img src="/88x31/NoDoc.png" loading="lazy" alt="Free your documents. No .doc"></a> <img src="/88x31/NoTERFs.GIF" loading="lazy" alt="No TERFs"> <a href="https://www.python.org" target="_blank" rel="noopener"><img src="/88x31/Python.GIF" loading="lazy" alt="Python powered"></a> <a href="https://sm64hacks.com" target="_blank" rel="noopener"><img src="/88x31/SM64Hacks.png" loading="lazy" alt="SM64 Hacks"></a> <a href="https://sm64romhacks.com" target="_blank" rel="noopener"><img src="/88x31/SM64ROMHacks.png" loading="lazy" alt="SM64RomHacks.com"></a> <a href="https://www.torproject.org/download/" target="_blank" rel="noopener"><img src="/88x31/TOR.GIF" loading="lazy" alt="TOR"></a> <a href="https://www.transrightsnow.org" target="_blank" rel="noopener"><img src="/88x31/TransRightsNow.gif" loading="lazy" alt="Trans Rights Now"></a> <a href="https://resistcovideugenics.carrd.co/#masks" target="_blank" rel="noopener"><img src="/88x31/MaskNow.png" loading="lazy" alt="Wear a mask now!"></a> <a href="https://wikileaks.org/" target="_blank" rel="noopener"><img src="/88x31/WikiLeaks.PNG" loading="lazy" alt="WikiLeaks"></a> <a href="https://wikipedia.org" target="_blank" rel="noopener"><img src="/88x31/Wikipedia.gif" loading="lazy" alt="Support Wikipedia"></a> <a href="https://www.weirdal.com/" target="_blank" rel="noopener"><img src="/88x31/Yankovic.PNG" loading="lazy" alt="Yankovic NOW!"></a> <a href="https://archive.org" target="_blank" rel="noopener"><img src="/88x31/internet-archive.gif" loading="lazy" alt="Internet Archive"></a> <a href="https://tilde.club" target="_blank" rel="noopener"><img src="/88x31/tilde_club.gif" loading="lazy" alt="Tilde Club!"></a> <a href="https://drewsh.com" target="_blank" rel="noopener"><img id="drew-button" src="/88x31/lisp_alien_drew.gif" width="88" height="31" loading="lazy" alt="green alien associated with lisp having five eyes waves a triangular flag that reads Drew"></a> <a href="https://oat.zone/" target="_blank" rel="noopener"><img src="/88x31/oatzone.gif" loading="lazy" alt="oat.zone"></a> <a href="https://maia.crimew.gay" target="_blank" rel="noopener"><img src="/88x31/maia.crimew.gay.png" loading="lazy" alt="maia.crimew.gay"></a> <a href="https://www.freebsd.org" target="_blank" rel="noopener"><img src="/88x31/power-button_20000304.gif" loading="lazy" alt="Powered by FreeBSD"></a> <a href="https://artixlinux.org" target="_blank" rel="noopener"><img src="/88x31/artix.png" loading="lazy" alt="Artix Linux"></a> <a href="https://netbsd.org" target="_blank" rel="noopener"><img src="/88x31/netbsd.gif" loading="lazy" alt="NetBSD"></a> <a href="https://archlinux.org" target="_blank" rel="noopener"><img src="/88x31/archlinux.gif" loading="lazy" alt="Arch Linux"></a> <a href="https://kde.org" target="_blank" rel="noopener"><img src="/88x31/KDE.gif" loading="lazy" alt="KDE be free"></a> <a href="https://neovim.io" target="_blank" rel="noopener"><img src="/88x31/neovim.gif" loading="lazy" alt="Made with Neovim"></a> <a href="https://netcup.de" target="_blank" rel="noopener"><img src="/88x31/netcup.gif" loading="lazy" alt="netcup.de"></a>
+79
http/content/about.md
···
+
+++
+
title = "About"
+
menu = "about"
+
layout = "page"
+
[params]
+
author = "hyperreal"
+
+++
+
+
## About me
+
+
- Based in the Chicago area.
+
- Born on March 15th, 1988.
+
- I'm shy and might come across as reserved and standoffish at first, but I open up when I get more comfortable with people.
+
- I have a Bachelor of Science in Computer Science from University of Illinois-Springfield.
+
- I'm a mental illness and mental health advocate.
+
- Some of my favorite things include: free and open source software/culture/content/access, diversity, automation, programming, logic, video games, role-playing games, language, and coffee.
+
- I dislike monocultures, non-consensual power structures, and closed-mindedness.
+
- My pronouns are he/him/his or they/them/their.
+
- I'm autistic.
+
- I'm genderfluid. More specifically, I'm a demi-gendered man, which means I identify as mostly masculine and have some feminine markers.
+
- I have schizoaffective disorder and OCD. I was diagnosed in September of 2007 and have been taking medication since 2006. Secondary symptoms that stem from these, and which overlap with my neurodivergence, include agoraphobia, social phobia, selective mutism, and alogia/speech articulation issues.
+
- I'm an atheist, naturalist, and secular humanist.
+
- Politically, I'm a libertarian socialist.
+
+
### Links
+
+
[Autism](https://autisticadvocacy.org/about-asan/about-autism/)
+
[Schizoaffective disorder](https://en.wikipedia.org/wiki/Schizoaffective_disorder)
+
[OCD](https://en.wikipedia.org/wiki/Obsessive%E2%80%93compulsive_disorder)
+
[Agoraphobia](https://en.wikipedia.org/wiki/Agoraphobia)
+
[Social phobia](https://en.wikipedia.org/wiki/Social_anxiety_disorder)
+
[Selective mutism](https://en.wikipedia.org/wiki/Selective_mutism)
+
[Alogia](https://en.wikipedia.org/wiki/Alogia)
+
[Atheism](https://en.wikipedia.org/wiki/Atheism)
+
[Naturalism](https://en.wikipedia.org/wiki/Naturalism_%5C%28philosophy%5C%29)
+
[Secular humanism](https://en.wikipedia.org/wiki/Secular_humanism)
+
[Libertarian socialism](https://en.wikipedia.org/wiki/Libertarian_socialism)
+
[Resume](https://files.hyperreal.coffee/Jeffrey_Serio_-_System_Administrator__DevOps.pdf)
+
[More info about me](https://hyperreal.coffee/about/facts/)
+
+
## Interests
+
+
Below is an outline of things I'm interested in and would like to learn more about.
+
+
- Python and Go
+
- Unix/Linux system administration
+
- computer networks
+
- infosec / cybersecurity
+
- shell scripting with bash, zsh, and Nushell
+
- self-hosting
+
- digital homemaking
+
- digital archiving and preservation
+
- retro-computing
+
- decentralized internet
+
- privacy and digital rights
+
- free and open source software / culture/ content / access
+
- Wikipedia and other Wikimedia projects
+
- mental illness and mental health awareness
+
- neurodivergence
+
- minimalism
+
- history
+
- psychology
+
- anthropology
+
- philosophy
+
- language and linguistics
+
- mythology and folklore
+
- Hacker culture and Hacker ethic
+
- high fantasy and science fiction
+
- role-playing games. Only video games for now, but One Of These Days™ I will get into table-top gaming.
+
+
### Links
+
+
[Free and open-source software](https://en.wikipedia.org/wiki/Free_and_open-source_software)
+
[Free-culture movement](https://en.wikipedia.org/wiki/Free-culture_movement)
+
[Free content](https://en.wikipedia.org/wiki/Free_content)
+
[Open access](https://en.wikipedia.org/wiki/Open_access)
+
[Neurodiversity](https://en.wikipedia.org/wiki/Neurodiversity)
+
[Hacker culture](https://en.wikipedia.org/wiki/Hacker_culture)
+
[Hacker ethic](https://en.wikipedia.org/wiki/Hacker_ethic)
+55
http/content/beef-and-red-lentil-chili.md
···
+
+++
+
title = "Beef and red lentil chili"
+
layout = "page"
+
date = 2025-10-24T12:22:33-05:00
+
+++
+
+
## Ingredients
+
+
> Note that the kosher salt and black pepper are listed twice, because each portion is added to the pot at different times during the cooking process. I keep them in separate containers to make it easier to add.
+
+
- 2 tbsp olive oil
+
- 1 tbsp unsalted butter (or plant-based alternative for vegan)
+
- 1 cup chopped white onion
+
- 3 garlic cloves, chopped
+
- 1 serrano chile, seeded and minced
+
- 0.75 tsp kosher salt
+
- 1.25 tsp kosher salt
+
- 0.5 tsp ground black pepper
+
- 0.5 tsp ground black pepper
+
- 1 large zucchini
+
- 1 large yellow squash
+
- 1 lb ground beef (optional for vegan)
+
- 3 tbsp chili powder
+
- 1 tsp ground cumin
+
- 1 tsp garlic powder
+
- 4 cups (32 oz) chicken stock (or vegan-friendly vegetable stock)
+
- 1 (15 oz) can red kidney beans
+
- 1 cup uncooked red lentils, rinsed
+
- 1 (28 oz) can whole peeled plum tomatoes, crushed by hand
+
- 1 bunch of kale, chopped
+
+
## Utensils
+
+
- 1 large pot
+
- 1 container to hold 1 cup of chopped onion, 3 cloves of chopped garlic, minced serrano pepper, 0.75 tsp of salt, and 0.5 tsp of black pepper.
+
- 1 container to hold chopped zucchini and yellow squash.
+
- 1 smaller container to hold chili powder, cumin, garlic powder, 1.25 tsp of salt, and 0.5 tsp of black pepper.
+
+
## Instructions
+
+
> Note: If you have raw skin or open sore on your fingers, beware when seeding and mincing the serrano chile pepper (trust me). Wear rubber gloves or use another form of protection.
+
+
- Chop onion, zucchini, yellow squash, and kale. Seed and mince serrano pepper.
+
- Place chopped onion, garlic, serrano pepper, 0.75 tsp of salt, and 0.5 tsp of black pepper in a single container.
+
- Place chopped zucchini and yellow squash in another single container.
+
- Place chili powder, cumin, garlic powder, 1.25 tsp of salt, and 0.5 tsp of black pepper in another, smaller container.
+
- Heat olive oil and butter in covered pot over medium heat, until butter melts. ~1 minute.
+
- Add onion, garlic, serrano, salt, and pepper to pot. Cook, stirring occasionally until onion is softened. ~3 minutes.
+
- Stir in zucchini and yellow squash. Cook, stirring often, until softened. ~3 minutes.
+
- Add ground beef, chili powder, cumin, garlic powder, salt, and black pepper. Stir to crumble beef. ~1-2 minutes.
+
- Cover pot and cook, stirring occasionally until beef is cooked through. ~3-5 minutes.
+
- Stir in chicken stock, beans, and lentils. Increase heat to high and bring to boil.
+
- Reduce heat to low; cover and cook, stirring occasionally until lentils are softened. ~25-30 minutes.
+
- Stir in crushed tomatoes; cover and simmer on low, stirring occasionally. ~20 minutes.
+
- Stir in kale until wilted. Cook, stirring occasionally. ~25 minutes.
+45
http/content/community-driven-distros.md
···
+
+++
+
title = "Community-driven FOSS distributions"
+
layout = "page"
+
menu = "resources"
+
+++
+
+
I've.com)piled a list of.com)munity-driven, non-corporate FOSS operating systems. What I mean by .com)munity-driven" is distributions that are self-governed, where decisions regarding the direction of the distribution are ultimately made by the.com)munity itself and its leadership. This is in contrast to distributions that are beholden to corporations like IBM/Red Hat, Canonical, and Novell.
+
+
## Linux
+
+
[AlmaLinux](https://almalinux.org)
+
[Alpine Linux](https://alpinelinux.org)
+
[Arch Linux](https://archlinux.org)
+
[Artix Linux](https://artixlinux.org)
+
[CachyOS](https://cachyos.org)
+
[Chimera Linux](https://chimera-linux.org)
+
[Debian GNU/Linux](https://www.debian.org)
+
[Devuan GNU+Linux](https://www.devuan.org)
+
[GNU Guix System](https://guix.gnu.org/en)
+
[Gentoo Linux](https://gentoo.org)
+
[Hyperbola GNU/Linux-libre](https://hyperbola.info)
+
[Linux Mint](https://linuxmint.com)
+
[MX Linux](https://mxlinux.org)
+
[Parabola GNU/Linux-libre](https://parabola.nu)
+
[Qubes OS](https://qubes-os.org)
+
[Rocky Linux](https://rockylinux.org)
+
[Slackware](https://slackware.com)
+
[Tails](https://tails.net)
+
[Void Linux](https://voidlinux.org)
+
[antiX Linux](https://antixlinux.com)
+
[postmarketOS](https://postmarketos.org)
+
+
## BSD
+
+
[DragonFly BSD](https://dragonflybsd.org)
+
[FreeBSD](https://freebsd.org)
+
[HardenedBSD](https://hardenedbsd.org)
+
[NetBSD](https://netbsd.org)
+
[OpenBSD](https://openbsdfoundation.org)
+
+
## Android
+
+
[/e/OS](https://e.foundation/e-os/)
+
[CalyxOS](https://calyxos.org)
+
[GrapheneOS](https://grapheneos.org)
+54
http/content/computing.md
···
+
+++
+
title = "Computing"
+
menu = "computing"
+
layout = "page"
+
[params]
+
author = "hyperreal"
+
+++
+
+
## Hardware
+
+
[Homelab](homelab.md)
+
[VPS and cloud servers](vps-cloud-servers.md)
+
+
## Software
+
+
These are my daily drivers.
+
+
[Amfora](https://github.com/makew0rld/amfora)
+
[Bash](https://www.gnu.org/software/bash/)
+
[Borgbackup](https://www.borgbackup.org/)
+
[Borgmatic](https://torsion.org/borgmatic/)
+
[Btrfs](https://btrfs.readthedocs.io/en/latest/)
+
[CachyOS](https://cachyos.org)
+
[Calibre](https://calibre-ebook.com/)
+
[Catgirl](https://git.causal.agency/catgirl/about/)
+
[Debian stable](https://www.debian.org/)
+
[Discord](https://discordapp.com)
+
[FreeBSD](https://www.freebsd.org/)
+
[GNOME](https://gnome.org/)
+
[Grafana](https://grafana.com/)
+
[Jellyfin](https://jellyfin.org/)
+
[Just](https://just.systems)
+
[KDE Plasma](https://kde.org/plasma-desktop/)
+
[KDEConnect](https://kdeconnect.kde.org/)
+
[Konsole](https://apps.kde.org/konsole/)
+
[Lagrange](https://gmi.skyjake.fi/lagrange/)
+
[LibreWolf](https://librewolf.net/)
+
[Miniflux](https://miniflux.app/)
+
[Murena /e/os](https://doc.e.foundation/what-s-e)
+
[Neovim](https://neovim.io/)
+
[Newsboat](https://newsboat.org/)
+
[Nextcloud](https://nextcloud.com/) / [Murena Workspace](https://murena.com/workspace/)
+
[Nushell](https://www.nushell.sh/)
+
[Prometheus](https://prometheus.io/)
+
[Signal](https://signal.org/)
+
[Tailscale](https://tailscale.com/)
+
[Tmuxinator](https://github.com/tmuxinator/tmuxinator)
+
[Z shell](https://www.zsh.org/)
+
[ZFS](https://openzfs.org/wiki/Main_Page)
+
[Zellij](https://zellij.dev/)
+
[Zen Browser](https://zen-browser.app/)
+
[firewalld](https://firewalld.org/)
+
[qBittorrent](https://www.qbittorrent.org/)
+
[starship.rs](https://starship.rs/)
+33
http/content/facts.md
···
+
+++
+
title = "Facts"
+
layout = "page"
+
date = 2025-10-24T01:46:38-05:00
+
[params]
+
author = "hyperreal"
+
+++
+
+
- I only drink filtered black coffee, and it has to be sufficiently dark roast.
+
- I've never worn jeans. I can't tolerate the denim material.
+
- I can't tolerate tight- or snug-fitting clothing generally. In the winter I wear stretchy, baggy sweatpants. In the summer I wear stretchy athletic shorts. If I absolutely have to dress up, I would find slacks that are baggy and have an elastic waistband.
+
- I'm <i>super</i> picky when it comes to eating meat. I tend to prefer meat that is lean, dry, and well-done; not bloody, juicy, and fatty. I won't eat pork chops, but I like the cut of pork used in pulled pork sandwiches. If I eat bacon it has to be crispy. Steaks and beef tenderloin that are barely cooked are disgusting to me. The only kind of beef I tend to eat is the kind used in Italian beef sandwiches, the arrachera skirt steak in Mexican tacos (even this is sometimes gross to me, depending on how well it's cooked and its fat content), and ground beef like in chili recipes. I'll eat corned beef and pastrami depending on how non-fatty they are -- I'll often peel the fat off when I have a corned beef sandwich.
+
- I smoke tobacco cigarettes, but I can't stand any menthol flavor.
+
- I don't drink alcohol. I just don't care for it taste-wise, and I prefer to be sober-minded and in control of myself. There were some beers that I used to enjoy in moderation, like Guiness and dark craft brews, but I no longer see the point of being buzzed at all. I never liked hard alcohol either.
+
- I'm 37 years old at the time of this writing, and I'm still a virgin, if that means anything. I don't see losing my virginity as a sort of accomplishment, and I think the concept of losing virginity as a rite of passage is sexist and patriarchal. However, I do hope to eventually experience sex someday if I meet the right person. I'm also not against casual sex or going to a brothel as long as it's consensual and legal.
+
- My favorite pop (soda) is Dr. Pepper and Pepsi.
+
- I don't like bell peppers or plain uncooked tomatoes. The latter makes me gag.
+
- I'm kind of a mysophobe. It's not at a clinical OCD level.
+
- I can be super fussy about things to the point of decision paralysis. I do tend to eventually resolve the issue, though.
+
- I'm monotropic, which means I can only focus on one stream of activity or sensory input at a time. This is part of my autism. Regarding sensory input, I find that I can focus on one main activity with a few other non-intense sensory inputs. I can't have a conversation while driving. It's also hard to drive while listening to others talking. If there is just me in the car then I can drive with the radio on or listen to a podcast; otherwise, it's hard to focus on driving with other sensory distractions.
+
- I find that I'm quite sensory-averse, in that I have a hard preference for low-key, quiet, and non-chaotic environments.
+
- As per sensory aversion, I'm prone to misophonia with certain sounds. This depends on various other factors, such as my mood.
+
- I prefer the cooler fall and winter months to the warmer months. I <i>hate</i> the summer heat. I also take medication that makes me prone to overheating.
+
- My favorite holidays and seasons are Halloween, Thanksgiving (United States), and Christmas. I'm not religious, so I only celebrate the cultural aspects of Christmas. I don't celebrate Thanksgiving as a colonial heritage; I just love the food lol. Halloween will always have a special place in my heart. I love the "spooky" culture and folklore. I don't describe myself as a horror geek, but my older brother is, so I've been exposed to the horror classics for most of my life and I enjoy them as an integral part of the Halloween culture.
+
- My favorite pizza toppings are mushrooms, olives, spinach, and garlic. I'll take any or all. There is an Italian restaurant in Chicago called Pompei, and they have this Sicilian style baked clam pizza that is super good.
+
- I'm of Italian and German heritage. Both my parents are half Italian and half German. Culturally we're more Italian, though. I don't know much about the ancestry of my German relatives. My paternal great-great-grandfather, Cosimo Serio, immigrated from Cefalù, Sicily. Apparently the Serio surname is most common there. Serio means <i>serious</i> in Italian. It also means <i>serious</i> in Spanish, and the French version is <i>serieux</i>.
+
- I have an affinity for Latin and Greek words and their derivatives. I excelled in two years of Spanish in high school and one semester in college. I have a "peripheral goal" to learn the Italian and German languages, or at least a significant amount of them.
+
- I hope to travel someday. I'd like to see Canada and most of Europe, especially Italy. I'd also like to see Australia and Japan, but they are less of a priority. I think I would need a travel partner, like a significant other.
+
- I have an extreme fear of insects, especially spiders and centipedes.
+
- I'm not a water person. I never cared for swimming pools. I would describe myself as "hydrophobic" in the sense that I have a strong sensory aversion to getting wet, not that I'm irrationally afraid of water.
+
- I'm not as funny as I think I am. That's okay. It's valid.
+
- I tend to be routinized, but I try not to be too rigid. I'm not a fan of major changes. I get cranky when my routine is disrupted unexpectedly. I generally need a lot of time to process routine changes, so I appreciate notices a few to several days in advance.
+
- I am prone to irritability spells. This involves me being cranky, not wanting to interact with anyone, and not taking kindly to demands on my time.
+36
http/content/ground-beef-vegetable-soup-with-gnocchi.md
···
+
+++
+
title = "Ground beef vegetable soup with gnocchi"
+
layout = "page"
+
date = 2025-10-24T12:22:33-05:00
+
+++
+
+
Source: <https://www.southernliving.com/recipes/ground-beef-vegetable-soup-gnocchi>
+
+
![Ground beef vegetable soup with gnocchi](/images/ground-beef-vegetable-soup-with-gnocchi.jpg)
+
+
## Ingredients
+
+
- 2 tsp of olive oil
+
- 1 pound of ground chuck
+
- 1 large yellow onion, chopped (about 3 cups)
+
- 4 celery ribs, thinly sliced (about 2 cups)
+
- 3 garlic cloves, finely chopped (about 4 tsp)
+
- 1 (28 oz) can of whole, peeled plum tomatoes, drained
+
- 2 tsp of dried oregano
+
- 8 cups of low-sodium chicken broth
+
- 1 (12 oz) package of gnocchi
+
- 1 (6 oz) package of fresh spinach
+
- 3 tsp of kosher salt
+
- 1/8 tsp of black pepper
+
- grated Parmesan cheese, for serving
+
+
## Instructions
+
+
- Heat oil in a large saucepan over high heat. Add beef and coo, stirring occasionally, until browned. (~8 minutes)
+
- Add onion, celery, and garlic. Cook, stirring often, until vegetables are softened. (~8 minutes)
+
- Stir in tomatoes and oregano, breaking up tomatoes with wooden spoon.
+
- Stir in broth and bring to a boil.
+
- Reduce heat to medium-low, and gently boil until the vegetables are tender. (~8 minutes)
+
- Add gnocchi, and cook until just tender. (~3 minutes)
+
- Remove from heat. Stir in spinach, salt, and black pepper.
+
- Sprinkle each serving with grated Parmesan.
+64
http/content/homelab.md
···
+
+++
+
title = "Homelab"
+
layout = "page"
+
date = 2025-11-22T06:27:56-06:00
+
+++
+
+
## Desktop / Gaming
+
+
* Machine: System76 Thelio Major (r4)
+
* CPU: AMD Ryzen 7 7700X (8 cores, 16 threads) @ 5.6 GHz
+
* GPU: NVIDIA GeForce RTX 4090 (discrete), 24 GB with 16384 CUDA Cores
+
* RAM: 64 GB Dual Channel DDR5 (4x16 GB), 4800 MHz
+
* HDD: 2 TB PCIe Gen4, Read: 7000 MB/s, Write: 5100 MB/s
+
* Networking: 2.5 GB/s Ethernet, Built-in Intel WiFi 6E + Bluetooth 5.3
+
* OS: CachyOS with GNOME
+
+
## Laptop
+
+
* Machine: Lenovo Thinkpad X1 Carbon (11th gen)
+
* CPU: 12th Gen Intel Core i7-1260Pz (8 cores, 16 threads) @ 4.70 GHz
+
* GPU: Intel Iris Xe Graphics @ 1.40 GHz (integrated)
+
* RAM: 16 GB LPDDR5 6000 MHz
+
* HDD: 476.9 GB NVMe
+
* Networking: Built-in Intel WiFi 6E + Bluetooth 5.3
+
* OS: CachyOS with KDE Plasma
+
+
## NAS
+
+
* Machine: System76 Meerkat (meer9)
+
* CPU: Intel Core Ultra 7 155H, (16 cores, 22 threads) @ 4.8 GHz
+
* GPU: Intel Arc Graphics @ 2.25 GHz (integrated)
+
* RAM: 64 GB Dual Channel DDR5 5600 MHz
+
* HDD: 500 GB M.2 PCIe Gen4 NVMe
+
* Networking: 2.5 GB/s Ethernet, Built-in Intel WiFi 6E + Bluetooth 5.3
+
* OS: FreeBSD
+
+
### Notes
+
+
In addition to the internal hard drive, I have a NAS enclosure that contains 8x22 TB Enterprise HDDs. The NAS enclosure I use is Syba 8-bay hot swappable 2.5" 3.5" SATA non-RAID external USB 3.0.
+
+
[Syba 8-Bay, Hot Swappable 2.5" 3.5" SATA Non RAID External USB 3.0 Enclosure](https://www.amazon.com/dp/B07MD2LNYX)
+
+
I use the NAS for digital archiving. It runs the following services:
+
+
* ArchiveBox
+
* Jellyfin
+
* qBittorrent in a dedicated thick VNET jail over ProtonVPN/WireGuard
+
+
[ArchiveBox](https://archivebox.io)
+
[Techne: Dedicated thick VNET jail](https://techne.hyperreal.coffee/torrenting.html)
+
+
For all the machines from which I want to backup data, each machine runs borgmatic to backup data to borgbackup repositories located on the NAS.
+
+
The 8x22 TB Enterprise HDDs comprise a 176 TB ZFS pool. I have separate ZFS datasets for various categories of data.
+
+
## Phone
+
+
* Machine: Motorola Edge 2025
+
* CPU: Octa-core (4x2.6 GHz Cortex-A78 & 4x2.0 GHz Cortex-A55)
+
* GPU: Mali-G615 MC2
+
* RAM: 8 GB
+
* HDD: 256 GB
+
* Networking: GSM / HSPA / LTE / 5G
+
* OS: stock Android 15 (for now, until a ROM becomes available for Murena /e/OS)
+33
http/content/italian-pastina-soup.md
···
+
+++
+
title = "Italian pastina soup"
+
layout = "page"
+
date = 2025-10-24T12:28:16-05:00
+
+++
+
+
Source: <https://allrecipes.com/classic-italian-pastina-soup-recipe-7971739>
+
+
![Italian pastina soup](/images/italian-pastina-soup.jpg)
+
+
## Ingredients
+
+
- 1 3-4 lb. whole chicken, neck and insides removed
+
- 10-12 cups cold water
+
- 3 stalks of celery, divided
+
- 2 medium white or yellow onions, peeled, divided
+
- 3 large carrots, peeled, divided
+
- 1 tbsp kosher salt, plus more to taste, divided
+
- 2 tsp black pepper, divided
+
- 2 tbsp of olive oil
+
- 2 cloves of garlic, minced
+
- 1 tbsp of reduced sodium chicken base, such as Better Than Bouillon
+
- 1 cup of pastina or other tiny pasta, such as stars
+
- 1 tbsp of finely chopped parsley, or to taste (optional)
+
- 2 tbsp of freshly grated Parmesan cheese, or to taste (optional)
+
+
## Instructions
+
+
- Place chicken in large pot and pour water over to cover.
+
- Roughly chop 2 ribs of celery, 1.5 onions, and 2 carrots. Add to pot with chicken. Season with 2 teaspoons of salt and 1 teaspoon of black pepper. Bring pot to a boil over high heat. Reduce the heat to medium-low and allow the chicken to simmer 1 hour, covered.
+
- Remove chicken from the pot and allow to cool before removing and shredding the meat. Strain the stock and discard the solids. Reserve liquid and add water if necessary to measure 12 cups of liquid. Wipe pot clean.
+
- Finely chop remaining celery, onion, and carrot. Place pot over medium-high heat and add oil. Add chopped vegetables, remaining salt, black pepper, and garlic, and cook frequently until vegetables are tender and onion is translucent (the veggies should not be browned). Add reserved stock and chicken base and stir to combine. Bring mixture to a boil and reduce it to simmer. Allow soup to simmer 10 minutes.
+
- Increase heat to high and bring to a boil. Add pasta and cook, stirring occasionally 15 minutes or until pasta is tender. Reduce heat to low and add chicken and season if desired. Cook 5 additional minutes. Stir in chopped parsley and serve with grated Parmesan cheese.
+27
http/content/keto-no-noodle-chicken-cabbage-soup.md
···
+
+++
+
title = "Keto no-noodle chicken cabbage soup"
+
layout = "page"
+
date = 2025-10-24T12:28:16-05:00
+
+++
+
+
## Ingredients
+
+
- 4 oz butter
+
- 2 tbsp dried minced onion
+
- 2 (2.75 oz) celery ribs, chopped
+
- 6 oz mushrooms, sliced
+
- 2 minced garlic cloves
+
- 8 cups of chicken broth
+
- 2 oz (7 tbsp) carrots, sliced
+
- 2 tsp dried parsley
+
- 1 tsp salt
+
- 1/4 tsp ground black pepper
+
- 1.5 (2.66 lbs) rotisserie chicken, shredded
+
- 5 oz. green cabbage, sliced into strips
+
+
## Instructions
+
+
- Melt butter in large pot, over medium heat.
+
- Add dried onion, chopped celery, sliced mushrooms, and garlic into the pot and cook. ~3-4 minutes.
+
- Add broth, sliced carrots, parsley, salt, and pepper. Simmer until vegetables are tender.
+
- Add cooked chicken and cabbage. Simmer for an additional 8-12 minutes until the cabbage is tender.
+126
http/content/posts/2021-04-13-the-wonderful-world-of-restic.md
···
+
+++
+
title = 'The Wonderful World of Restic'
+
date = 2021-04-13
+
tags = ['restic', 'backup']
+
+++
+
+
## Context
+
+
I recently decided to start using my own home server to store my dotfiles. The main reasons are simplicity, privacy, and security. I previously stored them in a repository on my GitHub account and installed them with Ansible, but I have increasingly found it cumbersome when trying to keep them updated and in sync. On GitHub, the changes (and mistakes!) I make to my dotfiles are publicly viewable; sometimes I’ll make changes several times a day, sometimes scrapping a change entirely when I later realize it was not such a good idea or breaks something in my activity flow. I also would love the convenience of keeping SSH keys and GPG keychains in sync and updated, and storing them on a public server is obviously not an option, nor even in a private repository hosted on GitHub or GitLab.
+
+
## Cue Restic
+
+
My home server is basically just my old 2013 MacBook Pro running Fedora Server edition. It has a 250GB SSD, which is more than enough for what I need. I also have a 1TB external SSD which I will use to emulate redundancy. I installed and configure the rest-server software to act as a backend for my Restic backups.
+
+
## Setting up the rest server
+
+
First build the rest-server binary and move it to a directory in PATH. This step requires Go 1.11 or higher. Optionally, you can download the latest compiled rest-server binary from its releases page.
+
+
* [GitHub :: restic/rest-server/releases](https://github.com/restic/rest-server/releases)
+
+
```shell
+
git clone https://github.com/restic/rest-server
+
cd rest-server/
+
CGO_ENABLED=0 go build -o rest-server ./cmd/rest-server
+
sudo cp -v rest-server /usr/local/bin/
+
```
+
+
I also configured the systemd unit file so that rest-server runs on startup with the appropriate flags. I need only configure the options User, Group, ExecStart, and ReadWritePaths in the \[Service] section:
+
+
```shell
+
cd ~/rest-server/examples/systemd/
+
ls .
+
```
+
+
rest-server.service:
+
+
```systemd
+
[Service]
+
Type=simple
+
User=restic-data
+
Group=restic-data
+
ExecStart=/usr/local/bin/rest-server --path /opt/restic-backups --no-auth
+
Restart=always
+
RestartSec=5
+
+
# Optional security enhancements
+
NoNewPrivileges=yes
+
PrivateTmp=yes
+
ProtectSystem=strict
+
ProtectHome=yes
+
ReadWritePaths=/opt/restic-backups
+
```
+
+
Since this is a local home server, I pass the `--no-auth` flag to the rest-server ExecStart command.
+
+
I now create the restic-data user and group.
+
+
* Ensure a default home directory is not created under /home by passing the `-M` flag.
+
* Set a custom home directory for the user at /opt/restic-backups with the `-d` flag.
+
* Ensure the shell is assigned to `/sbin/nologin`.
+
* The restic-data user is not meant to be used for logging in, so we pass the `--system` flag.
+
+
```shell
+
sudo useradd -c "Restic Data" -M -d /opt/restic-backups -s /sbin/nologin --system restic-data
+
```
+
+
* Ensure the backups path exists and has appropriate permissions.
+
* Copy the systemd unit file to a location where systemd will look for it.
+
* Enable and start the rest-server systemd service.
+
+
```shell
+
sudo mkdir /opt/restic-backups
+
sudo chown -R restic-data:restic-data /opt/restic-backups
+
sudo cp -v rest-server.service /etc/systemd/system/
+
sudo systemctl daemon-reload
+
sudo systemctl enable --now rest-server.service
+
```
+
+
Since I'm using a firewall, I ensure the port the rest-server listens on is allowed locally:
+
+
```shell
+
sudo firewall-cmd --zone`FedoraServer --permanent --add-port`8000/tcp
+
sudo firewall-cmd --reload
+
```
+
+
Now on the host, which in this case is my laptop, I have the Restic client installed from my distribution's package repository.
+
+
* Initialize a Restic storage repository on the server from the host, and supply it with a password. This password will be used every time I attempt to access the storage repository.
+
* Backup my dotfiles
+
+
````shell
+
restic -r rest:http://local-server:8000/dotfiles init
+
restic -r rest:http://local-server:8000/dotfiles backup ~/dotfiles
+
+
One of the best features of Restic is that it makes restory backups really simple. It also provides snapshot functionality, so I can restore different versions of specific files from other snapshots.
+
```shell
+
restic -r rest:http://local-server:8000/dotfiles snapshots
+
+
enter password for repository:
+
repository 9a280eb7 opened successfully, password is correct
+
ID Time Host Tags Paths
+
------------------------------------------------------------------------------
+
11738fec 2021-04-12 09:13:17 toolbox /var/home/jeff/dotfiles
+
dfc99aa3 2021-04-12 10:31:39 toolbox /var/home/jeff/dotfiles
+
f951eedf 2021-04-12 11:25:21 toolbox /var/home/jeff/dotfiles
+
62371897 2021-04-12 18:43:53 toolbox /var/home/jeff/dotfiles
+
------------------------------------------------------------------------------
+
4 snapshots
+
````
+
+
Since Restic saves the backup's absolute path, restoring it to / will ensure it is restored to its original location on the local filesystem. To restore a snapshot:
+
+
```shell
+
restic -r rest:http://local-server:8000/dotfiles restore dfc99aa3 --target /
+
```
+
+
To list files in a snapshot:
+
+
```shell
+
restic -r rest:http://local-server:8000/dotfiles ls dfc99aa3
+
```
+
+
Yay, very nice!
+
+
* <https://restic.net/>
+
* <https://github.com/restic/rest-server>
+17
http/content/posts/2024-05-21-my-caretaking-duty-is-coming-to-a-close.md
···
+
+++
+
title = 'My caretaking duty is coming to a close'
+
date = 2024-05-21
+
tags = ['caretaking']
+
+++
+
+
## The bittersweet end of an era
+
+
For the last three years, I've been living with and caretaking for my grandfather. He's 87 years old, and his needs have progressed beyond what I'm capable of handling. The hard reality is that he now has to live in an assisted living home. From what I've heard from the family members who helped make this decision, the assisted living home sounds like a 5-star hotel. They took my grandpa on a tour and they were all impressed by it. Compared to the other assisted living homes I've seen and heard about, I don't think they really get much better than this. He's reluctant about how expensive it will be. He's sad and nervous about leaving his house of 48 years to go to a completely foreign place. I would be too. The memories that were made in this house are deeply cherished. For my entire life, this was *grandma's and grandpa's house*--a moniker that has a far greater meaning to us than the literal words alone. It carries with it the wholesomeness, the hospitality, the love, the childhood memories. This house will be put up for sale when my grandpa goes into assisted living, and he wants me to live here until it gets sold.
+
+
## What's next for me
+
+
I'll be going back to live with my parents. Over the past few years, both my parents have shown improvement in their willingness to understand my mental illness, neurodivergence, and the limitations these place on me. They seem to be taking it more seriously, listening to me, and valuing my perspective and experiences. Living with them again will still be somewhat of a toxic environment because they are stuck in their ways, but I'm hopeful that their improvements will make it more tolerable, even if only marginally so.
+
+
I feel confident enough in my skills at this point that I can start actively looking and applying for a remote system administrator job. My mental illness is mostly under control as long as I don't have to be in the physical presence of other people. I'm not exactly in a position to be making these kinds of requests from employers, but I would hope they would be okay communicating with me solely through text. Otherwise, my social phobia, alogia, and speech articulation issues would make communication significantly more challenging, which would certainly interfere with my value to them as an employee.
+
+
A perfect example of the kind of job I'm looking for and for which I feel I'd be a great fit: [Tails - Privacy loving Linux generalist](https://tails.net/jobs/Linux_generalist/). Unfortunately that particular job opening is on hold and it is too late to send an application, but I'm quite sure there are other similar jobs openings out there. I'm excited for the future. I have a passion for FOSS and digital freedom and a drive to contribute to those efforts. I'm also looking forward to making an actual salary because, along with basic survival, my sequestered lifestyle, goals, and special interests cost money.
+35
http/content/posts/2024-07-20-i-finally-sorted-out-my-self-hosting-stuff-tm.md
···
+
+++
+
title = 'I finally sorted out my self-hosting stuff™'
+
date = 2024-07-20
+
tags = ['selfhosting', 'homelab']
+
+++
+
+
I think. Infodump commencing...
+
+
## My previous setup
+
+
My previous setup included running nirn.quest services on a $30/month SeedHost.eu dedicated server, and my hyperreal.coffee services in a virtual machine in my homelab. For the latter, I had Linode managing the DNS for my hyperreal.coffee domain, and the domain itself pointed to a $5/month Linode VPS, which used Tailscale to forward HTTP and port 1965 traffic to the virtual machine in my homelab.
+
+
I originally got the $30/month SeedHost.eu dedicated server with 8T of storage to use as a seedbox for Sci Hub torrents. I later decided to get a dedicated app hosting package for $173/month, which included 72T of storage and a 10Gbps network throughput speed. I figured this was better for torrenting Sci Hub. I then repurposed the $30/month dedicated server and started running nirn.quest services on it.
+
+
With the previous setup, I would be spending $30 ~`$173`~ $5 = $208/month.
+
+
## My current setup
+
+
The previous setup was fine until I found a $18/month dedicated server on netcup.de, which has better specs minus the 8T storage space. I don't really need the 8T anymore, since I now have a dedicated app hosting package on SeedHost that can store the entire Sci Hub collection. This netcup.de dedicated server has 256G storage which is plenty for my use-case. On this new dedicated server from netcup.de, I can host everything I had on hyperreal.coffee as well as nirn.quest. So I decided to start using only my hyperreal.coffee domain, which simplifies things like DNS and web server configuration. The nirn.quest domain will expire in a few months, and it was super cheap--like $3 if I recall correctly--so I'm not too sore about leaving it but for the cool domain name. The netcup.de dedicated server is located in Manassas, Virginia, US. Now that everything is being hosted there, I no longer need Linode to manage my hyperreal.coffee domain, nor do I need a Linode VPS to act as a relay between the Internet and my homelab virtual machine. My monthly expenditure will now be $18 + $173 = $191/month.
+
+
My Mastodon instance uses ElasticSearch for full-text search. When the ElasticSearch daemon runs, it automatically allocates half of the available RAM on the host. To conserve the total available 16G of RAM on my remote server, I have a Tailscale connection between a virtual machine on my homelab running ElasticSearch and my new remote netcup.de server where my Mastodon instance is running. On my homelab virtual machine, Firewalld is configured to only accept connections to port 9200 from the remote server's Tailnet IP address.
+
+
## Backups
+
+
I'm using Wasabi object storage for backups of Mastodon and important files on the remote server. I've written a [backup script](https://codeberg.org/hyperreal/homelab-scripts/src/commit/a346f8b1c6d7c3d7863096fd390708cfaed0e88e/bin/server0-backup) that utilizes rclone to sync and copy the files to the configured Wasabi remote. I'm currently trying to figure out how to properly setup using a Wasabi bucket for Mastodon S3 object storage. I'm pretty sure I have everything configured as it should be, but when I set `S3_ENABLED=true` and reload Mastodon, the avatars and attachments are blank, and I get S3 XML AccessDenied error messages when attempting to view resources in their own tab. According to [Getting Mastodon working with Amazon S3 file-hosting](https://github.com/cybrespace/cybrespace-meta/blob/master/s3.md), this means the permissions on either the files or the bucket are not set correctly. When using `awscli` to sync the `public/system/` folder over to the bucket, I made sure to use the `--acl public-read` option, but this didn't seem to work. I wondered if it is because Wasabi does not enable public access to the buckets by default, so I emailed Wasabi support, and they suggested a more secure work-around that doesn't seem to fit with my Mastodon use-case. So, until I can get this sorted out, I'm using local filesystem storage on my instance.
+
+
Wasabi costs $6.99/TB/month, which isn't too bad when I have less than 1T of data stored there. Eventually, I'm going to ask SeedHost.eu if they can offer MinIO as an app option for dedicated app hosting. Then I would be able to use some of the 72T for S3-compatible object storage and not have to pay extra for Wasabi.
+
+
## Sci Hub torrents
+
+
I'm going to peruse the [awesome-libgen](https://github.com/freereadorg/awesome-libgen) repository for things I can use to help Sci Hub and the broader open access movement. I had an idea to write a Python script that (1) checks for which Sci Hub torrents need seeders and (2) configure my qBittorrent instance to prioritize those torrents.
+
+
## Other notes
+
+
Since I don't pay the electric bill, I've been making it a point not to use too much energy with my computers and homelab equipment. I'm not currently using my OPNsense device, and my homelab is now basically just my TrueNAS machine ~`my remote dedicated server. My Orange Pi 5`~'s and Pine64 devices are currently out of commission. Someday soon when I get a job, move to a place of my own, and pay my own electric bill, I will start using them again. My daily driver setup right now includes my workstation PC, my gaming PC, my laptop, my smartphone, my ISP router, a 2.5Gbps Ethernet switch, and my TrueNAS machine. The gaming PC and laptop go into sleep mode to conserve energy when I'm not using them.
+16
http/content/posts/2024-08-20-listening-to-podcasts-while-driving.md
···
+
+++
+
title = 'Listening to podcasts while driving'
+
date = 2024-08-20
+
tags = ['podcasts']
+
+++
+
+
I've become frustrated constantly switching through our local radio stations to find something I want to listen to while driving, especially when more than one of those stations plays ads for like 10 minutes between songs. For a while I had been just turning off the radio and driving in silence, or with whatever entertainment or chaotic discontent my brain afforded to me.
+
+
I solved this problem by buying a USB-C to 3.5 audio aux jack so that I can connect my Google Pixel 6 (running GrapheneOS) to the aux port in my car. This enables me to listen to podcasts or run a music playlist on my phone through the car's speakers when I drive.
+
+
The podcasts I've been enjoying lately include the Self-Hosted Show and LINUX Unplugged, both from Jupiter Broadcasting. It's so refreshing to listen to stuff I want to listen to and not what radio stations impose on me. Driving is now somewhat more tolerable.
+
+
I look forward to the day when I can afford a car that is capable of running an open source operating system where I can install a podcast app. Like GrapheneOS for auto-mobile devices, or something.
+
+
* [LINUX Unplugged](https://linuxunplugged.com/)
+
* [Self-Hosted Show](https://selfhosted.show/)
+20
http/content/posts/2024-08-30-reducing-social-media-cross-posting-complexity.md
···
+
+++
+
title = 'Reducing social media cross-posting complexity'
+
date = 2024-08-30
+
tags = ['socialmedia']
+
+++
+
+
What could be useful for me to minimize the complexity of cross-posting to Facebook, Twitter, Bsky, and Mastodon: a Python or Go program that does the following:
+
+
* Connects to my accounts via API.
+
* Uses [gum](https://github.com/charmbracelet/gum), [bubbletea](https://github.com/charmbracelet/bubbletea), or [huh](https://github.com/charmbracelet/huh) to prompt the user for the post content.
+
* Editing, replying, and/or delete functionality would be seamless with the exception of Bsky and Twitter, in which case I'd have to delete the post and redo it.
+
* Command-line flags for `--facebook`, `--twitter`, `--bsky`, and `--mastodon` to control which accounts to make the post to. If no account flags are supplied, then assume all. If Bsky, Twitter, and Mastodon are explicitly or implicitly passed, provide visual feedback to the user about the number of characters. The complements of each flag could also be supplied to exclude accounts, e.g. `--no-twitter`. Accounts can also be configured in a JSON file to avoid using the command-line flags.
+
* Can post photos by providing the absolute path to the file(s) on the local filesystem.
+
* Allows using content warnings Mastodon-style at the top of the post. On Mastodon it would use the content warning feature. On Twitter, Bsky, and Facebook it would place "CW: <text>" at the top of the post.
+
* Allows using sensitive content shields for photos.
+
* Allows adding alt-text.
+
* Allows tagging accounts by parsing a tag format like "%twitter:@account", "%bsky:@account". Tagged accounts on one platform would only apply to that platform. The tag format syntax would otherwise not show up in the post. Account tags and hashtags would not be used inline; they would be added to the end of the post and based on user input from optional account tag and hashtag prompts.
+
* Possibly an option for some hacky string gymnastics to prevent URLs from creating link previews. I dunno if this is feasible unless there is a way to opt out of them that is built in to the API methods, e.g. by adding a specific boolean parameter to the API request or something. It seems this would even benefit the platforms by reducing the load on the servers from resolving the links. I haven't looked at the APIs yet, though. But also there might be a reason there isn't, namely so that the platforms can validate the legitimacy of the links.
+
+
I'm eager, but not quite ready to get started on this yet, as I have other coding projects to refine and other entropy to clean up.
+20
http/content/posts/2024-09-18-experimenting-with-freebsd-and-comments-on-the-future-of-invidious.md
···
+
+++
+
title = 'Experimenting with FreeBSD and comments on the future of Invidious'
+
date = 2024-09-18
+
tags = ['freebsd', 'invidious', 'youtube', 'google']
+
+++
+
+
## Experimenting with FreeBSD
+
+
I’ve always admired the BSD family of operating systems even though I mostly use Linux. I currently run a Debian Linux server that hosts a bunch of alternative services like PrivateBin, Invidious, RedLib, etc. Most of these require the use of Docker and/or systemd. Docker doesn’t seem to be a hard requirement, though, because inside the Dockerfile there has got to be a Unixy way to setup and run the services. So I’m planning on spinning up a temporary FreeBSD VPS on Vultr and experimenting with getting those services running without Docker. If all goes well, I will convert my main Debian server to FreeBSD. One thing I would miss, however, is FirewallD. BSD’s PF (Packet Filter) firewall doesn’t have a command-line interface to interact with firewall policies. As far as I know everything goes into a/etc/pf.conf configuration file. I’d have to look into PF configuration options that are effectively the same as the ones I use with FirewallD.
+
+
## Comments on the future of the Invidious project
+
+
Re: Invidious, it’s currently broken on my instance because of Google blocking the use of the API to by-pass the ads. From what I understand, it’s a bit of an arms race between the Invidious developers circumventing the Google blocks and Google catching on and imposing restrictions. I’m not sure about the future of the project. Hosting an Invidious instance, and keeping in line with the requirements to remain an official instance recommended by the project in their instances list, heavily relies on Docker workflows, so it might not be feasible for me to get it running on FreeBSD and continue to satisfy those requirements. I don’t think it’s worth running an instance until a more permanent solution to the Google blocking problem is found, anyway.
+
+
See [this issue on the Invidious GitHub repo](https://github.com/iv-org/invidious/issues/4734#) for more information on what's going on with it. Every time there is a fix, a new problem pops up that breaks Invidious instances. [This comment](https://github.com/iv-org/invidious/issues/4734#issuecomment-2349782180) on the GitHub issue was the last straw for me. Previous fixes require using and depending on a bunch of hacky tools from the developers that aren't guaranteed to be long-term solutions. I very much appreciate the time the devs have put into the project. I really, really hate Google's unrelenting mission to break the fixes in order to maintain their monopoly on video content. YouTube is just too popular to fail at this point, and Google will never let it fail. The only way forward that I can see from here is just to promote [PeerTube](https://joinpeertube.org/) in the fediverse or other FOSS video hosting alternatives.
+
+
## Links
+
+
* [The FreeBSD Project](https://freebsd.org)
+
* [Invidious](https://invidious.io/)
+22
http/content/posts/2024-09-20-i-want-to-tell-google-to-eff-off.md
···
+
+++
+
title = 'I want to tell Google to eff off'
+
date = 2024-09-20
+
tags = ['google', 'protonmail', 'gmail', 'youtube']
+
+++
+
+
I'm thinking of deleting my Google account. I've downloaded all my Gmail data. I know I have some services that use my old Gmail address. I need to think about how this might affect my interconnected system of Internet services that have dependencies on my Google account. Changing my email on services still using my Gmail is mostly trivial. I just have to remember/find out what all those services are. I can peruse through my Gmail archive that is mostly spam or unwanted email and see if there are any critical services I'd have to change my email address for. I figure going back about six months through my Gmail archive would suffice. Any entity that doesn't contact me during a six month period likely doesn't have any important tendrils attached, and I probably don't want anything to do with them, either.
+
+
I would also lose access to my YouTube account, which is fine, because I don't mind using it without logging in. If need be, I can use Invidious during times when the Invidious devs have the upper hand in the arms race. I can also use it with youtube-dl + VLC or something.
+
+
I've been able to download my ebooks from Google Play Books and put them in a Calibre library. If I want new ebooks in the future, I'd like to find a non-big-tech service to download them from via the Calibre interface. However, since I have and frequently use an Amazon account, I suppose Amazon will become my new ebook supplier for the time being. I also don't know if any non-big-tech ebook services I might find would have the ebooks that I want available in their catalog.
+
+
I'm also trying to have just one email address. I currently have four, besides the Gmail one, that are in use by various services. Three of them are all part of my Proton Mail account, so they all go to the same inbox.
+
+
* <verandis@protonmail.com>: permanent, main Proton Mail account.
+
* <hyperreal64@pm.me>: part of my Proton Mail account, but I've been trying to phase it out.
+
* <hyperreal@moonshadow.dev>: permanent, in use as a custom domain for my Proton Mail account. I'm trying to make this my main one.
+
* <hyperreal@fedoraproject.org>: an alias from the Fedora Project that is provided to Fedora contributors. It forwards to my Proton Mail account. It was mostly just for bling to represent my involvement with the Fedora Project. I still consider myself very much part of the Fedora community, but my personality*neurodivergence*what-not is such that I can't make a monogamous for-life commitment to any one distro. I feel more comfortable making a for-life commitment to the broader free and open source movement.
+
+
I now use GrapheneOS on my Google Pixel 6, so in some sense there are still some minor Googly tendrils stuck in me. The Google Pixel 6 is getting old, but it still works tolerably well. Perhaps soon I will get a PinePhone or some other non-big-tech device to run GrapheneOS or PostmarketOS. It's a matter of whether my cellular carrier supports it.
+
+
I'm sure there are some other things I'm missing here in my personal tech ecosystem bubble that depend on me having a Google account.
+23
http/content/posts/2024-09-30-rubber-duck-helps-me-debug-my-daily-driver-issues.md
···
+
+++
+
title = 'Rubber duck helps me debug my daily driver issues'
+
date = 2024-09-30
+
tags = ['rubberduck', 'dailydriver']
+
+++
+
+
**ME**: I love Fedora, but I don't like having to do updates and reboot more than once a week. If only there was a Debian-like LTS for Fedora ...
+
+
**RUBBER DUCK**: There kinda is. You could install Rocky Linux, AlmaLinux, or CentOS Stream and use one of those as your daily driver. I mean, you use Nix as a package manager anyway, so it's not like you'll miss anything from the Fedora repos.
+
+
**ME**: Oh, uh, you might actually be onto something there, Rubber duck. But the idea of using an enterprise server-oriented distro as my daily driver? That ... that doesn't quite sit right with me.
+
+
**RUBBER DUCK**: Well, you could also try Fedora Kinoite. It's rock-solid, and you would only have to run `rpm-ostree update` once a week. You could setup a basic toolbox container with Distrobox and install the Nix package manager via the daemon-less single-user method. The toolbox container could even be Debian stable.
+
+
**ME**: Yeah 🤔. That does sound very appealing. And I wouldn't mind using the latest Fedora as a toolbox container; it's mostly when running updates requires a reboot because the kernel and core system libraries were updated. With the toolbox container, at most I would just have to restart the container. For other graphical applications, I could either use flatpaks or install them with Nix and configure `update-desktop-database` to search for them in my Nix profile. There is really no hard reason I need to do anything important outside the mutable parts of the filesystem. Aside from the /home directory, /etc and /usr/local are also mutable.
+
+
**RUBBER DUCK**: Yep. Also, if you're going the immutable-ish route, you might as well just use NixOS, then, no?
+
+
**ME**: Yeah, I've tried that before, but the filesystem and userspace just felt ... I dunno ... *weird*. And using the Nix language for anything other than development environments and home directory configuration feels rather ... I dunno ... *weird*. And I'd rather not get lost in the labyrinth of a Nix flakes rabbit hole. It just seems needlessly complicated for little benefit, to me. My goal is to find something and stick with it consistently, and have it be my daily driver, the same way my physical desk is just here, and reliable, and low-maintenance. I want to avoid wasting time fussing about with my NixOS configuration.
+
+
**RUBBER DUCK**: Fair enough, I hear you.
+
+
**ME**: Anyway, I think I know what I want now. Thanks for the chat, Rubber duck!
+15
http/content/posts/2024-10-11-invega-mental-health-and-hygiene.md
···
+
+++
+
title = 'Invega, mental health, and hygiene'
+
date = 2024-10-11
+
tags = ['invega', 'mentalhealth']
+
+++
+
+
Since I've been on a lower dose of Invega, I've noticed that I've had more spoons for maintaining my hygiene. This may be coincidental, or it may be causative.
+
+
In retrospect, during my adult years, my poor hygiene correlates with increases in my Invega dose. 2011-2019 were probably the most unhygienic years for me, and that coincides with being on 9-12 mg of Invega. Invega causes me to be fatigued and drowsy during the day, which means I have less spoons for maintaining my hygiene. Also, it's one thing to not have energy for maintaining my hygiene, but it's another to simply not care about it. Whatever Invega does to my brain chemistry that reduces positive symptoms of psychosis somehow also makes me care less about my hygiene. Barring other possible reasons, if it is the case that Invega causes me to care less about hygiene, then I would expect to get my "normal" pre-Invega hygiene habits back if I were weened off completely. It's almost like Invega decreased positive symptoms of psychosis and traded them off for an increase in negative symptoms.
+
+
Before Invega, I cared a lot about my hygiene, sometimes even irrationally so. 2003-2006 me would never let me go a day without showering or cleaning my teeth. But, maybe this reflects more my values regarding hygiene back then compared to my values from 2011-2019. And the uptick in hygiene-consciousness today could be related to my general mental health improvement, which in turn could be related to natural changes in my brain as I've aged. Another possibility is that my reclusiveness could affect whether I consider taking care of my hygiene to be worth it. But if that were the case, then it wouldn't explain why I'm more hygiene-conscious today, because I'm still just as reclusive. I want to be and feel clean for my own comfort and peace of mind.
+
+
I haven't noticed any significant uptick in positive symptoms of psychosis since I've been on 4.5 mg of Invega (since early September). My general anxiety and social anxiety have remained about the same, with better and worse days, as usual. I've been more talkative, more energy to vocally and verbally express what's on my mind. In fact, I feel like I've had more "content" available on my mind to express. The relation between energy levels, verbal*vocal expression*articulation, and thought content is not clear to me. Paranoia-related intrusive thoughts are not as prominent today, or they are more easily dispelled by reason.
+
+
Someone on Twitter a while back asked if I've ever been hospitalized. I never really needed to be. My personality made me more withdrawn and wanting to isolate. I've had times of paranoia-influenced quarrelsome behavior with other people, but it was never to the point of being a danger to myself or others. I also had other more intense moments, but if I describe those here then I would be airing my dirty laundry, so I won't do that. For the most part, I've felt in control of my behavior. To qualify the previous statement: I'm more outspoken and comfortable expressing my thoughts and feelings in text on the Internet, so my social inhibitions are lower for what I consider appropriate to express verbally. If I feel paranoid and suspicious of people on the Internet, I'm more likely to express it verbally and confront them, whereas in person I'm more likely to escape, withdraw, and avoid confrontation.
+52
http/content/posts/2024-10-13-home-networking-and-preventing-dns-leaks.md
···
+
+++
+
title = 'Home networking and preventing DNS leaks'
+
date = 2024-10-13
+
tags = ['homelab', 'networking', 'dns', 'opnsense', 'comcast']
+
+++
+
+
I'm thinking of getting my OPNsense device back up again. At my previous place of residence, I had AT\&T internet, and AT\&T had all sorts of configurable options in their modem that played well with my OPNsense device. At my current place of residence, I have Xfinity Comcast, and the only option I can configure on their modem that would allow me to use my OPNsense device is "Enable/disable bridge mode". When I first moved in here, I tried doing that, but for some reason the IPv4 gateway on my OPNsense device wasn't picking up anything. I believe I had everything configured correctly, the Xfinity modem was in Bridge mode, and the OPNsense router was assigned the public IP address from my Xfinity account. This was four months ago, and it's very likely I missed something in the configuration, so it can't hurt to try again. The worst-case scenario is that I reset my Xfinity modem to factory defaults and continue to use that. But it would sure be nice if I could have more control over that portion of my internet.
+
+
I think I've figured out how to prevent my Fedora Linux desktop from leaking DNS to Xfinity. My Linux desktop is part of a Tailscale network that uses Mullvad's ad-blocking and malware blocking public DNS server, but I still have DNS leaks because my main network interface is using the Xfinity DNS servers from its DHCP connection via the Xfinity modem. Below are the steps I took to prevent DNS leaks to Xfinity.
+
+
### systemd-networkd
+
+
NetworkManager is the default on Fedora 40. I disabled NetworkManager and enabled systemd-networkd with the following configuration:
+
+
```systemd
+
[Match]
+
Name=eno1
+
+
[Network]
+
DHCP=yes
+
DNS=100.100.100.100
+
DNSSEC=allow-downgrade
+
+
[DHCPv4]
+
UseDNS=no
+
```
+
+
In the `[DHCPv4]` section, `UseDNS=no` ensures that you're not using the DNS servers provided by the DHCP connection. In my case, my DHCP connection via my Xfinity modem was setting the DNS to the Xfinity DNS servers. So that is no longer the case now. For good measure, I added my tailnet's DNS as a static DNS server in the `[Network]` section.
+
+
`resolvectl status` now shows that my primary network interface `eno1` uses only the DNS from my Tailscale network, which is `100.100.100.100`.
+
+
![resolvectl status](/images/resolvectl-status.png)
+
+
### Disable IPv6
+
+
Another possible source of DNS leaks is IPv6. On Fedora 40, the way to disable IPv6 is by adding a kernel argument to the GRUB bootloader configuration. This can be done with the following command:
+
+
```shell
+
sudo grubby --args`ipv6.disable`1 --update-kernel=ALL
+
```
+
+
Reboot the system for the change to take effect.
+
+
### Ensure Firefox or LibreWolf are not using DNS over HTTPS
+
+
In most cases Firefox/LibreWolf are configured to use the system DNS resolver by default, but if you have it configured to use one of the "protection" settings for DNS over HTTPS, this could be a source of DNS leaks.
+
+
![Librewolf DOH settings](/images/librewolf-doh-settings.png)
+
+
### Check for DNS leaks with Mullvad's connection checker
+
+
![Mullvad DNS leak checker](/images/mullvad-dns-leak-checker.png)
+22
http/content/posts/2024-11-05-on-using-reproducible-python-development-environments.md
···
+
+++
+
title = 'On using reproducible Python development environments'
+
date = 2024-11-05
+
tags = ['python', 'devenv', 'nix-shell', 'virtualenvs']
+
+++
+
+
One of the things I find annoying about using Python is that there are so many ways of making the development environment of a package or set of scripts reproducible. I have a [repository](https://codeberg.org/hyperreal/admin-scripts) that contains several Python scripts that help me with various tasks, mostly related to qBittorrent. Maybe one or two of these scripts can be separated out into a distinct, individual package, but it's generally more convenient for me to have a directory-level development environment activated with direnv where I can run the other scripts too. I've been using `nix-shell` with a shell.nix file, but this tends to require that I learn the Nix expression language in order to configure shell.nix. I don't like using tools I don't fully understand, and I'm not willing to prioritize learning Nix. It would be nice if I could just use a TOML file to declare everything I need, similar to pyproject.toml, and `nix-shell` would read this instead of shell.nix. As far as I know, the Nix language doesn't have a way to map the TOML structure to Nix expressions. I've tried [devenv.sh](https://devenv.sh/), but this adds extra files and cruft that I don't want polluting my development environment. If I use a plain requirements.txt file with a virtualenv, it can't pull in the Python tools I use, like black, isort, bpython, and pyright.
+
+
One solution I'm leaning toward is to install these tools with pipx, where they'd be available to my shell environment relative to my home directory at ~`/.local/bin/`, and use something like
+
+
```shell
+
uv venv
+
source .venv/bin/activate
+
uv pip install -r requirements.txt
+
echo "layout python3" > .envrc
+
direnv allow
+
printf ".venv\n.direnv\n" | tee -a .gitignore
+
```
+
+
direnv would activate the virtualenv, which in turn would be relative to that git repository directory.
+
+
I'm open to suggestions and am curious how others might have solved this problem. Feel free to reach out to me in the Fediverse at [@hyperreal@fedi.hyperreal.coffee](https://fedi.hyperreal.coffee/hyperreal).
+20
http/content/posts/2024-12-08-my-speech-language-enhancing-technology-wishes.md
···
+
+++
+
title = 'My speech and language-enhancing technology wishes'
+
date = 2024-12-08
+
tags = ['speech', 'language', 'llm']
+
+++
+
+
I wish there was a speech/language technology that could:
+
+
1. Interface with my brain, somehow.
+
2. Instantaneously (like milliseconds) create a rough model of *the ideas I want to express verbally* at any given moment.
+
3. Find words, phrases, and social scripts that are as close to a 1:1 correspondence with *the ideas I want to express verbally* as our language permits, and present these to my brain for me to choose on my own volition.
+
+
Could we hypothetically leverage LLM technology to do this? I feel like this would be super practical for me specifically because of my speech issues.
+
+
I feel like it would also enhance my language skills, because:
+
+
1. More information/options would be presented to my brain that would enable me to use my best human judgment in choosing appropriate words, phrases, and social scripts for a given social situation.
+
2. After some amount of repetition of these patterns, I would eventually *learn* better ways to express ideas for a given social situation, and gradually become less reliant on the technology.
+
+
Though, there would still be times when I just don't have the cognitive spoons to articulate things myself, and in these instances I wouldn't mind the technology doing it for me, and all I would have to do is the physical act of vocalizing it.
+19
http/content/posts/2024-12-09-20-years-of-mental-illness.md
···
+
+++
+
title = '20 years of mental illness'
+
date = 2024-12-09
+
tags = ['mentalillness']
+
+++
+
+
20 years ago (autumn of 2004) I experienced the full onset of schizoaffective disorder. In retrospect, I would say the prodromal phase began around the spring of 2004, because that's when things started to feel different, and when I started having ideations of a delusional quality.
+
+
In the autumn of 2004, I had a panic attack\[fn:1] after work one night, and I believe that marked the onset of my condition, because I instantly became more acutely paranoid and socially withdrawn. I'd go entire days at school avoiding everyone I didn't have to interact with. I didn't socialize for fun, because I was paranoid and highly suspicious of almost everyone except close family members. I thought there was some huge conspiracy, and my parents, siblings, and other family weren't in on it, and that this was by design of the conspirators. The conspirators I believed were people at school and work. I didn't have any concept of exactly what the conspiracy was about; I just keenly felt that there was *something* going on, and that there was some hidden line of communication between school and work.
+
+
At this point, whoever I was before that, my entire self-concept, disintegrated, melted away into nothing. In retrospect, I think about how I thought of myself back then, and I can't pick out anything that I identified with. I was like a robot that was programmed to show up to school, and then go to work. Weirdly, I was able to work well at my job as a bus boy and dishwasher at a restaurant, because apparently robots are diligent and don't waste time socializing with other coworkers. When I had to speak to customers and the wait staff, I was extremely passive, my voice was monotonous and lacking any personal quality. As a bus boy, I had compulsions to clean off the dirty tables a certain way after the customers had left, and stack dishes on the bussing cart a certain way. I had figured this way was efficient, predictable, and added structure to a mostly unpredictable work flow.
+
+
This is just a snippet/snapshot of my experience back then -- there are many layers I can unfold about symptoms I experienced during this period, like body dysmorphia, social phobia, and perceptual abnormalities that I recognize in retrospect. I'm not willing to spend time unfolding those here, but I would be willing if anyone asked about it.
+
+
Three years later in September of 2007, after realizing that *something is not quite right* with my brain and seeking professional help, I was diagnosed with schizoaffective disorder (depressive type) and OCD. I don't know what the diagnostic process consisted of, or what information they had about me, but I don't think they based the entire diagnosis on a single one-on-one interview with me describing my symptoms. I would imagine they got records and information from my school and my guidance counselor and from the psychiatrist I was seeing at the time. I'm not sure if they would bother my previous employer or coworkers to ask about my behavior -- maybe there is a legal reason they wouldn't.
+
+
I don't know how else to end this blog post. Someone on Facebook shared an old photo of themself from 2004, and it got me thinking of what I was doing in 2004. It reminded me of the fact that it's been 20 years now. I just wanted to relate a snapshot of what it was like back then. I'm doing better today, and I think have a more solid self-concept.
+
+
\[fn:1] What I mean by *panic attack* here is that I started hyperventilating, my vision got blurry, I felt like I was in slow-motion, and I collapsed to the ground. People sometimes describe non-panic attack anxiety as "butterflies in the stomach", but I would descirbe the abdominal feeling I experienced at that moment to have been more like swarm of vampire bats. I don't think I blacked out. I got up after about a minute and got my bearings, but things were very not okay afterward. I don't think I slept at all that night. I went to school the next day probably looking like I saw a ghost. If anyone was paying attention to my body language, they would have seen that something was wrong. I think this is around the time I went to see my guidance counselor and I just started balling, I couldn't hold back the crying. I think I went to see my guidance counselor to ask if I can switch out of a class with a teacher I was paranoid about.
+41
http/content/posts/2024-12-09-my-tentative-file-syncing-solution.md
···
+
+++
+
title = 'My tentative file-syncing solution'
+
date = 2024-12-09
+
tags = ['linux', 'file-sync', 'selfhosting', 'rsync', 'rclone', 'protondrive']
+
+++
+
+
The devices I want to keep certain files in sync between are my Linux desktop, Linux laptop, gaming PC, and Android phone. The gaming PC and Android phone are not strictly necessary to keep in sync with the others, but it's moderately convenient to have certain files synced and available on them.
+
+
For my Linux desktop and laptop, I will continue to use rsync. I have a [justfile](https://just.systems) that contains commands that sync between them using their tailnet FQDNs.
+
+
```shell
+
.justfile
+
+
to-laptop:
+
rsync -aAXP /home/jas/sync/ jas@laptop.tailnet.ts.net:/home/jas/sync
+
+
to-desktop:
+
rsync -aAXP /home/jas/sync/ jas@desktop.tailnet.ts.net:/home/jas/sync
+
```
+
+
I only use my laptop when I leave the house to a location where I have enough time and convenient space to set it up and use for a while. I also use it while still at the house if I'm on my desk treadmill or sitting out on the deck in the backyard. Before leaving the desktop and using the laptop, I would run `just to-laptop`, and /vice versa/ before leaving the laptop and going back to the desktop.
+
+
For my gaming PC and Android phone, there is a Proton Drive client for both Windows and Android, so I have it installed on those devices. I could then use rclone from my Linux desktop or laptop to sync the contents of the `/home/jas/sync` directory to Proton Drive. I would add the following to my justfile:
+
+
```shell
+
.justfile
+
+
to-protondrive:
+
rclone sync --transfers 16 -P /home/jas/sync/ protondrive:/
+
+
from-protondrive:
+
rclone sync --transfers 16 -P protondrive:/ /home/jas/sync
+
```
+
+
I usually tend to know ahead of time whether I will need to use any of the above commands -- rarely is there a time when I'm using one device and find myself in need of a file that exists on another device. So this will suffice until Proton Technologies develops a Proton Drive client for Linux.
+
+
Regarding Proton Technologies developing a Proton Drive client for Linux: I'm starting to wonder if it's a matter of /if/ rather than /when/. It doesn't seem to be a priority for them at this time, which I find kind of baffling. It makes sense from an economic standpoint to only support macOS, iOS, Windows, and Android, since the majority of devices in the world run one of those. I'm just surprised that they don't make the Linux desktop a priority out of principle because they otherwise seem dedicated to privacy and FOSS.
+
+
I was using [MEGA sync](https://mega.io) for a while, and maybe I'll just go back to using that. They have clients for Linux, and they also seem dedicated to privacy and FOSS. It's just that...I have 500 GB of storage on Proton Drive with my Proton Plus account and it irks me that I can't use it the way I want to.
+
+
I'm aware of the [celeste](https://github.com/hwittenborn/celeste) app, which is supposed to be a Dropbox-like GUI solution that allows syncing with multiple cloud services, including Proton Drive. I've tried it twice, and it always kind of froze when syncing with Proton Drive. The Celeste app is still under development so there are many rough edges to smooth out, but I believe it uses rclone for Proton Drive anyway.
+47
http/content/posts/2024-12-12-my-nas-solution-and-other-homelab-projects.md
···
+
+++
+
title = 'My NAS solution and other homelab projects'
+
date = 2024-12-12
+
tags = ['nas', 'homelab', 'llm', 'ollama', 'llava', 'kubernetes', 'debian', 'truenas']
+
+++
+
+
## Network-attached storage solution
+
+
Back in April (2024), I built a NAS machine with the following components:
+
+
* CPU: 12th Gen Intel i5-12600K 10-core (16 threads) at 4.9GHz with integrated graphics (Alderlake-S GT1)
+
* RAM: 64 GB (4x16GB) Corsair Vengeance LPX DDR4
+
* SilverStone Technology CS382 8-bay SAS-12G/SATA-6G Hot-swappable Micro ATX NAS chassis
+
* four Seagate Exos X22 20TB SATA 6Gb/s 7200RPM 3.5-inch Enterprise HDDs
+
* Corsair SF850L fully modular low-noise SFX power supply
+
* MSI PRO B760M-A WiFi DDR4 ProSeries motherboard, 2.5Gbps LAN
+
+
When I moved back in with my parents in June, I had this machine running for a couple months. My parents, who pay the electric bill, are strict about conserving energy and saving money, so they yell at me for leaving lights on and such. (But they have their own "parent math", such that they get mad when lights are needlessly left on but they justify other expenditures that seem needless to me. But it's their money, so.) I figured having this NAS machine running 24/7 was probably contributing to a good portion of the electric bill. So I decided to buy a 4-bay external NAS hard drive enclosure that supports up to 80 TB, and connect this to my laptop to use as a NAS solution. I used this for a while until last week, when I decided to get the NAS machine I built back up and running again. I told my parents that I will pay them $50 a month toward the electric bill. They are fine with this deal.
+
+
I didn't bother taking the hard drives out of the 4-bay external NAS enclosure, and I just connected it to a USB port on the back of the NAS machine. The NAS chassis I bought is built to hold up to 8 HDDs, but the motherboard only has 4 SATA connector ports, so the machine can only support 4 HDDs. If I ever want to expand from 80 TB up to 160 TB, I can do that, but 80 TB is plenty, at least for now.
+
+
I previously used TrueNAS SCALE on the NAS machine when I first got it back in April and until I shelved it. Now it runs regular Debian, which gives me more granular control over the system than the sort of locked-down approach of TrueNAS. The four 20 TB enterprise HDDs are part of a RAID0 ZFS pool. Perhaps if I want redundancy in the future I can get four more 20 TB HDDs and make them mirror the other four, but redundancy is not really a priority for the type of data I store on them. I only really want redundancy for personal data, not public archive data. On my Linux desktop, I have a 5 TB Btrfs RAID1 mirror that consists of three 5 TB external HDDs, and on this 5 TB RAID1 mirror I have my personal data in an encrypted Borgbackup repository. For additional redundancy and separation I also have this Borgbackup repository mirrored on my Linux desktop's 1 TB local hard drive.
+
+
My NAS machine also runs some local services, like Invidious, Grafana, Prometheus, Loki, Promtail, Linkding, qBittorrent, and two qBittorrent Prometheus exporters. One of those qBittorrent exporters is for my local qBittorrent instance where I torrent Linux distribution ISOs and other stuff that is legal in the U.S. The other qBittorrent exporter is for my remote qBittorrent instance on SeedHost that resides in Amsterdam, which I use for public digital archive stuff.
+
+
## Kubernetes cluster
+
+
I have three Orange Pi 5 Plus devices that are currently doing nothing right now. I came across an article for setting up a K3s cluster on Orange Pi 5 Plus running Armbian. I'm considering doing this. I also came across another article for setting up [Ollama](https://github.com/ollama/ollama) in a Kubernetes cluster, and there's also a way to set it up with [TrueCharts](https://truecharts.org/charts/stable/ollama). Ollama is about as ethical as LLM use can get at this time. It allows you to download open source LLMs and run them locally. I came across another article that discusses generating alt-text from images with [LLaVA](https://llava-vl.github.io/). Most of the time my brain deadlocks when I want to describe an image for alt-text, so I've tended to avoid doing it. This causes friction with my belief that content on the Internet should be accessible to visually-impaired users. Lately I've been trying to get into the habit of adding alt-text to the best of my ability, but it takes a lot, and I fear that even the little I can do at a given time is inadequate, which isn't fair to visually-impaired users. So I find this to be an acceptable use-case for LLMs. I generally believe LLMs have a ton of potential for accessibility.
+
+
Other things I'm considering running on the Orange Pi 5 Plus Kubernetes cluster:
+
+
* [Semaphore](https://truecharts.org/charts/incubator/semaphore) : an open source alternative to Ansible Tower, which allows you to create, manage, and monitor Ansible projects, playbooks, and roles.
+
* [blocky](https://truecharts.org/charts/premium/blocky) : DNS proxy, DNS enhancer, and ad-blocker for the LAN written in Go.
+
* [Vaultwarden](https://truecharts.org/charts/premium/vaultwarden) : Unofficial Bitwarden compatible server written in Rust. I wouldn't use this as a replacement for Bitwarden, but I would use it to mirror my Bitwarden vault locally.
+
* [apt-cacher-ng](https://truecharts.org/charts/stable/apt-cacher-ng) : Caching proxy for Debian packages, but apparently not limited to Debian.
+
* [Atuin](https://github.com/atuinsh/atuin) : Magical shell history. It replaces existing shell history with a SQLite database and records additional context for your commands. Can also sync shell history across devices.
+
* [calibre](https://truecharts.org/charts/stable/calibre/) : An open source e-book manager. I currently use the desktop version of calibre, but I think it's worth seeing how running it in a K3s cluster would work out. Additionally, [calibre-web](https://truecharts.org/charts/stable/calibre-web).
+
* [ciao](https://truecharts.org/charts/stable/ciao/) : Checks HTTP(S) URL endpoints for a status code and sends a notification on change via email or webhooks. I might also just deploy this on my NAS machine.
+
* Grafana, Prometheus, Loki, Promtail, and rsyslog -- though I'd prefer not to mess with their current installation on my NAS machine.
+
* Invidious
+
* [netbootxyz](https://truecharts.org/charts/stable/netbootxyz) : PXE boot for any type of operating system or utility disk. Could be highly useful for me.
+
* [Pihole](https://truecharts.org/charts/stable/pihole) : If not blocky, then Pihole.
+
* [protonmail-bridge](https://truecharts.org/charts/stable/protonmail-bridge) : This could be highly useful for me to have available on my LAN.
+
* [Seafile](https://truecharts.org/charts/stable/seafile) : File-sync solution. Maybe?
+
* [Tailscale](https://truecharts.org/charts/stable/tailscale) : Obviously need to have these services accessible on my tailnet somehow.
+
+
I doubt I will have every one of the above services setup on the cluster, but they are definitely good candidates. I would also need to find a way to make my NAS storage available to the cluster.
+21
http/content/posts/2024-12-16-update-on-homelab-projects.md
···
+
+++
+
title = 'Update on homelab projects'
+
date = 2024-12-16
+
tags = ['homelab', 'orangepi', 'ansible', 'k3s', 'kubernetes', 'armbian', 'poe', 'emacs', 'guix']
+
+++
+
+
On December 14, 2024, I made the following post on Mastodon:
+
+
> Homelab projects for this weekend:
+
>
+
> * Try out Guix as a daily driver
+
> * Take off the Doom Emacs training wheels and setup a custom Emacs config
+
> * Setup K3s cluster on my three Orange Pi 5 Plus devices
+
+
Guix is a no-go, because KDE Plasma is not an officially supported desktop environment on Guix yet. Nor does Tailscale have a reliable way to install and manage on Guix. Maybe when the Non-Guix maintainers decide to port Tailscale to their channel.
+
+
I've decided to keep using Doom Emacs for now. Once I get my K3s cluster up and running and in working order, I will take time to pick apart my Doom Emacs config. This would involve finding the packages and configuration that are builtin to Doom Emacs, which I mostly take for granted -- aside from the ones I have defined in `packages.el`. I would have to find a way to conveniently manage packages without the `doom sync` and `doom upgrade` commands. But, for now, everything just works, and I'd like to keep it that way as I'm working on the K3s cluster.
+
+
I have my three Orange Pi 5 Plus's ready to be plugged in. I have Armbian on a microSD card, ready to be installed to each of the eMMCs. I have ethernet cables running between my unmanaged switch and each of the Pi's. Once Armbian is installed and configured on them, I will run an Ansible playbook that bootstraps the K3s cluster. I have a `.org` file as a reference. All I have to do now is cut the ribbon. Am kinda nervous about it, tho, so I've been kinda procrastinating. But, I've got this.
+
+
About two years ago I bought a PoE (Power-over-Ethernet) switch that supports gigabit ethernet. I stopped using it when I got 5Gbps Internet from AT\&T when I was still living with my grandfather about a little over a year ago. Now that I live back with my parents, I have 2.5Gbps Internet from Comcast Xfinity. Since I've had no luck finding a 2.5Gbps PoE to USB-C splitter, I'll have to make do with what I've got. There's no reason for me to be a spoiled snob about utilizing my network's full throughput capacity for this use-case -- gigabit ethernet is ample, and I don't need to spend more money on a 2.5Gbps PoE switch. I bought three 1Gbps PoE to USB-C splitters. When they are delivered, I will unplug the power cords of the three Orange Pi 5 Plus's, plugin the gigabit PoE switch, run an ethernet cable from my unmanaged switch to the PoE switch, run three ethernet cables to each of the PoE to USB-C splitters, and plug the USB-C connectors into the power sockets of the three Pi's.
+19
http/content/posts/2024-12-18-my-disillusionment-and-aspirations.md
···
+
+++
+
title = 'My disillusionment and aspirations'
+
date = 2024-12-18
+
tags = ['foss', 'privacy', 'jobs', 'digital-freedom', 'kubernetes', 'devops']
+
+++
+
+
I'm having a hard time articulating things right now, so please bear with me. I'm recovering from being triggered earlier today when I heard Trump claim that pesticides are responsible for the "rise" in autism cases. I feel like I'm sufficiently cooled off, but some of my anger might still be lingering in the background, which may affect my ability to be objective here.
+
+
Anyway.
+
+
My failure to wrap my head around Kubernetes today as I tried to setup a three-node cluster has made me realize that I don't particularly like all this containerization and catering to corporate infrastructure needs in the tech industry. I'm not dunking on the merits of the technology -- it undoubtedly solves a great many problems. It's just that those problems are not something I'm personally interested in solving.
+
+
I'm feeling more of an affinity toward minimalism, the Unix philosophy, and suckless.org principles.
+
+
Since I've graduated from uni with a Bachelor's degree in computer science, I've felt this anxiety regarding finding a job, and this kind of spurred me toward thinking I need to learn DevOps technologies like Docker, Kubernetes, AWS, and other cloud-based services. I no longer want to feel that anxiety. It has prevented me from following my curiosity in learning things I've wanted to learn when I first became interested in computer science, because I've always felt like I needed to prioritize those job skill requirements.
+
+
I'm 36 years old, and I'm starting to worry that I might never find a career doing something I love and have a deep appreciation for. $400 a month in disability benefits is not sustainable. If it wasn't for my family, I'd probably be homeless and/or working at a job that doesn't pay a living wage anyway, let alone making enough to pay off my student debt. I'm disillusioned by this university education culture that promised a better life outcome if I earned a degree. This feels like such a scam when I realize the skills I learned as a computer science major could have been learned on my own, without putting myself into $70k student debt. I know this is a unique-to-me situation, and other C.S. graduates have gotten jobs and are making good money. But I'd bet that few if any of them have had to deal with debilitating mental illness for their entire adult life. I'd also bet that the majority of them are working at corporate offices, in service to the American capitalist GDP machine.
+
+
My ideal job would be something that helps a community and is centered around my values regarding digital freedom, privacy, anti-Big corporate, information freedom, and free and open source software. Those are the societal problems I am interested in solving.
+74
http/content/posts/2025-01-04-my-network-wide-bullshit-blocking-setup.md
···
+
+++
+
title = 'My network-wide bullshit blocking setup'
+
date = 2025-01-04
+
tags = ['networking', 'dns', 'adblock', 'blocky', 'tailscale', 'sbc']
+
+++
+
+
## Orange Pi 5 Plus
+
+
* Unbound for recursive DNS resolver on 127.0.0.1:5335.
+
* [Blocky](https://0xerr0r.github.io/blocky/latest/) for DNS proxy, ad-blocking, and malware-blocking on 0.0.0.0:53. Uses Unbound on 127.0.0.1:5335 as upstream resolver.
+
* Tailscale with `--accept-dns=false`.
+
* `unbound-resolvconf.service` is disabled, and `/etc/resolv.conf` is not managed by any service, so I just put `nameserver 9.9.9.9` in it for local DNS resolution.
+
+
I intend on eventually making this fault-tolerant by using another device as a failover with keepalived. Where and what that other device will be is to be determined. I have Blocky configured to use the `strict` strategy for the `upstreams` setting, so after a timeout of the topmost upstream server it will fallback to the next one, which is Quad9. An idea I have is to setup a cheap VPS on Vultr and run a public DNS resolver on it, but Quad9 is fine for now. Using a completely self-hosted recursive DNS resolver is fairly important to me, but as long as it's not going through Google or my ISP it is fine.
+
+
I have the Orange Pi 5 Plus Tailnet IP address configured to be my Tailnet's global nameserver. So every device on my Tailnet that uses MagicDNS will be using Blocky and Unbound.
+
+
## Blocky configuration
+
+
```yaml
+
upstreams:
+
strategy: strict
+
groups:
+
default:
+
- 127.0.0.1:5335
+
- 9.9.9.9
+
- 149.112.112.112
+
+
blocking:
+
denylists:
+
ads:
+
- https://raw.githubusercontent.com/StevenBlack/hosts/master/hosts
+
- https://adaway.org/hosts.txt
+
- https://v.firebog.net/hosts/AdguardDNS.txt
+
suspicious:
+
- https://v.firebog.net/hosts/static/w3kbl.txt
+
tracking:
+
- https://gitlab.com/quidsup/notrack-blocklists/raw/master/notrack-blocklist.txt
+
- https://v.firebog.net/hosts/Easyprivacy.txt
+
- https://v.firebog.net/hosts/Prigent-Ads.txt
+
malicious:
+
- http://phishing.mailscanner.info/phishing.bad.sites.conf
+
- https://v.firebog.net/hosts/Prigent-Crypto.txt
+
- https://raw.githubusercontent.com/StevenBlack/hosts/master/alternates/fakenews/hosts
+
+
clientGroupsBlock:
+
default:
+
- ads
+
- suspicious
+
- tracking
+
- malicious
+
+
ports:
+
dns: 53
+
http: 4000
+
+
prometheus:
+
enable: yes
+
+
caching:
+
minTime: 60s
+
maxItemsCount: 10000
+
prefetching: yes
+
prefetchMaxItemsCount: 2000
+
+
queryLog:
+
type: csv-client
+
target: /home/jas/dns-query-logs
+
logRetentionDays: 5
+
clientLookup:
+
upstream: 10.0.0.1
+
singleNameOrder:
+
- 1
+
```
+103
http/content/posts/2025-01-12-my-comcast-home-isp-proof-qbittorrent-setup.md
···
+
+++
+
title = 'My Comcast/home ISP-proof qBittorrent setup'
+
date = 2025-01-12
+
tags = ['qbittorrent', 'bittorrent', 'comcast', 'isp', 'vpn', 'protonvpn', 'orangepi', 'networking', 'openaccess']
+
+++
+
+
This setup consists of two Orange Pi 5 Plus devices. One of them I use as my NAS server, which we'll call /nas-node/. The other is an auxiliary that runs the qBittorrent Docker container, which we'll call /aux-node/.
+
+
## nas-node
+
+
My NAS server uses Tailscale so that I can conveniently access it from any device on my tailnet. I have an external NAS hard drive enclosure connected to it via USB 3.0, and this NAS enclosure contains four 20 TB enterprise HDDs, so I have a total of roughly 80 TB of storage space that comprises a "RAID0" ZFS pool. My goal is to use some of this storage space for open access data, such as Anna's Archive. The problem is if I start bittorrenting those archives, it's possible my Comcast ISP will complain or block, or I'll get legal scare letters, or some such nonsense. A solution, or a way to circumvent detection by Comcast, would be to use a VPN for the qBittorrent connection. I could use ProtonVPN from my Proton Unlimited account, but this would interfere with the Tailscale VPN. A solution to this, in turn, is to use one of my other Orange Pi 5 Plus devices as an auxiliary node to run the qBittorrent Docker container, and have qBittorrent configured to save downloaded data to the NAS via an NFS share on the nas-node. In order to ensure a consistent and fast connection to the nas-node, I decided to use the second ethernet ports on the Orange Pi 5 Plus devices. So I have a 12-inch ethernet cable connecting both Orange Pi 5 Plus devices to their second ethernet ports. I configured this with systemd-networkd by setting up a subnet between the two devices.
+
+
For the sake of this post, eth0 refers to the primary ethernet port that receives Internet, and eth1 refers to the second ethernet port that connects to the subnet.
+
+
On /nas-node/, I created a network file for systemd at `/etc/systemd/network/eth1.network`:
+
+
```systemd
+
[Match]
+
Name=eth1
+
+
[Network]
+
Address=10.0.4.1/24
+
```
+
+
On /aux-node/, I created a network file for systemd at `/etc/systemd/network/eth1.network`:
+
+
```systemd
+
[Match]
+
Name=eth1
+
+
[Network]
+
Address=10.0.4.2/24
+
```
+
+
Both nas-node and aux-node are running Ubuntu 24.04, which uses netplan.io to configure the network interfaces. I had to disable netplan.io by removing its package, enable systemd-networkd, and reboot in order to use systemd-networkd.
+
+
```shell
+
sudo apt purge netplan.io
+
sudo apt autoremove
+
sudo systemctl enable systemd-networkd
+
sudo systemctl reboot
+
```
+
+
Now that I have a li'l subnet for nas-node and aux-node, I configured the NFS share on nas-node to allow connection from the aux-node IP address `10.0.4.2`. First, I had to create a ZFS dataset to store the torrent data, and then configure that dataset to be an NFS share.
+
+
```shell
+
sudo zfs create naspool/torrents
+
sudo zfs set sharenfs`"rw`@10.0.4.0/24" naspool/torrents
+
sudo chown -R jas:jas /naspool/torrents
+
```
+
+
In `/etc/exports`:
+
+
```shell
+
/naspool/torrents 10.0.4.2(rw,sync,no//subtree//check)
+
```
+
+
I set the ownership of the `naspool/torrents` dataset to the `jas` user, so that the `jas` user on both the nas-node and aux-node can access it.
+
+
## aux-node
+
+
I configured `/etc/fstab` to mount the NFS share from nas-node automatically on boot.
+
+
```shell
+
10.0.4.1:/naspool/torrents /mnt/torrents nfs4 rw,relatime,vers`4.2,rsize`1048576,wsize`1048576,namlen`255,hard,proto`tcp,timeo`600,retrans`2,sec`sys,clientaddr`10.0.4.2,local_lock`none,addr=10.0.4.1 0 0
+
```
+
+
I installed Docker and the wireguard-tools packages on aux-node. I created and downloaded a ProtonVPN Wireguard configuration file and saved it to `/etc/wireguard/wg0.conf`. I actually have several of these from various geographic locations in case one stops working for whatever reason. When creating the Wireguard configurations for ProtonVPN, I made sure to select NAT port-fowarding for peer-to-peer filesharing.
+
+
For the qBittorrent Docker container, I used `docker compose` with the following `compose.yml` file:
+
+
```yaml
+
---
+
services:
+
qbittorrent:
+
image: lscr.io/linuxserver/qbittorrent:latest
+
container_name: qbittorrent
+
environment:
+
- PUID=1000
+
- PGID=1000
+
- TZ=Etc/UTC
+
- WEBUI_PORT=8080
+
- TORRENTING_PORT=6881
+
volumes:
+
- /mnt/torrents/downloads:/downloads
+
- qbittorrent-config:/config
+
ports:
+
- 8080:8080
+
- 6881:6881
+
- 6881:6881/udp
+
- 9000:9000
+
- 9000:9000/udp
+
restart: unless-stopped
+
+
volumes:
+
qbittorrent-config:
+
```
+
+
Note that `/mnt/torrents` on aux-node is the NFS share from nas-node via the subnet I created for nas-node and aux-node. Port 8080 is so that I can access the qBittorrent web UI. Port 6881 for TCP and UDP are the torrenting ports that will be forwarded through the ProtonVPN connection. Port 9000 for TCP and UDP is to allow port-forwarding for the embedded tracker in qBittorrent. The qBittorrent Docker container automatically uses the ProtonVPN connection from the host. I checked this by entering the qBittorrent container's shell environment and running `curl ipinfo.io` to check its public IP address, which was indeed the ProtonVPN IP address.
+
+
## Closing
+
+
So, with this setup, I am able to use some of my ~80 TB NAS storage to help out the open access community, with my Comcast ISP being none the wiser. Though, to be epistemically thorough, it's possible there is some hole in this setup that Comcast can hypothetically circumvent. At the very least, they are able to tell I'm using a VPN.
+21
http/content/posts/2025-02-08-mental-health-improvement-or-something.md
···
+
+++
+
title = 'Mental health improvement or something'
+
date = 2025-02-08
+
tags = ['mentalhealth']
+
+++
+
+
On February 8th, 2024, I made the following Fediverse post:
+
+
> Paranoid/self-focused: X claims to be a body positivity advocate and presents a veneer of social liberalism but this instance in which they subtly mock my weight issues exposes their hypocrisy and shows that even so-called "champions" of justice will succumb to selfish motives like status-seeking at my expense.
+
>
+
> Bayesian: X is demonstrably a body positivity advocate; they have a track record of fighting bigotry online, and have never been seen making petty criticisms of others' personal issues. It's not likely that they were subtly mocking my weight issues in this instance. Whatever I picked out as mockery is likely coincidence, and they probably have better priorities than to make fun of me.
+
>
+
> I often find myself trapped in a twilight zone between these two possible worlds.
+
+
Over the past year, I've found myself less frequently trapped in this sort of twilight zone. The paranoid possible world is more easily dismissed and I don't tend to go down its rabbit hole.
+
+
The reasons for this improvement (if that's what it is) are not obvious to me, especially considering that I've been on a lower dose of Invega since September of 2024. I don't know really how to explain it. Maybe I'm less insecure about things in general, and the Invega maybe never really had any bearing on my insecurity, as my insecurities might be separate from the thing that Invega treats. Maybe I'm less insecure about my weight issues in particular, due to losing weight on Wegovy. It's also possible that I've just surrounded myself with less shitty people (shrug).
+
+
What I mean by "this sort of twilight zone" is that such paranoid thought processes are not only limited to personal issues like my obesity. They could be about other personal issues or just things about me in general that I feel insecure about.
+
+
One thing I can say with confidence is that this improvement is, at the very least, applicable to my current baseline, which is my sequestered, reclusive, and extremely online lifestyle. It's likely that the insecurities increase in contexts where they tend to be more triggered, such as around a lot of people or in public places. Hence, it's also likely that the paranoia would increase and I would find myself in the sort of twilight zone described above if I were to put myself in those contexts. Any therapist worth their co-pay would likely tell me that the more I put myself in those contexts, the more I get used to it, and I could eventually reach a point where my insecurities don't bother me in those contexts. However, I'm not 19 years old anymore, I don't have my physical and mental "prime" ahead of me anymore. I'm almost 37, and at this point, I have priorities and obligations that make putting myself in triggering situations extremely inconvenient. In the context of autonomy and personal freedom, I think I have a right not to put myself in extremely uncomfortable situations if I can help it. I see a path in my future where I can survive just fine in this lifestyle. Of course I will miss many other opportunities, but at the moment this is acceptable to me.
+15
http/content/posts/2025-04-05-i-really-dislike-computers-sometimes.md
···
+
+++
+
title = 'I really dislike computers sometimes'
+
date = 2025-04-05
+
tags = ['computers', 'foss', 'windows', 'homelab']
+
+++
+
+
I've got to figure something out with the arrangement of my bedroom/office. Right now, I have two desks in the shape of an L in the corner. This corner is necessary because that's where the outlets are. One of the desks holds my gaming PC, and the other desk holds my main Linux workstation along with my NAS and homelab machines. I'd rather have: (1) one desk for my gaming PC and Linux workstation, and (2) the other desk for my homelab equipment.
+
+
The problem with (1) is that I'd like to be able to have one set of peripheral devices that can connect to both my gaming PC and Linux workstation, and conveniently switch between them when I want to. One way this is possible is just by unplugging and plugging in each peripheral device (keyboard, mouse, monitor) into the desired machine. But this would be a pain in the fundament, because my gaming PC doesn't have any ports conveniently on the front of the machine, so I'd have to crawl down under the desk and reach into the back of the machine every time. I could also use USB hubs for this and save myself from having to crawl under the desk. I can have a USB hub for each machine. This would at least cover the keyboard and mouse. As for the monitor, my current monitor only has one DisplayPort port, so I'd have to keep unplugging and plugging in DisplayPort cables for both machines. Maybe I can find a monitor that has more than one DisplayPort, and use the monitor's buttons to toggle between them. Or some kind of splitter/switch hub thingy that has a button that I can just press to toggle which machine uses the monitor (if such a thing exists?). Another way would be Bluetooth peripheral devices that I'd have to keep charged and paired constantly -- but that idea can go straight the fuck to Hell where it belongs.
+
+
What's wrong with using the Windows 11 gaming PC as my main workstation like a normie instead of having a separate Linux workstation? Honestly, I've seriously considered this, as it would sure make all this easier. But the answer ought to be obvious to anyone who cares about digital rights\[1]. Why don't I just dual boot on the gaming PC, then? Because reasons.
+
+
\[1] Maybe there is a way I can isolate some things similar to Qubes OS, and try to keep personal data off the Windows host OS as much as possible. Maybe I can leverage WSL for this somehow. I can look into making Windows less privacy-invasive without breaking certain functionality, if that's even possible these days.
+
+
Of course, none of this would be a problem if I had more space in my bedroom/office with outlets at convenient locations, but that's not possible for the foreseeable future, so I have to work with what I've got. I think any arrangement I come up with is going to have an entropistic Cyberpunk 2077 look, and, uh, that's supposed to be a dystopia best avoided. (Ironically, my Secret Lab Magnus Pro desk has a Cyberpunk 2077 theme lol.)
+36
http/content/posts/2025-08-09-upgrade-dietpi-to-debian-trixie.md
···
+
+++
+
title = 'Upgrade DietPi to Debian Trixie'
+
date = 2025-08-09
+
tags = ['debian', 'dietpi']
+
+++
+
+
I have DietPi running on an Orange Pi 5 Plus. The services that DietPi runs include: Pihole + local unbound, my private FreshRSS instance, my private Nextcloud instance, Prometheus node-exporter, a Docker container for the Tapo P110 Prometheus exporter, a Docker container for the qBittorrent exporter, and a Docker container for the Ntfy service.
+
+
## Attempt 1
+
+
On the DietPi website, they mention using a [script](https://github.com/MichaIng/DietPi/issues/7644) to upgrade DietPi from Bookworm to Trixie. I ran the following command:
+
+
```shell
+
sudo bash -c "$(curl -sSf 'https://raw.githubusercontent.com/MichaIng/DietPi/dev/.meta/dietpi-trixie-upgrade')"
+
```
+
+
This script is well-designed and well-written. It offers the user a chance to run DietPi-backup before proceeding, which I did. After the backup completed, I followed the menu options to initiate the upgrade process. This ran well until it wanted to upgrade Docker packages, such as `docker-compose-plugin`. The upgrade script downloads a `docker-compose` .deb package and attempts to install it, but it conflicts with the already-installed `docker-compose-plugin` package, and apparently dpkg didn't know how to proceed. This left my DietPi system in a misconfigured and broken state. I was able to run the `dietpi-backup` script to restore the backup that was done prior to running the upgrade script. I then rebooted.
+
+
## Attempt 2
+
+
On the freshly booted and restored DietPi system, I ran the following command to remove all Docker-related packages before trying the upgrade script again.
+
+
```shell
+
sudo apt remove docker.io docker-doc docker-compose podman-docker containerd containerd.io runc docker-compose-plugin
+
```
+
+
I then ran the upgrade script with the same command as above, and it succeeded. I rebooted, then ran the following commands to finalize the upgrade and install Docker again.
+
+
```shell
+
sudo apt autopurge
+
sudo apt install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
+
```
+
+
Pihole, FreshRSS, and Nextcloud were migrated seamlessly, the latter two now using updated versions of PHP and MySQL. After running `docker ps`, I noticed my containers are running, and I didn't have to reconstruct or rebuild any of them. Their data is mostly stored under `/mnt/dietpi_userdata/docker-data`, which was left untouched when I removed and reinstalled Docker.
+
+
Yay!
+15
http/content/posts/2025-09-14-possible-solution-for-self-hosting-bluebuild-images-without-ci.md
···
+
+++
+
title = 'Possible solution for self-hosting Bluebuild images without CI'
+
date = 2025-09-14
+
tags = ['selfhosting', 'bluebuild', 'ublue', 'fedora', 'containers', 'bootc']
+
+++
+
+
As an anti-Big Tech self-hoster, I don't like using GitHub to build and store my Ublue/Bluebuild container images.
+
+
I'm thinking of doing the building on my own machine and pushing the image to a self-hosted container registry. The [bluebuild cli](https://github.com/blue-build/cli) makes this easier. For a self-hosted container registry I can use [Harbor](https://goharbor.io/).
+
+
I would write a script that fetches the latest version from my Codeberg repo, runs something like `bluebuild build -v --push --registry $HARBOR_REGISTRY recipes/recipe.yml` locally, and sends the log output to a file for debugging purposes.
+
+
I would have the script run as a systemd service with a daily timer. If I use a systemd service then I wouldn't necessarily have to store the log output to a file, as I could view it with `journalctl -xeu bluebuild-build.service`, but it might be nice to have separate log files in addition to that.
+
+
This way I can self-host it without having to fiddle with Gitea or Codeberg CI.
+55
http/content/posts/2025-10-02-uising-codeberg-gitea-or-forgejo-as-oidc-provider-for-tailscale.md
···
+
+++
+
title = 'Using Codeberg, Gitea, or Forgejo as OIDC provider for Tailscale'
+
date = 2025-10-02 22:37:00
+
tags = ["oidc", "codeberg", "gitea", "forgejo", "tailscale"]
+
+++
+
+
## Requirements
+
+
* An account on Codeberg, Gitea instance, or Forgejo instance.
+
* A domain name. E.g., I use moonshadow.dev.
+
* The primary email address on your Codeberg, Gitea, or Forgejo account must be from the above domain name. E.g., mine is <hyperreal@moonshadow.dev>.
+
* A publicly accessible web server to host your webfinger file. You could also use [Codeberg pages](https://docs.codeberg.org/codeberg-pages/) for this with your [custom domain](https://docs.codeberg.org/codeberg-pages/using-custom-domain/). The web server must serve content at your domain. E.g., <https://moonshadow.dev>.
+
+
## Webfinger
+
+
In the web root of your web server, create the `.well-known/webfinger` file. For example, on mine, I have the following:
+
+
```json
+
{
+
"subject": "acct:hyperreal@moonshadow.dev",
+
"links": [
+
{
+
"rel": "http://openid.net/specs/connect/1.0/issuer",
+
"href": "https://codeberg.org"
+
}
+
]
+
}
+
```
+
+
You can use the [Webfinger lookup tool](https://webfinger.net/lookup/) to make sure it is setup correctly.
+
+
The value of the "subject" field must contain the email address at the domain you own. The value of the "href" field must be the URL of Codeberg, Gitea instance, or Forgejo instance.
+
+
## Create an OAuth2 application on Codeberg, Gitea, or Forgejo
+
+
On Codeberg, Gitea, or Forgejo, go to your User Settings -> Applications -> Manage OAuth2 applications.
+
+
* Application name: tailscale
+
* Redirect URI: `https://login.tailscale.com/a/oauth_response`
+
* Confidential client: checked
+
+
Click on Create. Now copy and save the Client ID and Client secret that was generated.
+
+
## Sign up with Tailscale
+
+
1. Go to the Tailscale login page, and select "Sign up with OIDC".
+
2. Enter your email at your custom domain. E.g., <hyperreal@moonshadow.dev>.
+
3. Choose Codeberg or Gitea as the identity provider. This step is optional and doesn't really matter. Forgejo instances can choose Gitea.
+
4. Select "Get OIDC Issuer".
+
5. Enter the Client ID and Client secret you saved from your OAuth2 application. Leave everything else as default, and make sure that "consent" is checked under Prompts.
+
6. Click "Sign up with OIDC", and you should be able to login to Tailscale and be redirected to your Tailscale admin console.
+
+
## Resources
+
+
* [Custom OIDC providers - Tailscale Docs](https://tailscale.com/kb/1240/sso-custom-oidc)
+90
http/content/posts/2025-10-10-my-current-self-hosted-bluebuild-solution.md
···
+
+++
+
title = 'My current self-hosted Bluebuild solution'
+
date = 2025-10-10 10:06:10
+
tags = ["bluebuild", "bootc", "fedora", "atomic", "ublue", "selfhosted"]
+
+++
+
+
It just feels wrong/off for me to have my Bluebuild images hosted and built with GitHub CI. I now have a self-hosted solution for this that is, I believe, less failure-prone than using ordinary CI/CD.
+
+
The basic ingredients are as follows:
+
+
* Private-facing server with adequate storage, accessed only via Tailscale, to serve as a build host
+
* Docker or Podman
+
* [docker-registry-ui](https://github.com/Joxit/docker-registry-ui) without authentication (because Tailscale)
+
* Caddy web server to reverse-proxy the container registry
+
* [bluebuild-cli](https://github.com/blue-build/cli)
+
* Bash script to run the `bluebuild` program with logging and notifying on build failures
+
* systemd service and systemd timer to run the Bash script on a schedule
+
* Cosign package installed on the build host
+
+
The container registry is configured to allow pushing without authentication. I don't need to worry about authentication because it is not open to the public internet. The `bluebuild build` command is simply supplied with the registry URL on my Tailnet.
+
+
Here is the Bash script I wrote to build Bazzite and Bluefin images and push them to the container registry:
+
+
```bash
+
#!/usr/bin/env bash
+
+
set -x
+
+
DATE=$(date '+%Y%m%d_%H%M%S')
+
LOGFILE="${HOME}/bluebuild-logs/${DATE}.log"
+
NTFY_SERVER="https://nas-aux.carp-wyvern.ts.net"
+
+
if [ ! -d "${HOME}/bluebuild-logs" ]; then
+
mkdir -p "${HOME}/bluebuild-logs"
+
fi
+
+
notify_fail() {
+
curl \
+
-H prio:urgent \
+
-H tags:warning \
+
-d "${1}: failed to build. See logs for details." \
+
"${NTFY_SERVER}/bluebuild"
+
}
+
+
print_header() {
+
echo "===================================================================="
+
echo "Start build of ${1}"
+
echo "Date: $(date '+%Y-%m-%d %H:%M:%S')"
+
echo "Commit: $(git log --oneline --no-decorate -n 1)"
+
echo "===================================================================="
+
}
+
+
print_footer() {
+
echo "===================================================================="
+
echo "End build of ${1}"
+
echo "Time elapsed: ${2}"
+
}
+
+
if [ ! -f "$(pwd)/cosign.key" ]; then
+
echo "cosign.key not found. Copying it from backup."
+
cp -fv "${HOME}/.cosign.key" "$(pwd)/cosign.key"
+
fi
+
+
for recipe in $(/bin/ls ./recipes/recipe-*.yml); do
+
print_header "$(basename -s .yml "$recipe")" >>"$LOGFILE"
+
start_time=$(date '+%s')
+
if ! bluebuild build \
+
-p \
+
--registry aux-remote.carp-wyvern.ts.net \
+
-B docker \
+
-S cosign \
+
"${recipe}" >>"$LOGFILE" 2>&1; then
+
notify_fail "$(basename -s .yml "$recipe")"
+
fi
+
end_time=$(date '+%s')
+
runtime=$((end_time - start_time))
+
time_elapsed=$(date -d @$runtime -u '+%H:%M:%S')
+
print_footer "$(basename -s .yml "$recipe")" "$time_elapsed" >>"$LOGFILE"
+
done
+
+
# vim: ts=4 sts=4 sw=4 et ai ft=bash
+
```
+
+
Source: <https://tildegit.org/hyperreal/bluebuild-hyperreal>
+
+
This script is then run with a systemd service and timer every day at 01:00 (CST). In terms of results, it is very similar to running it in a CI/CD pipeline. Each recipe is slated to run, and if one fails, a notification is sent to my ntfy server (also on my Tailnet), and the script continues to build the next recipe. Build output is redirected to logfiles. Everything is run as an unprivileged user from the repo's root as the working directory.
+
+
`git pull` is run by systemd before the execution of the script, so when updates are pushed to the repo, they are reflected in the next scheduled build. If I need to build them immediately, I can just run `systemctl --user start bluebuild_build.service` manually to trigger a build. Nothing in the script changes the state of the git repository during the build process, so each run will be ensured a clean git repo.
+
+
So, yeah, that's it. I think it's kinda neat.
+15
http/content/posts/2025-10-12-cachyos-as-my-daily-driver.md
···
+
+++
+
title = 'CachyOS as my daily driver'
+
date = 2025-10-12 01:07:24
+
tags = ["cachyos", "archbtw", "gamingonlinux", "daily-driver"]
+
+++
+
+
So I'm using [CachyOS](https://cachyos.org/) with KDE Plasma. I guess cutting-edge is tolerable as long as there's an efficient backup and rollback mechanism. Limine and Snapper make this super convenient. It is configured to take snapshots hourly, daily, and whenever pacman installs packages. I'm using a Btrfs filesystem with LUKS encryption. Limine is a boot manager that allows you to select snapshots to boot into from the boot menu.
+
+
I can confirm the OS is "blazingly fast". CachyOS also provides tooling for setting up and optimizing gaming on Linux, which is nice. Since it is based on Arch Linux, I have access to Arch Linux package repositories, including the AUR. This means I don't need Linuxbrew. I also have my usual Flatpaks.
+
+
It's also nice to be back on a normal, mutable filesystem and not have to use Distrobox. Though, to be fair, that was only a minor inconvenience on Bazzite and I got used to it pretty quickly to where it didn't get in the way. But still, it's nice to not have to do that.
+
+
I did not really plan this. It just kinda happened today. But I look forward to exploring CachyOS as a daily driver, for a while at least.
+
+
![cachyos-fastfetch](/images/cachyos-fastfetch.png)
+17
http/content/posts/2025-10-19-feelings-on-immutable-atomic-distros.md
···
+
+++
+
title = 'Feelings on immutable atomic distros'
+
date = 2025-10-19 22:37:35
+
tags = ["immutable", "atomic", "fedora", "cachyos", "corporate-influence"]
+
+++
+
+
I'm currently working on a project to get Bazzite features on a non-atomic Fedora KDE Plasma installation. At the moment, it's a work-in-progress justfile. I intend to test it out on a Fedora virtual machine.
+
+
But, *sigh*.
+
+
I'm still kind of torn between this project and CachyOS. Everything just works the way I want on CachyOS. There is no hard reason for me to use Fedora. The only thing inspiring me to do this that I'm just used to and like the Fedora ecosystem.
+
+
I don't want to use Bazzite anymore -- I just don't like the restrictiveness of the atomic/immutable filesystem. It was a moderate burden that I tolerated for a few months, but it gets in the way a lot.
+
+
Sure, there are ways to do the things I want in atomic/immutable distros, but it tends to require some convoluted hack with containers and CI workflows and trial and error that I'd prefer not to spend time on. I feel like in some ways it's a *just nerd harder* thing, for a sense of accomplishment for doing something hard that didn't really need doing in the first place. It feels like building a [Rube Goldberg machine](https://en.wikipedia.org/wiki/Rube_Goldberg_machine). Whereas all it takes on a normal filesystem is a single command or script that, for example, changes something in `/usr/share`.
+
+
I can't say whether immutable/atomic distros are "the future of Linux" in the sense that non-immutable distros will "die out" eventually. They clearly have a strong foothold in the wider Linux ecosystem, so they will be around for a long time. In that sense, they are a big *part* of the future of Linux. My fear is that, with enough backing from corporate sponsors and the consequent momentum/pressure this puts on other distros, immutable distros might eventually become the de facto standard for Linux, and render the non-immutable distros niche. But this fear is exactly that, and doesn't necessarily coincide with reality. There are strong communities behind the likes of Debian, Arch Linux, FreeBSD, [*et al*](https://wiki.hyperreal.coffee/wiki/Resources:Community-driven_FOSS_distros), which tend to push back against corporate influence.
+18
http/content/posts/2025-10-20-ideas-for-setting-up-vanilla-fedora-for-gaming.md
···
+
+++
+
title = 'Ideas for setting up vanilla Fedora for gaming'
+
date = 2025-10-20 15:46:10
+
tags = ["fedora", "gaming"]
+
+++
+
+
So I've setup regular Fedora KDE Plasma for gaming on my machine, with several third-party repos to install the graphics drivers, gaming, and multimedia stuff. I'm also running the Bazzite kernel.
+
+
Instead of making a justfile, I think it would be better if I wrote up a blog post on how to get this setup on a vanilla Fedora. This way, people reading it are in full control of all the commands that need to run, the repositories that need to be configured, and the Bazzite kernel to install.
+
+
The tricky part, and a problem for me to solve, is keeping the Bazzite kernel up to date with each new release. I figure I can host a public yum repository to store the packages. I can write a script that does the following:
+
+
- The current kernel version number will be stored in a file, e.g., `/etc/current_kernel_version` on the yum repo host machine.
+
- Check for the latest kernel version in the bazzite-org/kernel-bazzite releases.
+
- Compare this version to the current.
+
- If it's newer, download the newer kernels from the bazzite-org/kernel-bazzite repo releases and move them into the yum repo.
+
+
Then when a new release is available, it can be upgraded to with `dnf update`. I have to figure out a way to make it so that it is prioritized over the upstream Fedora kernel.
+20
http/content/posts/2025-10-28-homelab-update-v20251028.md
···
+
+++
+
title = 'Homelab update v20251028'
+
date = 2025-10-28 10:16:08
+
tags = ["homelab", "vps", "selfhosting", "nas", "fedora", "debian"]
+
+++
+
+
My homelab previously consisted of the following machines:
+
+
* Orange Pi 5+ running Ubuntu 24.04, serving as a centralized monitoring station with Prometheus, Grafana, Prometheus exporters for qbittorrent and my Tapo TP-Link smartplugs, and syslog-ng forwarding.
+
* Orange Pi 5+ running DietPi, serving FreshRSS, Nextcloud, Blocky DNS proxy with Unbound recursive DNS resolver.
+
* System76 Meerkat (meer7) running Debian 13, serving my public web content, including my website and other public-facing web services. I had port forwarding enabled in my router to this machine.
+
* System76 Thelio Major running FreeBSD 14.3, serving as a NAS.
+
+
I've rearranged, cleaned up, simplified, and repurposed the first three. I'm no longer port forwarding through my router.
+
+
My public stuff is on a Debian 13 VPS from netcup.de that resides in Manassas, Virginia, USA. From there, it can benefit from higher availability and uptime, easier snapshotting and backup of the entire VPS, IPv6, and it closes off an attack vector on my home network.
+
+
Since I use [Murena Workspace](https://murena.com/workspace/) for Nextcloud and other cloud stuff, which integrates nicely with /e/os on my phone, I no longer need to self-host Nextcloud. It is therefore superfluous to have the DietPi machine running. I can just consolidate the Blocky DNS proxy and FreshRSS into the centralized monitoring machine. However, since my System76 Meerkat is now free, I'd prefer to use it for these tasks instead as it is far more powerful. This means I can reduce four machines into two, namely the Orange Pi 5+ machines will be laid off and the Meerkat will replace them. Sad for the Orange Pi 5+ devices, but they're just machines without feelings, families, or survival needs, so they'll be fine if a bit dusty.
+
+
As it turns out, [Fedora 43](https://getfedora.org) was just released today. So I'm going to install Fedora 43 Server on the Meerkat.
+21
http/content/posts/2025-10-30-homelab-update-v20251030.md
···
+
+++
+
title = 'Homelab update v20251030'
+
date = 2025-10-30 23:18:32
+
tags = ["homelab", "bazzite", "sysadmin", "gaming", "cachyos"]
+
+++
+
+
Thelio Major is now running bazzite:nvidia. Just regular Bazzite; no custom modifications or builds. I don't intend to use it as a regular workstation, so no personalized software is installed. Just Steam, Lutris, MangoJuice, and a few flatpaks. I'm using the Firefox flatpak with sync enabled for minimally viable browsing. So it's basically like a glorified gaming console. I'm using the GSYNC monitor for this machine. It is configured to go to sleep after 60 minutes of idleness.
+
+
Meerkat (meer9) is now my main workstation, with CachyOS KDE Plasma. I've also decided to run homelab monitoring stuff like Ntfy, Prometheus, Grafana, Loki, and Promtail with syslog-ng forwarding on it. I don't quite see a sufficient reason to keep this monitoring stack separate from my workstation. I do everything there anyway, so the services might as well run on localhost. I can still connect to the Grafana dashboard over Tailscale from my laptop.
+
+
I played [Prey](https://en.wikipedia.org/wiki/Prey_(2017_video_game)) for a couple hours on Bazzite, and somehow the performance of the game felt more efficient than it did on CachyOS. I don't know why, but it's alright by me.
+
+
On Bazzite, I also have my Nextcloud via Murena Workspace account accessible on it with the Nextcloud desktop client flatpak. Most of my Steam games store saved games in the Steam Cloud, but GOG stores everything under `~/Gaming/gog/`. Lutris allows using the native system paths for some games. Like Dishonored stores saved games and settings under `~\Documents\My Games` on Windows. The Linux XDG equivalent would be `~/Documents`, which for me is a symbolic link to `~/Nextcloud/Documents`, so that stuff is synced with Nextcloud. In contrast, Prey stores saved games under `~/Games/gog/prey/drive_c/Users/jas/Saved Games/Arkane Studios/...`. For now I just rsynced the saved games there, but I have to figure out an efficient way to sync that directory on Nextcloud. Maybe if I keep the actual files under `~/Nextcloud/Documents/Saved Games` and create a symlink to that directory from `~/Games/gog/prey/drive_c/Users/jas/Saved Games`. Now that I think of it, I recall there being a program on GitHub called [GameImage](https://github.com/ruanformigoni/gameimage) that might provide a more efficient way to keep gaming stuff synced on Linux. I can't just sync `~/Games` on Nextcloud because Lutris downloads and stores the entire game files there, roughly more than 100 GB of data with the games I currently have installed. Not something I want to sync over Nextcloud lol.
+
+
Anyway I'm pretty satisfied with this setup.
+
+
In other news, my NAS has to remain shut down until we figure out what is wrong with our house's electrical wiring. My NAS is the most consistently power-hungry machine in my homelab, so it will be good to keep it off until we fix whatever needs fixing. My parents' electrician friend is coming this weekend to see what's wrong. Last week a circuit breaker shorted out, which powers stuff in our garage and outside the house. The wiring in our house is pretty old, and probably wasn't setup to handle digital age power demands. I'd like for my parents to consider getting solar panels, but that's too liberal-coded for them and they hastily dismiss the idea without a second thought. *We don't need no goddamn hippie solar panels.*
+
+
My bedroom is pretty quiet now.
+
+
+17
http/content/posts/2025-11-27-hot-take-on-vivaldi-browser.md
···
+
+++
+
title = 'Hot take on Vivaldi browser'
+
date = 2025-11-27 18:05:13
+
tags = ["web-browsers", "mozilla", "firefox", "vivaldi", "open-source"]
+
+++
+
+
So I installed Vivaldi to use Netflix for Stranger Things 5, and holy crap. It's like the KDE of browsers in terms of appearance and configurability.
+
+
It's such a shame that it's partly proprietary. But I don't know. It's tempting for me to be open-minded about using it.
+
+
* 92% of the code base is open source from Chromium.
+
* 3% is open source from Vivaldi.
+
* 5% is proprietary from Vivaldi, which is mostly the UI stuff.
+
+
They've also made a public commitment to not integrating AI into their browser. This gives them points for trustworthiness and putting the user above AI hype and profit.
+
+
So... I'm not usually in the habit of giving hot takes on software, but I'm kind of thinking that despite its 5% proprietary code, and in light of Mozilla's terribleness lately, it's ethically and technically superior to Firefox.
+13
http/content/posts/2025-11-27-interesting-episode-of-late-night-linux-podcast.md
···
+
+++
+
title = 'Interesting episode of Late Night Linux podcast'
+
date = 2025-11-27 17:50:48
+
tags = ["linux", "ubuntu", "mark-shuttleworth", "small-things", "iot", "distros"]
+
+++
+
+
Yesterday I listened to Late Night Linux podcast episode 358, where the hosts were at a recent Ubuntu summit and they got to interview Mark Shuttleworth.
+
+
A lot of what Shuttleworth said resonated with me -- he mentioned he's fascinated by the small things self-hosting and IoT stuff. He also discussed the merits of Snap packages, which made me less hostile to the fact that Ubuntu prioritizes them over regular .deb packages.
+
+
Shuttleworth seems like a pretty cool guy. Hopefully he stays that way.
+
+
Another thing that resonated with me in the podcast is that the hosts talk about how the big players in the FOSS ecosystem -- Ubuntu/Canonical, Fedora/Red Hat, Suse/Novell -- all raise the tide for the smaller community-oriented distros and projects. So it's like a symbiotic relationship in that regard. It's not so much a zero-sum game for distros, even though there is some nominal level of competition among them.
+56
http/content/posts/2025-11-27-unexpected-legacy-of-timothy-leary.md
···
+
+++
+
title = 'An unexpected legacy of Timothy Leary'
+
date = 2025-11-27 18:09:39
+
tags = ["timothy-leary", "psychedelics", "psychology", "counter-culture"]
+
+++
+
+
I don't condone the use of psychedelics. I've never tried them myself either. But it's difficult for me not to be in awe of the life Timothy Leary led.
+
+
I never knew much about him other than that he developed LSD, and I suspect that's what most people think of when they hear his name. There is quite a legacy behind the person.
+
+
The following text is quoted from the Facebook page This Day in History, with my own paragraph spacing added.
+
+
<https://www.facebook.com/share/p/16jkn5KcEP/>
+
+
> Timothy Leary arrived at California Men's Colony prison in 1970 facing twenty years behind bars. He was fifty years old, a former Harvard psychologist turned counterculture icon, sentenced for marijuana possession in an era when the establishment treated drug advocacy as existential threat. Prison officials processed him like any other inmate: fingerprints, prison blues, a psychological evaluation to determine security placement.
+
Then they handed him the test.
+
+
> Leary looked at the questions and recognized his own work. Years earlier, during his respectable academic career, he'd developed the Leary Interpersonal Behavior Inventory—a personality assessment designed to evaluate how people relate to authority, handle stress, and respond to institutional control. Now the same system he'd created was being used to classify him.
+
+
> He filled out the questionnaire in under ten minutes, deliberately shaping his answers to present exactly what the evaluators wanted to see: a middle-aged man with no fight left, interested in gardening and forestry, compliant, unlikely to cause trouble. The results placed him in minimum security with an assignment tending the prison gardens.
+
Leary had just manipulated his own psychological test to engineer the conditions for his escape.
+
+
> He wasn't always a rebel. Timothy Leary started as an establishment academic, exactly the kind of psychologist Harvard hired in 1959 expecting orderly research and publishable papers. He'd earned his PhD from Berkeley, directed psychiatric research at Kaiser Foundation Hospital, published respected work on personality assessment. His career trajectory pointed toward tenure and professional respectability.
+
+
> Then he went to Mexico in the summer of 1960 and tried psilocybin mushrooms.
+
+
> The experience didn't just alter his consciousness—it altered his understanding of what psychology could be. He returned to Harvard convinced that psychedelic compounds offered therapeutic potential that traditional psychiatry couldn't match. He started the Harvard Psilocybin Project, conducting research with graduate students, prisoners, and intellectuals. Subjects included Allen Ginsberg, Jack Kerouac, and religious scholars. They took controlled doses, wrote detailed reports, participated in therapeutic sessions.
+
> The research was legitimate. The methodology was sound. But the implications terrified administrators who saw a professor encouraging students to chemically alter their perception of reality. Colleagues whispered about loss of scientific objectivity. Newspapers sensationalized the experiments. By 1963, Harvard decided Leary had become a liability. They fired him, officially for leaving campus during the semester without authorization, but everyone understood the real reason: he'd stopped being a respectable psychologist and become something the institution couldn't control.
+
> Leary saw the dismissal as liberation. Freed from academic constraints, he became the public face of psychedelic exploration. He traveled, lectured, founded research centers first in Mexico then in Millbrook, New York. He coined phrases that became counterculture mantras: "Turn on, tune in, drop out." Critics heard nihilism. Followers heard permission to question inherited assumptions about consciousness, authority, identity.
+
+
> The establishment heard threat.
+
+
> In 1965, authorities arrested him at the Texas-Mexico border for marijuana possession. Prosecutors pushed for harsh sentencing, treating him as a symbol of cultural decay that needed crushing. Leary fought back through the legal system. He appealed all the way to the Supreme Court and won—not through cultural arguments about drug policy, but through constitutional law. The Court ruled in Leary v. United States that the marijuana tax law he'd been charged under violated the Fifth Amendment's protection against self-incrimination.
+
+
> But victories in court didn't stop the targeting. In 1968, police arrested him again in Laguna Beach. Combined with his previous offense, he now faced twenty years in prison. This time, there would be no Supreme Court rescue.
+
+
> Once transferred to the minimum-security facility at California Men's Colony, Leary began planning the impossible. The Weather Underground, a radical leftist organization, agreed to help for $25,000 paid by The Brotherhood of Eternal Love, a group of psychedelic advocates. They smuggled him tools and coordinated logistics for a nighttime escape.
+
+
> On September 13, 1970, Leary climbed onto a prison rooftop, pulled himself up a telephone pole, and moved hand-over-hand along a cable spanning the prison yard—over barbed wire, over security perimeter, beyond what guards thought anyone would attempt. He dropped to the road outside where Weather Underground operatives waited.
+
+
> He left behind his prison clothes and a note that reportedly read: "I declare myself free."
+
> The escape became international news. Prison officials found themselves explaining how one of America's most recognizable prisoners had simply climbed out while they watched. Leary fled to Algeria, where he stayed briefly with Black Panther Eldridge Cleaver's government-in-exile. Then Switzerland. Then Afghanistan. He traveled under assumed names, gave lectures in disguise, wrote manifestos. Intelligence agencies tracked him across continents. He became a fugitive philosophy professor.
+
+
> The chase ended in 1973 when Afghan authorities, working with American intelligence, arrested him in Kabul. He returned to the United States in handcuffs. Newspapers framed it as law finally catching up with chaos. Leary framed it differently. In interviews, he emphasized that the real threat wasn't psychedelics—it was the questions they made people ask about who controlled their consciousness and why.
+
+
> He served additional years in prison, during which he wrote extensively about neurology, consciousness, and human potential. When finally released in 1976, he didn't retreat into quiet obscurity. Instead, he evolved. He lectured on cyberculture before most people understood what the internet would become. He talked about space colonization, artificial intelligence, consciousness expansion through technology. He refused to become a museum piece from the 1960s, choosing instead to adapt his message to new frontiers.
+
+
> Critics dismissed him as a relic trying to stay relevant. But Leary understood something fundamental: the questions he'd been asking—about autonomy, consciousness, institutional control, who decides what's acceptable to think and feel—didn't stop being important just because the decade changed.
+
+
> Near the end of his life in the 1990s, still lecturing and writing, someone asked why he'd spent decades provoking institutions that imprisoned him, surveilled him, tried to silence him. Why keep pushing when the cost had been so high?
+
+
> Leary's answer captured everything about his approach to authority, consciousness, and control: "The moment you stop questioning, somebody else starts answering for you."
+
+
> Because that was the real story of Timothy Leary—not the drugs, not the slogans, not the escapes. It was his refusal to let anyone else define the boundaries of acceptable thought. He'd figured out how to game a psychological test because he understood how institutions try to categorize and control people. He'd escaped from prison because he understood that the only real prison is the one you accept. He'd kept questioning authority because he understood that the alternative wasn't safety—it was surrender.
+
+
> The establishment called him dangerous. Leary called them predictable. And in 1970, when they handed him his own test thinking they'd finally contained him, he proved exactly how predictable they were.
+13
http/content/recipes.md
···
+
+++
+
title = "Recipes"
+
menu = "recipes"
+
layout = "page"
+
[params]
+
author = "hyperreal"
+
+++
+
+
[Beef and red lentil chili](beef-and-red-lentil-chili.md)
+
[Ground beef vegetable soup with gnocchi](ground-beef-vegetable-soup-with-gnocchi.md)
+
[Italian pastina soup](italian-pastina-soup.md)
+
[Keto no-noodle chicken cabbage soup](keto-no-noodle-chicken-cabbage-soup.md)
+
[White bean soup with pasta](white-bean-soup-with-pasta.md)
+36
http/content/resources.md
···
+
+++
+
title = "Resources"
+
menu = "resources"
+
layout = "page"
+
[params]
+
author = "hyperreal"
+
+++
+
+
[Community-driven FOSS distros](community-driven-distros.md)
+
[My Asciinema profile](https://asciinema.org/~hyperreal)
+
[My Bookmarks](https://bookmarks.hyperreal.coffee)
+
[My GitHub profile](https://github.com/hyperreal64)
+
[My Keyoxide profile](https://keyoxide.org/hyperreal%40moonshadow.dev)
+
[My code on Tildegit.org](https://tildegit.org/hyperreal)
+
[My digital archive collection](https://archives.hyperreal.coffee)
+
+
## Podcasts I listen to
+
+
[BSD Now](https://www.bsdnow.tv/)
+
[Destination Linux](https://tuxdigital.com/podcasts/destination-linux/)
+
[Linux Out Loud](https://dlnxtend.com/)
+
[Linux & Open Source News](https://podcast.thelinuxexp.com/@tlenewspodcast)
+
[Security Now](https://twit.tv/shows/security-now)
+
+
## Public web services I host
+
+
These are mainly alternative, FOSS, ad-free, minimalistic front-ends to various websites and services.
+
+
[AnonymousOverflow](https://anonoverflow.hyperreal.coffee)
+
[BreezeWiki](https://breezewiki.hyperreal.coffee)
+
[Dumb](https://dumb.hyperreal.coffee)
+
[Lingva Translate](https://lingva.hyperreal.coffee)
+
[Mirror of Anna's Archive torrents](https://annas-archive.hyperreal.coffee)
+
[PrivateBin](https://pb.hyperreal.coffee)
+
[SearXNG](https://searxng.hyperreal.coffee)
+
[txtdot](https://txtdot.hyperreal.coffee)
+29
http/content/vps-cloud-servers.md
···
+
+++
+
title = "VPS and cloud servers"
+
layout = "page"
+
date = 2025-11-22T06:27:56-06:00
+
+++
+
+
## netcup.de: hyperreal
+
+
* Machine: VPS 1000 G11 iv 12M MNZ
+
* CPU: AMD EPYC-Genoa (4-core) @ 2.25 GHz
+
* RAM: 8 GB
+
* HDD: 256 GB SSD
+
* Networking: 2.5 GB/s uplink
+
* Monthly traffic: 2 TB per 24 hours, otherwise 200 MB/s
+
* OS: Debian 13
+
* Price: €5.75 = $6.65 per month
+
+
### Notes
+
+
This is my main public-facing server. It hosts my website, blog, and Gemini capsule. Additionally, it hosts the following alternative front-end web services:
+
+
* Anonymous Overflow : alternative front-end to Stack Overflow)
+
* BreezeWiki : alternative front-end to Fandom.com wikis
+
* Dumb : alternative front-end to Genius lyrics
+
* Lingva Translate : language translation service
+
* PrivateBin : Private pastebin
+
* SearXNG : privacy-focused meta-search engine
+
* txtdot : render web pages as text
+
* Anna's Archive torrent mirror : A mirror site for Anna's Archive .torrent files.
+36
http/content/white-bean-soup-with-pasta.md
···
+
+++
+
title = "White bean soup with pasta"
+
layout = "page"
+
date = 2025-10-24T12:30:29-05:00
+
+++
+
+
Source: <https://www.eatingwell.com/recipe/7923697/white-bean-soup-with-pasta/>
+
+
![White bean soup with pasta](/images/white-bean-soup-with-pasta.jpg)
+
+
## Ingredients
+
+
- 1 tbsp of extra-virgin olive oil
+
- 1.5 cups of frozen mirepoix (diced onion, celery, and carrot)
+
- 2 cloves of garlic, minced
+
- 1 tsp of Italian seasoning
+
- 1 tsp of salt
+
- 0.25 tsp of crushed red pepper
+
- 0.25 tsp of ground black pepper
+
- 1 (28 oz) can of no-salt-added diced tomatoes
+
- 2 cups of low-sodium chicken broth
+
- 1 (15 oz) can of low-sodium cannellini beans, rinsed
+
- 8 ounces of small whole-wheat pasta, such as elbows
+
- 1.5 cups of frozen cut-leaf spinach
+
- 4 tbsp of grated Parmesan cheese
+
+
## Instructions
+
+
- Put a large saucepan of water on to boil.
+
- Heat 1 tbsp of olive oil in a a large pot over medium-high heat. Add 1.5 cups of frozen mirepoix and cook, stirring until softened. (~3 minutes)
+
- Add 2 cloves of minced garlic, 1 tsp of Italian seasoning, 1 tsp of salt, 0.25 tsp of crushed red pepper, and 0.25 tsp of ground black pepper, and cook, stirring until fragrant. (~1 minute)
+
- Add 1 can of diced tomatoes and their juices, 2 cups of chicken broth, and 1 can of beans. Bring to a boil.
+
- Reduce heat to maintain a lively simmer. Cover and cook, stirring occasionally, until tomatoes begin to break down. (~10 minutes)
+
- Meanwhile, cook 8 ounces of pasta in the boiling water for 1 minute less than the package directions. Drain pasta.
+
- Stir 1.5 cups of spinach into the soup. Stir in the pasta just before serving.
+
- Serve topped with 4 tbsp of Parmesan cheese.
+75
http/hugo.toml
···
+
baseURL = "https://hyperreal.coffee/"
+
theme = "hugo-bearcub"
+
title = "hyperreal's nook of the interwebz"
+
copyright = "Jeffrey Serio (CC BY-SA 4.0)"
+
defaultContentLanguage = "en"
+
+
enableRobotsTXT = true
+
+
[markup]
+
[markup.highlight]
+
lineNos = false
+
lineNumbersInTable = false
+
noClasses = true
+
style = "catppuccin-mocha"
+
tabWidth = 4
+
wrapperClass = "highlight"
+
[markup.goldmark.renderer]
+
hardWraps = true
+
unsafe = true
+
+
[languages]
+
[languages.en]
+
title = "hyperreal.coffee"
+
languageName = "en-US 🇺🇸"
+
LanguageCode = "en-US"
+
contentDir = "content"
+
[languages.en.params]
+
madeWith = "Made with my fork of [Bear Cub](https://codeberg.org/hyperreal/hugo-bearcub)"
+
+
[params]
+
description = "The website of me. I'm hyperreal."
+
favicon = "favicon.png"
+
title = "hyperreal.coffee"
+
dateFormat = "2006-01-02"
+
themeStyle = "catppuccin"
+
generateSocialCard = true
+
+
[params.social]
+
mastodon = "https://tilde.zone/@hyperreal"
+
+
[params.author]
+
name = "Jeffrey Serio"
+
email = "hyperreal@moonshadow.dev"
+
+
[menu]
+
[[menu.main]]
+
identifier = "posts"
+
name = "Posts"
+
url = "/posts"
+
weight = 10
+
[[menu.main]]
+
identifier = "about"
+
name = "About"
+
url = "/about"
+
weight = 20
+
[[menu.main]]
+
identifier = "computing"
+
name = "Computing"
+
url = "/computing"
+
weight = 30
+
[[menu.main]]
+
identifier = "recipes"
+
name = "Recipes"
+
url = "/recipes"
+
weight = 40
+
[[menu.main]]
+
identifier = "resources"
+
name = "Resources"
+
url = "/resources"
+
weight = 50
+
[[menu.main]]
+
identifier = "techne"
+
name = "Techne"
+
url = "https://techne.hyperreal.coffee"
+
weight = 60
http/static/88x31/32BitCafe.PNG

This is a binary file and will not be displayed.

http/static/88x31/512kb_green.gif

This is a binary file and will not be displayed.

http/static/88x31/AI.GIF

This is a binary file and will not be displayed.

http/static/88x31/AaronSwartz.png

This is a binary file and will not be displayed.

http/static/88x31/AntiNFT.gif

This is a binary file and will not be displayed.

http/static/88x31/Autism.jpg

This is a binary file and will not be displayed.

http/static/88x31/AutisticPride.png

This is a binary file and will not be displayed.

http/static/88x31/BLM.png

This is a binary file and will not be displayed.

http/static/88x31/COVIDNotOver.png

This is a binary file and will not be displayed.

http/static/88x31/Coffee.gif

This is a binary file and will not be displayed.

http/static/88x31/ComeAsYouAre.GIF

This is a binary file and will not be displayed.

http/static/88x31/DBD.gif

This is a binary file and will not be displayed.

http/static/88x31/Debian.gif

This is a binary file and will not be displayed.

http/static/88x31/Ducks.png

This is a binary file and will not be displayed.

http/static/88x31/Emulate.png

This is a binary file and will not be displayed.

http/static/88x31/Encrypt.GIF

This is a binary file and will not be displayed.

http/static/88x31/FediRing.gif

This is a binary file and will not be displayed.

http/static/88x31/Fediverse.png

This is a binary file and will not be displayed.

http/static/88x31/Fight.gif

This is a binary file and will not be displayed.

http/static/88x31/IA.png

This is a binary file and will not be displayed.

http/static/88x31/ISIProgressPride.png

This is a binary file and will not be displayed.

http/static/88x31/IndiePocalypse.png

This is a binary file and will not be displayed.

http/static/88x31/IndieWeb.gif

This is a binary file and will not be displayed.

http/static/88x31/Interop.gif

This is a binary file and will not be displayed.

http/static/88x31/KDE.gif

This is a binary file and will not be displayed.

http/static/88x31/LTJM.gif

This is a binary file and will not be displayed.

http/static/88x31/Lemmy.png

This is a binary file and will not be displayed.

http/static/88x31/MOULEWORLD.gif

This is a binary file and will not be displayed.

http/static/88x31/MaskNow.png

This is a binary file and will not be displayed.

http/static/88x31/NoDoc.png

This is a binary file and will not be displayed.

http/static/88x31/NoTERFs.GIF

This is a binary file and will not be displayed.

http/static/88x31/NoWeb3.gif

This is a binary file and will not be displayed.

http/static/88x31/Python.GIF

This is a binary file and will not be displayed.

http/static/88x31/Repair.gif

This is a binary file and will not be displayed.

http/static/88x31/SM64Hacks.png

This is a binary file and will not be displayed.

http/static/88x31/SM64ROMHacks.png

This is a binary file and will not be displayed.

http/static/88x31/TOR.GIF

This is a binary file and will not be displayed.

http/static/88x31/TransRightsNow.gif

This is a binary file and will not be displayed.

http/static/88x31/WikiLeaks.PNG

This is a binary file and will not be displayed.

http/static/88x31/Wikipedia.gif

This is a binary file and will not be displayed.

http/static/88x31/Yankovic.PNG

This is a binary file and will not be displayed.

http/static/88x31/archlinux.gif

This is a binary file and will not be displayed.

http/static/88x31/artix.png

This is a binary file and will not be displayed.

http/static/88x31/hellnet_8831_buttons_nodupes.zip

This is a binary file and will not be displayed.

http/static/88x31/internet-archive.gif

This is a binary file and will not be displayed.

http/static/88x31/lisp_alien_drew.gif

This is a binary file and will not be displayed.

http/static/88x31/made_with_emacs.png

This is a binary file and will not be displayed.

http/static/88x31/maia.crimew.gay.png

This is a binary file and will not be displayed.

http/static/88x31/neovim.gif

This is a binary file and will not be displayed.

http/static/88x31/netbsd.gif

This is a binary file and will not be displayed.

http/static/88x31/netcup.gif

This is a binary file and will not be displayed.

http/static/88x31/oatzone.gif

This is a binary file and will not be displayed.

http/static/88x31/power-button_20000304.gif

This is a binary file and will not be displayed.

http/static/88x31/tilde_club.gif

This is a binary file and will not be displayed.

http/static/android-chrome-192x192.png

This is a binary file and will not be displayed.

http/static/android-chrome-512x512.png

This is a binary file and will not be displayed.

http/static/apple-touch-icon.png

This is a binary file and will not be displayed.

http/static/favicon.ico

This is a binary file and will not be displayed.

http/static/favicon.png

This is a binary file and will not be displayed.

+92
http/static/hyperreal.pgp.asc
···
+
-----BEGIN PGP PUBLIC KEY BLOCK-----
+
+
mDMEZ5gVQBYJKwYBBAHaRw8BAQdAhbX7GOQsr3ncsCxsZT7IDUmsbSb6JJGiYoHf
+
szyrxwm0KEplZmZyZXkgU2VyaW8gPGh5cGVycmVhbEBtb29uc2hhZG93LmRldj6J
+
A5QEExYIAzwCGwMFCQPCZwAFCwkIBwIGFQoJCAsCBBYCAwECHgECF4AWIQTmqurJ
+
uvA6vgsIYfb9vrfSFNW77wUCaNnHbU0UgAAAAAAQADRwcm9vZkBhcmlhZG5lLmlk
+
b3BlbnBncDRmcHI6RTZBQUVBQzlCQUYwM0FCRTBCMDg2MUY2RkRCRUI3RDIxNEQ1
+
QkJFRjYUgAAAAAAQAB1wcm9vZkBhcmlhZG5lLmlkaHR0cHM6Ly90aWxkZS56b25l
+
L0BoeXBlcnJlYWw2FIAAAAAAEAAdcHJvb2ZAYXJpYWRuZS5pZGh0dHBzOi8vZGlz
+
Y29yZC5nZy9EVmQ0ZWFZeUdmXRSAAAAAABAARHByb29mQGFyaWFkbmUuaWRodHRw
+
czovL2dpc3QuZ2l0aHViLmNvbS9oeXBlcnJlYWw2NC9kOGIxM2Q2NDFkNzg3NGVm
+
Y2E3MjExYTE3NzEwZDgxMTQUgAAAAAAQABtwcm9vZkBhcmlhZG5lLmlkZG5zOm1v
+
b25zaGFkb3cuZGV2P3R5cGU9VFhUNhSAAAAAABAAHXByb29mQGFyaWFkbmUuaWRk
+
bnM6aHlwZXJyZWFsLmNvZmZlZT90eXBlPVRYVEYUgAAAAAAQAC1wcm9vZkBhcmlh
+
ZG5lLmlkaHR0cHM6Ly9jb2RlYmVyZy5vcmcvaHlwZXJyZWFsL2tleW94aWRlX3By
+
b29mNxSAAAAAABAAHnByb29mQGFyaWFkbmUuaWRodHRwczovL2xlbW15Lm1sL3Uv
+
aHlwZXJyZWFsNjRlFIAAAAAAEABMcHJvb2ZAYXJpYWRuZS5pZGh0dHBzOi8vYnNr
+
eS5hcHAvcHJvZmlsZS9kaWQ6cGxjOm51YzMzdGhuc2lxemh5dGtsZXlyNWplay9w
+
b3N0LzNsd3dmZ3FhN2xjMnhLFIAAAAAAEAAycHJvb2ZAYXJpYWRuZS5pZGh0dHBz
+
Oi8vdW5pdmVyc2FsLWJsdWUuZGlzY291cnNlLmdyb3VwL3UvaHlwZXJyZWFsRhSA
+
AAAAABAALXByb29mQGFyaWFkbmUuaWRodHRwczovL3RpbGRlZ2l0Lm9yZy9oeXBl
+
cnJlYWwva2V5b3hpZGVfcHJvb2YACgkQ/b630hTVu+/QgAD/bwX17Nuqpj6C9meJ
+
4uT3YiVF+NEEJPjfGfoy5ysrwdMBAKVSAH6n2ZsTH6jZ5BFS+a3jXlsCxP1Zxcj6
+
mMv1pj8HiQNPBBMWCAL3AhsDBQkDwmcABQsJCAcCBhUKCQgLAgQWAgMBAh4BAheA
+
FiEE5qrqybrwOr4LCGH2/b630hTVu+8FAminT95LFIAAAAAAEAAycHJvb2ZAYXJp
+
YWRuZS5pZGh0dHBzOi8vdW5pdmVyc2FsLWJsdWUuZGlzY291cnNlLmdyb3VwL3Uv
+
aHlwZXJyZWFsZRSAAAAAABAATHByb29mQGFyaWFkbmUuaWRodHRwczovL2Jza3ku
+
YXBwL3Byb2ZpbGUvZGlkOnBsYzpudWMzM3RobnNpcXpoeXRrbGV5cjVqZWsvcG9z
+
dC8zbHd3ZmdxYTdsYzJ4NxSAAAAAABAAHnByb29mQGFyaWFkbmUuaWRodHRwczov
+
L2xlbW15Lm1sL3UvaHlwZXJyZWFsNjRGFIAAAAAAEAAtcHJvb2ZAYXJpYWRuZS5p
+
ZGh0dHBzOi8vY29kZWJlcmcub3JnL2h5cGVycmVhbC9rZXlveGlkZV9wcm9vZjYU
+
gAAAAAAQAB1wcm9vZkBhcmlhZG5lLmlkZG5zOmh5cGVycmVhbC5jb2ZmZWU/dHlw
+
ZT1UWFQ0FIAAAAAAEAAbcHJvb2ZAYXJpYWRuZS5pZGRuczptb29uc2hhZG93LmRl
+
dj90eXBlPVRYVF0UgAAAAAAQAERwcm9vZkBhcmlhZG5lLmlkaHR0cHM6Ly9naXN0
+
LmdpdGh1Yi5jb20vaHlwZXJyZWFsNjQvZDhiMTNkNjQxZDc4NzRlZmNhNzIxMWEx
+
NzcxMGQ4MTE2FIAAAAAAEAAdcHJvb2ZAYXJpYWRuZS5pZGh0dHBzOi8vZGlzY29y
+
ZC5nZy9EVmQ0ZWFZeUdmNhSAAAAAABAAHXByb29mQGFyaWFkbmUuaWRodHRwczov
+
L3RpbGRlLnpvbmUvQGh5cGVycmVhbE8UgAAAAAAQADZwcm9vZkBhcmlhZG5lLmlk
+
aHR0cHM6Ly9naXRsYWIuaHlwZXJyZWFsLmNvZmZlZS9oeXBlcnJlYWwvZ2l0bGFi
+
X3Byb29mAAoJEP2+t9IU1bvv9YoA+QHKxpa5HNyuXm5sKpV7oHWRovYRzqV4tu83
+
+Le9K+NnAP9Y+CuQi2V9OdpF4hiP0BGqhAWUkUmcBH4d5eJU+bGABIkDAwQTFggC
+
qwIbAwUJA8JnAAULCQgHAgYVCgkICwIEFgIDAQIeAQIXgBYhBOaq6sm68Dq+Cwhh
+
9v2+t9IU1bvvBQJop06STxSAAAAAABAANnByb29mQGFyaWFkbmUuaWRodHRwczov
+
L2dpdGxhYi5oeXBlcnJlYWwuY29mZmVlL2h5cGVycmVhbC9naXRsYWJfcHJvb2Y2
+
FIAAAAAAEAAdcHJvb2ZAYXJpYWRuZS5pZGh0dHBzOi8vdGlsZGUuem9uZS9AaHlw
+
ZXJyZWFsNhSAAAAAABAAHXByb29mQGFyaWFkbmUuaWRodHRwczovL2Rpc2NvcmQu
+
Z2cvRFZkNGVhWXlHZl0UgAAAAAAQAERwcm9vZkBhcmlhZG5lLmlkaHR0cHM6Ly9n
+
aXN0LmdpdGh1Yi5jb20vaHlwZXJyZWFsNjQvZDhiMTNkNjQxZDc4NzRlZmNhNzIx
+
MWExNzcxMGQ4MTE0FIAAAAAAEAAbcHJvb2ZAYXJpYWRuZS5pZGRuczptb29uc2hh
+
ZG93LmRldj90eXBlPVRYVDYUgAAAAAAQAB1wcm9vZkBhcmlhZG5lLmlkZG5zOmh5
+
cGVycmVhbC5jb2ZmZWU/dHlwZT1UWFRGFIAAAAAAEAAtcHJvb2ZAYXJpYWRuZS5p
+
ZGh0dHBzOi8vY29kZWJlcmcub3JnL2h5cGVycmVhbC9rZXlveGlkZV9wcm9vZjcU
+
gAAAAAAQAB5wcm9vZkBhcmlhZG5lLmlkaHR0cHM6Ly9sZW1teS5tbC91L2h5cGVy
+
cmVhbDY0ZRSAAAAAABAATHByb29mQGFyaWFkbmUuaWRodHRwczovL2Jza3kuYXBw
+
L3Byb2ZpbGUvZGlkOnBsYzpudWMzM3RobnNpcXpoeXRrbGV5cjVqZWsvcG9zdC8z
+
bHd3ZmdxYTdsYzJ4AAoJEP2+t9IU1bvva0kA/2aXND9cX3QKRfVGyAg62lWkNHUr
+
fw4W+kuH8lbd8nsIAP9UaoQG0gtji6xHrxqgtRhEoRrm7EeLU4WXrXI9HnWNA4kC
+
4AQTFggCiAIbAwUJA8JnAAULCQgHAgYVCgkICwIEFgIDAQIeAQIXgBYhBOaq6sm6
+
8Dq+Cwhh9v2+t9IU1bvvBQJop00jTxSAAAAAABAANnByb29mQGFyaWFkbmUuaWRo
+
dHRwczovL2dpdGxhYi5oeXBlcnJlYWwuY29mZmVlL2h5cGVycmVhbC9naXRsYWJf
+
cHJvb2Y2FIAAAAAAEAAdcHJvb2ZAYXJpYWRuZS5pZGh0dHBzOi8vdGlsZGUuem9u
+
ZS9AaHlwZXJyZWFsNhSAAAAAABAAHXByb29mQGFyaWFkbmUuaWRodHRwczovL2Rp
+
c2NvcmQuZ2cvRFZkNGVhWXlHZl0UgAAAAAAQAERwcm9vZkBhcmlhZG5lLmlkaHR0
+
cHM6Ly9naXN0LmdpdGh1Yi5jb20vaHlwZXJyZWFsNjQvZDhiMTNkNjQxZDc4NzRl
+
ZmNhNzIxMWExNzcxMGQ4MTE0FIAAAAAAEAAbcHJvb2ZAYXJpYWRuZS5pZGRuczpt
+
b29uc2hhZG93LmRldj90eXBlPVRYVEIUgAAAAAAQAClwcm9vZkBhcmlhZG5lLmlk
+
aHR0cHM6Ly9ic2t5LmFwcC9wcm9maWxlL2h5cGVycmVhbC5jb2ZmZWU2FIAAAAAA
+
EAAdcHJvb2ZAYXJpYWRuZS5pZGRuczpoeXBlcnJlYWwuY29mZmVlP3R5cGU9VFhU
+
RhSAAAAAABAALXByb29mQGFyaWFkbmUuaWRodHRwczovL2NvZGViZXJnLm9yZy9o
+
eXBlcnJlYWwva2V5b3hpZGVfcHJvb2Y3FIAAAAAAEAAecHJvb2ZAYXJpYWRuZS5p
+
ZGh0dHBzOi8vbGVtbXkubWwvdS9oeXBlcnJlYWw2NAAKCRD9vrfSFNW778xLAP41
+
rYG16Y12UiKpSX+Kja/eKPf0QVStT7sbw0mPgn6LMQEAi0lKcr4PdTi5zUQcg/wr
+
gm9jdSawGsb9J+GOX40R1QOJApAEExYIAjgCGwMFCQPCZwAFCwkIBwIGFQoJCAsC
+
BBYCAwECHgECF4AWIQTmqurJuvA6vgsIYfb9vrfSFNW77wUCaKdL+zcUgAAAAAAQ
+
AB5wcm9vZkBhcmlhZG5lLmlkaHR0cHM6Ly9sZW1teS5tbC91L2h5cGVycmVhbDY0
+
RhSAAAAAABAALXByb29mQGFyaWFkbmUuaWRodHRwczovL2NvZGViZXJnLm9yZy9o
+
eXBlcnJlYWwva2V5b3hpZGVfcHJvb2Y2FIAAAAAAEAAdcHJvb2ZAYXJpYWRuZS5p
+
ZGRuczpoeXBlcnJlYWwuY29mZmVlP3R5cGU9VFhUQhSAAAAAABAAKXByb29mQGFy
+
aWFkbmUuaWRodHRwczovL2Jza3kuYXBwL3Byb2ZpbGUvaHlwZXJyZWFsLmNvZmZl
+
ZTQUgAAAAAAQABtwcm9vZkBhcmlhZG5lLmlkZG5zOm1vb25zaGFkb3cuZGV2P3R5
+
cGU9VFhUXRSAAAAAABAARHByb29mQGFyaWFkbmUuaWRodHRwczovL2dpc3QuZ2l0
+
aHViLmNvbS9oeXBlcnJlYWw2NC9kOGIxM2Q2NDFkNzg3NGVmY2E3MjExYTE3NzEw
+
ZDgxMTYUgAAAAAAQAB1wcm9vZkBhcmlhZG5lLmlkaHR0cHM6Ly9kaXNjb3JkLmdn
+
L0RWZDRlYVl5R2Y2FIAAAAAAEAAdcHJvb2ZAYXJpYWRuZS5pZGh0dHBzOi8vdGls
+
ZGUuem9uZS9AaHlwZXJyZWFsAAoJEP2+t9IU1bvvo60BAJ4z1vYEBjKimvq//qFb
+
lcB9VSnlge8g7zc/0SfO7q+iAQDa4YXtY5FrLvJHXpUCs8OadENLamUhOf7sqSWl
+
OYpIB7g4BGeYFUASCisGAQQBl1UBBQEBB0BheBN/VeHBFksgFUT0knizvK63Zvzl
+
Kc4wTcvu1xnIXAMBCAeIfgQYFggAJhYhBOaq6sm68Dq+Cwhh9v2+t9IU1bvvBQJn
+
mBVAAhsMBQkDwmcAAAoJEP2+t9IU1bvv0IcBAKD2t+NpE9CdZplTuVv1Bd5EwTk6
+
JiSSDsQPzfm6V1p+AQD/OiHZac1PddqNTRpMv+rL9g+ZPXXWaTj0K64XyWZSCw==
+
=DGS2
+
-----END PGP PUBLIC KEY BLOCK-----
http/static/images/cachyos-fastfetch.png

This is a binary file and will not be displayed.

http/static/images/ground-beef-vegetable-soup-with-gnocchi.jpg

This is a binary file and will not be displayed.

http/static/images/italian-pastina-soup.jpg

This is a binary file and will not be displayed.

http/static/images/librewolf-doh-settings.png

This is a binary file and will not be displayed.

http/static/images/mullvad-dns-leak-checker.png

This is a binary file and will not be displayed.

http/static/images/resolvectl-status.png

This is a binary file and will not be displayed.

http/static/images/white-bean-soup-with-pasta.jpg

This is a binary file and will not be displayed.

+1
http/static/logo.svg
···
+
<svg width="24" height="24" viewBox="0 0 2048 1792" xmlns="http://www.w3.org/2000/svg" fill="#f38ba8"><path d="M1728 640q0-80-56-136t-136-56h-64v384h64q80 0 136-56t56-136zm-1664 768h1792q0 106-75 181t-181 75h-1280q-106 0-181-75t-75-181zm1856-768q0 159-112.5 271.5t-271.5 112.5h-64v32q0 92-66 158t-158 66h-704q-92 0-158-66t-66-158v-736q0-26 19-45t45-19h1152q159 0 271.5 112.5t112.5 271.5z"/></svg>
http/static/og-image.png

This is a binary file and will not be displayed.

+32
http/themes/hugo-bearcub/.github/workflows/gh-pages.yml
···
+
name: github pages
+
+
on:
+
push:
+
branches:
+
- main # Set a branch that will trigger a deployment
+
pull_request:
+
+
jobs:
+
deploy:
+
runs-on: ubuntu-22.04
+
steps:
+
- uses: actions/checkout@v3
+
with:
+
submodules: true # Fetch Hugo themes (true OR recursive)
+
fetch-depth: 0 # Fetch all history for .GitInfo and .Lastmod
+
+
- name: Setup Hugo
+
uses: peaceiris/actions-hugo@v3
+
with:
+
hugo-version: 'latest'
+
extended: true
+
+
- name: Build
+
run: hugo --minify --gc --destination ../public --source ./exampleSite --themesDir ../.. --baseURL https://clente.github.io/hugo-bearcub/
+
+
- name: Deploy
+
uses: peaceiris/actions-gh-pages@v4
+
if: github.ref == 'refs/heads/main'
+
with:
+
github_token: ${{ secrets.GITHUB_TOKEN }}
+
publish_dir: ./public
+5
http/themes/hugo-bearcub/.gitignore
···
+
.hugo_build.lock
+
.DS_Store
+
resources/
+
todo.md
+
exampleSite/public/
+21
http/themes/hugo-bearcub/LICENSE
···
+
The MIT License (MIT)
+
+
Copyright (c) 2020 Jan Raasch
+
Copyright (c) 2023 Caio Lente
+
+
Permission is hereby granted, free of charge, to any person obtaining a copy of
+
this software and associated documentation files (the "Software"), to deal in
+
the Software without restriction, including without limitation the rights to
+
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+
the Software, and to permit persons to whom the Software is furnished to do so,
+
subject to the following conditions:
+
+
The above copyright notice and this permission notice shall be included in all
+
copies or substantial portions of the Software.
+
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+245
http/themes/hugo-bearcub/README.md
···
+
# ᕦʕ •ᴥ•ʔᕤ Bear Cub
+
+
[![github pages](https://github.com/clente/hugo-bearcub/actions/workflows/gh-pages.yml/badge.svg)](https://github.com/clente/hugo-bearcub/actions/workflows/gh-pages.yml)
+
[![MIT license](https://img.shields.io/github/license/clente/hugo-bearcub)](https://github.com/clente/hugo-bearcub/blob/main/LICENSE)
+
+
## Overview
+
+
🐻 A lightweight [Hugo](https://gohugo.io/) theme based on [Bear
+
Blog](https://bearblog.dev) and [Hugo Bear
+
Blog](https://github.com/janraasch/hugo-bearblog).
+
+
**Bear Cub** takes care of speed and optimization, so you can focus on writing
+
good content. It is free, multilingual, optimized for search engines,
+
no-nonsense, responsive, light, and fast. Really fast.
+
+
## Installation
+
+
Follow Hugo's [quick start](https://gohugo.io/getting-started/quick-start/) to
+
create an empty website and then clone **Bear Cub** into the themes directory as
+
a [Git submodule](https://git-scm.com/book/en/v2/Git-Tools-Submodules):
+
+
```sh
+
git submodule add https://github.com/clente/hugo-bearcub themes/hugo-bearcub
+
```
+
+
To finish off, append a line to the site configuration file:
+
+
```sh
+
echo 'theme = "hugo-bearcub"' >> hugo.toml
+
```
+
+
## Features
+
+
Like [Bear Blog](https://bearblog.dev), this theme:
+
- Is free and open source
+
- Looks great on any device
+
- Makes tiny (~5kb), optimized, and awesome pages
+
- Has no trackers, ads, or scripts
+
- Automatically generates an RSS feed
+
+
But that's not all! **Bear Cub** is also...
+
+
### Accessible
+
+
**Bear Cub** has a few accessibility upgrades when compared to its predecessors.
+
The color palette has been overhauled to make sure everything is
+
[readable](https://web.dev/color-and-contrast-accessibility/) for users with low
+
vision impairments or color deficiencies, and some interactive elements were
+
made bigger to facilitate [clicking](https://web.dev/accessible-tap-targets/)
+
for users with a motor impairment.
+
+
These small changes mean that **Bear Cub** passes Google's [PageSpeed
+
test](https://pagespeed.web.dev/report?url=https%3A%2F%2Fclente.github.io%2Fhugo-bearcub%2F)
+
with flying colors.
+
+
![PageSpeed score](https://raw.githubusercontent.com/clente/hugo-bearcub/main/images/pagespeed.webp)
+
+
### Secure
+
+
[**Bear Cub**'s demo](https://clente.github.io/hugo-bearcub/) is hosted on GitHub
+
and therefore I'm not in control of its [Content Security
+
Policy](https://infosec.mozilla.org/guidelines/web_security#content-security-policy).
+
However, the theme itself was made with security in mind: there are no inline
+
styles and it uses no JavaScript at all.
+
+
If you want to improve your [Mozilla
+
Observatory](https://observatory.mozilla.org/) score even further, you should be
+
able to simply add a few headers to your hosting service's configuration (e.g.
+
[Netlify](https://docs.netlify.com/routing/headers/) or [Cloudflare
+
Pages](https://developers.cloudflare.com/pages/platform/headers/)) and never
+
have to think about it again. My `_headers` file, for example, looks like this:
+
+
```
+
/*
+
X-Content-Type-Options: nosniff
+
Strict-Transport-Security: "max-age=31536000; includeSubDomains; preload" env=HTTPS
+
Cache-Control: max-age=31536000, public
+
X-Frame-Options: deny
+
Referrer-Policy: no-referrer
+
Feature-Policy: microphone 'none'; payment 'none'; geolocation 'none'; midi 'none'; sync-xhr 'none'; camera 'none'; magnetometer 'none'; gyroscope 'none'
+
Content-Security-Policy: default-src 'none'; manifest-src 'self'; font-src 'self'; img-src 'self'; style-src 'self'; form-action 'none'; frame-ancestors 'none'; base-uri 'none'
+
X-XSS-Protection: 1; mode=block
+
```
+
+
### Multilingual
+
+
If you need to write a blog that supports more than one language, **Bear Cub**
+
has you covered! Check out the demo's [`hugo.toml`
+
file](https://github.com/clente/hugo-bearcub/blob/main/exampleSite/hugo.toml)
+
for a sample of how you can setup multilingual support.
+
+
By default, the theme creates a translation button that gets disabled when the
+
current page is only available in any other language. You can also choose to
+
hide this button (instead of disabling it) by setting `hideUntranslated =
+
true`.
+
+
### More
+
+
Every once in a while, as I keep using **Bear Cub**, I notice that there is some
+
functionality missing. Currently, these are the "advanced features" that I have
+
already implemented:
+
+
- Full-text RSS feed: an enhanced RSS feed template that includes the (properly
+
encoded) full content of your posts in the feed itself.
+
- Static content: you can create empty blog entries that act as links to static
+
files by including `link: "{url}"` in a post's [front
+
matter](https://gohugo.io/content-management/front-matter/). You can also add
+
`render: false` to your [build
+
options](https://gohugo.io/content-management/build-options/#readout) to avoid
+
rendering blank posts.
+
- Skip link: a "skip to main content" link that is temporarily invisible, but
+
can be focused by people who need a keyboard to navigate the web (see [PR
+
#5](https://github.com/clente/hugo-bearcub/pull/5) by
+
[@2kool4idkwhat](https://github.com/2kool4idkwhat) for more information).
+
- Reply by email: if you supply an email address, the theme creates a "Reply to
+
this post by email" button at the end of every post (see Kev Quirk's [original
+
implementation](https://kevquirk.com/adding-the-post-title-to-my-reply-by-email-button)).
+
This button can be suppressed on a case-by-case by setting `hideReply: true`
+
in a post's [front matter](https://gohugo.io/content-management/front-matter/)
+
(see [PR #18](https://github.com/clente/hugo-bearcub/pull/18) by
+
[@chrsmutti](https://github.com/chrsmutti)).
+
- `absfigure` shortcode: a shortcut to use the `figure` shortcode that also
+
converts relative URLs into absolute URLs by using the `absURL` function.
+
- Single-use CSS (EXPERIMENTAL): you can add some styles to a single page by
+
writing the CSS you need in `assets/{custom_css}.css` and then including
+
`style: "{custom_css}.css"` in the [front
+
matter](https://gohugo.io/content-management/front-matter/) of said page.
+
- Conditional CSS (EXPERIMENTAL): since **Bear Cub** does syntax highlighting
+
without inline styles (see `hugo.toml` for more information), it only load its
+
`syntax.css` if, and only if, a code block is actually present in the current
+
page.
+
- Alternative "Herman" style (EXPERIMENTAL): if you want to check out a more
+
modern CSS style, you can change the `themeStyle` parameter to `"herman"` in
+
order to activate [Herman Martinus's](https://herman.bearblog.dev/) version of
+
the [Blogster Minimal](https://blogster-minimal.netlify.app/) theme for
+
[Astro](https://astro.build/).
+
- Dynamic social card generation (EXPERIMENTAL): if you don't add preview images
+
to a post, this template will generate one based on the title. You can see an
+
example below.
+
+
![Social card example](https://raw.githubusercontent.com/clente/hugo-bearcub/main/images/social_card.webp)
+
+
## Configuration
+
+
**Bear Cub** can be customized with a `hugo.toml` file. Check out the
+
[configuration](https://github.com/clente/hugo-bearcub/blob/main/exampleSite/hugo.toml)
+
of the [demo](https://clente.github.io/hugo-bearcub/) for more information.
+
+
```toml
+
# Basic config
+
baseURL = "https://example.com"
+
theme = "hugo-bearcub"
+
copyright = "John Doe (CC BY 4.0)"
+
defaultContentLanguage = "en"
+
+
# Generate a nice robots.txt for SEO
+
enableRobotsTXT = true
+
+
# Setup syntax highlighting without inline styles. For more information about
+
# why you'd want to avoid inline styles, see
+
# https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/style-src#unsafe_inline_styles
+
[markup]
+
[markup.highlight]
+
lineNos = true
+
lineNumbersInTable = false
+
# This allows Bear Cub to use a variation of Dracula that is more accessible
+
# to people with poor eyesight. For more information about color contrast
+
# and accessibility, see https://web.dev/color-and-contrast-accessibility/
+
noClasses = false
+
+
# Multilingual mode config. More for information about how to setup translation,
+
# see https://gohugo.io/content-management/multilingual/
+
[languages]
+
[languages.en]
+
title = "Bear Cub"
+
languageName = "en-US 🇺🇸"
+
LanguageCode = "en-US"
+
contentDir = "content"
+
[languages.en.params]
+
madeWith = "Made with [Bear Cub](https://github.com/clente/hugo-bearcub)"
+
[languages.pt]
+
title = "Bear Cub"
+
languageName = "pt-BR 🇧🇷"
+
LanguageCode = "pt-BR"
+
contentDir = "content.pt"
+
[languages.pt.params]
+
madeWith = "Feito com [Bear Cub](https://github.com/clente/hugo-bearcub)"
+
+
[params]
+
# The description of your website
+
description = "Bear Cub Demo"
+
+
# The path to your favicon
+
favicon = "images/favicon.png"
+
+
# These images will show up when services want to generate a preview of a link
+
# to your site. Ignored if `generateSocialCard = true`. For more information
+
# about previews, see https://gohugo.io/templates/internal#twitter-cards and
+
# https://gohugo.io/templates/internal#open-graph
+
images = ["images/share.webp"]
+
+
# This title is used as the site_name on the Hugo's internal opengraph
+
# structured data template
+
title = "Bear Cub"
+
+
# Dates are displayed following the format below. For more information about
+
# formatting, see https://gohugo.io/functions/format/
+
dateFormat = "2006-01-02"
+
+
# If your blog is multilingual but you haven't translated a page, this theme
+
# will create a disabled link. By setting `hideUntranslated` to true, you can
+
# have the theme simply not show any link
+
hideUntranslated = false
+
+
# (EXPERIMENTAL) This theme has two options for its CSS styles: "original" and
+
# "herman". The former is what you see on Bear Cub's demo (an optimized
+
# version of Hugo Bear Blog), while the latter has a more modern look based on
+
# Herman Martinus's version of the Blogster Minimal theme for Astro.
+
themeStyle = "original"
+
+
# (EXPERIMENTAL) This theme is capable of dynamically generating social cards
+
# for posts that don't have `images` defined in their front matter; By setting
+
# `generateSocialCard` to false, you can prevent this behavior. For more
+
# information see layouts/partials/social_card.html
+
generateSocialCard = true
+
+
# Social media. Delete any item you aren't using to make sure it won't show up
+
# in your website's metadata.
+
[params.social]
+
twitter = "example" # Twitter handle (without '@')
+
facebook_admin = "0000000000" # Facebook Page Admin ID
+
+
# Author metadata. This is mostly used for the RSS feed of your site, but the
+
# email is also added to the footer of each post. You can hide the "reply to"
+
# link by using a `hideReply` param in front matter.
+
[params.author]
+
name = "John Doe" # Your name as shown in the RSS feed metadata
+
email = "me@example.com" # Added to the footer so readers can reply to posts
+
```
+
+
## Contributing
+
+
If you come across any problems while using **Bear Cub**, you can file an
+
[issue](https://github.com/clente/hugo-bearcub/issues) or create a [pull
+
request](https://github.com/clente/hugo-bearcub/pulls).
+183
http/themes/hugo-bearcub/assets/catppuccin.css
···
+
body {
+
font-family: monospace;
+
font-size: 115%;
+
margin: auto;
+
padding: 20px;
+
max-width: 720px;
+
text-align: left;
+
background-color: #1e1e2e;
+
word-wrap: break-word;
+
overflow-wrap: break-word;
+
line-height: 1.5;
+
color: #cdd6f4;
+
}
+
+
h1,
+
h2,
+
h3,
+
h4,
+
h5,
+
h6,
+
strong,
+
b {
+
color: #cdd6f4;
+
}
+
+
a {
+
color: #f38ba8;
+
}
+
+
.title {
+
text-decoration: none;
+
border: 0;
+
}
+
+
.title h1 {
+
font-size: 24px;
+
margin: 19.92px 0 19.92px 0;
+
}
+
+
.title span {
+
font-weight: 400;
+
}
+
+
nav a {
+
margin-right: 10px;
+
}
+
+
textarea {
+
background-color: #313244;
+
color: #bac2de;
+
width: 100%;
+
font-size: 16px;
+
}
+
+
input {
+
background-color: #313244;
+
color: #bac2de;
+
font-size: 16px;
+
}
+
+
content {
+
line-height: 1.6;
+
}
+
+
table {
+
width: 100%;
+
}
+
+
table,
+
th,
+
td {
+
border-collapse: collapse;
+
border-bottom: 1px solid #45475a;
+
padding: 5px;
+
}
+
+
img {
+
max-width: 100%;
+
height: auto;
+
}
+
+
code {
+
padding: 2px 5px;
+
color: #cdd6f4;
+
background-color: #313244;
+
font-family: monospace;
+
font-size: 115%;
+
}
+
+
pre code {
+
display: block;
+
padding: 20px;
+
white-space: pre-wrap;
+
overflow-x: auto;
+
text-wrap: nowrap;
+
font-family: monospace;
+
font-size: 115%;
+
}
+
+
blockquote {
+
border-left: 1px solid #a6adc8;
+
color: #a6adc8;
+
padding-left: 20px;
+
font-style: italic;
+
}
+
+
footer {
+
text-align: center;
+
}
+
+
.helptext {
+
color: #a6adc8;
+
font-size: small;
+
}
+
+
.errorlist {
+
color: #f9e2af;
+
font-size: small;
+
}
+
+
/* blog posts */
+
ul.blog-posts {
+
list-style-type: none;
+
padding: unset;
+
}
+
+
ul.blog-posts li {
+
display: flex;
+
margin-bottom: 10px;
+
}
+
+
ul.blog-posts li span {
+
flex: 0 0 130px;
+
}
+
+
ul.blog-posts li a:visited {
+
color: #f38ba8;
+
}
+
+
a.blog-tags {
+
line-height: 2;
+
margin-right: 12px;
+
}
+
+
h3.blog-filter {
+
margin-bottom: 0;
+
}
+
+
.disabled {
+
color: currentColor;
+
cursor: not-allowed;
+
opacity: 0.7;
+
}
+
+
p.byline {
+
font-style: italic;
+
}
+
+
/* "Skip to main content" link */
+
.skip-link {
+
position: absolute;
+
top: 5;
+
transform: translateY(-600%);
+
transition: transform 0.5s;
+
background-color: #1e1e2e;
+
padding: 6px;
+
}
+
+
.skip-link:focus {
+
transform: translateY(0%);
+
}
+
+
figure {
+
margin-inline-start: 0em;
+
margin-inline-end: 0em;
+
}
+
+
figcaption>p {
+
margin-block-start: 0px;
+
text-align: center;
+
font-style: italic;
+
color: #cdd6f4;
+
}
+202
http/themes/hugo-bearcub/assets/herman.css
···
+
:root {
+
font-size: 62.5%; /* 10px */
+
--color-dark: #181a20;
+
--color-light: #fafafa;
+
--color-primary: #1a8fe3;
+
--size: 1rem;
+
--spacing: calc(var(--size) * 2.4);
+
}
+
+
body {
+
background: var(--color-dark);
+
color: var(--color-light);
+
padding: 4rem;
+
font-family: Avenir, 'Avenir Next LT Pro', Montserrat, Corbel, 'URW Gothic',
+
source-sans-pro, sans-serif, "Apple Color Emoji", "Segoe UI Emoji",
+
"Segoe UI Symbol", "Noto Color Emoji";
+
font-size: calc(var(--size) * 1.8);
+
line-height: 1.5;
+
min-height: 80vh;
+
max-width: 1600px;
+
margin: 0 auto;
+
word-wrap: break-word;
+
}
+
+
header,
+
main,
+
footer {
+
max-width: 70ch;
+
margin-inline: auto;
+
}
+
+
header {
+
padding-bottom: var(--spacing);
+
}
+
+
nav a, a.blog-tags {
+
margin-right: calc(var(--spacing) / 2);
+
}
+
a.blog-tags {
+
line-height: 2;
+
}
+
+
main {
+
padding-bottom: var(--spacing);
+
}
+
+
footer {
+
text-align: center;
+
padding-top: var(--spacing);
+
}
+
+
a {
+
color: currentColor;
+
text-decoration-color: var(--color-primary);
+
text-decoration-thickness: 0.3ex;
+
text-underline-offset: 0.3ex;
+
}
+
+
a:hover {
+
text-decoration-thickness: 0.4ex;
+
}
+
+
img {
+
display: block;
+
max-width: 100%;
+
height: auto;
+
}
+
+
h1,
+
h2,
+
h3,
+
h4 {
+
font-weight: 700;
+
line-height: 1.3;
+
}
+
+
h1 {
+
font-size: calc(var(--size) * 4.2);
+
}
+
h2 {
+
font-size: calc(var(--size) * 3.4);
+
}
+
h3 {
+
font-size: calc(var(--size) * 2.6);
+
}
+
h4 {
+
font-size: calc(var(--size) * 1.8);
+
}
+
+
ul,
+
ol {
+
padding-inline-start: var(--spacing);
+
}
+
li {
+
margin-block-start: var(--spacing);
+
}
+
+
blockquote {
+
padding-inline-start: var(--spacing);
+
border-inline-start: 0.2em solid;
+
font-style: italic;
+
max-width: 50ch;
+
}
+
+
:is(h1, h2, h3, h4, blockquote) {
+
margin-block-end: calc(var(--spacing) / 2);
+
}
+
:is(h1, h2, h3, h4) + * {
+
margin-block-start: calc(var(--spacing) / 3);
+
}
+
:is(h1, h2, h3, h4) + :where(h2, h3, h4) {
+
margin-block-start: calc(var(--spacing) * 2);
+
}
+
+
.title {
+
text-decoration: none;
+
}
+
.title h1 {
+
font-size: calc(var(--size) * 3.4);
+
margin-top: calc(var(--spacing) / 2);
+
}
+
+
ul.blog-posts {
+
list-style-type: none;
+
padding: unset;
+
}
+
ul.blog-posts li {
+
display: flex;
+
flex-direction: column;
+
}
+
ul.blog-posts li span {
+
min-width: 11ch;
+
}
+
+
p.byline {
+
opacity: 0.5;
+
}
+
+
code {
+
font-family: ui-monospace, 'Cascadia Code', 'Source Code Pro',
+
Menlo, Consolas, 'DejaVu Sans Mono', monospace;
+
padding: 2px calc(var(--spacing) / 4);
+
background-color: #282a36;
+
font-size: calc(var(--size) * 1.4);
+
}
+
pre code {
+
display: block;
+
padding: var(--spacing);
+
overflow-x: auto;
+
-webkit-text-size-adjust: 100%;
+
-moz-text-size-adjust: 100%;
+
}
+
+
table {
+
width: 100%;
+
}
+
table,
+
th,
+
td {
+
border: 1px solid;
+
border-collapse: collapse;
+
border-color: var(--color-light);
+
padding: calc(var(--spacing) / 2);
+
}
+
+
.disabled {
+
color: currentColor;
+
cursor: not-allowed;
+
opacity: 0.5;
+
}
+
+
@media screen and (min-width: 600px) {
+
ul.blog-posts li {
+
flex-direction: row;
+
gap: calc(var(--spacing) / 2);
+
}
+
}
+
+
/* "Skip to main content" link */
+
.skip-link {
+
position: absolute;
+
top: 5;
+
transform: translateY(-600%);
+
transition: transform 0.5s;
+
background-color: #181a20;
+
padding: 6px;
+
}
+
+
.skip-link:focus {
+
transform: translateY(0%);
+
}
+
+
figure {
+
margin-inline-start: 0em;
+
margin-inline-end: 0em;
+
}
+
+
figcaption > p {
+
margin-block-start: 9px;
+
text-align: center;
+
font-style: italic;
+
}
http/themes/hugo-bearcub/assets/images/social_card_bg.png

This is a binary file and will not be displayed.

http/themes/hugo-bearcub/assets/images/social_card_fg.png

This is a binary file and will not be displayed.

+180
http/themes/hugo-bearcub/assets/original.css
···
+
body {
+
font-family: Verdana, sans-serif;
+
margin: auto;
+
padding: 20px;
+
max-width: 720px;
+
text-align: left;
+
background-color: #1d1f27;
+
word-wrap: break-word;
+
overflow-wrap: break-word;
+
line-height: 1.5;
+
color: #c9d1d9;
+
}
+
+
h1,
+
h2,
+
h3,
+
h4,
+
h5,
+
h6,
+
strong,
+
b {
+
color: #eee;
+
}
+
+
a {
+
color: #8cc2dd;
+
}
+
+
.title {
+
text-decoration: none;
+
border: 0;
+
}
+
.title h1 {
+
font-size: 24px;
+
margin: 19.92px 0 19.92px 0;
+
}
+
+
.title span {
+
font-weight: 400;
+
}
+
+
nav a {
+
margin-right: 10px;
+
}
+
+
textarea {
+
background-color: #252525;
+
color: #ddd;
+
width: 100%;
+
font-size: 16px;
+
}
+
+
input {
+
background-color: #252525;
+
color: #ddd;
+
font-size: 16px;
+
}
+
+
content {
+
line-height: 1.6;
+
}
+
+
table {
+
width: 100%;
+
}
+
+
table,
+
th,
+
td {
+
border: 1px solid;
+
border-collapse: collapse;
+
border-color: #c9d1d9;
+
padding: 5px;
+
}
+
+
img {
+
max-width: 100%;
+
height: auto;
+
}
+
+
code {
+
padding: 2px 5px;
+
color: #f8f8f2;
+
background-color: #282a36;
+
}
+
+
pre code {
+
display: block;
+
padding: 20px;
+
white-space: pre-wrap;
+
font-size: 14px;
+
overflow-x: auto;
+
text-wrap: nowrap;
+
}
+
+
blockquote {
+
border-left: 1px solid #999;
+
color: #ccc;
+
padding-left: 20px;
+
font-style: italic;
+
}
+
+
footer {
+
padding: 25px;
+
text-align: center;
+
}
+
+
.helptext {
+
color: #aaa;
+
font-size: small;
+
}
+
+
.errorlist {
+
color: #eba613;
+
font-size: small;
+
}
+
+
/* blog posts */
+
ul.blog-posts {
+
list-style-type: none;
+
padding: unset;
+
}
+
+
ul.blog-posts li {
+
display: flex;
+
margin-bottom: 10px;
+
}
+
+
ul.blog-posts li span {
+
flex: 0 0 130px;
+
}
+
+
ul.blog-posts li a:visited {
+
color: #8b6fcb;
+
}
+
+
a.blog-tags {
+
line-height: 2;
+
margin-right: 12px;
+
}
+
+
h3.blog-filter {
+
margin-bottom: 0;
+
}
+
+
.disabled {
+
color: currentColor;
+
cursor: not-allowed;
+
opacity: 0.7;
+
}
+
+
p.byline {
+
font-style: italic;
+
}
+
+
/* "Skip to main content" link */
+
.skip-link {
+
position: absolute;
+
top: 5;
+
transform: translateY(-600%);
+
transition: transform 0.5s;
+
background-color: #1d1f27;
+
padding: 6px;
+
}
+
+
.skip-link:focus {
+
transform: translateY(0%);
+
}
+
+
figure {
+
margin-inline-start: 0em;
+
margin-inline-end: 0em;
+
}
+
+
figcaption > p {
+
margin-block-start: 0px;
+
text-align: center;
+
font-style: italic;
+
color: #ccc;
+
}
+88
http/themes/hugo-bearcub/assets/syntax.css
···
+
/* Generated using: hugo gen chromastyles --style=catppuccin-mocha */
+
+
/* Background */ .bg { color:#cdd6f4;background-color:#1e1e2e; }
+
/* PreWrapper */ .chroma { color:#cdd6f4;background-color:#1e1e2e; }
+
/* Other */ .chroma .x { }
+
/* Error */ .chroma .err { color:#f38ba8 }
+
/* CodeLine */ .chroma .cl { }
+
/* LineLink */ .chroma .lnlinks { outline:none;text-decoration:none;color:inherit }
+
/* LineTableTD */ .chroma .lntd { vertical-align:top;padding:0;margin:0;border:0; }
+
/* LineTable */ .chroma .lntable { border-spacing:0;padding:0;margin:0;border:0; }
+
/* LineHighlight */ .chroma .hl { background-color:#45475a }
+
/* LineNumbersTable */ .chroma .lnt { white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f849c }
+
/* LineNumbers */ .chroma .ln { white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f849c }
+
/* Line */ .chroma .line { display:flex; }
+
/* Keyword */ .chroma .k { color:#cba6f7 }
+
/* KeywordConstant */ .chroma .kc { color:#fab387 }
+
/* KeywordDeclaration */ .chroma .kd { color:#f38ba8 }
+
/* KeywordNamespace */ .chroma .kn { color:#94e2d5 }
+
/* KeywordPseudo */ .chroma .kp { color:#cba6f7 }
+
/* KeywordReserved */ .chroma .kr { color:#cba6f7 }
+
/* KeywordType */ .chroma .kt { color:#f38ba8 }
+
/* Name */ .chroma .n { }
+
/* NameAttribute */ .chroma .na { color:#89b4fa }
+
/* NameBuiltin */ .chroma .nb { color:#89dceb }
+
/* NameBuiltinPseudo */ .chroma .bp { color:#89dceb }
+
/* NameClass */ .chroma .nc { color:#f9e2af }
+
/* NameConstant */ .chroma .no { color:#f9e2af }
+
/* NameDecorator */ .chroma .nd { color:#89b4fa;font-weight:bold }
+
/* NameEntity */ .chroma .ni { color:#94e2d5 }
+
/* NameException */ .chroma .ne { color:#fab387 }
+
/* NameFunction */ .chroma .nf { color:#89b4fa }
+
/* NameFunctionMagic */ .chroma .fm { color:#89b4fa }
+
/* NameLabel */ .chroma .nl { color:#89dceb }
+
/* NameNamespace */ .chroma .nn { color:#fab387 }
+
/* NameOther */ .chroma .nx { }
+
/* NameProperty */ .chroma .py { color:#fab387 }
+
/* NameTag */ .chroma .nt { color:#cba6f7 }
+
/* NameVariable */ .chroma .nv { color:#f5e0dc }
+
/* NameVariableClass */ .chroma .vc { color:#f5e0dc }
+
/* NameVariableGlobal */ .chroma .vg { color:#f5e0dc }
+
/* NameVariableInstance */ .chroma .vi { color:#f5e0dc }
+
/* NameVariableMagic */ .chroma .vm { color:#f5e0dc }
+
/* Literal */ .chroma .l { }
+
/* LiteralDate */ .chroma .ld { }
+
/* LiteralString */ .chroma .s { color:#a6e3a1 }
+
/* LiteralStringAffix */ .chroma .sa { color:#f38ba8 }
+
/* LiteralStringBacktick */ .chroma .sb { color:#a6e3a1 }
+
/* LiteralStringChar */ .chroma .sc { color:#a6e3a1 }
+
/* LiteralStringDelimiter */ .chroma .dl { color:#89b4fa }
+
/* LiteralStringDoc */ .chroma .sd { color:#6c7086 }
+
/* LiteralStringDouble */ .chroma .s2 { color:#a6e3a1 }
+
/* LiteralStringEscape */ .chroma .se { color:#89b4fa }
+
/* LiteralStringHeredoc */ .chroma .sh { color:#6c7086 }
+
/* LiteralStringInterpol */ .chroma .si { color:#a6e3a1 }
+
/* LiteralStringOther */ .chroma .sx { color:#a6e3a1 }
+
/* LiteralStringRegex */ .chroma .sr { color:#94e2d5 }
+
/* LiteralStringSingle */ .chroma .s1 { color:#a6e3a1 }
+
/* LiteralStringSymbol */ .chroma .ss { color:#a6e3a1 }
+
/* LiteralNumber */ .chroma .m { color:#fab387 }
+
/* LiteralNumberBin */ .chroma .mb { color:#fab387 }
+
/* LiteralNumberFloat */ .chroma .mf { color:#fab387 }
+
/* LiteralNumberHex */ .chroma .mh { color:#fab387 }
+
/* LiteralNumberInteger */ .chroma .mi { color:#fab387 }
+
/* LiteralNumberIntegerLong */ .chroma .il { color:#fab387 }
+
/* LiteralNumberOct */ .chroma .mo { color:#fab387 }
+
/* Operator */ .chroma .o { color:#89dceb;font-weight:bold }
+
/* OperatorWord */ .chroma .ow { color:#89dceb;font-weight:bold }
+
/* Punctuation */ .chroma .p { }
+
/* Comment */ .chroma .c { color:#6c7086;font-style:italic }
+
/* CommentHashbang */ .chroma .ch { color:#6c7086;font-style:italic }
+
/* CommentMultiline */ .chroma .cm { color:#6c7086;font-style:italic }
+
/* CommentSingle */ .chroma .c1 { color:#6c7086;font-style:italic }
+
/* CommentSpecial */ .chroma .cs { color:#6c7086;font-style:italic }
+
/* CommentPreproc */ .chroma .cp { color:#6c7086;font-style:italic }
+
/* CommentPreprocFile */ .chroma .cpf { color:#6c7086;font-weight:bold;font-style:italic }
+
/* Generic */ .chroma .g { }
+
/* GenericDeleted */ .chroma .gd { color:#f38ba8;background-color:#313244 }
+
/* GenericEmph */ .chroma .ge { font-style:italic }
+
/* GenericError */ .chroma .gr { color:#f38ba8 }
+
/* GenericHeading */ .chroma .gh { color:#fab387;font-weight:bold }
+
/* GenericInserted */ .chroma .gi { color:#a6e3a1;background-color:#313244 }
+
/* GenericOutput */ .chroma .go { }
+
/* GenericPrompt */ .chroma .gp { }
+
/* GenericStrong */ .chroma .gs { font-weight:bold }
+
/* GenericSubheading */ .chroma .gu { color:#fab387;font-weight:bold }
+
/* GenericTraceback */ .chroma .gt { color:#f38ba8 }
+
/* GenericUnderline */ .chroma .gl { text-decoration:underline }
+
/* TextWhitespace */ .chroma .w { }
+35
http/themes/hugo-bearcub/exampleSite/content.pt/_index.md
···
+
---
+
title: "Início"
+
menu: "main"
+
weight: 1
+
---
+
+
# ᕦʕ •ᴥ•ʔᕤ Bear Cub
+
+
Os sites de hoje em dia são pesados, lentos e cheios de scripts, propagandas e
+
rastreadores. Isso ficou tão comum que nós perdemos toda a perspectiva, tanto
+
que achamos normal uma página web ter vários megabytes.
+
+
> The internet has become a bloated mess. Huge JavaScript libraries, countless
+
> client-side queries and overly complex frontend frameworks are par for the
+
> course these days.
+
>
+
> --- [Kev Quirk](https://512kb.club/)
+
+
Vamos mudar isso, um site de cada vez! **Bear Cub** é um tema
+
[Hugo](https://gohugo.io/) baseado no [Hugo
+
Bear](https://github.com/janraasch/hugo-bearblog/) que toma conta da velocidade
+
e otimização para que você possa focar em escrever bons textos.
+
+
Ele é gratuito, multilíngue, otimizado para buscadores, simples, responsivo,
+
leve e rápido. Muito rápido.
+
+
Quando comparado ao seu predecessor, o **Bear Cub** tem alguns upgrades de
+
[privacidade](https://themarkup.org/blacklight?url=clente.github.io/hugo-bearcub/)
+
e
+
[acessibilidade](https://pagespeed.web.dev/report?url=https%3A%2F%2Fclente.github.io%2Fhugo-bearcub%2F).
+
Ele também é compatível com as práticas mais modernas de
+
[segurança](https://github.com/clente/hugo-bearcub#secure) para que seus
+
usuários possam aproveitar seu site sem medo.
+
+
Feito com 💟 por [Caio lente](https://lente.dev).
+5
http/themes/hugo-bearcub/exampleSite/content.pt/blog/_index.md
···
+
---
+
title: "Blog"
+
menu: "main"
+
weight: 2
+
---
+35
http/themes/hugo-bearcub/exampleSite/content/_index.md
···
+
---
+
title: "Home"
+
menu: "main"
+
weight: 1
+
---
+
+
# ᕦʕ •ᴥ•ʔᕤ Bear Cub
+
+
Today's websites are bloated, slow, and full of scripts, ads, and trackers. This
+
became so commonplace that we lost all sense of perspective, to the point that
+
we now think multi-megabyte webpages are normal.
+
+
> The internet has become a bloated mess. Huge JavaScript libraries, countless
+
> client-side queries and overly complex frontend frameworks are par for the
+
> course these days.
+
>
+
> --- [Kev Quirk](https://512kb.club/)
+
+
Let's change this, one website at a time! **Bear Cub** is a
+
[Hugo](https://gohugo.io/) theme based on [Hugo
+
Bear](https://github.com/janraasch/hugo-bearblog/) that takes care of speed and
+
optimization, so you can focus on writing good content.
+
+
It is free, multilingual, optimized for search engines, no-nonsense, responsive,
+
light, and fast. Really fast.
+
+
When compared to its predecessor, **Bear Cub** has a few
+
[privacy](https://themarkup.org/blacklight?url=clente.github.io/hugo-bearcub/)
+
and
+
[accessibility](https://pagespeed.web.dev/report?url=https%3A%2F%2Fclente.github.io%2Fhugo-bearcub%2F)
+
upgrades. It's also compatible with modern
+
[security](https://github.com/clente/hugo-bearcub#secure) standards, so your
+
users don't have to worry about browsing your website.
+
+
Made with 💟 by [Caio lente](https://lente.dev/en).
+5
http/themes/hugo-bearcub/exampleSite/content/blog/_index.md
···
+
---
+
title: "Blog"
+
menu: "main"
+
weight: 2
+
---
+46
http/themes/hugo-bearcub/exampleSite/content/blog/emoji-support.md
···
+
+++
+
author = "Hugo Authors"
+
title = "Emoji Support"
+
date = "2019-03-05"
+
description = "Guide to emoji usage in Hugo"
+
tags = [
+
"emoji",
+
]
+
+++
+
+
Emoji can be enabled in a Hugo project in a number of ways.
+
<!--more-->
+
The [`emojify`](https://gohugo.io/functions/emojify/) function can be called directly in templates or [Inline Shortcodes](https://gohugo.io/templates/shortcode-templates/#inline-shortcodes).
+
+
To enable emoji globally, set `enableEmoji` to `true` in your site's [configuration](https://gohugo.io/getting-started/configuration/) and then you can type emoji shorthand codes directly in content files; e.g.
+
+
<p><span class="nowrap"><span class="emojify">🙈</span> <code>:see_no_evil:</code></span> <span class="nowrap"><span class="emojify">🙉</span> <code>:hear_no_evil:</code></span> <span class="nowrap"><span class="emojify">🙊</span> <code>:speak_no_evil:</code></span></p>
+
<br>
+
+
The [Emoji cheat sheet](http://www.emoji-cheat-sheet.com/) is a useful reference for emoji shorthand codes.
+
+
***
+
+
**N.B.** The above steps enable Unicode Standard emoji characters and sequences in Hugo, however the rendering of these glyphs depends on the browser and the platform. To style the emoji you can either use a third party emoji font or a font stack; e.g.
+
+
{{< highlight html >}}
+
.emoji {
+
font-family: Apple Color Emoji, Segoe UI Emoji, NotoColorEmoji, Segoe UI Symbol, Android Emoji, EmojiSymbols;
+
}
+
{{< /highlight >}}
+
+
{{< css.inline >}}
+
<style>
+
.emojify {
+
font-family: Apple Color Emoji, Segoe UI Emoji, NotoColorEmoji, Segoe UI Symbol, Android Emoji, EmojiSymbols;
+
font-size: 2rem;
+
vertical-align: middle;
+
}
+
@media screen and (max-width:650px) {
+
.nowrap {
+
display: block;
+
margin: 25px 0;
+
}
+
}
+
</style>
+
{{< /css.inline >}}
+148
http/themes/hugo-bearcub/exampleSite/content/blog/markdown-syntax.md
···
+
+++
+
author = "Hugo Authors"
+
title = "Markdown Syntax Guide"
+
date = "2019-03-11"
+
description = "Sample article showcasing basic Markdown syntax and formatting for HTML elements."
+
tags = [
+
"markdown",
+
"css",
+
"html",
+
]
+
categories = [
+
"themes",
+
"syntax",
+
]
+
series = ["Themes Guide"]
+
aliases = ["migrate-from-jekyl"]
+
+++
+
+
This article offers a sample of basic Markdown syntax that can be used in Hugo content files, also it shows whether basic HTML elements are decorated with CSS in a Hugo theme.
+
<!--more-->
+
+
## Headings
+
+
The following HTML `<h1>`—`<h6>` elements represent six levels of section headings. `<h1>` is the highest section level while `<h6>` is the lowest.
+
+
# H1
+
## H2
+
### H3
+
#### H4
+
##### H5
+
###### H6
+
+
## Paragraph
+
+
Xerum, quo qui aut unt expliquam qui dolut labo. Aque venitatiusda cum, voluptionse latur sitiae dolessi aut parist aut dollo enim qui voluptate ma dolestendit peritin re plis aut quas inctum laceat est volestemque commosa as cus endigna tectur, offic to cor sequas etum rerum idem sintibus eiur? Quianimin porecus evelectur, cum que nis nust voloribus ratem aut omnimi, sitatur? Quiatem. Nam, omnis sum am facea corem alique molestrunt et eos evelece arcillit ut aut eos eos nus, sin conecerem erum fuga. Ri oditatquam, ad quibus unda veliamenimin cusam et facea ipsamus es exerum sitate dolores editium rerore eost, temped molorro ratiae volorro te reribus dolorer sperchicium faceata tiustia prat.
+
+
Itatur? Quiatae cullecum rem ent aut odis in re eossequodi nonsequ idebis ne sapicia is sinveli squiatum, core et que aut hariosam ex eat.
+
+
## Blockquotes
+
+
The blockquote element represents content that is quoted from another source, optionally with a citation which must be within a `footer` or `cite` element, and optionally with in-line changes such as annotations and abbreviations.
+
+
#### Blockquote without attribution
+
+
> Tiam, ad mint andaepu dandae nostion secatur sequo quae.
+
> **Note** that you can use *Markdown syntax* within a blockquote.
+
+
#### Blockquote with attribution
+
+
> Don't communicate by sharing memory, share memory by communicating.<br>
+
> — <cite>Rob Pike[^1]</cite>
+
+
[^1]: The above quote is excerpted from Rob Pike's [talk](https://www.youtube.com/watch?v=PAAkCSZUG1c) during Gopherfest, November 18, 2015.
+
+
## Tables
+
+
Tables aren't part of the core Markdown spec, but Hugo supports supports them out-of-the-box.
+
+
Name | Age
+
--------|------
+
Bob | 27
+
Alice | 23
+
+
#### Inline Markdown within tables
+
+
| Italics | Bold | Code |
+
| -------- | -------- | ------ |
+
| *italics* | **bold** | `code` |
+
+
## Code Blocks
+
+
#### Code block with backticks
+
+
```html
+
<!doctype html>
+
<html lang="en">
+
<head>
+
<meta charset="utf-8">
+
<title>Example HTML5 Document</title>
+
</head>
+
<body>
+
<p>Test</p>
+
</body>
+
</html>
+
```
+
+
#### Code block indented with four spaces
+
+
<!doctype html>
+
<html lang="en">
+
<head>
+
<meta charset="utf-8">
+
<title>Example HTML5 Document</title>
+
</head>
+
<body>
+
<p>Test</p>
+
</body>
+
</html>
+
+
#### Code block with Hugo's internal highlight shortcode
+
{{< highlight html >}}
+
<!doctype html>
+
<html lang="en">
+
<head>
+
<meta charset="utf-8">
+
<title>Example HTML5 Document</title>
+
</head>
+
<body>
+
<p>Test</p>
+
</body>
+
</html>
+
{{< /highlight >}}
+
+
## List Types
+
+
#### Ordered List
+
+
1. First item
+
2. Second item
+
3. Third item
+
+
#### Unordered List
+
+
* List item
+
* Another item
+
* And another item
+
+
#### Nested list
+
+
* Fruit
+
* Apple
+
* Orange
+
* Banana
+
* Dairy
+
* Milk
+
* Cheese
+
+
## Other Elements — abbr, sub, sup, kbd, mark
+
+
<abbr title="Graphics Interchange Format">GIF</abbr> is a bitmap image format.
+
+
H<sub>2</sub>O
+
+
X<sup>n</sup> + Y<sup>n</sup> = Z<sup>n</sup>
+
+
Press <kbd><kbd>CTRL</kbd>+<kbd>ALT</kbd>+<kbd>Delete</kbd></kbd> to end the session.
+
+
Most <mark>salamanders</mark> are nocturnal, and hunt for insects, worms, and other small creatures.
+49
http/themes/hugo-bearcub/exampleSite/content/blog/math-typesetting.md
···
+
---
+
author: Hugo Authors
+
title: Math Typesetting
+
date: 2019-03-08
+
description: A brief guide to setup KaTeX
+
math: true
+
---
+
+
Mathematical notation in a Hugo project can be enabled by using third party JavaScript libraries.
+
<!--more-->
+
+
In this example we will be using [KaTeX](https://katex.org/)
+
+
- Create a partial under `/layouts/partials/math.html`
+
- Within this partial reference the [Auto-render Extension](https://katex.org/docs/autorender.html) or host these scripts locally.
+
- Include the partial in your templates like so:
+
+
```bash
+
{{ if or .Params.math .Site.Params.math }}
+
{{ partial "math.html" . }}
+
{{ end }}
+
```
+
+
- To enable KaTex globally set the parameter `math` to `true` in a project's configuration
+
- To enable KaTex on a per page basis include the parameter `math: true` in content files
+
+
**Note:** Use the online reference of [Supported TeX Functions](https://katex.org/docs/supported.html)
+
+
{{< math.inline >}}
+
{{ if or .Page.Params.math .Site.Params.math }}
+
<!-- KaTeX -->
+
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/katex@0.11.1/dist/katex.min.css" integrity="sha384-zB1R0rpPzHqg7Kpt0Aljp8JPLqbXI3bhnPWROx27a9N0Ll6ZP/+DiW/UqRcLbRjq" crossorigin="anonymous">
+
<script defer src="https://cdn.jsdelivr.net/npm/katex@0.11.1/dist/katex.min.js" integrity="sha384-y23I5Q6l+B6vatafAwxRu/0oK/79VlbSz7Q9aiSZUvyWYIYsd+qj+o24G5ZU2zJz" crossorigin="anonymous"></script>
+
<script defer src="https://cdn.jsdelivr.net/npm/katex@0.11.1/dist/contrib/auto-render.min.js" integrity="sha384-kWPLUVMOks5AQFrykwIup5lo0m3iMkkHrD0uJ4H5cjeGihAutqP0yW0J6dpFiVkI" crossorigin="anonymous" onload="renderMathInElement(document.body);"></script>
+
{{ end }}
+
{{</ math.inline >}}
+
+
### Examples
+
+
{{< math.inline >}}
+
<p>
+
Inline math: \(\varphi = \dfrac{1+\sqrt5}{2}= 1.6180339887…\)
+
</p>
+
{{</ math.inline >}}
+
+
Block math:
+
$$
+
\varphi = 1+\frac{1} {1+\frac{1} {1+\frac{1} {1+\cdots} } }
+
$$
+45
http/themes/hugo-bearcub/exampleSite/content/blog/placeholder-text.md
···
+
+++
+
author = "Hugo Authors"
+
title = "Placeholder Text"
+
date = "2019-03-09"
+
description = "Lorem Ipsum Dolor Si Amet"
+
tags = [
+
"markdown",
+
"text",
+
]
+
+++
+
+
Lorem est tota propiore conpellat pectoribus de pectora summo. <!--more-->Redit teque digerit hominumque toris verebor lumina non cervice subde tollit usus habet Arctonque, furores quas nec ferunt. Quoque montibus nunc caluere tempus inhospita parcite confusaque translucet patri vestro qui optatis lumine cognoscere flos nubis! Fronde ipsamque patulos Dryopen deorum.
+
+
1. Exierant elisi ambit vivere dedere
+
2. Duce pollice
+
3. Eris modo
+
4. Spargitque ferrea quos palude
+
+
Rursus nulli murmur; hastile inridet ut ab gravi sententia! Nomine potitus silentia flumen, sustinet placuit petis in dilapsa erat sunt. Atria tractus malis.
+
+
1. Comas hunc haec pietate fetum procerum dixit
+
2. Post torum vates letum Tiresia
+
3. Flumen querellas
+
4. Arcanaque montibus omnes
+
5. Quidem et
+
+
# Vagus elidunt
+
+
<svg class="canon" xmlns="http://www.w3.org/2000/svg" overflow="visible" viewBox="0 0 496 373" height="373" width="496"><g fill="none"><path stroke="#000" stroke-width=".75" d="M.599 372.348L495.263 1.206M.312.633l494.95 370.853M.312 372.633L247.643.92M248.502.92l246.76 370.566M330.828 123.869V1.134M330.396 1.134L165.104 124.515"></path><path stroke="#ED1C24" stroke-width=".75" d="M275.73 41.616h166.224v249.05H275.73zM54.478 41.616h166.225v249.052H54.478z"></path><path stroke="#000" stroke-width=".75" d="M.479.375h495v372h-495zM247.979.875v372"></path><ellipse cx="498.729" cy="177.625" rx=".75" ry="1.25"></ellipse><ellipse cx="247.229" cy="377.375" rx=".75" ry="1.25"></ellipse></g></svg>
+
+
[The Van de Graaf Canon](https://en.wikipedia.org/wiki/Canons_of_page_construction#Van_de_Graaf_canon)
+
+
## Mane refeci capiebant unda mulcebat
+
+
Victa caducifer, malo vulnere contra dicere aurato, ludit regale, voca! Retorsit colit est profanae esse virescere furit nec; iaculi matertera et visa est, viribus. Divesque creatis, tecta novat collumque vulnus est, parvas. **Faces illo pepulere** tempus adest. Tendit flamma, ab opes virum sustinet, sidus sequendo urbis.
+
+
Iubar proles corpore raptos vero auctor imperium; sed et huic: manus caeli Lelegas tu lux. Verbis obstitit intus oblectamina fixis linguisque ausus sperare Echionides cornuaque tenent clausit possit. Omnia putatur. Praeteritae refert ausus; ferebant e primus lora nutat, vici quae mea ipse. Et iter nil spectatae vulnus haerentia iuste et exercebat, sui et.
+
+
Eurytus Hector, materna ipsumque ut Politen, nec, nate, ignari, vernum cohaesit sequitur. Vel **mitis temploque** vocatus, inque alis, *oculos nomen* non silvis corpore coniunx ne displicet illa. Crescunt non unus, vidit visa quantum inmiti flumina mortis facto sic: undique a alios vincula sunt iactata abdita! Suspenderat ego fuit tendit: luna, ante urbem Propoetides **parte**.
+
+
{{< css.inline >}}
+
<style>
+
.canon { background: white; width: 100%; height: auto; }
+
</style>
+
{{< /css.inline >}}
+34
http/themes/hugo-bearcub/exampleSite/content/blog/rich-content.md
···
+
+++
+
author = "Hugo Authors"
+
title = "Rich Content"
+
date = "2019-03-10"
+
description = "A brief description of Hugo Shortcodes"
+
tags = [
+
"shortcodes",
+
"privacy",
+
]
+
+++
+
+
Hugo ships with several [Built-in Shortcodes](https://gohugo.io/content-management/shortcodes/#use-hugos-built-in-shortcodes) for rich content, along with a [Privacy Config](https://gohugo.io/about/hugo-and-gdpr/) and a set of Simple Shortcodes that enable static and no-JS versions of various social media embeds.
+
<!--more-->
+
---
+
+
## YouTube Privacy Enhanced Shortcode
+
+
{{< youtube ZJthWmvUzzc >}}
+
+
<br>
+
+
---
+
+
## Twitter Simple Shortcode
+
+
{{< x user="DesignReviewed" id="1085870671291310081" >}}
+
+
<br>
+
+
---
+
+
## Vimeo Simple Shortcode
+
+
{{< vimeo_simple 48912912 >}}
+89
http/themes/hugo-bearcub/exampleSite/hugo.toml
···
+
# Basic config
+
baseURL = "https://example.com"
+
theme = "hugo-bearcub"
+
copyright = "John Doe (CC BY 4.0)"
+
defaultContentLanguage = "en"
+
+
# Generate a nice robots.txt for SEO
+
enableRobotsTXT = true
+
+
# Setup syntax highlighting without inline styles. For more information about
+
# why you'd want to avoid inline styles, see
+
# https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/style-src#unsafe_inline_styles
+
[markup]
+
[markup.highlight]
+
lineNos = true
+
lineNumbersInTable = false
+
# This allows Bear Cub to use a variation of Dracula that is more accessible
+
# to people with poor eyesight. For more information about color contrast
+
# and accessibility, see https://web.dev/color-and-contrast-accessibility/
+
noClasses = false
+
+
# Multilingual mode config. More for information about how to setup translation,
+
# see https://gohugo.io/content-management/multilingual/
+
[languages]
+
[languages.en]
+
title = "Bear Cub"
+
languageName = "en-US 🇺🇸"
+
LanguageCode = "en-US"
+
contentDir = "content"
+
[languages.en.params]
+
madeWith = "Made with [Bear Cub](https://github.com/clente/hugo-bearcub)"
+
[languages.pt]
+
title = "Bear Cub"
+
languageName = "pt-BR 🇧🇷"
+
LanguageCode = "pt-BR"
+
contentDir = "content.pt"
+
[languages.pt.params]
+
madeWith = "Feito com [Bear Cub](https://github.com/clente/hugo-bearcub)"
+
+
[params]
+
# The description of your website
+
description = "Bear Cub Demo"
+
+
# The path to your favicon
+
favicon = "images/favicon.png"
+
+
# These images will show up when services want to generate a preview of a link
+
# to your site. Ignored if `generateSocialCard = true`. For more information
+
# about previews, see https://gohugo.io/templates/internal#twitter-cards and
+
# https://gohugo.io/templates/internal#open-graph
+
images = ["images/share.webp"]
+
+
# This title is used as the site_name on the Hugo's internal opengraph
+
# structured data template
+
title = "Bear Cub"
+
+
# Dates are displayed following the format below. For more information about
+
# formatting, see https://gohugo.io/functions/format/
+
dateFormat = "2006-01-02"
+
+
# If your blog is multilingual but you haven't translated a page, this theme
+
# will create a disabled link. By setting `hideUntranslated` to true, you can
+
# have the theme simply not show any link
+
hideUntranslated = false
+
+
# (EXPERIMENTAL) This theme has two options for its CSS styles: "original" and
+
# "herman". The former is what you see on Bear Cub's demo (an optimized
+
# version of Hugo Bear Blog), while the latter has a more modern look based on
+
# Herman Martinus's version of the Blogster Minimal theme for Astro.
+
themeStyle = "original"
+
+
# (EXPERIMENTAL) This theme is capable of dynamically generating social cards
+
# for posts that don't have `images` defined in their front matter; By setting
+
# `generateSocialCard` to false, you can prevent this behavior. For more
+
# information see layouts/partials/social_card.html
+
generateSocialCard = true
+
+
# Social media. Delete any item you aren't using to make sure it won't show up
+
# in your website's metadata.
+
[params.social]
+
twitter = "example" # Twitter handle (without '@')
+
facebook_admin = "0000000000" # Facebook Page Admin ID
+
+
# Author metadata. This is mostly used for the RSS feed of your site, but the
+
# email is also added to the footer of each post. You can hide the "reply to"
+
# link by using a `hideReply` param in front matter.
+
[params.author]
+
name = "John Doe" # Your name as shown in the RSS feed metadata
+
email = "me@example.com" # Added to the footer so readers can reply to posts
http/themes/hugo-bearcub/exampleSite/static/images/favicon.png

This is a binary file and will not be displayed.

http/themes/hugo-bearcub/exampleSite/static/images/share.webp

This is a binary file and will not be displayed.

+14
http/themes/hugo-bearcub/i18n/de.toml
···
+
[filtering-for]
+
other = "Filtern nach"
+
+
[no-posts]
+
other = "Noch keine Beträge"
+
+
[email-subject]
+
other = "Antwort auf "
+
+
[email-reply]
+
other = "Auf diesen Beitrag per Email antworten "
+
+
[skip-link]
+
other = "Zum Hauptinhalt"
+14
http/themes/hugo-bearcub/i18n/en.toml
···
+
[filtering-for]
+
other = "Filtering for"
+
+
[no-posts]
+
other = "No posts yet"
+
+
[email-subject]
+
other = "Reply to "
+
+
[email-reply]
+
other = "Reply to this post by email"
+
+
[skip-link]
+
other = "Skip to main content"
+14
http/themes/hugo-bearcub/i18n/pt.toml
···
+
[filtering-for]
+
other = "Filtrando para"
+
+
[no-posts]
+
other = "Nenhum post ainda"
+
+
[email-subject]
+
other = "Resposta a "
+
+
[email-reply]
+
other = "Responda a este post por email"
+
+
[skip-link]
+
other = "Pular para conteúdo principal"
http/themes/hugo-bearcub/images/pagespeed.webp

This is a binary file and will not be displayed.

http/themes/hugo-bearcub/images/screenshot.png

This is a binary file and will not be displayed.

http/themes/hugo-bearcub/images/social_card.webp

This is a binary file and will not be displayed.

http/themes/hugo-bearcub/images/tn.png

This is a binary file and will not be displayed.

+8
http/themes/hugo-bearcub/layouts/404.html
···
+
{{ define "title" }}404{{ end }}
+
+
{{ define "main" }}
+
<h1>404 Uwrur</h1>
+
<p>The page you are looking for is not found on the server.</p>
+
<p>Probably because it doesn't exist, or you maked a symtax error.</p>
+
<p>Kthxbai.</p>
+
{{ end }}
+6
http/themes/hugo-bearcub/layouts/_default/_markup/render-codeblock.html
···
+
<!-- https://github.com/jmooring/hugo-testing/blob/hugo-forum-topic-40998/layouts/_default/_markup/render-codeblock-katex.html -->
+
{{ .Page.Store.Set "hasCodeBlock" true }}
+
+
<!-- https://www.veriphor.com/articles/code-block-render-hooks/ -->
+
{{ $result := transform.HighlightCodeBlock . }}
+
{{ $result.Wrapped }}
+47
http/themes/hugo-bearcub/layouts/_default/baseof.html
···
+
<!DOCTYPE html>
+
<html lang="{{ with .Site.LanguageCode }}{{ . }}{{ else }}en-US{{ end }}">
+
+
<head>
+
<meta http-equiv="X-Clacks-Overhead" content="GNU Terry Pratchett" />
+
<meta charset="utf-8">
+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
+
{{- partial "favicon.html" . -}}
+
<title>{{- block "title" . }}{{ with .Title }}{{ . }} | {{ end }}{{ .Site.Title }}{{- end }}</title>
+
+
{{- partial "seo_tags.html" . -}}
+
<meta name="referrer" content="no-referrer-when-downgrade" />
+
+
{{ $style := print (default "original" .Site.Params.themeStyle) ".css" | resources.Get | minify }}
+
<link href="{{ $style.RelPermalink }}" rel="stylesheet">
+
+
{{ if (.Page.Store.Get "hasCodeBlock") }}
+
{{ $syntax := resources.Get "syntax.css" | minify }}
+
<link href="{{ $syntax.RelPermalink }}" rel="stylesheet">
+
{{ end }}
+
+
{{ with .Params.style }}
+
{{ $extra := resources.Get . | minify }}
+
<link href="{{ $extra.RelPermalink }}" rel="stylesheet">
+
{{ end }}
+
+
{{ with .OutputFormats.Get "rss" -}}
+
{{ printf `
+
<link rel="%s" type="%s" href="%s" title="%s" />` .Rel .MediaType.Type .Permalink $.Site.Title | safeHTML }}
+
{{ end -}}
+
+
</head>
+
+
<body>
+
<header>
+
{{- partial "header.html" . -}}
+
</header>
+
<main id="main-content">
+
{{- block "main" . }}{{- end }}
+
</main>
+
<footer>
+
{{- partial "footer.html" . -}}
+
</footer>
+
+
</body>
+
+
</html>
+36
http/themes/hugo-bearcub/layouts/_default/list.html
···
+
{{ define "main" }}
+
<content>
+
{{ if .Data.Singular }}
+
<h3 class="blog-filter">{{ i18n "filtering-for" }} "{{ .Title }}"</h3>
+
{{ end }}
+
<ul class="blog-posts">
+
{{ range .Pages }}
+
<li>
+
<span>
+
<i>
+
<time datetime='{{ .Date.Format "2006-01-02" }}' pubdate>
+
{{ .Date.Format (default "2006-01-02" .Site.Params.dateFormat) }}
+
</time>
+
</i>
+
</span>
+
{{ if .Params.link }}
+
<a href="{{ .Params.link }}" target="_blank">{{ .Title }} ↪</a>
+
{{ else }}
+
<a href="{{ .RelPermalink }}">{{ .Title }}</a>
+
{{ end }}
+
</li>
+
{{ else }}
+
<li>
+
{{ i18n "no-posts" }}
+
</li>
+
{{ end }}
+
</ul>
+
{{ if not .Data.Singular }}
+
<div>
+
{{ range .Site.Taxonomies.tags }}
+
<a class="blog-tags" href="{{ .Page.RelPermalink }}">#{{ lower .Page.Title }}</a>
+
{{ end }}
+
</div>
+
{{ end }}
+
</content>
+
{{ end }}
+72
http/themes/hugo-bearcub/layouts/_default/rss.xml
···
+
{{- /* Deprecate site.Author.email in favor of site.Params.author.email */}}
+
{{- $authorEmail := "" }}
+
{{- with site.Params.author }}
+
{{- if reflect.IsMap . }}
+
{{- with .email }}
+
{{- $authorEmail = . }}
+
{{- end }}
+
{{- end }}
+
{{- else }}
+
{{- with site.Author.email }}
+
{{- $authorEmail = . }}
+
{{- warnf "The author key in site configuration is deprecated. Use params.author.email instead." }}
+
{{- end }}
+
{{- end }}
+
+
{{- /* Deprecate site.Author.name in favor of site.Params.author.name */}}
+
{{- $authorName := "" }}
+
{{- with site.Params.author }}
+
{{- if reflect.IsMap . }}
+
{{- with .name }}
+
{{- $authorName = . }}
+
{{- end }}
+
{{- else }}
+
{{- $authorName = . }}
+
{{- end }}
+
{{- else }}
+
{{- with site.Author.name }}
+
{{- $authorName = . }}
+
{{- warnf "The author key in site configuration is deprecated. Use params.author.name instead." }}
+
{{- end }}
+
{{- end }}
+
+
{{- $pctx := . }}
+
{{- if .IsHome }}{{ $pctx = .Site }}{{ end }}
+
{{- $pages := slice }}
+
{{- if or $.IsHome $.IsSection }}
+
{{- $pages = $pctx.RegularPages }}
+
{{- else }}
+
{{- $pages = $pctx.Pages }}
+
{{- end }}
+
{{- $limit := .Site.Config.Services.RSS.Limit }}
+
{{- if ge $limit 1 }}
+
{{- $pages = $pages | first $limit }}
+
{{- end }}
+
{{- printf "<?xml version=\"1.0\" encoding=\"utf-8\" standalone=\"yes\"?>" | safeHTML }}
+
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/">
+
<channel>
+
<title>{{ if .IsHome }}{{ .Site.Title }}{{ else }}{{ with .Title }}{{ . }} on {{ end }}{{ .Site.Title }}{{ end }}</title>
+
<link>{{ .Permalink }}</link>
+
<description>Recent content {{ if not .IsHome }}{{ with .Title }}in {{ . }} {{ end }}{{ end }}on {{ .Site.Title }}</description>
+
<generator>Hugo -- gohugo.io</generator>
+
<language>{{ site.Language.LanguageCode }}</language>{{ with $authorEmail }}
+
<managingEditor>{{.}}{{ with $authorName }} ({{ . }}){{ end }}</managingEditor>{{ end }}{{ with $authorEmail }}
+
<webMaster>{{ . }}{{ with $authorName }} ({{ . }}){{ end }}</webMaster>{{ end }}{{ with .Site.Copyright }}
+
<copyright>{{ . }}</copyright>{{ end }}{{ if not .Date.IsZero }}
+
<lastBuildDate>{{ .Date.Format "Mon, 02 Jan 2006 15:04:05 -0700" | safeHTML }}</lastBuildDate>{{ end }}
+
{{- with .OutputFormats.Get "RSS" }}
+
{{ printf "<atom:link href=%q rel=\"self\" type=%q />" .Permalink .MediaType | safeHTML }}
+
{{- end }}
+
{{- range $pages }}
+
<item>
+
<title>{{ .Title }}</title>
+
<link>{{ .Permalink }}</link>
+
<pubDate>{{ .Date.Format "Mon, 02 Jan 2006 15:04:05 -0700" | safeHTML }}</pubDate>
+
{{- with $authorEmail }}<author>{{ . }}{{ with $authorName }} ({{ . }}){{ end }}</author>{{ end }}
+
<guid>{{ .Permalink }}</guid>
+
<description>{{ .Summary | transform.XMLEscape | safeHTML }}</description>
+
<content:encoded>{{ `<![CDATA[` | safeHTML }}{{ .Content | safeHTML }}{{ `]]>` | safeHTML }}</content:encoded>
+
</item>
+
{{- end }}
+
</channel>
+
</rss>
+28
http/themes/hugo-bearcub/layouts/_default/single.html
···
+
{{ define "main" }}
+
{{ if not .Params.menu }}
+
<h1>{{ .Title }}</h1>
+
<p class="byline">
+
<time datetime='{{ .Date.Format "2006-01-02" }}' pubdate>
+
{{ .Date.Format (default "2006-01-02" .Site.Params.dateFormat) }}
+
</time>
+
{{ with .Params.author }}· {{.}}{{ end }}
+
</p>
+
{{ end }}
+
<content>
+
{{ .Content }}
+
</content>
+
<p>
+
{{ range (.GetTerms "tags") }}
+
<a class="blog-tags" href="{{ .RelPermalink }}">#{{ lower .LinkTitle }}</a>
+
{{ end }}
+
</p>
+
{{ if not .Params.hideReply }}
+
{{ with .Site.Params.author.email }}
+
<p>
+
<a href='mailto:{{ . }}?subject={{ i18n "email-subject" }}"{{ default $.Site.Title $.Page.Title }}"'>
+
{{ i18n "email-reply" }} ↪
+
</a>
+
</p>
+
{{ end }}
+
{{ end }}
+
{{ end }}
+3
http/themes/hugo-bearcub/layouts/index.html
···
+
{{ define "main" }}
+
{{ .Content }}
+
{{ end }}
+6
http/themes/hugo-bearcub/layouts/page/_markup/render-codeblock.html
···
+
<!-- https://github.com/jmooring/hugo-testing/blob/hugo-forum-topic-40998/layouts/_default/_markup/render-codeblock-katex.html -->
+
{{ .Page.Store.Set "hasCodeBlock" true }}
+
+
<!-- https://www.veriphor.com/articles/code-block-render-hooks/ -->
+
{{ $result := transform.HighlightCodeBlock . }}
+
{{ $result.Wrapped }}
+47
http/themes/hugo-bearcub/layouts/page/baseof.html
···
+
<!DOCTYPE html>
+
<html lang="{{ with .Site.LanguageCode }}{{ . }}{{ else }}en-US{{ end }}">
+
+
<head>
+
<meta http-equiv="X-Clacks-Overhead" content="GNU Terry Pratchett" />
+
<meta charset="utf-8">
+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
+
{{- partial "favicon.html" . -}}
+
<title>{{- block "title" . }}{{ with .Title }}{{ . }} | {{ end }}{{ .Site.Title }}{{- end }}</title>
+
+
{{- partial "seo_tags.html" . -}}
+
<meta name="referrer" content="no-referrer-when-downgrade" />
+
+
{{ $style := print (default "original" .Site.Params.themeStyle) ".css" | resources.Get | minify }}
+
<link href="{{ $style.RelPermalink }}" rel="stylesheet">
+
+
{{ if (.Page.Store.Get "hasCodeBlock") }}
+
{{ $syntax := resources.Get "syntax.css" | minify }}
+
<link href="{{ $syntax.RelPermalink }}" rel="stylesheet">
+
{{ end }}
+
+
{{ with .Params.style }}
+
{{ $extra := resources.Get . | minify }}
+
<link href="{{ $extra.RelPermalink }}" rel="stylesheet">
+
{{ end }}
+
+
{{ with .OutputFormats.Get "rss" -}}
+
{{ printf `
+
<link rel="%s" type="%s" href="%s" title="%s" />` .Rel .MediaType.Type .Permalink $.Site.Title | safeHTML }}
+
{{ end -}}
+
+
</head>
+
+
<body>
+
<header>
+
{{- partial "header.html" . -}}
+
</header>
+
<main id="main-content">
+
{{- block "main" . }}{{- end }}
+
</main>
+
<footer>
+
{{- partial "footer.html" . -}}
+
</footer>
+
+
</body>
+
+
</html>
+22
http/themes/hugo-bearcub/layouts/page/single.html
···
+
{{ define "main" }}
+
{{ if not .Params.menu }}
+
<h1>{{ .Title }}</h1>
+
{{ end }}
+
<content>
+
{{ .Content }}
+
</content>
+
<p>
+
{{ range (.GetTerms "tags") }}
+
<a class="blog-tags" href="{{ .RelPermalink }}">#{{ lower .LinkTitle }}</a>
+
{{ end }}
+
</p>
+
{{ if not .Params.hideReply }}
+
{{ with .Site.Params.author.email }}
+
<p>
+
<a href='mailto:{{ . }}?subject={{ i18n "email-subject" }}"{{ default $.Site.Title $.Page.Title }}"'>
+
{{ i18n "email-reply" }} ↪
+
</a>
+
</p>
+
{{ end }}
+
{{ end }}
+
{{ end }}
+6
http/themes/hugo-bearcub/layouts/partials/breadcrumbs.html
···
+
<ul id="breadcrumbs">
+
{{- range .Ancestors.Reverse }}
+
<li><a href="{{ .RelPermalink }}">{{ .Title }}</a></li>
+
{{- end }}
+
<li><a href="{{ .RelPermalink }}">{{ .Title }}</a></li>
+
</ul>
+3
http/themes/hugo-bearcub/layouts/partials/custom_body.html
···
+
<!-- A partial to be overwritten by the user.
+
Simply place a custom_body.html into
+
your local /layouts/partials-directory -->
+3
http/themes/hugo-bearcub/layouts/partials/custom_head.html
···
+
<!-- A partial to be overwritten by the user.
+
Simply place a custom_head.html into
+
your local /layouts/partials-directory -->
+2
http/themes/hugo-bearcub/layouts/partials/favicon.html
···
+
{{ with .Site.Params.favicon }}
+
<link rel="shortcut icon" href="{{ absURL . }}" />{{ end }}
+3
http/themes/hugo-bearcub/layouts/partials/footer.html
···
+
<small>
+
{{ .Site.Copyright }} | {{ markdownify .Site.Params.madeWith }}
+
</small>
+6
http/themes/hugo-bearcub/layouts/partials/header.html
···
+
<a class="skip-link" href="#main-content">{{ i18n "skip-link" }}</a>
+
+
<a href="{{ relURL .Site.Home.RelPermalink }}" class="title">
+
<h1>{{ .Site.Title }}</h1>
+
</a>
+
<nav>{{- partial "nav.html" . -}}</nav>
+22
http/themes/hugo-bearcub/layouts/partials/nav.html
···
+
{{ range .Site.Menus.main.ByWeight }}
+
<a href="{{ .URL }}">{{ .Name }}</a>
+
{{ end }}
+
<a href='{{ absURL "index.xml" }}'>RSS</a>
+
+
<!-- Convert this page's translations into a dict -->
+
{{ $translations := dict }}
+
{{ range .Translations }}
+
{{ $translations = merge $translations (dict .Language.Lang .) }}
+
{{ end }}
+
+
<!-- Create a link to every translation -->
+
{{ range where .Site.Languages "Lang" "!=" .Page.Lang }}
+
{{ with (index $translations .Lang) }}
+
<a href="{{ .RelPermalink }}">{{ .Language.LanguageName }}</a>
+
{{ else }}
+
<!-- The complicated setup was necessary to make a grayed out link -->
+
{{ if not .Params.hideUntranslated }}
+
<a class="disabled" role="link" aria-disabled="true">{{ .LanguageName }}</a>
+
{{ end }}
+
{{ end }}
+
{{ end }}
+22
http/themes/hugo-bearcub/layouts/partials/seo_tags.html
···
+
<!-- Primary Meta Tags -->
+
<meta name="title" content="{{ with .Title }}{{ . }}{{ else }}{{ .Site.Title }}{{ end }}" />
+
<meta name="description" content="{{ with .Description }}{{ . }}{{ else }}{{if .IsPage}}{{ .Summary }}{{ else }}{{ with .Site.Params.description }}{{ . }}{{ end }}{{ end }}{{ end }}" />
+
<meta name="author" content="{{ with .Params.author }}{{ . }}{{ end }}" />
+
<meta name="keywords" content="{{ if .IsPage}}{{ range $index, $tag := .Params.tags }}{{ $tag }},{{ end }}{{ else }}{{ range $plural, $terms := .Site.Taxonomies }}{{ range $term, $val := $terms }}{{ printf "%s," $term }}{{ end }}{{ end }}{{ end }}" />
+
+
<!-- Only generate social card if: -->
+
<!-- - generateSocialCard = true -->
+
<!-- - there aren't images set in frontmatter -->
+
<!-- - page is of .Kind "page" -->
+
{{ if and (and (default false .Site.Params.generateSocialCard) (not (isset .Params "images"))) (eq .Kind "page") }}
+
{{ partial "social_card.html" . }}
+
{{ else }}
+
<!-- Open Graph / Facebook -->
+
{{ template "_internal/opengraph.html" . }}
+
+
<!-- Twitter -->
+
{{ template "_internal/twitter_cards.html" . }}
+
+
<!-- Microdata -->
+
{{ template "_internal/schema.html" . }}
+
{{ end }}
+136
http/themes/hugo-bearcub/layouts/partials/social_card.html
···
+
<!-- Dynamic social card generation -->
+
{{ $font := resources.GetRemote "https://github.com/google/fonts/raw/main/ofl/firamono/FiraMono-Bold.ttf" }}
+
{{ $fg := resources.Get "images/social_card_fg.png"}}
+
{{ $bg := resources.Get "images/social_card_bg.png"}}
+
+
{{ if gt (len .Title) 45 }}
+
{{ $fg = $fg.Filter (images.Text .Title (dict
+
"font" $font
+
"color" "#fafafa"
+
"size" 95
+
"linespacing" 16
+
"x" 0
+
"y" 0
+
)) }}
+
{{ else }}
+
{{ $fg = $fg.Filter (images.Text .Title (dict
+
"font" $font
+
"color" "#fafafa"
+
"size" 130
+
"linespacing" 20
+
"x" 0
+
"y" 0
+
)) }}
+
{{ end }}
+
+
{{ $date := .Date.Format (default "2006-01-02" .Site.Params.dateFormat) }}
+
{{ $author := (default $.Site.Params.author.name ($.Param "author") ) }}
+
{{ $byline := (printf "%s | %s" $author $date) }}
+
+
{{ $fg = $fg.Filter (images.Text $byline (dict
+
"font" $font
+
"color" "#898a8d"
+
"size" 60
+
"linespacing" 30
+
"x" 0
+
"y" 425
+
)) }}
+
+
{{ $card := $bg.Filter (images.Overlay $fg 112 140 ) }}
+
{{ $card := $card.Resize "900x webp q100" }}
+
+
<!-- Open Graph / Facebook -->
+
<!-- Source: https://github.com/gohugoio/hugo/blob/master/tpl/tplimpl/embedded/templates/opengraph.html -->
+
<meta property="og:title" content="{{ .Title }}" />
+
<meta property="og:description" content="{{ with .Description }}{{ . }}{{ else }}{{if .IsPage}}{{ .Summary }}{{ else }}{{ with .Site.Params.description }}{{ . }}{{ end }}{{ end }}{{ end }}" />
+
<meta property="og:type" content="{{ if .IsPage }}article{{ else }}website{{ end }}" />
+
<meta property="og:url" content="{{ .Permalink }}" />
+
+
<meta property="og:image" content="{{ $card.Permalink | absURL }}"/>
+
+
{{- if .IsPage }}
+
{{- $iso8601 := "2006-01-02T15:04:05-07:00" -}}
+
<meta property="article:section" content="{{ .Section }}" />
+
{{ with .PublishDate }}<meta property="article:published_time" {{ .Format $iso8601 | printf "content=%q" | safeHTMLAttr }} />{{ end }}
+
{{ with .Lastmod }}<meta property="article:modified_time" {{ .Format $iso8601 | printf "content=%q" | safeHTMLAttr }} />{{ end }}
+
{{- end -}}
+
+
{{- with .Params.audio }}<meta property="og:audio" content="{{ . }}" />{{ end }}
+
{{- with .Params.locale }}<meta property="og:locale" content="{{ . }}" />{{ end }}
+
{{- with .Site.Params.title }}<meta property="og:site_name" content="{{ . }}" />{{ end }}
+
{{- with .Params.videos }}{{- range . }}
+
<meta property="og:video" content="{{ . | absURL }}" />
+
{{ end }}{{ end }}
+
+
{{- /* If it is part of a series, link to related articles */}}
+
{{- $permalink := .Permalink }}
+
{{- $siteSeries := .Site.Taxonomies.series }}
+
{{- if $siteSeries }}
+
{{ with .Params.series }}{{- range $name := . }}
+
{{- $series := index $siteSeries ($name | urlize) }}
+
{{- range $page := first 6 $series.Pages }}
+
{{- if ne $page.Permalink $permalink }}<meta property="og:see_also" content="{{ $page.Permalink }}" />{{ end }}
+
{{- end }}
+
{{ end }}{{ end }}
+
{{- end }}
+
+
{{- /* Deprecate site.Social.facebook_admin in favor of site.Params.social.facebook_admin */}}
+
{{- $facebookAdmin := "" }}
+
{{- with site.Params.social }}
+
{{- if reflect.IsMap . }}
+
{{- $facebookAdmin = .facebook_admin }}
+
{{- end }}
+
{{- else }}
+
{{- with site.Social.facebook_admin }}
+
{{- $facebookAdmin = . }}
+
{{- warnf "The social key in site configuration is deprecated. Use params.social.facebook_admin instead." }}
+
{{- end }}
+
{{- end }}
+
+
{{- /* Facebook Page Admin ID for Domain Insights */}}
+
{{ with $facebookAdmin }}<meta property="fb:admins" content="{{ . }}" />{{ end }}
+
+
<!-- Twitter -->
+
<!-- Source: https://github.com/gohugoio/hugo/blob/master/tpl/tplimpl/embedded/templates/twitter_cards.html -->
+
<meta name="twitter:card" content="summary_large_image"/>
+
<meta name="twitter:image" content="{{ $card.Permalink | absURL }}"/>
+
<meta name="twitter:title" content="{{ .Title }}"/>
+
<meta name="twitter:description" content="{{ with .Description }}{{ . }}{{ else }}{{if .IsPage}}{{ .Summary }}{{ else }}{{ with .Site.Params.description }}{{ . }}{{ end }}{{ end }}{{ end -}}"/>
+
+
{{- /* Deprecate site.Social.twitter in favor of site.Params.social.twitter */}}
+
{{- $twitterSite := "" }}
+
{{- with site.Params.social }}
+
{{- if reflect.IsMap . }}
+
{{- $twitterSite = .twitter }}
+
{{- end }}
+
{{- else }}
+
{{- with site.Social.twitter }}
+
{{- $twitterSite = . }}
+
{{- warnf "The social key in site configuration is deprecated. Use params.social.twitter instead." }}
+
{{- end }}
+
{{- end }}
+
+
{{- with $twitterSite }}
+
{{- $content := . }}
+
{{- if not (strings.HasPrefix . "@") }}
+
{{- $content = printf "@%v" $twitterSite }}
+
{{- end }}
+
<meta name="twitter:site" content="{{ $content }}"/>
+
{{- end }}
+
+
<!-- Microdata -->
+
<!-- Source: https://github.com/gohugoio/hugo/blob/master/tpl/tplimpl/embedded/templates/schema.html -->
+
<meta itemprop="name" content="{{ .Title }}">
+
<meta itemprop="description" content="{{ with .Description }}{{ . }}{{ else }}{{if .IsPage}}{{ .Summary }}{{ else }}{{ with .Site.Params.description }}{{ . }}{{ end }}{{ end }}{{ end }}">
+
+
{{- if .IsPage -}}
+
{{- $iso8601 := "2006-01-02T15:04:05-07:00" -}}
+
{{ with .PublishDate }}<meta itemprop="datePublished" {{ .Format $iso8601 | printf "content=%q" | safeHTMLAttr }} />{{ end}}
+
{{ with .Lastmod }}<meta itemprop="dateModified" {{ .Format $iso8601 | printf "content=%q" | safeHTMLAttr }} />{{ end}}
+
<meta itemprop="wordCount" content="{{ .WordCount }}">
+
+
<meta itemprop="image" content="{{ $card.Permalink | absURL }}"/>
+
+
<!-- Output all taxonomies as schema.org keywords -->
+
<meta itemprop="keywords" content="{{ if .IsPage}}{{ range $index, $tag := .Params.tags }}{{ $tag }},{{ end }}{{ else }}{{ range $plural, $terms := .Site.Taxonomies }}{{ range $term, $val := $terms }}{{ printf "%s," $term }}{{ end }}{{ end }}{{ end }}" />
+
{{- end -}}
+3
http/themes/hugo-bearcub/layouts/robots.txt
···
+
User-agent: *
+
Allow: /
+
Sitemap: {{ "sitemap.xml" | absURL }}
+29
http/themes/hugo-bearcub/layouts/shortcodes/absfigure.html
···
+
<figure{{ with .Get "class" }} class="{{ . }}"{{ end }}>
+
{{- if .Get "link" -}}
+
<a href="{{ .Get "link" }}"{{ with .Get "target" }} target="{{ . }}"{{ end }}{{ with .Get "rel" }} rel="{{ . }}"{{ end }}>
+
{{- end -}}
+
<img src="{{ .Get "src" | absURL}}"
+
{{- if or (.Get "alt") (.Get "caption") }}
+
alt="{{ with .Get "alt" }}{{ . }}{{ else }}{{ .Get "caption" | markdownify| plainify }}{{ end }}"
+
{{- end -}}
+
{{- with .Get "width" }} width="{{ . }}"{{ end -}}
+
{{- with .Get "height" }} height="{{ . }}"{{ end -}}
+
{{- with .Get "loading" }} loading="{{ . }}"{{ end -}}
+
/><!-- Closing img tag -->
+
{{- if .Get "link" }}</a>{{ end -}}
+
{{- if or (or (.Get "title") (.Get "caption")) (.Get "attr") -}}
+
<figcaption>
+
{{ with (.Get "title") -}}
+
<h4>{{ . }}</h4>
+
{{- end -}}
+
{{- if or (.Get "caption") (.Get "attr") -}}<p>
+
{{- .Get "caption" | markdownify -}}
+
{{- with .Get "attrlink" }}
+
<a href="{{ . }}">
+
{{- end -}}
+
{{- .Get "attr" | markdownify -}}
+
{{- if .Get "attrlink" }}</a>{{ end }}</p>
+
{{- end }}
+
</figcaption>
+
{{- end }}
+
</figure>
+5
http/themes/hugo-bearcub/layouts/shortcodes/highlight.html
···
+
<!-- https://github.com/jmooring/hugo-testing/blob/hugo-forum-topic-40998/layouts/_default/_markup/render-codeblock-katex.html -->
+
{{ .Page.Store.Set "hasCodeBlock" true }}
+
+
<!-- https://github.com/gohugoio/hugo/blob/master/tpl/tplimpl/embedded/templates/shortcodes/highlight.html -->
+
{{ if len .Params | eq 2 }}{{ highlight (trim .InnerDeindent "\n\r") (.Get 0) (.Get 1) }}{{ else }}{{ highlight (trim .InnerDeindent "\n\r") (.Get 0) "" }}{{ end }}
+2
http/themes/hugo-bearcub/layouts/shortcodes/rawhtml.html
···
+
<!-- raw html -->
+
{{.Inner}}
+29
http/themes/hugo-bearcub/theme.toml
···
+
name = "Bear Cub"
+
license = "MIT"
+
licenselink = "https://github.com/clente/hugo-bearcub/blob/master/LICENSE"
+
description = "A lightweight Hugo theme based on Bear Blog and Hugo Bear Blog. It is free, multilingual, optimized for search engines, no-nonsense, responsive, light, and fast. Really fast."
+
+
# The home page of the theme, where the source can be found.
+
homepage = "https://github.com/clente/hugo-bearcub"
+
+
# If you have a running demo of the theme.
+
demosite = "https://clente.github.io/hugo-bearcub"
+
+
tags = ["blog", "responsive", "minimal", "personal", "dark", "multilingual"]
+
features = ["favicon", "seo", "no javascript", "rss", "social cards"]
+
+
# If the theme has a single author
+
[author]
+
name = "Caio Lente"
+
homepage = "https://lente.dev"
+
+
# If porting an existing theme
+
[original]
+
author = "Jan Raasch"
+
homepage = "https://www.janraasch.com"
+
repo = "https://github.com/janraasch/hugo-bearblog"
+
+
# Hugo versions the theme supports
+
[module]
+
[module.hugoVersion]
+
min = "0.90"
+146
scripts/blog2gemlog
···
+
#!/usr/bin/env -S uv run --script
+
# /// script
+
# dependencies = [
+
# "feedgen",
+
# "feedparser",
+
# "md2gemini",
+
# ]
+
# ///
+
+
# 1. Take a markdown blog post as input, convert it to gemtext.
+
# 2. Update gemlog index.
+
# 3. Update the gemlog Atom feed.
+
+
import sys
+
from datetime import datetime
+
from pathlib import Path
+
from zoneinfo import ZoneInfo
+
+
import feedparser
+
from feedgen.feed import FeedGenerator
+
from md2gemini import md2gemini
+
+
# This is so that Python doesn't yell at me if I forget an argument. Not
+
# likely to happen, but still.
+
if len(sys.argv) != 3:
+
print('Usage: blog2gemlog /path/to/blog/post.md "Blog Post Title"')
+
exit(1)
+
+
# Set the absolute path to the gemini content directory
+
gemini_dir = Path.home().joinpath(
+
"repos/tildegit.org/hyperreal/hyperreal.coffee/gemini"
+
)
+
+
# Get the current date in YYYY-MM-DD format
+
date_now = datetime.now().strftime("%Y-%m-%d")
+
+
# Read blog post path from sys.argv[1] and ensure it is an absolute path
+
blog_post_path = Path(sys.argv[1])
+
if not blog_post_path.is_absolute():
+
print("Supply absolute path to blog post.")
+
exit(1)
+
+
# Convert the markdown blog post to gemtext
+
with open(blog_post_path, "r") as md_f:
+
content = md2gemini(md_f.read(), frontmatter=True, links="paragraph", md_links=True)
+
+
# Set the absolute path to the gemlog post
+
gemlog_post_path = gemini_dir.joinpath(f"gemlog/{blog_post_path.stem}.gmi")
+
+
# Write the gemtext content to the gemlog post path
+
with open(gemlog_post_path, "w") as gmi_f:
+
gmi_f.write(content)
+
+
# Set the string for the END section of the gemlog post
+
gemlog_end = f"\n\n## END\nLast updated: {date_now}\n\n=> ../gemlog Gemlog archive\n=> ../ hyperreal.coffee"
+
+
# Append gemlog_end to the end of the gemlog post
+
with open(gemlog_post_path, "a") as gmi_f:
+
gmi_f.write(gemlog_end)
+
+
# Read the gemlog post file lines into a list
+
with open(gemlog_post_path, "r") as gmi_f:
+
contents = gmi_f.readlines()
+
+
# Get the gemlog post title from sys.argv[2]
+
gemlog_post_title = str(sys.argv[2])
+
+
# Insert the gemlog post title as the level 1 heading on line 1
+
contents.insert(0, f"# {gemlog_post_title}\n\n")
+
+
# Write the new contents as a string to the gemlog file
+
with open(gemlog_post_path, "w") as gmi_f:
+
contents = "".join(contents)
+
gmi_f.write(contents)
+
+
# Read the lines of the gemlog index into a list
+
with open(gemini_dir.joinpath("gemlog/index.gmi"), "r") as index_f:
+
contents = index_f.readlines()
+
+
# Set the content of the gemlog index entry line
+
gemlog_index_line = f"=> ./{gemlog_post_path.name} {date_now} {gemlog_post_title}\n"
+
+
# Insert the new gemlog index line into the list on line 6
+
contents.insert(5, gemlog_index_line)
+
+
# Write the new contents as a string to the gemlog index file
+
with open(gemini_dir.joinpath("gemlog/index.gmi"), "w") as index_f:
+
contents = "".join(contents)
+
index_f.write(contents)
+
+
# Get a timezone-aware datetime object from a timestamp of the present moment
+
aware_ts = datetime.fromtimestamp(
+
datetime.timestamp(datetime.now()), tz=ZoneInfo("America/Chicago")
+
)
+
+
# Format the timezone-aware datetime object for the <updated> element of the
+
# Atom feed
+
updated_ts = aware_ts.strftime("%Y-%m-%dT%H:%M:%S%z")
+
+
# Instantiate a FeedParserDict object
+
d = feedparser.parse(gemini_dir.joinpath("gemlog/atom.xml"))
+
+
# Update the <updated> element's value to the current timestamp
+
d["updated"] = updated_ts
+
+
# Define a dictionary for the new Atom feed entry
+
new_entry_dict = {
+
"id": f"gemini://hyperreal.coffee/gemlog/{gemlog_post_path.name}",
+
"title": gemlog_post_title,
+
"updated": updated_ts,
+
"links": [
+
{
+
"href": f"gemini://hyperreal.coffee/gemlog/{gemlog_post_path.name}",
+
"rel": "alternate",
+
"type": "text/gemini",
+
}
+
],
+
}
+
+
# Insert the new Atom feed entry into the FeedParserDict
+
d["entries"].insert(0, new_entry_dict)
+
+
# Instantiate a FeedGenerator object and set the methods for the feed
+
fg = FeedGenerator()
+
fg.id(d["feed"]["id"])
+
fg.title(d["feed"]["title"])
+
fg.updated(d["feed"]["updated"])
+
fg.link(d["feed"]["links"])
+
+
# Reverse the order of d["entries"] so that they are written to the file in
+
# the correct order
+
d["entries"].reverse()
+
+
# For each entry, add a new entry to the FeedGenerator object
+
for entry in d["entries"]:
+
fe = fg.add_entry()
+
fe.id(entry["id"])
+
fe.title(entry["title"])
+
fe.updated(entry["updated"])
+
fe.link(entry["links"])
+
+
# Finally, render the FeedGenerator object as an Atom feed and write it to
+
# the atom.xml file
+
fg.atom_file(gemini_dir.joinpath("gemlog/atom.xml"), pretty=True)
+
+
# vim: ai et ft=python sts=4 sw=4 ts=4
+12
scripts/board_capsule
···
+
#!/usr/bin/env bash
+
+
WEBSITE_DIR="${HOME}/repos/tildegit.org/hyperreal/hyperreal.coffee/http"
+
GEMINI_DIR="${HOME}/repos/tildegit.org/hyperreal/hyperreal.coffee/gemini"
+
+
find "${WEBSITE_DIR}/content" \
+
-maxdepth 1 \
+
-type f \
+
-not -name "_index.md" \
+
-exec md2gemini -w -d "$GEMINI_DIR" -f -m {} \;
+
+
# vim: ai et ft=bash sts=4 sw=4 ts=4