summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore13
-rw-r--r--archetypes/default.md6
-rw-r--r--content/archives.md7
-rw-r--r--content/blog/adventures-on-monitorless-server.md44
-rw-r--r--content/blog/cs166-tips-tricks.md181
-rw-r--r--content/blog/link-clearance/1.md35
-rw-r--r--content/blog/on-continuations.md148
-rw-r--r--content/blog/org-mode-watchlist.md78
-rw-r--r--content/blog/tailscale-and-sjsu-vpn.md146
-rw-r--r--content/blog/vim-kitty-compat.md45
-rw-r--r--content/search.md5
-rw-r--r--hugo.yaml75
-rw-r--r--layouts/_default/archives.html4
-rw-r--r--themes/PaperMod/.github/ISSUE_TEMPLATE/bug.yaml (renamed from .github/ISSUE_TEMPLATE/bug.yaml)0
-rw-r--r--themes/PaperMod/.github/ISSUE_TEMPLATE/config.yml (renamed from .github/ISSUE_TEMPLATE/config.yml)0
-rw-r--r--themes/PaperMod/.github/ISSUE_TEMPLATE/enhancement.yaml (renamed from .github/ISSUE_TEMPLATE/enhancement.yaml)0
-rw-r--r--themes/PaperMod/.github/PULL_REQUEST_TEMPLATE.md (renamed from .github/PULL_REQUEST_TEMPLATE.md)0
-rw-r--r--themes/PaperMod/.github/workflows/gh-pages.yml (renamed from .github/workflows/gh-pages.yml)0
-rw-r--r--themes/PaperMod/LICENSE (renamed from LICENSE)0
-rw-r--r--themes/PaperMod/README.md (renamed from README.md)0
-rw-r--r--themes/PaperMod/assets/css/common/404.css (renamed from assets/css/common/404.css)0
-rw-r--r--themes/PaperMod/assets/css/common/archive.css (renamed from assets/css/common/archive.css)0
-rw-r--r--themes/PaperMod/assets/css/common/footer.css (renamed from assets/css/common/footer.css)0
-rw-r--r--themes/PaperMod/assets/css/common/header.css (renamed from assets/css/common/header.css)0
-rw-r--r--themes/PaperMod/assets/css/common/main.css (renamed from assets/css/common/main.css)0
-rw-r--r--themes/PaperMod/assets/css/common/post-entry.css (renamed from assets/css/common/post-entry.css)0
-rw-r--r--themes/PaperMod/assets/css/common/post-single.css (renamed from assets/css/common/post-single.css)0
-rw-r--r--themes/PaperMod/assets/css/common/profile-mode.css (renamed from assets/css/common/profile-mode.css)0
-rw-r--r--themes/PaperMod/assets/css/common/search.css (renamed from assets/css/common/search.css)0
-rw-r--r--themes/PaperMod/assets/css/common/terms.css (renamed from assets/css/common/terms.css)0
-rw-r--r--themes/PaperMod/assets/css/core/license.css (renamed from assets/css/core/license.css)0
-rw-r--r--themes/PaperMod/assets/css/core/reset.css (renamed from assets/css/core/reset.css)0
-rw-r--r--themes/PaperMod/assets/css/core/theme-vars.css (renamed from assets/css/core/theme-vars.css)0
-rw-r--r--themes/PaperMod/assets/css/core/zmedia.css (renamed from assets/css/core/zmedia.css)0
-rw-r--r--themes/PaperMod/assets/css/extended/blank.css (renamed from assets/css/extended/blank.css)0
-rw-r--r--themes/PaperMod/assets/css/includes/chroma-mod.css (renamed from assets/css/includes/chroma-mod.css)0
-rw-r--r--themes/PaperMod/assets/css/includes/chroma-styles.css (renamed from assets/css/includes/chroma-styles.css)0
-rw-r--r--themes/PaperMod/assets/css/includes/scroll-bar.css (renamed from assets/css/includes/scroll-bar.css)0
-rw-r--r--themes/PaperMod/assets/js/fastsearch.js (renamed from assets/js/fastsearch.js)0
-rw-r--r--themes/PaperMod/assets/js/fuse.basic.min.js (renamed from assets/js/fuse.basic.min.js)0
-rw-r--r--themes/PaperMod/assets/js/license.js (renamed from assets/js/license.js)0
-rw-r--r--themes/PaperMod/go.mod (renamed from go.mod)0
-rw-r--r--themes/PaperMod/i18n/ar.yaml (renamed from i18n/ar.yaml)0
-rw-r--r--themes/PaperMod/i18n/be.yaml (renamed from i18n/be.yaml)0
-rw-r--r--themes/PaperMod/i18n/bg.yaml (renamed from i18n/bg.yaml)0
-rw-r--r--themes/PaperMod/i18n/bn.yaml (renamed from i18n/bn.yaml)0
-rw-r--r--themes/PaperMod/i18n/ca.yaml (renamed from i18n/ca.yaml)0
-rw-r--r--themes/PaperMod/i18n/ckb.yaml (renamed from i18n/ckb.yaml)0
-rw-r--r--themes/PaperMod/i18n/cs.yaml (renamed from i18n/cs.yaml)0
-rw-r--r--themes/PaperMod/i18n/da.yaml (renamed from i18n/da.yaml)0
-rw-r--r--themes/PaperMod/i18n/de.yaml (renamed from i18n/de.yaml)0
-rw-r--r--themes/PaperMod/i18n/el.yaml (renamed from i18n/el.yaml)0
-rw-r--r--themes/PaperMod/i18n/en.yaml (renamed from i18n/en.yaml)0
-rw-r--r--themes/PaperMod/i18n/eo.yaml (renamed from i18n/eo.yaml)0
-rw-r--r--themes/PaperMod/i18n/es.yaml (renamed from i18n/es.yaml)0
-rw-r--r--themes/PaperMod/i18n/fa.yaml (renamed from i18n/fa.yaml)0
-rw-r--r--themes/PaperMod/i18n/fi.yaml (renamed from i18n/fi.yaml)0
-rw-r--r--themes/PaperMod/i18n/fr.yaml (renamed from i18n/fr.yaml)0
-rw-r--r--themes/PaperMod/i18n/he.yaml (renamed from i18n/he.yaml)0
-rw-r--r--themes/PaperMod/i18n/hi.yaml (renamed from i18n/hi.yaml)0
-rw-r--r--themes/PaperMod/i18n/hr.yaml (renamed from i18n/hr.yaml)0
-rw-r--r--themes/PaperMod/i18n/hu.yaml (renamed from i18n/hu.yaml)0
-rw-r--r--themes/PaperMod/i18n/id.yaml (renamed from i18n/id.yaml)0
-rw-r--r--themes/PaperMod/i18n/it.yaml (renamed from i18n/it.yaml)0
-rw-r--r--themes/PaperMod/i18n/ja.yaml (renamed from i18n/ja.yaml)0
-rw-r--r--themes/PaperMod/i18n/ko.yaml (renamed from i18n/ko.yaml)0
-rw-r--r--themes/PaperMod/i18n/ku.yaml (renamed from i18n/ku.yaml)0
-rw-r--r--themes/PaperMod/i18n/mn.yaml (renamed from i18n/mn.yaml)0
-rw-r--r--themes/PaperMod/i18n/ms.yaml (renamed from i18n/ms.yaml)0
-rw-r--r--themes/PaperMod/i18n/nl.yaml (renamed from i18n/nl.yaml)0
-rw-r--r--themes/PaperMod/i18n/no.yaml (renamed from i18n/no.yaml)0
-rw-r--r--themes/PaperMod/i18n/oc.yaml (renamed from i18n/oc.yaml)0
-rw-r--r--themes/PaperMod/i18n/pa.yaml (renamed from i18n/pa.yaml)0
-rw-r--r--themes/PaperMod/i18n/pl.yaml (renamed from i18n/pl.yaml)0
-rw-r--r--themes/PaperMod/i18n/pnb.yaml (renamed from i18n/pnb.yaml)0
-rw-r--r--themes/PaperMod/i18n/pt.yaml (renamed from i18n/pt.yaml)0
-rw-r--r--themes/PaperMod/i18n/ro.yaml (renamed from i18n/ro.yaml)0
-rw-r--r--themes/PaperMod/i18n/ru.yaml (renamed from i18n/ru.yaml)0
-rw-r--r--themes/PaperMod/i18n/sk.yaml (renamed from i18n/sk.yaml)0
-rw-r--r--themes/PaperMod/i18n/sv.yaml (renamed from i18n/sv.yaml)0
-rw-r--r--themes/PaperMod/i18n/sw.yaml (renamed from i18n/sw.yaml)0
-rw-r--r--themes/PaperMod/i18n/th.yaml (renamed from i18n/th.yaml)0
-rw-r--r--themes/PaperMod/i18n/tr.yaml (renamed from i18n/tr.yaml)0
-rw-r--r--themes/PaperMod/i18n/uk.yaml (renamed from i18n/uk.yaml)0
-rw-r--r--themes/PaperMod/i18n/uz.yaml (renamed from i18n/uz.yaml)0
-rw-r--r--themes/PaperMod/i18n/vi.yaml (renamed from i18n/vi.yaml)0
-rw-r--r--themes/PaperMod/i18n/zh-tw.yaml (renamed from i18n/zh-tw.yaml)0
-rw-r--r--themes/PaperMod/i18n/zh.yaml (renamed from i18n/zh.yaml)0
-rw-r--r--themes/PaperMod/images/screenshot.png (renamed from images/screenshot.png)bin141511 -> 141511 bytes
-rw-r--r--themes/PaperMod/images/tn.png (renamed from images/tn.png)bin15898 -> 15898 bytes
-rw-r--r--themes/PaperMod/layouts/404.html (renamed from layouts/404.html)0
-rw-r--r--themes/PaperMod/layouts/_default/_markup/render-image.html (renamed from layouts/_default/_markup/render-image.html)0
-rw-r--r--themes/PaperMod/layouts/_default/archives.html83
-rw-r--r--themes/PaperMod/layouts/_default/baseof.html (renamed from layouts/_default/baseof.html)0
-rw-r--r--themes/PaperMod/layouts/_default/index.json (renamed from layouts/_default/index.json)0
-rw-r--r--themes/PaperMod/layouts/_default/list.html (renamed from layouts/_default/list.html)0
-rw-r--r--themes/PaperMod/layouts/_default/rss.xml (renamed from layouts/_default/rss.xml)0
-rw-r--r--themes/PaperMod/layouts/_default/search.html (renamed from layouts/_default/search.html)0
-rw-r--r--themes/PaperMod/layouts/_default/single.html (renamed from layouts/_default/single.html)0
-rw-r--r--themes/PaperMod/layouts/_default/terms.html (renamed from layouts/_default/terms.html)0
-rw-r--r--themes/PaperMod/layouts/partials/anchored_headings.html (renamed from layouts/partials/anchored_headings.html)0
-rw-r--r--themes/PaperMod/layouts/partials/author.html (renamed from layouts/partials/author.html)0
-rw-r--r--themes/PaperMod/layouts/partials/breadcrumbs.html (renamed from layouts/partials/breadcrumbs.html)0
-rw-r--r--themes/PaperMod/layouts/partials/comments.html (renamed from layouts/partials/comments.html)0
-rw-r--r--themes/PaperMod/layouts/partials/cover.html (renamed from layouts/partials/cover.html)0
-rw-r--r--themes/PaperMod/layouts/partials/edit_post.html (renamed from layouts/partials/edit_post.html)0
-rw-r--r--themes/PaperMod/layouts/partials/extend_footer.html (renamed from layouts/partials/extend_footer.html)0
-rw-r--r--themes/PaperMod/layouts/partials/extend_head.html (renamed from layouts/partials/extend_head.html)0
-rw-r--r--themes/PaperMod/layouts/partials/footer.html (renamed from layouts/partials/footer.html)0
-rw-r--r--themes/PaperMod/layouts/partials/head.html (renamed from layouts/partials/head.html)0
-rw-r--r--themes/PaperMod/layouts/partials/header.html (renamed from layouts/partials/header.html)0
-rw-r--r--themes/PaperMod/layouts/partials/home_info.html (renamed from layouts/partials/home_info.html)0
-rw-r--r--themes/PaperMod/layouts/partials/index_profile.html (renamed from layouts/partials/index_profile.html)0
-rw-r--r--themes/PaperMod/layouts/partials/post_canonical.html (renamed from layouts/partials/post_canonical.html)0
-rw-r--r--themes/PaperMod/layouts/partials/post_meta.html (renamed from layouts/partials/post_meta.html)0
-rw-r--r--themes/PaperMod/layouts/partials/post_nav_links.html (renamed from layouts/partials/post_nav_links.html)0
-rw-r--r--themes/PaperMod/layouts/partials/share_icons.html (renamed from layouts/partials/share_icons.html)0
-rw-r--r--themes/PaperMod/layouts/partials/social_icons.html (renamed from layouts/partials/social_icons.html)0
-rw-r--r--themes/PaperMod/layouts/partials/svg.html (renamed from layouts/partials/svg.html)0
-rw-r--r--themes/PaperMod/layouts/partials/templates/_funcs/get-page-images.html (renamed from layouts/partials/templates/_funcs/get-page-images.html)0
-rw-r--r--themes/PaperMod/layouts/partials/templates/opengraph.html (renamed from layouts/partials/templates/opengraph.html)0
-rw-r--r--themes/PaperMod/layouts/partials/templates/schema_json.html (renamed from layouts/partials/templates/schema_json.html)0
-rw-r--r--themes/PaperMod/layouts/partials/templates/twitter_cards.html (renamed from layouts/partials/templates/twitter_cards.html)0
-rw-r--r--themes/PaperMod/layouts/partials/toc.html (renamed from layouts/partials/toc.html)0
-rw-r--r--themes/PaperMod/layouts/partials/translation_list.html (renamed from layouts/partials/translation_list.html)0
-rw-r--r--themes/PaperMod/layouts/robots.txt (renamed from layouts/robots.txt)0
-rw-r--r--themes/PaperMod/layouts/shortcodes/collapse.html (renamed from layouts/shortcodes/collapse.html)0
-rw-r--r--themes/PaperMod/layouts/shortcodes/figure.html (renamed from layouts/shortcodes/figure.html)0
-rw-r--r--themes/PaperMod/layouts/shortcodes/inTextImg.html (renamed from layouts/shortcodes/inTextImg.html)0
-rw-r--r--themes/PaperMod/layouts/shortcodes/ltr.html (renamed from layouts/shortcodes/ltr.html)0
-rw-r--r--themes/PaperMod/layouts/shortcodes/rawhtml.html (renamed from layouts/shortcodes/rawhtml.html)0
-rw-r--r--themes/PaperMod/layouts/shortcodes/rtl.html (renamed from layouts/shortcodes/rtl.html)0
-rw-r--r--themes/PaperMod/theme.toml (renamed from theme.toml)0
133 files changed, 870 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..86c95ef
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,13 @@
+# Generated files by hugo
+/public/
+/resources/_gen/
+/assets/jsconfig.json
+hugo_stats.json
+
+# Executable may be added to repository
+hugo.exe
+hugo.darwin
+hugo.linux
+
+# Temporary lock file while building
+/.hugo_build.lock
diff --git a/archetypes/default.md b/archetypes/default.md
new file mode 100644
index 0000000..00e77bd
--- /dev/null
+++ b/archetypes/default.md
@@ -0,0 +1,6 @@
+---
+title: "{{ replace .Name "-" " " | title }}"
+date: {{ .Date }}
+draft: true
+---
+
diff --git a/content/archives.md b/content/archives.md
new file mode 100644
index 0000000..6d0673d
--- /dev/null
+++ b/content/archives.md
@@ -0,0 +1,7 @@
+---
+title: "An Archive of All Posts"
+layout: "archives"
+summary: "archives"
+---
+
+Browse by: [↳ tags](/tags) or [↳ categories](/categories)
diff --git a/content/blog/adventures-on-monitorless-server.md b/content/blog/adventures-on-monitorless-server.md
new file mode 100644
index 0000000..47b61db
--- /dev/null
+++ b/content/blog/adventures-on-monitorless-server.md
@@ -0,0 +1,44 @@
+---
+title: "Adventures on server setup without a monitor"
+date: 2024-11-18T21:41:35-08:00
+tags: ["networking"]
+ShowToc: false
+---
+
+A story of frantically rescuing a deployed headless server, where I forget to statically assign an IP address.
+It just won't have network connection. No SSH. No fixie.
+
+Except _there is nothing saying a DHCP server has to be running on the router or gateway_.
+So, just install and configure `kea` (or a DHCP server of your choice) on any other computer on the network, reboot the server in question, and voilà!
+SSH to your hearts content.
+
+---
+
+So the story goes like this.
+I recently got hands on a nice little old desktop tower, plenty of RAM and a good number of SATA ports for selfhosting: Seafile, Immich and what not.
+Now it _is_ rather old machine, with only VGA and DVI on the motherboard. This means my little trusty HDMI to USB video capture dongle won't be helpful!
+I also need to deploy this machine to my parent's house, for I plan on giving them access to a photo backup solution.
+I need to bring a monitor that has a VGA port on it.
+
+So I at the comfort of my home, I took some time to install Debian, as well as all other packages I could possibly need. Also configured a SSH key.
+
+And as all good stories go, the _one thing_ I was supposed to do was not done. I didn't assign a static IP to `eth0` beforehand.
+
+_Uh. oh._
+
+There is no proper DHCP in the lan, I had everything else setup with static IPs. I don't know its MAC, so no calculating SLAAC by hand to get a link local IPv6 either. In fact, if I remember correctly I don't even think the gateway was properly setup with IPv6 at all.
+
+No network, no SSH.
+
+No monitor, no way to see what's happening on screen to configure its WiFi connection properly.
+
+Quickly, I thought "what if I could just type out all the commands without a monitor?"
+Trying to open vim on `/etc/network/interfaces` and blindly modifying a complex configuration file obviously did not work so well.
+Although I did figure out one helpful tidbit: since this machine has a beeper, I can run things like `foobar && tput bel` in TTY to get an audio confirmation that something succeeded.
+
+After ten minutes of desparately trying various commands and questioning if I had been making typos all along, an enlightenment suddenly found its way into my mind: nothing is stopping me from running an ad-hoc DHCP server just for this purpose!
+As far as I know, all of the networking implementations shipped by various Linux distros default to DHCP. This includes `NetworkManager`, `systemd-networkd`, or even Debian's default networking setup.
+
+[Kea](https://www.isc.org/kea/) is apparently the recommended implementation, so I installed it on my laptop, and after some fiddling of configs per the [ArchWiki](https://wiki.archlinux.org/title/Kea) (because ArchWiki is the one wiki to rule them all), it did work. The server allocates the first address in the pool, so I just picked `192.168.233.1/16` and successfully SSH-ed in.
+
+No need to drive 30 minutes round trip to get my VGA monitor!
diff --git a/content/blog/cs166-tips-tricks.md b/content/blog/cs166-tips-tricks.md
new file mode 100644
index 0000000..82a17e9
--- /dev/null
+++ b/content/blog/cs166-tips-tricks.md
@@ -0,0 +1,181 @@
+---
+title: "Tips and tricks: CS 166 Information Security taught by Mark Stamp"
+date: 2025-05-13T15:27:00-07:00
+tags: ["SJSU"]
+---
+
+A collection of troubleshooting notes, general tips and tricks, or personal thoughts on the CS 166 Information Security class taught by Mark Stamp at SJSU.
+
+Part of this, dealing with specific homework problems, is written with the intention of being a last-resort rescue manual. I only include information you need to get out of potential deep water. No solutions to hard problems. No hand holding, especially no "here is how you solve this problem".
+
+The other part, the tips and thoughts, is just that. I will not stop myself blabbering on for forever.
+
+---
+
+# Recommended Tools
+
+## Hex editor
+I'm only listing two of my favorites here.
+
+HxD <https://mh-nexus.de/en/hxd/>
+
+A very light, Windows-only hex editor. I use it on my laptop for quick things. It definitely will suffice for this class.
+
+ImHex <https://imhex.werwolv.net/>
+
+Much more powerful, but heavier. It has builtin support for pattern matching, processing, disassembly, etc. It also just looks _really really nice_, 200% eye candy factor.
+
+## C compiler
+Some assignments supply C source code that you'll have to compile. In general, they are not compatible with MSVC (Visual Studio), so special care needs taken on Windows.
+
+- macOS: install Xcode Command Line Tools, which contains an Apple-flavored clang. Alternatively, install either clang or gcc from [Homebrew](https://brew.sh/).
+- Liunx: your distro's gcc will do. Or clang if you like that. Honestly if you use Linux why are you even reading this section, go away. :P
+- Windows: install some flavor of gcc
+ - I highly recommend <https://nuwen.net/mingw.html>
+ It’s tiny, just a zip file. Unzip it, you get a `open_distro_window.bat`, which when opened gives you a terminal with everything setup. There is _zero_ room for `PATH` to go wrong.
+ - Otherwise, https://www.msys2.org/
+
+{{< details summary="What's MinGW and what does it have to do with msys2 and cygwin" >}}
+In short, gcc is to MinGW as Linux is to distros.
+
+gcc is a whole bunch of code that can turn C source code, among other things, into an executable. It's designed to run on various \*nix platforms.
+
+MinGW is a bunch of extra code _on top of gcc_ to make it (1) run on Windows, and (2) produce Windows ("PECOFF") executable.
+
+Both projects are just code, they don't provide downloads ("builds"). For gcc, various Linux distros compile them and ship it as a package.
+For MinGW, these projects do the same job:
+
+- https://winlibs.com/
+- https://github.com/niXman/mingw-builds-binaries
+- https://cygwin.com/ \
+ This one tries to emulate the *nix environment on Windows. Comes with quite a few extra programs like bash. _See google._
+- https://www.msys2.org/ \
+ This one builds a whole bunch of softwares in addition to MinGW: bash, make, etc. It's quite complicated, due to those software requring compatibility layers like cygwin to function. I won't explain here. _See google._
+- etc.
+
+Regardless of which one you download, you get a copy of gcc (and MinGW). The difference is the default configs, and the extra software they ship with gcc.
+
+In fact, you'll hear people call these things "MinGW distros".
+The MinGW project has a [list of notable distros](https://www.mingw-w64.org/downloads/).
+
+I would have linked something instead of writing this myself, but I literally can't find anything of good quality on the internet...
+{{< /details >}}
+
+## x86 Static Analysis
+
+Some assignments ask you to disassemble and understand what a program is doing. For this—as is explained in Chapter 12 of the 3rd ed. textbook—you will need a disassembler that turns the bytes in the executable into assembly code.
+
+I am talking specifically about the offline disassembly and analysis functions. [They also do debugging](#x86-dynamic-analysis).
+
+I recommend **Ghidra** because that's what I use.
+Realistically, for the things you'll do in this class, either choice will work just fine.
+Similarly, comments below are targeted to use for this class. They're are shallow on purpose.
+
+- [Ghidra](https://ghidra-sre.org). Completely free and open-source. Looks kind of ugly but once you get over that and interaction logic, it's good.
+
+- [ ] [IDA Pro](https://hex-rays.com/ida-pro). Slightly closer eye candy. The built-in pattern matching works slightly better. Lots of people like it, so it (must also be) good. _This costs money_, there is a [free version](https://hex-rays.com/ida-free) but it doesn't come with a decompiler... not good.
+
+ According to legend, alfs who have passed the great challenge will be rewarded a completely legitimate, legal way of using IDA Pro. Let the brave thus sail forth.
+
+- [Binary Ninja](https://binary.ninja). Apparently this is a thing so I'm including it here for completeness, never used, never heard until today, no remarks.
+
+None of these are intuitive, so please consult the respective _manuals_ and youtube _tutorial videos_ copiously. I shall not provide any guidance here because this blog will turn into the thickness of _Critique of Pure Reason_ or something.
+
+## x86 Dynamic Analysis
+
+Do note that all the tools above can also do debugging. Perfectly capable for the job for this class.
+
+I really like [x64dbg](https://x64dbg.com) (which does both x86\_32 and x86\_64). For reference, the 3rd edition of the textbook recommends [OllyDbg](https://www.ollydbg.de) (32-bit only), but it doesn't receive updates anymore, so it won't be as much of a transferable skill. It'll still work great though.
+
+## Java Decompiler
+
+As of the writing of this blog, I shall claim FernFlower is the best Java decompiler available._<sub>runs<sub><sub>don't slap me don't slap me</sub></sub></sub>_
+
+Admittedly, I'm biased because I worked on Minecraft modding for a while, and Fernflower is what the whole community settled on... anyways!
+
+It's bundled in **IntelliJ IDEA**. You can just open any .class file and it will decompile.
+
+It's also available as a **CLI tool**. If you're going this route, consider using one of the forks that grew from the Minecraft modding efforts, such as [Vineflower](https://vineflower.org). It's not going to matter for whatever you'll be doing in this class, but support their efforts!
+
+# Chapter 5
+## Problem 4 - hash collision
+Hint: the expected answer _is not_ the exact solution. That's way too complicated
+
+I did end up in quite a rabbit hole trying to find the exact solution. These are not relevant to the textbook at all, but they're still interesting reads:
+- https://math.stackexchange.com/questions/407307/second-pair-of-matching-birthdays
+- https://math.stackexchange.com/questions/2313215/birthday-paradox-2-pairs (same thing, just less general and less verbose)
+- https://math.stackexchange.com/questions/1539271/probability-of-exactly-two-pairs-share-a-birthday-and-each-pair-shares-differen
+
+{{< details summary="More hint" >}}
+It's the square root approximation that’s implied, but much glossed over in the textbook. Fuller explaination here:
+https://en.m.wikipedia.org/wiki/Birthday_problem#Square_approximation
+{{< /details >}}
+
+## Problem 24 - MD5 collision
+### I'm getting different hashes
+The messages are supposed to be binary files, but the textbook gave them in hex codes.
+You probably need something like `xxd -r -p`, or [powershell](https://stackoverflow.com/a/64927815), or your hex editor of choice, to turn it into a binary message.
+
+{{< details >}}
+Something like these will work:
+```sh
+$ cut -d ' ' -f 2- <<'EOF' | xxd -r -p > msg1.bin
+00000000 d1 31 dd 02 c5 e6 ee c4 69 3d 9a 06 98 af f9 5c
+00000010 2f ca b5 87 12 46 7e ab 40 04 58 3e b8 fb 7f 89
+00000020 55 ad 34 06 09 f4 b3 02 83 e4 88 83 25 71 41 5a
+00000030 08 51 25 e8 f7 cd c9 9f d9 1d bd f2 80 37 3c 5b
+00000040 96 0b 1d d1 dc 41 7b 9c e4 d8 97 f4 5a 65 55 d5
+00000050 35 73 9a c7 f0 eb fd 0c 30 29 f1 66 d1 09 b1 8f
+00000060 75 27 7f 79 30 d5 5c eb 22 e8 ad ba 79 cc 15 5c
+00000070 ed 74 cb dd 5f c5 d3 6d b1 9b 0a d8 35 cc a7 e3
+EOF
+$ cut -d ' ' -f 2- <<'EOF' | xxd -r -p > msg2.bin
+00000000 d1 31 dd 02 c5 e6 ee c4 69 3d 9a 06 98 af f9 5c
+00000010 2f ca b5 07 12 46 7e ab 40 04 58 3e b8 fb 7f 89
+00000020 55 ad 34 06 09 f4 b3 02 83 e4 88 83 25 f1 41 5a
+00000030 08 51 25 e8 f7 cd c9 9f d9 1d bd 72 80 37 3c 5b
+00000040 96 0b 1d d1 dc 41 7b 9c e4 d8 97 f4 5a 65 55 d5
+00000050 35 73 9a 47 f0 eb fd 0c 30 29 f1 66 d1 09 b1 8f
+00000060 75 27 7f 79 30 d5 5c eb 22 e8 ad ba 79 4c 15 5c
+00000070 ed 74 cb dd 5f c5 d3 6d b1 9b 0a 58 35 cc a7 e3
+EOF
+$ md5sum msg1.bin msg2.bin
+```
+
+FYI, `cut` is used to strip the address column from the string.
+{{< /details >}}
+
+## Problem 39 - stenography
+### Getting a blank PDF on windows
+The given `stegoRead.c` and `stego.c` is using `fopen(2)` in text mode, and CRT on Windows _may_ expand byte sequence 0A (\n) to 0D 0A (\r\n). I'm honestly not sure when it decides to do that.
+
+Add `b` to the mode of all instances of `fopen(...)`. For example, change `fopen(outfname, "w")` into `fopen(outfname, "wb")`
+
+# Chapter 12
+Remember to use your favorite search engine to learn. The internet exists for a reason.
+
+## Your OS
+All the programs provided here are Windows PECOFF executables.
+
+If you have macOS/Linux, they should all work just fine in Wine (or variants it thereof). You may also grab a Windows VM to run them if Wine doesn't work somehow. Do consider using an under version, e.g. XP or 7 just so it's lighter on the resource usage. (Remember to disconnect internet to the VM if you are using an old Windows!)
+
+## x86 assembly
+You'll need a basic understanding of x86 32-bit assembly for this chapter. Very little is required, so whatever you know above another assembly should be transferable.
+
+General tip 0: x86 assembly has 2 syntax flavors, AT&T and Intel. Internet resources may use either, just be ware. GCC and whatnot by default produces AT&T syntax (🤮); if you see lots of % everywhere, or things like `movq` it's this. The textbook and all the reverse engineering tools use Intel syntax (💖 as they should); if you see square brackets `[rip+32h]` or bare `mov`'s, it's this.
+
+General tip 1: `je`/`jz` and `jne`/`jnz` are the same instructions, just different mnemonics. You can always replace either with an unconditional `jmp` in place, they have the same encoding length.
+
+General tip 2: `test reg1,reg2` means taking a bitwise AND, and set zero/carry flags accordingly. `xor reg1,reg1` is a convenient, 2 byte instruction that zeros any register.
+
+General tip 3: almost all the string literals are contained in the `.rdata` section.
+
+General tip 4: `rip` is the instruction pointer. Your debugger probably has a "set `rip` here" function to jump around.
+
+## The program just exits immediately after I type something
+Basically, when you double click to open a .exe that's a [Console program](https://stackoverflow.com/questions/574911), Windows only keeps the terminal open for as long as the program is running. Since the program exits right after it prints the last thing, it'll "exit immediately after I type something".
+
+The proper way to do this is open a Cmd or Powershell window, run the .exe from inside like `path/to/my/program.exe`.
+This is exactly the same thing as running a command-line program on macOS or Linux: you open Terminal.app, Konsole, Gnome Terminal or whatever, and type `/path/to/my/program`
+
+To save you some head scratching: Note that in Powershell supports `cd D:/path/to/my/folder` directly, but Cmd you have to **type `D:` on it's own to switch drive**, followed by a separate command `cd D:/path/to/my/folder` to change directory in that drive.
diff --git a/content/blog/link-clearance/1.md b/content/blog/link-clearance/1.md
new file mode 100644
index 0000000..8617a52
--- /dev/null
+++ b/content/blog/link-clearance/1.md
@@ -0,0 +1,35 @@
+---
+title: "Link clearance #1"
+date: 2025-03-19T17:13:00-07:00
+categories: ["link clearance"]
+---
+
+This series isn't periodical at all. It'll come out whenever I have enough of them accumulated over time.
+
+- [Famous hotel signs](https://www.ling.upenn.edu/~beatrice/humor/foreign-hotel-signs.html). If I recall correctly this is linked from a Hacker News discussion on... something linguistics. The rest of the posts on this site are equally funny though.
+
+- [Mozart2](http://mozart2.org) and [Clean](https://clean-lang.org). Two languages linked from The Lisp Curse post for being containing novel and desirable features, being not Lispes (and thus not the /most powerful thing ever/) yet still everyone can learn from.
+
+- Two discussions on parsing from the [Oils](https://github.com/oils-for-unix/oils/wiki/Lossless-Syntax-Tree-Pattern) [shell](https://github.com/oils-for-unix/oils/wiki/Parsing-is-Difficult) project.
+
+ For the ambitious compiler writers who like to reuse their parsing infrastructure for editor tooling as well. See the HN and reddit links, there are some interesting back and forth in there too.
+
+ A few other descendent links that may be interesting and hard to find:
+
+ - [Python's pgen](http://python-history.blogspot.com/2018/05/the-origins-of-pgen.html).
+ - [On context-sensitivity]( https://eli.thegreenplace.net/2011/05/02/the-context-sensitivity-of-cs-grammar-revisited).
+ - Some sort of [omni-compiler-framework](https://kythe.io/docs/kythe-compatible-compilers.html)?
+ - [bnfc](https://github.com/BNFC/bnfc)
+ - Computer Science - Brian Kernighan on successful language design - [YouTube](https://www.youtube.com/watch?v=Sg4U4r_AgJU)
+
+- A rather [interesting project](https://github.com/rtk0c/WinXInputEmu) that tries to do what my [WinXInputEmu](https://github.com/rtk0c/WinXInputEmu) does, but with remote thread code execution to patch out system functions instead of doing DLL hijacking. Looks much more featureful and much /much/ more complicated (likely unnecessarily).
+
+- Pair of twin articles on [libraries](http://trevorjim.com/libraries-and-open-access) and [open access](http://trevorjim.com/open-access-should-not-mean-sole-access).
+
+ All of publishers (money!!?!?) and libraries (out of control) and readers (difficulty in accessing) hates electronic journals. A different route: stop doing the _storage_, stop trying to emulate physical paper electronically — produce PDF or whatever, send to customers, done. Let the libraries take care of the website and everything just like how they take care of printed materials. Maintain a minimal internal archive, suddenly a lot of cost and product leakage_ concerns are gone.
+
+ One notable descendent, [what are libraries for](http://web.archive.org/web/20110723192224/http://www.inthelibrarywiththeleadpipe.org/2011/what-are-libraries-for/) (out of the many in there):
+
+- [For what is anything but a tool?](https://blog.sanctum.geek.nz/vim-koans)
+
+- Yet another [pamphlet](https://research.swtch.com/vgo-mvs) (and fortunately, not a treatise) on dependencies.
diff --git a/content/blog/on-continuations.md b/content/blog/on-continuations.md
new file mode 100644
index 0000000..918f85d
--- /dev/null
+++ b/content/blog/on-continuations.md
@@ -0,0 +1,148 @@
+---
+title: "On continuations"
+date: 2025-03-22T15:51:27-07:00
+---
+
+A short piece for teaching continuations, in the Platonic dialectic style. Whether it is helpful is for you to decide. Cheers to burritos![^refs]
+
+---
+
+**Theofanis:** Are you free right now, Asimoula?
+
+**Asimoula:** Well, surely if your matter of attention is short and concise, I shall give mine too regardless; and if it is long, we shall look upon its intriguability, and then making a decision.
+
+**Theofanis:** Well, to the very honest, it goes as such: this "continuation" thing has been perplexing me for days on end. [Some](https://en.wikipedia.org/wiki/Continuation) state it very short simple, "a stored and resuamble state of computation", but do not seem all that useful, or hint at why at all someone should use it. Others give very length examples,
+
+```scheme
+> (define cont '())
+> (+ (/ 12 2)
+ (* (+ 1 1)
+ (call/cc (lambda (cc) (set! cont cc) 4))))
+;; As if the (call/cc) part is just 4, returned by the lambda
+14
+> (cont 1)
+;; As if we've evaluated the expression *again*, but the (call/cc) is just 1
+8
+> (cont 2)
+10
+> (cont 4)
+14
+```
+
+which is indeed fascinating, though now _how_ it works and _why_ seem to hide themselves even further in the thick fog. [Calling them](http://community.schemewiki.org/?call-with-current-continuation-for-C-programmers) `setjmp`/`longjmp` makes perfect and clear sense, but at the cost of summoning Satanic monster who blasts putrid breathe all over my face[^demonic-breathe]. What's more, everybody seems so inclined to mention this thing called "continuation-passing style", which are mostly followed by some nonsensical rewriting of perfectly fine programs to pass [callbacks](https://stackoverflow.com/a/14022348) everywhere.
+
+**Asimoula:** A length topic indeed. But nonetheless an interesting one, so let us go through it! So I think I'll do this: that example you cited is good enough at demonstrating its power, and so hereby I too will give a short and simple, but foggy and slimy statement: continuations are values (objects, if you like that word) that store a callstack, that you can jump back to while passing in some values.
+
+**Theofanis:** ...sure?
+
+**Asimoula:** We should now then take a detours out of mathematics and theory land, and dive into the dirty waters of real CPUs and implementations. After that, we'll climb on mountain of asynchronous programming, so we can see a different way for using continuations—at the same time so we can look at it from a different, perhaps much higher vantage point. In this way, we'll not be blinded by the great city of Scheme and its fortress of walls, and be able to see the cloud of continuation in its full shape.
+
+But enough babbling about, let's jump in:
+
+As we know, in assembly land, function calls happen through the callstack and a few registers. Inside some place, let's say the function `foo()`, we decide to call another function `bar()`, so we push all the parameters onto the same, and then jump to the first instruction of `bar()`.
+
+```
+The Callstack
++----------------+
+| <variables> | --+
+| <return value> | |-- frame for bar()
+| foo(): 0xA3 | <- return address --+
++----------------+
+| <variables> | --+
+| <return value> | |-- frame for foo()
+| main(): 0x1E | <- return address --+
++----------------+
+| . |
+| . |
+| . |
+```
+
+**Theofanis:** Yes, that seems to make sense, now that you talk about. I do seem to recollect about this.
+_hesitating, for he being a JavaScript programmer by trade doesn't quite have the C model on top of the head_
+
+**Asimoula:** And so as you see, when we return from `bar()`, for hypothetically, we place the return value at a predetermined location, and read the "return address" from another predetermined location, and `jmp` to it. The frame of `bar()` is now free reign for anybody else to write on top of.[^calling-convention] In particular that return address points to a special chunk inside the assembly of `foo()`, that takes care of things after `call`ing `bar()`. But the details are unimportant for us right now.
+
+**Theofanis:** Right.
+
+**Asimoula:** Now if you take your hand, and cover up the part of the stack for variables of `bar()` and its babbage, and squint your eyes a little bit, so might realize a magical thing that seems to be happening here: for all we know, Deina who works on `bar()` has just wrote a few bytes into `<return value>` and `jmp`ed to another address at `[rsp+4]`, and he seem to have magically teleported to a place where the blinking lights and whistling crowd resumes into motion, in middle of `foo()`.
+
+**Theofanis:** That does seem sort of magical, if you put such metaphors on top of it.
+
+**Asimoula:** Right— all I'm really saying is, by doing these two things—reading and writing a few values to a fixed location (relative to the stack pointer, of course), and `jmp`ing, we can in essence resume the state of execution to an arbitrary place in time.
+
+**Theofanis:** That is right, but do not see how it is useful. How does that make function calls special?
+
+**Asimoula:** This is the crucial behavior of continuations that make them both theoretically _and_ practically powerful. They are a single vocabulary to describe function calls (replacing the stack upwards[^stack-dir]), exceptions (replacing the stack downwards to the handler), generators (restoring the stack to inside the generator function, and then restoring the stack to the caller), coroutines (same as generators), or even goto! goto within a function is just replacing the stack to _some state_ of the same function associated with some line number. So many more, countless uses.
+
+Now, what I just described in its full glory is not without simplifications compared to the machinery which Scheme offers. Yet nor is Scheme `call/cc` the true continuation. It is merely one physical incarnation of the concept. It is but rather the law of universal gravitation incarnation to the much more fundamental pattern that is inverse squares in nature.
+
+If you do intend to learn to wield Scheme's full power, sit down, grab a cup of tea (or coffee) and learn from the docs and examples. And documentation. And actual code. But... I digress.
+
+Of course, _power_ does not equate to _usefulness_, and as you can see: it's a heavyweight vocabulary to be wielding around. In fact, it's so powerful that most people find it too flexible.
+
+**Theofanis:** Now I see why these people are excited over it. For sure this demonstrates their power beautifully, Asimoula, but now can you also tell me what does these lovely continuation have to do with the "continuation-passing style"?
+
+**Asimoula:** Look at this ordinary program:
+
+```scheme
+(define (add a b)
+ (+ a b))
+
+;; evaluate `add` first, then evaluate `display`
+(let ((res (add 40 2)))
+ (display res))
+;; => prints 42
+```
+
+compare that with:
+
+```scheme
+(define (add a b cont)
+ (cont (+ a b)))
+
+;; `cont` is the thing (i.e. `display) we want to eval after `(add 40 2)`
+(let (cont (lambda (res)
+ (display res)))
+ (add 40 2 cont))
+;; => also prints 42
+```
+
+compare that with:
+
+```scheme
+;; same `add` definition
+(define (add a b cont)
+ (cont (+ a b)))
+
+;; Similarly, right outside of `call/cc` is the thing we want to eval after `(add 40 2)`
+(print (call/cc (add 40 2)))
+```
+
+Both latter examples are using continuations. Both of them do functions by using CPS. I shall reiterate: `call/cc` is but a specific incarnation of the general idea of continuations.
+
+To that idea, _CPS is a property that some programs have. CPS can be obtained either by voluntarily writing it like so, or by applying a mechanical transformation to a regular program._ Why have programs in CPS? Loosely, it's easier to write algorithms transforming them in useful ways, i.e. optimizations.
+
+**Theofanis:** I see. So `call/cc` is to continuations as Java `@FunctionInterface` is to first-class functions. Or as C++ templates[^ad-hoc-poly] is to parametric polymorphism.
+
+**Asimoula:** You got it exactly right, my friend.
+
+As some bonus chatter, an naive `call/cc` machinery by stack copying can be quite slow. It would literally copy the entire execution stack, megabytes of data, to the heap, and replace it when reentering the continuation.
+Non-naive implementations like [Chicken](https://www.more-magic.net/posts/internals-gc.html) exists, by rewriting the entire program to be CPS. This way, `call/cc` is free because literally everything is already a continuation. But this comes at the tradeoff that everything, even the code that does not _explicitly use_ continuations, are just a little bit slower.
+
+
+An naive `call/cc` machinery can be quite slow, by literally writing megabytes of data to replace the stack. Non-naive implementations like [Chicken](https://www.more-magic.net/posts/internals-gc.html) exists, but with tradeoffs like making everything, even the code that does not _explicitly use_ continuations just a little bit slower.
+
+
+
+[^refs]: If you, the reader, is really coming here confused, continuing may cause you to get more confused.
+The author is in fact aware of the [burrito monads](https://byorgey.wordpress.com/2009/01/12/abstraction-intuition-and-the-monad-tutorial-fallacy/) fallacy, and has no intention to stop. The author just found writing this amusing.
+Read on at your own risk (or benefit).
+
+[^demonic-breathe]: What I mean by this is `setjmp`/`longjmp` traditionally have a bad reputation among programmers, that it allows non-local control flow ("goto considered harmful").
+Also this metaphor isn't all that helpful to showing what continuations are *supposed to* enable; C programs really don't use `setjmp`/`longjmp` similarly to continuations at all. I guess a little bit?
+
+[^calling-convention]: These are all made up for the convenience for the demonstration. I don't remember if any real calling convetions work in this exact way, but even if they do, things like parameters, register spillage, and stack pointer handling are omitted here. Don't take it too seriously.
+
+[^stack-dir]: Usually, the callstack is said to grow downwards (lower address means deeper callstack), based on that most calling conventions do it this way. I am going to call it "upwards" because it probably makes more sense to more people.
+
+[^ad-hoc-poly]: Ignoring the template specializations part. I know that's ad-hoc polymorphism, but that's not the point.
diff --git a/content/blog/org-mode-watchlist.md b/content/blog/org-mode-watchlist.md
new file mode 100644
index 0000000..9c58819
--- /dev/null
+++ b/content/blog/org-mode-watchlist.md
@@ -0,0 +1,78 @@
+---
+title: "Watchlist × Emacs org-mode"
+date: 2025-04-19T12:29:00-07:00
+---
+
+Watch progress websites exist for [anime](https://myanimelist.net) and [film](https://letterboxd.com). They work great. Socialization is great.
+
+But they don't record the _exact time_ at which I finished each episode. I find such statistics amusing to dig through in some kind of a year-end review. I also found it tremendously helpful to know which episodes were most recently watched, and in what order. Helps with recollecting the context of each show, especially when chasing more than a couple of shows at the same time.
+Depending on your judgment, using Letterboxd and MyAnimeList may also constitute giving private information to 3rd parties.
+
+So I ended with an organization system that's, effectively, top layer of bullet points for the show, and inner layer for the episodes. Something like:
+
+```org
+* STRT SHIROBAKO
+** [2025-04-01 Tue 11:11] E01
+** [2025-04-16 Wed 22:22] E02
+* TODO Do It Yourself!!
+* DONE ゆるキャンプ
+** [2025-03-20 Thu 20:21] E10
+** [2025-03-21 Fri 20:59] E11
+** [2025-04-14 Mon 21:36] E12
+* STRT mono
+** [2025-04-13 Sun 16:56] E01
+```
+
+I want to be able to run a command, and get it as a linear timeline:
+
+```org
+* [2025-03-20 Thu 20:21] ゆるキャンプ E10
+* [2025-03-21 Fri 20:59] ゆるキャンプ E11
+* [2025-04-01 Tue 11:11] SHIROBAKO E01
+* [2025-04-13 Sun 16:56] mono E01
+* [2025-04-14 Mon 21:36] ゆるキャンプ E12
+* [2025-04-16 Wed 22:22] SHIROBAKO E02
+```
+
+Which turns out to be a pretty easy simple regex-based forward parsing algorithm. I thought about using `org-element-map`, but it seemed like a bit of an overkill?
+
+To use, I do <kbd>g g M-x org-category->timeline</kbd> (evidently, I use evil-mode), bringing me to a new buffer `*Category Timeline*` filled out appropriately.
+
+```emacs-lisp
+(defun org-category->timeline ()
+ "Collect category-timestamp tree into a single, chronologically
+ordered timestamp list. Starting at point."
+ (interactive)
+ (let ((pt (point))
+ (curr-category nil)
+ (curr-pt (search-forward "\n* " nil t))
+ (items '()))
+ ;; Collect items
+ (while curr-pt
+ (goto-char curr-pt)
+ ;; Skip org-todo marker
+ (forward-word) (forward-char)
+ (setq curr-category (buffer-substring-no-properties (point) (line-end-position))
+ curr-pt (save-excursion (search-forward "\n* " nil t)))
+ (while-let ((i (re-search-forward (rx "\n** ["
+ (group (* (not "]")))
+ "] ")
+ curr-pt t)))
+ (let ((time (match-string-no-properties 1))
+ (comment (buffer-substring-no-properties (point) (line-end-position))))
+ (push (list (encode-time (org-parse-time-string time))
+ time curr-category comment)
+ items))))
+ ;; Sort by time
+ (sort items (lambda (a b) (time-less-p (car a) (car b))))
+ ;; Restore to starting point in the source buffer
+ (goto-char pt)
+ ;; Print items into a new buffer
+ (switch-to-buffer "*Category Timeline*")
+ (erase-buffer)
+ (dolist (i items)
+ (let ((time (cadr i))
+ (category (caddr i))
+ (comment (cadddr i)))
+ (insert "* [" time "] " category " " comment ?\n)))))
+```
diff --git a/content/blog/tailscale-and-sjsu-vpn.md b/content/blog/tailscale-and-sjsu-vpn.md
new file mode 100644
index 0000000..46da685
--- /dev/null
+++ b/content/blog/tailscale-and-sjsu-vpn.md
@@ -0,0 +1,146 @@
+---
+title: "Setting up SJSU VPN for connection to home server"
+date: 2024-05-01T23:34:13-07:00
+tags: ["SJSU", "networking"]
+---
+
+Note this intended for relative networking novices, so I will try to explain every term used. Skip over them if you find it verbose. If you don't care about anything else and just wants to replicate my setup for your home server, go to [this section](#my-journey). Read the TL;DR's in there if that section alone is too long for you too.
+
+# Motivation
+Virtual mesh networking software, like Tailscale, ZeroTier, tinc, Hamachi and else, practically[^1] cannot establish a direct/p2p connection between a machine on the SJSU wifi and a machine somewhere else, running on a common residential internet. This situation is an example of a hard-NAT to easy-NAT connnection (I'm using terminology from [Tailscale's article on NAT traversal](https://tailscale.com/blog/how-nat-traversal-works)). I really only use Tailscale so that's what I'm concerned with here.
+
+Tailscale has an excellent relay service that can gaurentee _a_ connection between two machines even if it can't establish a direct connection. It has surprisingly good latency, mostly under 50ms for me going from SJSU wifi to a home server. But it has really limited bandwidth, on average 15Mbps based on a quick `iperf3` benchmark; this translates to about 1.2MB/s file transfer to my home server (from my experience), which isn't satisfactory for every task.
+
+# Some Background
+SJSU's network infrastructure works as follows (as of writing this, 2024-05-01):
+- There are 2 wifi, `SJSU_Premier` and `SJSU_Guest` available to students and faculty.
+ - The subnet is `10.0.0.0/8`. This means, for our purposes, every machine connected to the wifi will get a Local-Area Network/*LAN* ("the wifi") IP address between `10.0.0.1` to `10.255.255.254`. A *subnet* is, for our purposes, just a range of IP address that all machines connected in a LAN will get their local IP address from.
+ - Both of them seems to be on the same subnet, i.e. machine A in `SJSU_Guest` can reach machine B in `SJSU_Premier` directly. This is based on my testing that joining to either one seems to allow connecting to another machine on the VPN.
+- The gateway of the network is an endpoint-dependent firewall and endpoint-dependent NAT (this combination is what "hard NAT" describes). I assume this is some enterprise grade equipment from Cisco, though that's not super relevant.
+- No IPv6 support whatsoever, both when connecting to the internet and inside the LAN.
+
+SJSU also provides a VPN service based on the Cisco AnyConnect software. It is designed to be used for two purposes. First, like a traditional VPN: once you setup the client, all traffic is routed to become originated from SJSU's network; presumably to make some pay-walled text lending service available to who need it at home. Second, it allows you to reach any machine on the subnet `10.0.0.0/8` (both wifi's, as said above), in order to allow faculty to connect to services hosted only on the LAN[^2].
+
+I wanted to utilize the second feature, to make Tailscale connect to my home server over "LAN" created by the VPN. For example if my home server had IP `10.0.12.1` from the VPN, my laptop will be able to connect by that IP directly. Tailscale will pick this up, avoiding having go through their relay.
+
+My home server is running Linux. You can very much accomplish the same thing on Windows or macOS since Cisco provides VPN software for those too. You also won't need to jump through the hoops I did for Linux.
+
+# My Journey
+What I need to do is basically two things. (1) Setup Cisco Anyconnect on my home server. (2) Make it so that only the LAN subnet goes through the VPN, not all internet traffic. (I don't need to pretend, for example github.com, to be coming from SJSU's network). Number (2) is technically optional but a nice to have.
+
+## Setting up the VPN
+TL;DR: I used [`openconnect-sso`](https://github.com/vlaci/openconnect-sso) on my browser to generate the VPN session token, and copy that to my home server over ssh, and launch OpenConnect with said token. This is because SJSU's account needs to authenticate with Okta/Duo, and that needs a browser.
+
+I can either use Cisco's official Linux software, or use a 3rd-party, open source reimplementation like [OpenConnect](https://www.infradead.org/openconnect/). I _strongly_ prefered the latter since Cisco's official software wants me to download a blob of bash script to do installation, in addition to downloading another "Cisco Secure Desktop" executable from the internet, and running it locally on running.
+
+- Install `openconnect-sso` using your method of choice. I got it from https://aur.archlinux.org/packages/openconnect-sso
+
+- Run `openconnect-sso --server vpn.sjsu.edu --authgroup Student-SSO --user YOUR_SJSU_ID --authenticate`
+ - Replace *YOUR_SJSU_ID* with, well, your SJSU ID (the 7 digit numbber)
+ - The flag `--authenticate` tells it to only generate the session token, don't try to create a tunnnel.
+ - This should print out something like
+ ```
+ HOST=https://vpn.sjsu.edu/
+ COOKIE=<a very long hexdecimal string>
+ FINGERPRINT=<a slightly shorter hexdecimal string>
+ ```
+ - From what I understood, `COOKIE` is Cisco Anyconnect's session token, which is only usable once. (That is to say, once you've connected to the VPN once with the step below, you need to do this current step again to get a new `COOKIE`.)
+
+ - Then, go to your machine that you actually wish the VPN to run on. In my case, it's my personal server `ssh rtk0c@my-priv-server`
+
+- Run, in place of the `...` copy paste the tokens you got from the last step
+ ```sh
+ $ export HOST=...
+ $ export COOKIE=...
+ $ export FINGERPRINT=...
+ $ echo $COOKIE | sudo openconnect $HOST --cookie-on-stdin --servercert $FINGERPRINT
+ ```
+ You will leave the `openconnect` process running, since it is the VPN connection itself. i.e., it pushes wraps internet traffic and pushes them through an encrypted tunnel. Pass the token over stdin to avoid it lingering in the command line. Although it's not like it matters, since I control the whole server.
+
+- Test with `curl http://icanhazip.com`, it should return an IP that belongs to SJSU. I got `130.65.9.242`.
+
+## Un-route the internet from the VPN
+TL;DR: use `ip route del default dev tun0` to get rid of the routing rule for all traffic, and then use `ip route add 10.0.0.0/8 dev tun0` to make the LAN subnet accesible.
+
+`openconnect` automatically sets up a routing rule in the linux kernel that sends all internet traffic (i.e. every non-*private-use* IP address) *and* the subnet `10.0.0.0/8` through its *tunnel*, except those going to IP address of SJSU VPN server.
+
+A *tunnel* manifests itself as a *network interface* in the linux kernel, in this case named `tun0`, just like a your WiFi card shows up as a network interface. Routing rules tell the kernel, when you see *packets* coming from such and such, and going to such and such IP address, send it through this network interface. A *private-use* IP address is one reserved by the IP standard, such that it will never appear on the internet. They're only used inside a LAN.
+
+I want to get rid of the routing rules for all internet traffic. You can list routing rules with `ip route`[^ip-route], in which you should see something like:
+```
+default via 10.40.25.168 dev tun0
+default via 192.168.1.1 dev wlp1s0 proto dhcp src 192.168.1.142 metric 600
+10.40.16.0/20 dev tun0 scope link
+130.65.9.242 via 192.168.1.1 dev wlp1s0 src 192.168.1.142 metric 600
+130.65.9.242 via 192.168.1.1 dev wlp1s0 src 192.168.1.142 metric 20600
+... rest are omitted ...
+```
+
+Each line here is a routing rule. They rules take priority not by their order, but by how specific they are. They more specific (longer the *subnet prefix*), the higher priority it has.
+
+*Subnet prefix* length is the number of bits in the subnet mask. For example, `10.0.0.0/8`'s prefix is length is 8, so it's *less specific* than `10.40.16.0/20`, which has 20 bits. See [your favorite search engine for more](https://www.google.com/search?client=firefox-b-1-d&q=subnet+prefix) if you're curious—the details don't matter here.
+
+The first line, `default via 10.40.25.168 dev tun0`, means that if the destination IP address doesn't match anything below ("default"), send it to the device `tun0` ("dev tun0"). The 2nd line is the normal rule for my local WiFi connection (internet traffic goes to the router). The 3rd, 4th, and 5th lines all come from openconnect. 3rd says if the destination IP is in the `10.40.16.0/20` subnet, send it over `tun0`; even if this rule didn't exist, packets going to the whole SJSU LAN subnet will be caught by the first rule, so it's unnecessary<sup>citation needed</sup>. 4th says if the destination IP is exactly `130.65.8.242`, which is SJSU's VPN sever, send it over my actual WiFi interface ("dev wlp1s0"); 5th is a duplicate but with a higher *metric*. I'm not sure why it writes these rules with so much redundency.
+
+*Metric* is a number indicating the cost of a route. The higher this number, the less likely the kernel will consider it if other options exist.
+
+In any case- all we need to do is get rid of the first line, and then add another rule to cover the whole `10.0.0.0/8` subnet (the current 3rd rule only covers a small section of the subnet). So we'll run:
+```sh
+$ sudo ip route del default dev tun0
+$ sudo ip route add 10.0.0.0/8 dev tun0
+```
+
+Now test with `curl http://icanhazip.com` again. I got my normal, home IP address back! And test if SJSU's LAN subnet is reachable with `ping 10.0.0.1`. (I need a machine on the SJSU network, typically the ...1 machine is used by the router, I tried it, and indeed it exists—though I'm not sure what it is, but existence is all that matters).
+
+# Script
+I wrote a bash script `sjsu.vpn.sh`, to update the token I just copy paste them to the top of the file, as varaibles.
+
+```bash
+#! /bin/bash
+
+HOST=https://vpn.sjsu.edu/
+COOKIE=000 #your token
+FINGERPRINT=000 #your fingerprint
+
+# https://stackoverflow.com/a/1885534
+read -p "Replacing the default everything route with 10.0.0.0/8 only route? (y/N)" REPLY
+echo #Move to next line
+if [[ $REPLY =~ ^[Yy]$ ]]
+then
+ ROUTE_LAN_ONLY=true
+fi
+
+echo $COOKIE | sudo openconnect $HOST --cookie-on-stdin --servercert $FINGERPRINT &
+
+if [[ $ROUTE_LAN_ONLY = true ]]
+then
+ sudo ip route del default dev tun0 && sudo ip route add 10.0.0.0/8 dev tun0
+fi
+
+onexit() {
+ kill $(jobs -p)
+ if [[ $ROUTE_LAN_ONLY = true ]]
+ then
+ sudo ip route del 10.0.0.0/8 dev tun0
+ fi
+}
+
+trap 'onexit' EXIT
+wait
+```
+
+# Results
+`iperf` (and `iperf3`) speed went from ~15Mbps on tailscale relay to ~55Mbps over the cisco vpn; ping didn't change meaningfully.
+
+# Closing Thoughts
+I'm not sure if SJSU's Cisco Anyconnect service is going through another hop on a relay server of their own, or it's just a direct connection. I was more or less expecting the latency to be better than going through Tailscale's relay in SFO, though it is what it is.
+
+I use ZeroTier for setting up game servers with my friends (advantage over Tailscale: no need for signing up an account). ZT doesn't not want to listen on the `10.xxx.yyy.zzz` address associated with the VPN, so even with the VPN in place, it still uses its own relay. I have no idea why, it could be its discovery mechanism (UDP local broadcast) is blocked by SJSU's network, or there is some kind of internal blacklist mechanism for blocking the `tun0` device used by OpenConnect. A quick github search in their source yield too many results for me to dig through; google did not hint at anything relevant.
+
+
+
+[^1]: Some software like Tailscale have some heuristics to more-or-less brute force a direction connection between hard-NAT and easy-NAT. It takes quite a bit of luck for this to happen in my experience: for the close to 1 year I've been here, direction connection only ever happened once.
+
+[^2]: "VPN allows users outside of the SJSU network access to restricted resources (like file shares, servers, and desktops) on the SJSU network, as if they are physically located on the SJSU campus network behind secured firewalls." https://sjsu.edu/it/services/network/internet-access/vpn.php
+
+[^ip-route]: Linux has the concept of different routing tables. `ip route` only shows the `main` routing table, but that's all we care about here. You can use `ip route show table <table name>` to show a specific table. Tailscale routes packets to the Tailnet IP addresses (the ones like 100.xxx.xxx.xxx) in the routing table `52`.
diff --git a/content/blog/vim-kitty-compat.md b/content/blog/vim-kitty-compat.md
new file mode 100644
index 0000000..67debeb
--- /dev/null
+++ b/content/blog/vim-kitty-compat.md
@@ -0,0 +1,45 @@
+---
+title: "Vim really does not like kitty"
+date: 2025-03-05T20:30:01-08:00
+ShowToc: false
+---
+
+**TL;DR**: kitty uses a custom terminfo `xterm-kitty`. Vim doesn't like it.
+If you're in a pinch, commit a [crime](#i-just-want-it-work-right-now) and hopefully it works fine.
+If you're not, switch to another terminal for vim, or switch to neovim, or [attempt to teach vim to speak kitty](#configure-vim).
+
+---
+
+If you use Vim in kitty, local machine or going through SSH, and (at least) one of these is happening:
+
+1. Paste <kbd>Ctrl+Shift+V</kbd> from system clipboard is egregiously slow. Like two lines per second slow[^arch].
+2. Paste is glitchy. All the whitespaces get eaten, nowhere to be seen. Lines get jumbled together, parts of the clipboard overwrite another, etc[^debian].
+3. kitty tells you your clipboard contains terminal escape sequences. Except it absolutely does not. Pasting elsewhere, still in kitty, like into `bash` or `nvim` works completely fine[^debian].
+
+[^arch]: happened on a local ArchLinux machine
+[^debian]: happened on SSH to an Debian Bookworm arm64 supplied by AWS EC2
+
+then congratulations, you have just discovered that Vim isn't very compatible with kitty as a terminal emulator. Instead of trying to poorly summarize _why_, you can instead read the problem being extensively discussed _con fuoco_ in the [Vim issue tracker](https://github.com/vim/vim/issues/11729).
+
+This problem is actually documented. On the Vim side, it's in [the help](https://vimhelp.org/term.txt.html#xterm-kitty), without any mention of how to fix it.
+
+<a name="configure-vim"></a>
+On the kitty side, [the FAQ](https://sw.kovidgoyal.net/kitty/faq/#using-a-color-theme-with-a-background-color-does-not-work-well-in-vim) mentions it, and also supplies some stuff to put in your `.vimrc` to make Vim happy.
+I have not personally tried any of these, and don't understand a single thing about what they're doing. Just for your reference.
+
+# I just want it work. Right now.
+Try `TERM=xterm-256color vim /my/file.txt`.
+
+It seems like by setting `TERM` to `xterm-256color`, Vim will understand at least the paste part mostly fine. I don't know if bracketed paste is happening.
+**This is highly discouraged** per kitty's [documentation](https://sw.kovidgoyal.net/kitty/faq/#i-get-errors-about-the-terminal-being-unknown-or-opening-the-terminal-failing-or-functional-keys-like-arrow-keys-don-t-work) and [opinion](https://github.com/kovidgoyal/kitty/issues/2192).
+Don't use it long term, or you'll find other inexplicable weirdness (which I had, but it's all a blurry mess so I can't recite to you the war story. alas).
+
+# Other solutions
+As far as I know, all other terminals pretend to be xterm well enough that Vim plays happily long. So you use them instead.
+I will keep a copy of Konsole on hand for situations where I have to use vim.
+
+Neovim doesn't seem to have any issue with kitty's terminfo.
+
+I prefer Neovim, and got in a habit to go out of my way to replace the default Vim on every system, in part because of this paste weirdness.
+Recently I got lazy and just went with the bundled Vim. This issue resurfaced, and I finally decided to research it in depth.
+I couldn't find any internet echos regarding this issue apart from the ones I linked here. Maybe my searching skills have deteriorated. Maybe search engines are not as good anymore. In any case, hopefully writing this adds another data point.
diff --git a/content/search.md b/content/search.md
new file mode 100644
index 0000000..5c6170b
--- /dev/null
+++ b/content/search.md
@@ -0,0 +1,5 @@
+---
+title: "Search"
+placeholder: Search demo site with full text fuzzy search ...
+layout: "search"
+---
diff --git a/hugo.yaml b/hugo.yaml
new file mode 100644
index 0000000..60be0c5
--- /dev/null
+++ b/hugo.yaml
@@ -0,0 +1,75 @@
+baseURL: "https://www.rtk0c.com"
+languageCode: "en-us"
+title: "rtk0c's hut"
+theme: "PaperMod"
+
+outputs:
+ home:
+ # Gotta read them somehow
+ - HTML
+ # Go get a RSS client (and some quality blogs), you will not regret it
+ # Hugo defaults to /index.xml, but if want to change: https://discourse.gohugo.io/t/how-can-i-change-the-rss-url/118/23
+ - RSS
+ # For fastsearch.json
+ - JSON
+
+languages:
+ en:
+ languageName: "English"
+ weight: 1
+ taxonomies:
+ category: categories
+ tag: tags
+ menu:
+ main:
+ - name: RSS
+ url: /index.xml
+ weight: 10
+ - name: Archive
+ url: /archives
+ weight: 5
+ - name: Search
+ url: /search
+ weight: 10
+ params:
+ homeInfoParams:
+ Title: "rtk0c's hut"
+ Content: >
+ Technical findings, life stories, and projects.
+ zh:
+ params:
+ homeInfoParams:
+ Title: "rtk0c的小窝"
+ Content: >
+
+params:
+ env: development
+ description: "rtk0c's personal writing output"
+ keywords: [Blog, Portfolio]
+ author: rtk0c
+
+ socialIcons:
+ - name: "github"
+ url: "https://github.com/rtk0c"
+ - name: "reddit"
+ url: "https://reddit.com/u/rtk0c"
+ - name: "twitter"
+ url: "https://twitter.com/rtk0c1"
+
+ defaultTheme: auto
+ disableThemeToggle: false
+ displayFullLangName: true
+ ShowShareButtons: false
+ ShowReadingTime: false
+ ShowPostNavLinks: true
+ ShowBreadCrumbs: true
+ ShowCodeCopyButtons: true
+ ShowRssButtonInSectionTermList: true
+ ShowAllPagesInArchive: true
+ ShowPageNums: true
+ ShowToc: true
+
+markup:
+ goldmark:
+ renderer:
+ unsafe: true
diff --git a/layouts/_default/archives.html b/layouts/_default/archives.html
index eea3fc8..3ff94ba 100644
--- a/layouts/_default/archives.html
+++ b/layouts/_default/archives.html
@@ -27,6 +27,10 @@
{{- end }}
</header>
+<div class="post-content">
+{{ .Content }}
+</div>
+
{{- $pages := where site.RegularPages "Type" "in" site.Params.mainSections }}
{{- if site.Params.ShowAllPagesInArchive }}
diff --git a/.github/ISSUE_TEMPLATE/bug.yaml b/themes/PaperMod/.github/ISSUE_TEMPLATE/bug.yaml
index d7d7656..d7d7656 100644
--- a/.github/ISSUE_TEMPLATE/bug.yaml
+++ b/themes/PaperMod/.github/ISSUE_TEMPLATE/bug.yaml
diff --git a/.github/ISSUE_TEMPLATE/config.yml b/themes/PaperMod/.github/ISSUE_TEMPLATE/config.yml
index eeb6e55..eeb6e55 100644
--- a/.github/ISSUE_TEMPLATE/config.yml
+++ b/themes/PaperMod/.github/ISSUE_TEMPLATE/config.yml
diff --git a/.github/ISSUE_TEMPLATE/enhancement.yaml b/themes/PaperMod/.github/ISSUE_TEMPLATE/enhancement.yaml
index 3976a80..3976a80 100644
--- a/.github/ISSUE_TEMPLATE/enhancement.yaml
+++ b/themes/PaperMod/.github/ISSUE_TEMPLATE/enhancement.yaml
diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/themes/PaperMod/.github/PULL_REQUEST_TEMPLATE.md
index 673d1c4..673d1c4 100644
--- a/.github/PULL_REQUEST_TEMPLATE.md
+++ b/themes/PaperMod/.github/PULL_REQUEST_TEMPLATE.md
diff --git a/.github/workflows/gh-pages.yml b/themes/PaperMod/.github/workflows/gh-pages.yml
index 7dc6f1c..7dc6f1c 100644
--- a/.github/workflows/gh-pages.yml
+++ b/themes/PaperMod/.github/workflows/gh-pages.yml
diff --git a/LICENSE b/themes/PaperMod/LICENSE
index 533adaf..533adaf 100644
--- a/LICENSE
+++ b/themes/PaperMod/LICENSE
diff --git a/README.md b/themes/PaperMod/README.md
index 7b2956e..7b2956e 100644
--- a/README.md
+++ b/themes/PaperMod/README.md
diff --git a/assets/css/common/404.css b/themes/PaperMod/assets/css/common/404.css
index 8a23430..8a23430 100644
--- a/assets/css/common/404.css
+++ b/themes/PaperMod/assets/css/common/404.css
diff --git a/assets/css/common/archive.css b/themes/PaperMod/assets/css/common/archive.css
index 7e7e245..7e7e245 100644
--- a/assets/css/common/archive.css
+++ b/themes/PaperMod/assets/css/common/archive.css
diff --git a/assets/css/common/footer.css b/themes/PaperMod/assets/css/common/footer.css
index 5addb1e..5addb1e 100644
--- a/assets/css/common/footer.css
+++ b/themes/PaperMod/assets/css/common/footer.css
diff --git a/assets/css/common/header.css b/themes/PaperMod/assets/css/common/header.css
index 64894da..64894da 100644
--- a/assets/css/common/header.css
+++ b/themes/PaperMod/assets/css/common/header.css
diff --git a/assets/css/common/main.css b/themes/PaperMod/assets/css/common/main.css
index 25ae4da..25ae4da 100644
--- a/assets/css/common/main.css
+++ b/themes/PaperMod/assets/css/common/main.css
diff --git a/assets/css/common/post-entry.css b/themes/PaperMod/assets/css/common/post-entry.css
index 8ff3225..8ff3225 100644
--- a/assets/css/common/post-entry.css
+++ b/themes/PaperMod/assets/css/common/post-entry.css
diff --git a/assets/css/common/post-single.css b/themes/PaperMod/assets/css/common/post-single.css
index b9bb7d8..b9bb7d8 100644
--- a/assets/css/common/post-single.css
+++ b/themes/PaperMod/assets/css/common/post-single.css
diff --git a/assets/css/common/profile-mode.css b/themes/PaperMod/assets/css/common/profile-mode.css
index 9e98df5..9e98df5 100644
--- a/assets/css/common/profile-mode.css
+++ b/themes/PaperMod/assets/css/common/profile-mode.css
diff --git a/assets/css/common/search.css b/themes/PaperMod/assets/css/common/search.css
index 38d5b6b..38d5b6b 100644
--- a/assets/css/common/search.css
+++ b/themes/PaperMod/assets/css/common/search.css
diff --git a/assets/css/common/terms.css b/themes/PaperMod/assets/css/common/terms.css
index 244614b..244614b 100644
--- a/assets/css/common/terms.css
+++ b/themes/PaperMod/assets/css/common/terms.css
diff --git a/assets/css/core/license.css b/themes/PaperMod/assets/css/core/license.css
index 47b9c6f..47b9c6f 100644
--- a/assets/css/core/license.css
+++ b/themes/PaperMod/assets/css/core/license.css
diff --git a/assets/css/core/reset.css b/themes/PaperMod/assets/css/core/reset.css
index 7393d57..7393d57 100644
--- a/assets/css/core/reset.css
+++ b/themes/PaperMod/assets/css/core/reset.css
diff --git a/assets/css/core/theme-vars.css b/themes/PaperMod/assets/css/core/theme-vars.css
index db1845d..db1845d 100644
--- a/assets/css/core/theme-vars.css
+++ b/themes/PaperMod/assets/css/core/theme-vars.css
diff --git a/assets/css/core/zmedia.css b/themes/PaperMod/assets/css/core/zmedia.css
index a68fd71..a68fd71 100644
--- a/assets/css/core/zmedia.css
+++ b/themes/PaperMod/assets/css/core/zmedia.css
diff --git a/assets/css/extended/blank.css b/themes/PaperMod/assets/css/extended/blank.css
index a577295..a577295 100644
--- a/assets/css/extended/blank.css
+++ b/themes/PaperMod/assets/css/extended/blank.css
diff --git a/assets/css/includes/chroma-mod.css b/themes/PaperMod/assets/css/includes/chroma-mod.css
index ad89b96..ad89b96 100644
--- a/assets/css/includes/chroma-mod.css
+++ b/themes/PaperMod/assets/css/includes/chroma-mod.css
diff --git a/assets/css/includes/chroma-styles.css b/themes/PaperMod/assets/css/includes/chroma-styles.css
index 63a73ab..63a73ab 100644
--- a/assets/css/includes/chroma-styles.css
+++ b/themes/PaperMod/assets/css/includes/chroma-styles.css
diff --git a/assets/css/includes/scroll-bar.css b/themes/PaperMod/assets/css/includes/scroll-bar.css
index f6e577d..f6e577d 100644
--- a/assets/css/includes/scroll-bar.css
+++ b/themes/PaperMod/assets/css/includes/scroll-bar.css
diff --git a/assets/js/fastsearch.js b/themes/PaperMod/assets/js/fastsearch.js
index 9484e75..9484e75 100644
--- a/assets/js/fastsearch.js
+++ b/themes/PaperMod/assets/js/fastsearch.js
diff --git a/assets/js/fuse.basic.min.js b/themes/PaperMod/assets/js/fuse.basic.min.js
index 7457721..7457721 100644
--- a/assets/js/fuse.basic.min.js
+++ b/themes/PaperMod/assets/js/fuse.basic.min.js
diff --git a/assets/js/license.js b/themes/PaperMod/assets/js/license.js
index 47b9c6f..47b9c6f 100644
--- a/assets/js/license.js
+++ b/themes/PaperMod/assets/js/license.js
diff --git a/go.mod b/themes/PaperMod/go.mod
index af95855..af95855 100644
--- a/go.mod
+++ b/themes/PaperMod/go.mod
diff --git a/i18n/ar.yaml b/themes/PaperMod/i18n/ar.yaml
index 52990c2..52990c2 100644
--- a/i18n/ar.yaml
+++ b/themes/PaperMod/i18n/ar.yaml
diff --git a/i18n/be.yaml b/themes/PaperMod/i18n/be.yaml
index 22902ab..22902ab 100644
--- a/i18n/be.yaml
+++ b/themes/PaperMod/i18n/be.yaml
diff --git a/i18n/bg.yaml b/themes/PaperMod/i18n/bg.yaml
index 1e314af..1e314af 100644
--- a/i18n/bg.yaml
+++ b/themes/PaperMod/i18n/bg.yaml
diff --git a/i18n/bn.yaml b/themes/PaperMod/i18n/bn.yaml
index f42780f..f42780f 100644
--- a/i18n/bn.yaml
+++ b/themes/PaperMod/i18n/bn.yaml
diff --git a/i18n/ca.yaml b/themes/PaperMod/i18n/ca.yaml
index 15713e1..15713e1 100644
--- a/i18n/ca.yaml
+++ b/themes/PaperMod/i18n/ca.yaml
diff --git a/i18n/ckb.yaml b/themes/PaperMod/i18n/ckb.yaml
index 25789d1..25789d1 100644
--- a/i18n/ckb.yaml
+++ b/themes/PaperMod/i18n/ckb.yaml
diff --git a/i18n/cs.yaml b/themes/PaperMod/i18n/cs.yaml
index 058c3a1..058c3a1 100644
--- a/i18n/cs.yaml
+++ b/themes/PaperMod/i18n/cs.yaml
diff --git a/i18n/da.yaml b/themes/PaperMod/i18n/da.yaml
index 03b0abe..03b0abe 100644
--- a/i18n/da.yaml
+++ b/themes/PaperMod/i18n/da.yaml
diff --git a/i18n/de.yaml b/themes/PaperMod/i18n/de.yaml
index f64aad9..f64aad9 100644
--- a/i18n/de.yaml
+++ b/themes/PaperMod/i18n/de.yaml
diff --git a/i18n/el.yaml b/themes/PaperMod/i18n/el.yaml
index 4257bac..4257bac 100644
--- a/i18n/el.yaml
+++ b/themes/PaperMod/i18n/el.yaml
diff --git a/i18n/en.yaml b/themes/PaperMod/i18n/en.yaml
index 3a1e215..3a1e215 100644
--- a/i18n/en.yaml
+++ b/themes/PaperMod/i18n/en.yaml
diff --git a/i18n/eo.yaml b/themes/PaperMod/i18n/eo.yaml
index de5d744..de5d744 100644
--- a/i18n/eo.yaml
+++ b/themes/PaperMod/i18n/eo.yaml
diff --git a/i18n/es.yaml b/themes/PaperMod/i18n/es.yaml
index 52a559c..52a559c 100644
--- a/i18n/es.yaml
+++ b/themes/PaperMod/i18n/es.yaml
diff --git a/i18n/fa.yaml b/themes/PaperMod/i18n/fa.yaml
index 3fd5927..3fd5927 100644
--- a/i18n/fa.yaml
+++ b/themes/PaperMod/i18n/fa.yaml
diff --git a/i18n/fi.yaml b/themes/PaperMod/i18n/fi.yaml
index cbbf3c4..cbbf3c4 100644
--- a/i18n/fi.yaml
+++ b/themes/PaperMod/i18n/fi.yaml
diff --git a/i18n/fr.yaml b/themes/PaperMod/i18n/fr.yaml
index e48d8e9..e48d8e9 100644
--- a/i18n/fr.yaml
+++ b/themes/PaperMod/i18n/fr.yaml
diff --git a/i18n/he.yaml b/themes/PaperMod/i18n/he.yaml
index 30c3e74..30c3e74 100644
--- a/i18n/he.yaml
+++ b/themes/PaperMod/i18n/he.yaml
diff --git a/i18n/hi.yaml b/themes/PaperMod/i18n/hi.yaml
index 681efdc..681efdc 100644
--- a/i18n/hi.yaml
+++ b/themes/PaperMod/i18n/hi.yaml
diff --git a/i18n/hr.yaml b/themes/PaperMod/i18n/hr.yaml
index 2f2d228..2f2d228 100644
--- a/i18n/hr.yaml
+++ b/themes/PaperMod/i18n/hr.yaml
diff --git a/i18n/hu.yaml b/themes/PaperMod/i18n/hu.yaml
index a039dda..a039dda 100644
--- a/i18n/hu.yaml
+++ b/themes/PaperMod/i18n/hu.yaml
diff --git a/i18n/id.yaml b/themes/PaperMod/i18n/id.yaml
index 93d34f5..93d34f5 100644
--- a/i18n/id.yaml
+++ b/themes/PaperMod/i18n/id.yaml
diff --git a/i18n/it.yaml b/themes/PaperMod/i18n/it.yaml
index c87c95d..c87c95d 100644
--- a/i18n/it.yaml
+++ b/themes/PaperMod/i18n/it.yaml
diff --git a/i18n/ja.yaml b/themes/PaperMod/i18n/ja.yaml
index 93948d3..93948d3 100644
--- a/i18n/ja.yaml
+++ b/themes/PaperMod/i18n/ja.yaml
diff --git a/i18n/ko.yaml b/themes/PaperMod/i18n/ko.yaml
index 777dd93..777dd93 100644
--- a/i18n/ko.yaml
+++ b/themes/PaperMod/i18n/ko.yaml
diff --git a/i18n/ku.yaml b/themes/PaperMod/i18n/ku.yaml
index d1d30a5..d1d30a5 100644
--- a/i18n/ku.yaml
+++ b/themes/PaperMod/i18n/ku.yaml
diff --git a/i18n/mn.yaml b/themes/PaperMod/i18n/mn.yaml
index dbce2ce..dbce2ce 100644
--- a/i18n/mn.yaml
+++ b/themes/PaperMod/i18n/mn.yaml
diff --git a/i18n/ms.yaml b/themes/PaperMod/i18n/ms.yaml
index d8a9eff..d8a9eff 100644
--- a/i18n/ms.yaml
+++ b/themes/PaperMod/i18n/ms.yaml
diff --git a/i18n/nl.yaml b/themes/PaperMod/i18n/nl.yaml
index e9d06fa..e9d06fa 100644
--- a/i18n/nl.yaml
+++ b/themes/PaperMod/i18n/nl.yaml
diff --git a/i18n/no.yaml b/themes/PaperMod/i18n/no.yaml
index 2400348..2400348 100644
--- a/i18n/no.yaml
+++ b/themes/PaperMod/i18n/no.yaml
diff --git a/i18n/oc.yaml b/themes/PaperMod/i18n/oc.yaml
index 9292fd8..9292fd8 100644
--- a/i18n/oc.yaml
+++ b/themes/PaperMod/i18n/oc.yaml
diff --git a/i18n/pa.yaml b/themes/PaperMod/i18n/pa.yaml
index 32192c5..32192c5 100644
--- a/i18n/pa.yaml
+++ b/themes/PaperMod/i18n/pa.yaml
diff --git a/i18n/pl.yaml b/themes/PaperMod/i18n/pl.yaml
index 81b0e77..81b0e77 100644
--- a/i18n/pl.yaml
+++ b/themes/PaperMod/i18n/pl.yaml
diff --git a/i18n/pnb.yaml b/themes/PaperMod/i18n/pnb.yaml
index fa2f8a8..fa2f8a8 100644
--- a/i18n/pnb.yaml
+++ b/themes/PaperMod/i18n/pnb.yaml
diff --git a/i18n/pt.yaml b/themes/PaperMod/i18n/pt.yaml
index ab06429..ab06429 100644
--- a/i18n/pt.yaml
+++ b/themes/PaperMod/i18n/pt.yaml
diff --git a/i18n/ro.yaml b/themes/PaperMod/i18n/ro.yaml
index 694f20b..694f20b 100644
--- a/i18n/ro.yaml
+++ b/themes/PaperMod/i18n/ro.yaml
diff --git a/i18n/ru.yaml b/themes/PaperMod/i18n/ru.yaml
index a5dbb5c..a5dbb5c 100644
--- a/i18n/ru.yaml
+++ b/themes/PaperMod/i18n/ru.yaml
diff --git a/i18n/sk.yaml b/themes/PaperMod/i18n/sk.yaml
index f129d37..f129d37 100644
--- a/i18n/sk.yaml
+++ b/themes/PaperMod/i18n/sk.yaml
diff --git a/i18n/sv.yaml b/themes/PaperMod/i18n/sv.yaml
index 65ce422..65ce422 100644
--- a/i18n/sv.yaml
+++ b/themes/PaperMod/i18n/sv.yaml
diff --git a/i18n/sw.yaml b/themes/PaperMod/i18n/sw.yaml
index 5fceb1a..5fceb1a 100644
--- a/i18n/sw.yaml
+++ b/themes/PaperMod/i18n/sw.yaml
diff --git a/i18n/th.yaml b/themes/PaperMod/i18n/th.yaml
index d8036ae..d8036ae 100644
--- a/i18n/th.yaml
+++ b/themes/PaperMod/i18n/th.yaml
diff --git a/i18n/tr.yaml b/themes/PaperMod/i18n/tr.yaml
index b014a15..b014a15 100644
--- a/i18n/tr.yaml
+++ b/themes/PaperMod/i18n/tr.yaml
diff --git a/i18n/uk.yaml b/themes/PaperMod/i18n/uk.yaml
index 41be964..41be964 100644
--- a/i18n/uk.yaml
+++ b/themes/PaperMod/i18n/uk.yaml
diff --git a/i18n/uz.yaml b/themes/PaperMod/i18n/uz.yaml
index c9f2375..c9f2375 100644
--- a/i18n/uz.yaml
+++ b/themes/PaperMod/i18n/uz.yaml
diff --git a/i18n/vi.yaml b/themes/PaperMod/i18n/vi.yaml
index 2eb05d0..2eb05d0 100644
--- a/i18n/vi.yaml
+++ b/themes/PaperMod/i18n/vi.yaml
diff --git a/i18n/zh-tw.yaml b/themes/PaperMod/i18n/zh-tw.yaml
index 48b84d2..48b84d2 100644
--- a/i18n/zh-tw.yaml
+++ b/themes/PaperMod/i18n/zh-tw.yaml
diff --git a/i18n/zh.yaml b/themes/PaperMod/i18n/zh.yaml
index 0280425..0280425 100644
--- a/i18n/zh.yaml
+++ b/themes/PaperMod/i18n/zh.yaml
diff --git a/images/screenshot.png b/themes/PaperMod/images/screenshot.png
index a37c485..a37c485 100644
--- a/images/screenshot.png
+++ b/themes/PaperMod/images/screenshot.png
Binary files differ
diff --git a/images/tn.png b/themes/PaperMod/images/tn.png
index cf83179..cf83179 100644
--- a/images/tn.png
+++ b/themes/PaperMod/images/tn.png
Binary files differ
diff --git a/layouts/404.html b/themes/PaperMod/layouts/404.html
index a405573..a405573 100644
--- a/layouts/404.html
+++ b/themes/PaperMod/layouts/404.html
diff --git a/layouts/_default/_markup/render-image.html b/themes/PaperMod/layouts/_default/_markup/render-image.html
index f368ff8..f368ff8 100644
--- a/layouts/_default/_markup/render-image.html
+++ b/themes/PaperMod/layouts/_default/_markup/render-image.html
diff --git a/themes/PaperMod/layouts/_default/archives.html b/themes/PaperMod/layouts/_default/archives.html
new file mode 100644
index 0000000..eea3fc8
--- /dev/null
+++ b/themes/PaperMod/layouts/_default/archives.html
@@ -0,0 +1,83 @@
+{{- define "main" }}
+
+<header class="page-header">
+ <h1>
+ {{ .Title }}
+ {{- if (.Param "ShowRssButtonInSectionTermList") }}
+ {{- $rss := (.OutputFormats.Get "rss") }}
+ {{- if (eq .Kind `page`) }}
+ {{- $rss = (.Parent.OutputFormats.Get "rss") }}
+ {{- end }}
+ {{- with $rss }}
+ <a href="{{ .RelPermalink }}" title="RSS" aria-label="RSS">
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"
+ stroke-linecap="round" stroke-linejoin="round" height="23">
+ <path d="M4 11a9 9 0 0 1 9 9" />
+ <path d="M4 4a16 16 0 0 1 16 16" />
+ <circle cx="5" cy="19" r="1" />
+ </svg>
+ </a>
+ {{- end }}
+ {{- end }}
+ </h1>
+ {{- if .Description }}
+ <div class="post-description">
+ {{ .Description }}
+ </div>
+ {{- end }}
+</header>
+
+{{- $pages := where site.RegularPages "Type" "in" site.Params.mainSections }}
+
+{{- if site.Params.ShowAllPagesInArchive }}
+{{- $pages = site.RegularPages }}
+{{- end }}
+
+{{- range $pages.GroupByPublishDate "2006" }}
+{{- if ne .Key "0001" }}
+<div class="archive-year">
+ {{- $year := replace .Key "0001" "" }}
+ <h2 class="archive-year-header" id="{{ $year }}">
+ <a class="archive-header-link" href="#{{ $year }}">
+ {{- $year -}}
+ </a>
+ <sup class="archive-count">&nbsp;{{ len .Pages }}</sup>
+ </h2>
+ {{- range .Pages.GroupByDate "January" }}
+ <div class="archive-month">
+ <h3 class="archive-month-header" id="{{ $year }}-{{ .Key }}">
+ <a class="archive-header-link" href="#{{ $year }}-{{ .Key }}">
+ {{- .Key -}}
+ </a>
+ <sup class="archive-count">&nbsp;{{ len .Pages }}</sup>
+ </h3>
+ <div class="archive-posts">
+ {{- range .Pages }}
+ {{- if eq .Kind "page" }}
+ <div class="archive-entry">
+ <h3 class="archive-entry-title entry-hint-parent">
+ {{- .Title | markdownify }}
+ {{- if .Draft }}
+ <span class="entry-hint" title="Draft">
+ <svg xmlns="http://www.w3.org/2000/svg" height="15" viewBox="0 -960 960 960" fill="currentColor">
+ <path
+ d="M160-410v-60h300v60H160Zm0-165v-60h470v60H160Zm0-165v-60h470v60H160Zm360 580v-123l221-220q9-9 20-13t22-4q12 0 23 4.5t20 13.5l37 37q9 9 13 20t4 22q0 11-4.5 22.5T862.09-380L643-160H520Zm300-263-37-37 37 37ZM580-220h38l121-122-18-19-19-18-122 121v38Zm141-141-19-18 37 37-18-19Z" />
+ </svg>
+ </span>
+ {{- end }}
+ </h3>
+ <div class="archive-meta">
+ {{- partial "post_meta.html" . -}}
+ </div>
+ <a class="entry-link" aria-label="post link to {{ .Title | plainify }}" href="{{ .Permalink }}"></a>
+ </div>
+ {{- end }}
+ {{- end }}
+ </div>
+ </div>
+ {{- end }}
+</div>
+{{- end }}
+{{- end }}
+
+{{- end }}{{/* end main */}}
diff --git a/layouts/_default/baseof.html b/themes/PaperMod/layouts/_default/baseof.html
index db3a506..db3a506 100644
--- a/layouts/_default/baseof.html
+++ b/themes/PaperMod/layouts/_default/baseof.html
diff --git a/layouts/_default/index.json b/themes/PaperMod/layouts/_default/index.json
index feeb437..feeb437 100644
--- a/layouts/_default/index.json
+++ b/themes/PaperMod/layouts/_default/index.json
diff --git a/layouts/_default/list.html b/themes/PaperMod/layouts/_default/list.html
index 81aea6e..81aea6e 100644
--- a/layouts/_default/list.html
+++ b/themes/PaperMod/layouts/_default/list.html
diff --git a/layouts/_default/rss.xml b/themes/PaperMod/layouts/_default/rss.xml
index fed8ae9..fed8ae9 100644
--- a/layouts/_default/rss.xml
+++ b/themes/PaperMod/layouts/_default/rss.xml
diff --git a/layouts/_default/search.html b/themes/PaperMod/layouts/_default/search.html
index bb7d436..bb7d436 100644
--- a/layouts/_default/search.html
+++ b/themes/PaperMod/layouts/_default/search.html
diff --git a/layouts/_default/single.html b/themes/PaperMod/layouts/_default/single.html
index 19a624f..19a624f 100644
--- a/layouts/_default/single.html
+++ b/themes/PaperMod/layouts/_default/single.html
diff --git a/layouts/_default/terms.html b/themes/PaperMod/layouts/_default/terms.html
index 6fd2654..6fd2654 100644
--- a/layouts/_default/terms.html
+++ b/themes/PaperMod/layouts/_default/terms.html
diff --git a/layouts/partials/anchored_headings.html b/themes/PaperMod/layouts/partials/anchored_headings.html
index 377af89..377af89 100644
--- a/layouts/partials/anchored_headings.html
+++ b/themes/PaperMod/layouts/partials/anchored_headings.html
diff --git a/layouts/partials/author.html b/themes/PaperMod/layouts/partials/author.html
index 8f2758f..8f2758f 100644
--- a/layouts/partials/author.html
+++ b/themes/PaperMod/layouts/partials/author.html
diff --git a/layouts/partials/breadcrumbs.html b/themes/PaperMod/layouts/partials/breadcrumbs.html
index 2686ca0..2686ca0 100644
--- a/layouts/partials/breadcrumbs.html
+++ b/themes/PaperMod/layouts/partials/breadcrumbs.html
diff --git a/layouts/partials/comments.html b/themes/PaperMod/layouts/partials/comments.html
index 918451a..918451a 100644
--- a/layouts/partials/comments.html
+++ b/themes/PaperMod/layouts/partials/comments.html
diff --git a/layouts/partials/cover.html b/themes/PaperMod/layouts/partials/cover.html
index 9c1f9ea..9c1f9ea 100644
--- a/layouts/partials/cover.html
+++ b/themes/PaperMod/layouts/partials/cover.html
diff --git a/layouts/partials/edit_post.html b/themes/PaperMod/layouts/partials/edit_post.html
index 8d355d7..8d355d7 100644
--- a/layouts/partials/edit_post.html
+++ b/themes/PaperMod/layouts/partials/edit_post.html
diff --git a/layouts/partials/extend_footer.html b/themes/PaperMod/layouts/partials/extend_footer.html
index 0519748..0519748 100644
--- a/layouts/partials/extend_footer.html
+++ b/themes/PaperMod/layouts/partials/extend_footer.html
diff --git a/layouts/partials/extend_head.html b/themes/PaperMod/layouts/partials/extend_head.html
index 150cbef..150cbef 100644
--- a/layouts/partials/extend_head.html
+++ b/themes/PaperMod/layouts/partials/extend_head.html
diff --git a/layouts/partials/footer.html b/themes/PaperMod/layouts/partials/footer.html
index 832cdba..832cdba 100644
--- a/layouts/partials/footer.html
+++ b/themes/PaperMod/layouts/partials/footer.html
diff --git a/layouts/partials/head.html b/themes/PaperMod/layouts/partials/head.html
index ae6450a..ae6450a 100644
--- a/layouts/partials/head.html
+++ b/themes/PaperMod/layouts/partials/head.html
diff --git a/layouts/partials/header.html b/themes/PaperMod/layouts/partials/header.html
index 82d025b..82d025b 100644
--- a/layouts/partials/header.html
+++ b/themes/PaperMod/layouts/partials/header.html
diff --git a/layouts/partials/home_info.html b/themes/PaperMod/layouts/partials/home_info.html
index 199dfb7..199dfb7 100644
--- a/layouts/partials/home_info.html
+++ b/themes/PaperMod/layouts/partials/home_info.html
diff --git a/layouts/partials/index_profile.html b/themes/PaperMod/layouts/partials/index_profile.html
index 6882f39..6882f39 100644
--- a/layouts/partials/index_profile.html
+++ b/themes/PaperMod/layouts/partials/index_profile.html
diff --git a/layouts/partials/post_canonical.html b/themes/PaperMod/layouts/partials/post_canonical.html
index abfc1e3..abfc1e3 100644
--- a/layouts/partials/post_canonical.html
+++ b/themes/PaperMod/layouts/partials/post_canonical.html
diff --git a/layouts/partials/post_meta.html b/themes/PaperMod/layouts/partials/post_meta.html
index b0c0417..b0c0417 100644
--- a/layouts/partials/post_meta.html
+++ b/themes/PaperMod/layouts/partials/post_meta.html
diff --git a/layouts/partials/post_nav_links.html b/themes/PaperMod/layouts/partials/post_nav_links.html
index b988641..b988641 100644
--- a/layouts/partials/post_nav_links.html
+++ b/themes/PaperMod/layouts/partials/post_nav_links.html
diff --git a/layouts/partials/share_icons.html b/themes/PaperMod/layouts/partials/share_icons.html
index 910ba7f..910ba7f 100644
--- a/layouts/partials/share_icons.html
+++ b/themes/PaperMod/layouts/partials/share_icons.html
diff --git a/layouts/partials/social_icons.html b/themes/PaperMod/layouts/partials/social_icons.html
index ce76a30..ce76a30 100644
--- a/layouts/partials/social_icons.html
+++ b/themes/PaperMod/layouts/partials/social_icons.html
diff --git a/layouts/partials/svg.html b/themes/PaperMod/layouts/partials/svg.html
index 941c4a0..941c4a0 100644
--- a/layouts/partials/svg.html
+++ b/themes/PaperMod/layouts/partials/svg.html
diff --git a/layouts/partials/templates/_funcs/get-page-images.html b/themes/PaperMod/layouts/partials/templates/_funcs/get-page-images.html
index 268ceb4..268ceb4 100644
--- a/layouts/partials/templates/_funcs/get-page-images.html
+++ b/themes/PaperMod/layouts/partials/templates/_funcs/get-page-images.html
diff --git a/layouts/partials/templates/opengraph.html b/themes/PaperMod/layouts/partials/templates/opengraph.html
index fe5bf53..fe5bf53 100644
--- a/layouts/partials/templates/opengraph.html
+++ b/themes/PaperMod/layouts/partials/templates/opengraph.html
diff --git a/layouts/partials/templates/schema_json.html b/themes/PaperMod/layouts/partials/templates/schema_json.html
index 8a4efb4..8a4efb4 100644
--- a/layouts/partials/templates/schema_json.html
+++ b/themes/PaperMod/layouts/partials/templates/schema_json.html
diff --git a/layouts/partials/templates/twitter_cards.html b/themes/PaperMod/layouts/partials/templates/twitter_cards.html
index a6e1d05..a6e1d05 100644
--- a/layouts/partials/templates/twitter_cards.html
+++ b/themes/PaperMod/layouts/partials/templates/twitter_cards.html
diff --git a/layouts/partials/toc.html b/themes/PaperMod/layouts/partials/toc.html
index 28f8694..28f8694 100644
--- a/layouts/partials/toc.html
+++ b/themes/PaperMod/layouts/partials/toc.html
diff --git a/layouts/partials/translation_list.html b/themes/PaperMod/layouts/partials/translation_list.html
index 0028251..0028251 100644
--- a/layouts/partials/translation_list.html
+++ b/themes/PaperMod/layouts/partials/translation_list.html
diff --git a/layouts/robots.txt b/themes/PaperMod/layouts/robots.txt
index f26f508..f26f508 100644
--- a/layouts/robots.txt
+++ b/themes/PaperMod/layouts/robots.txt
diff --git a/layouts/shortcodes/collapse.html b/themes/PaperMod/layouts/shortcodes/collapse.html
index 17d8d3b..17d8d3b 100644
--- a/layouts/shortcodes/collapse.html
+++ b/themes/PaperMod/layouts/shortcodes/collapse.html
diff --git a/layouts/shortcodes/figure.html b/themes/PaperMod/layouts/shortcodes/figure.html
index 8c93eff..8c93eff 100644
--- a/layouts/shortcodes/figure.html
+++ b/themes/PaperMod/layouts/shortcodes/figure.html
diff --git a/layouts/shortcodes/inTextImg.html b/themes/PaperMod/layouts/shortcodes/inTextImg.html
index 0239fd6..0239fd6 100644
--- a/layouts/shortcodes/inTextImg.html
+++ b/themes/PaperMod/layouts/shortcodes/inTextImg.html
diff --git a/layouts/shortcodes/ltr.html b/themes/PaperMod/layouts/shortcodes/ltr.html
index 4ad7682..4ad7682 100644
--- a/layouts/shortcodes/ltr.html
+++ b/themes/PaperMod/layouts/shortcodes/ltr.html
diff --git a/layouts/shortcodes/rawhtml.html b/themes/PaperMod/layouts/shortcodes/rawhtml.html
index 9350c13..9350c13 100644
--- a/layouts/shortcodes/rawhtml.html
+++ b/themes/PaperMod/layouts/shortcodes/rawhtml.html
diff --git a/layouts/shortcodes/rtl.html b/themes/PaperMod/layouts/shortcodes/rtl.html
index a69b8ce..a69b8ce 100644
--- a/layouts/shortcodes/rtl.html
+++ b/themes/PaperMod/layouts/shortcodes/rtl.html
diff --git a/theme.toml b/themes/PaperMod/theme.toml
index e4352b9..e4352b9 100644
--- a/theme.toml
+++ b/themes/PaperMod/theme.toml