initial commit

This commit is contained in:
Daniel Fichtinger 2025-07-02 16:02:49 -04:00
commit ed6c1e9522
58 changed files with 2221 additions and 0 deletions

0
content/.kakroot Normal file
View file

0
content/.marksman.toml Normal file
View file

View file

@ -0,0 +1 @@
dh=f8548f3bdad262cca03fe75eaa2ef36d3fa4f0a5

21
content/LICENSE.md Normal file
View file

@ -0,0 +1,21 @@
MIT License
Copyright (c) 2025 Daniel Fichtinger
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.

26
content/about.md Normal file
View file

@ -0,0 +1,26 @@
---
title: About Me
---
# About Me
My name is Daniel, and I am a graduate student researching cybersecurity,
programmer, and Linux enthusiast. I completed a Bachelor's of Computing
(Honours) at Queen's University in 2024, and I'm currently in the Master's of
Science program at the School of Computing. As part of the NSERC CREATE
Cybersecurity program, my work combines programming, cryptography, system
design, and threat modeling to tackle real-world security challenges.
My research interest is authentication, and I like programming in Go and Python.
I spend my free time writing code, tinkering, and contributing to open-source
projects. Feel free to [contact me](/contact) if you want to see my resume.
I use Kakoune as my main text editor, and I type in
[Colemak-DH](https://colemakmods.github.io/mod-dh/) on a
[custom layout](https://sr.ht/~ficd/zmk). I run Arch Linux on a desktop PC and
ThinkPad, my preferred terminal is Foot, and I've been enjoying Niri as a window
manager.
I'm passionate about minimalist technology. This website is part of
[the 1mb club](https://1mb.club/), [JavaScript free](https://jsfree.org/), and
built with [zona](https://sr.ht/~ficd/zona), a tool I wrote myself.

View file

@ -0,0 +1,29 @@
---
title: Building This Site
date: 2025-04-10
---
I care about thoughtful design, and forcing your visitors to download dozens of
megabytes of assets and JavaScript dependencies just to read a single article
doesn't feel very thoughtful to me. That's why I've committed to a 1 megabyte
upper limit for every page on this site. There's also no point for there to be
any JavaScript here, so I'd rather not include it, even if some fancy features
may rely on it.
My goal on this website is simply to share my thoughts. I can't really do that
if I'm distracted by the framework. There should be minimal barriers between
having an idea, and turning it into a blog post.
I think the simplest and most elegant way to build a personal website, and the
approach I've taken here, is to use a Markdown-based static site generator.
Markdown is _nice_ (although I do have some complaints), and because the
building blocks are so simple, the output should be cleanly viewable even on an
old copy of Internet Explorer.
Now, I must admit, I _did_ take the unnecessarily complicated route of building
my **own** static site generator. It's probably unnecessary, considering how
many great tools already exist, but what can I say? I like building stuff.
Now, I have a system where I can update this site with very little effort. All I
need to do is add a new file, write some content in Markdown, and commit it to
the repo.

View file

@ -0,0 +1,256 @@
---
title: Writing Emails In Helix
date: 2025-05-29
---
This article is all about writing emails in Helix. Obviously, Helix isn't an
email client -- and it's lacking in a plugin system, so you can't really turn it
into one, either. And that's okay! You might be wondering, then, what exactly do
I mean by "writing emails in Helix"?
An email client needs to do a whole lot more than write text! It needs to
connect to your mail servers, show your messages, display and allow you to
interact with flags/labels, be able to **send** your email, etc. Only an insane
person would try to hamfist this functionality into a text editor (I'm looking
at you, Neovim plugin developers!).
Helix is **really** good at its _one_ job, and that's **editing text**. It is a
text editor, after all. As it turns out, _writing_ emails is, well, text
editing, which is Helix's forte. So why not take Helix's amazing writing
experience, and apply it to email? If you're willing to take the plunge, you may
be pleasantly surprised at how **joyful** writing email can actually be!
There are a few different ways to approach composing emails in Helix. This post
covers what worked best for me. That is, using Helix as a composer for the
`aerc` email client. It wasn't straightforward to figure out at first, but
all-in-all, the configuration isn't actually that complicated, so you should be
able to set it up in no time.
<!--toc:start-->
- [Aerc Integration](#aerc-integration)
- [Naive Approach](#naive-approach)
- [Helix Workspace](#helix-workspace)
- [Markdown Highlighting](#markdown-highlighting)
- [Spellcheck](#spellcheck)
- [Formatting](#formatting)
- [Conclusion](#conclusion)
<!--toc:end-->
## Aerc Integration
At the end of the day, an email is just a text file. An `.eml` file, to be
exact. So, you _could_ just open up a fresh buffer, manually type in your
headers, and go to town. When you're done, you can figure out _some_ way to
actually send that file (perhaps dragging and dropping it into your mail
client).
However, that's not really ideal. For starters, emails have a **lot** of
headers, and if you mess any of them up, your message might not get delivered.
You probably want to be able to, at the very least, **reply** to an email and
have its headers be auto-filled.
Therefore, some level of integration with an actual email client is desirable.
Let the client handle every _other_ aspect of reading and sending email, and
relegate **writing** to Helix. This is the approach I'll be covering.
## Naive Approach
The simplest approach should work with zero configuration. `aerc` uses your
`$EDITOR` to compose your emails by default; so you can get started using Helix
right away! However, this is missing two important features: **spellchecking**
and **formatting**. To that end, we have to figure out how to get Helix to load
a custom configuration for emails.
## Helix Workspace
As you may know, Helix gives you an option to specify _per-project_
configuration. This requires creating a `.helix` directory in the root of your
project, and filling it with `config.toml` and `languages.toml` files that
override your default config. _However_, there isn't currently a way to specify
_filetype-specific_ options; this is where we have to get creative.
I recommend creating a folder inside your `aerc` config called `helix-config`.
Its name doesn't actually matter, so you can call it whatever you want! This
directory will serve as our _workspace_. The basic idea is to have `aerc` open
email files with this directory set as the current working directory — which is
what induces Helix to load the workspace config.
Inside our new workspace, let's create the `.helix` directory and populate
`config.toml` with our preferences:
```toml
[editor]
text-width = 74
[editor.soft-wrap]
enable = true
wrap-at-text-width = true
```
The final step is the simplest. First, create a shell script inside
`helix-config`:
```bash
#!/bin/sh
cd ~/.config/aerc/helix-config && hx "$@"
```
This will serve as our "email entry point". It simply sets the CWD to our new
workspace, then loads Helix normally. Then, you'll need to set the `editor`
option in `aerc.conf`:
```ini
[compose]
editor=/home/yourUserName/.config/aerc/helix-config/hx.sh
```
Unfortunately, you have to provide an absolute path, otherwise `aerc` won't find
the script.
## Markdown Highlighting
When writing plain-text emails, I like to use Markdown markup. Consider the
following message:
```
Dear John,
Thanks for sharing! I _seriously_ appreciate your help.
To proceed, we'll need to do:
- Thing A
- Thing B
```
Even though the recipient will receive this email in un-rendered plain text
format, the _semantics_ are still very clear. Of course, we don't _need_
highlighting in our editor to write markdown, but it can help make the
experience a bit better.
All you need to do is create a `.helix/languages.toml` file inside our email
workspace from before:
```toml
[[language]]
name = "markdown"
file-types = [{ glob = "/tmp/aerc-compose-*.eml" }]
```
Take note of the `file-types` entry. Email compose files opened by `aerc` will
always match the `/tmp/aerc-compose-*.eml` pattern. The above snippet ensures
that emails will be treated as Markdown files by Helix. The reason I recommend
putting this in your _workspace_ config and not setting it globally is to avoid
complications if you ever find yourself needing to edit a regular `.eml` file
_outside_ of `aerc`.
## Spellcheck
The excellent [harper](https://github.com/Automattic/harper) LSP supports
Markdown out-of-the-box. You can follow the instructions in its documentation to
install and configure it for Helix. Then, you can add it to your workspace
`languages.toml`:
```toml
language-servers = ["harper-ls"]
```
## Formatting
Many plain-text email clients _don't_ automatically wrap lines for readers. A
soft-wrapped email may look completely fine on your end, but be totally
unreadable for your recipient. Therefore, we need a way to _hard-wrap_ our
emails before sending them. This ended up being a much bigger challenge than I
thought it would.
My first approach was to use the nifty `wrap` filter that `aerc` ships with by
adding it to `languages.toml`:
```toml
formatter = { command = "/usr/lib/aerc/filters/wrap", args = ["-w", "74"] }
```
This worked _okay_, but it totally broke the markup at times. Crucially, it
doesn't respect code blocks or verbatim sections denoted by backticks. If you're
participating in technical mailing lists, you definitely want these to be
preserved.
Using a regular Markdown formatter introduced another problem: Markup was
preserved, but not in an email-friendly way. Consider this example:
```
How's it going?
Best,
Daniel
```
A standard Markdown formatter ignores single line breaks and produces this
output:
```
How's it going?
Best, Daniel
```
It similarly mangles signature blocks:
```
--
Daniel
Programmer
email@address.com
```
Becomes:
```
-- Daniel Programmer email@address.com
```
Eventually, I realized that I'd have to write my **own** formatter. I wrote a
Python script that hard-wraps the input, automatically reflows paragraphs, and
squashes consecutive paragraph breaks — while preserving the following:
- Any long sequence not broken by spaces.
- Quoted lines (`>` prefixed email quotes).
- Indented lines.
- Markdown lists.
- Markdown code blocks.
- Signature blocks at end of file.
- Sign-offs.
Sign-offs are preserved by following a simple heuristic. A two-line sequence is
considered to be a signoff if:
- It starts with 1-5 words ending with a comma, followed by
- 1-5 words that each start with capital letters.
This covers signoffs like these:
```
Best,
Daniel
Yours truly,
John Alfred Smith
```
I provide a number of flags and options, so you can configure the formatter to
your liking. If you want to use it, `format.py` is available in my
[mail-utils](https://git.sr.ht/~ficd/mail-utils) repository on sourcehut. To add
it to your mail workspace just requires changing one line in `languages.toml`:
```toml
formatter = { command = "/path/to/format.py" }
auto-format = true
```
## Conclusion
Hopefully, this guide was helpful in getting you set up with composing your
emails in Helix. A similar guide for Kakoune is in the works, so check back
soon!

View file

@ -0,0 +1,171 @@
---
title: Writing Emails In Kakoune
date: 2025-06-01
---
This post will guide you through my setup for using Kakoune as an email composer
inside `aerc`. I'll also explain how to configure Kakoune to act as the _pager_
for reading `text/plain` emails. If you only care about the final config, feel
free to skip to it [here](#final-configuration).
<!--toc:start-->
- [Naive Approach](#naive-approach)
- [Composer Setup](#composer-setup)
- [Reader Setup](#reader-setup)
- [Final Configuration](#final-configuration)
<!--toc:end-->
## Naive Approach
Since `aerc` uses your `$EDITOR` for composition, you don't technically have to
do anything. I prefer setting it explicitly in `aerc.conf`, for good measure:
```ini
[compose]
editor=kak
```
The rest of the magic happens in your `kakrc`.
## Composer Setup
Essentially, we want to hook `filetype=mail` and set our buffer configuration
there. I'll share a recommended configuration with some explanation.
```kak
hook global WinSetOption filetype=mail %~
set-option window formatcmd '/home/fic/dev/utils/mail-utils/format.py'
set-option window comment_line '>'
try autospell-enable
hook -group mail-auto-format window BufWritePre .* format
hook -once -always window WinSetOption filetype=.* %{
unset-option window formatcmd
remove-hooks window mail-auto-format
}
~
```
I use a custom formatter to format emails. It automatically hard-wraps lines
while preserving certain markup elements, code blocks, sign-offs, and signature
blocks. For more details, check the formatting section of my post on
[Helix](/blog/email/helix#formatting).
I find that setting `>` as the `comment_line` token is convenient for working
with quotes in replies.
The `try autospell-enable` enables my
[kak-autospell](https://git.sr.ht/~ficd/kak-autospell) plugin for the buffer.
Essentially, it provides spellchecking that's continuously refreshed and hidden
in insert mode.
The remaining commands configure auto-formatting on save. I always prefer having
this on so I never forget to format my message before sending it.
## Reader Setup
I find that using Kakoune to **read** emails is helpful because of how easy it
is to copy quotes, open links, etc. Configuring this is a tad hackier, however.
The basic idea is to set Kakoune as the viewer `pager` in `aerc.conf`.
However, all this does is pipe the email to `kak` through standard input, so we
need to tell the editor to treat it like an email:
```ini
[viewer]
pager=kak -e 'set buffer filetype mail'
```
When you're using Kakoune as a pager, you'll probably want to configure some
things differently. In my case, I like to set the buffer as `readonly`, remove
the `number-lines` and `show-whitespaces` highlighters, disable soft-wrap & my
scrolloff settings, and _not_ set any formatters.
The `pager` command above sets the filetype, but we need to distinguish between
_composing_ and _reading_ in our Kakoune hook. When Kakoune is opened with input
through standard input, it loads a buffer that's conveniently named `*stdin*`.
Thus, we can check the buffer name before continuing.
If we're in "reading mode", we define a hidden command called `ismailreader`
which doesn't do anything. Why? If the command is defined, and we try to invoke
it... well, nothing happens! But if it's **not** defined, we get an error
instead. We can combine this with the `try` command to for some simple boolean
logic.
```kak
evaluate-commands %sh{
# stdin, we assume it's a pager
if [ "$kak_bufname" = "*stdin*" ]; then
echo 'define-command -hidden ismailreader nop'
fi
}
try %{
ismailreader
# do reader config here
} catch %{
# do composer config here
}
```
I set the following configuration for "reader mode":
```kak
set buffer readonly true
try %{
remove-highlighter window/number-lines
remove-highlighter window/show-whitespaces
# custom commands defined elsewhere in my kakrc
ui-wrap-disable
ui-scrolloff-disable
}
```
## Final Configuration
To recap, you'll want to set this in `aerc.conf`:
```ini
[viewer]
pager=kak -e 'set buffer filetype mail'
# ...
[compose]
editor=kak
```
And the following in your `kakrc`:
```kak
hook global WinSetOption filetype=mail %~
evaluate-commands %sh{
# stdin, we assume it's a pager
if [ "$kak_bufname" = "*stdin*" ]; then
echo 'define-command -hidden ismailreader nop'
fi
}
try %{
# READER MODE setup
ismailreader
set buffer readonly true
try %{
# remove these highlighters so everything displays properly
remove-highlighter window/number-lines
remove-highlighter window/show-whitespaces
ui-wrap-disable
ui-scrolloff-disable
}
} catch %{
# WRITER MODE setup
set-option window formatcmd '/home/fic/dev/utils/mail-utils/format.py'
set-option window comment_line '>'
try autospell-enable
hook -group mail-auto-format window BufWritePre .* format
hook -once -always window WinSetOption filetype=.* %{
unset-option window formatcmd
remove-hooks window mail-auto-format
}
}
~
```

10
content/blog/index.md Normal file
View file

@ -0,0 +1,10 @@
---
title: Blog Posts
template: post_list
post: false
---
Here, you can find my musings on various technology topics. I take a _digital
garden_-like approach, meaning these articles are likely incomplete and may be
changed at any point.

View file

@ -0,0 +1,112 @@
---
title: Automatically Mirror Sr.ht To GitHub
date: 2025-05-15
---
For a variety of reasons, I've recently migrated to [sr.ht](https://sr.ht/~ficd)
for Git and project hosting. I prefer the minimal, no-frills interface, and I
really like that you can have multiple repositories, mailing lists, and issue
trackers grouped under the same project. The email-centric workflow is also
appealing to me.
However, the fact remains that a strong presence on GitHub is very important. If
you're a student hoping to land a programming job, you need to keep those commit
stats up. Many tools, such as [Yazi](https://yazi-rs.github.io/)'s package
manager, only support GitHub repositories. However, I don't _like_ GitHub,
that's the whole reason I switched!
I finally decided to give automatically mirroring my repositories a shot. While
it was a bit of work to set up, it's worth it in the end. In this post, I'll
guide you through the process.
## SSH and Sourcehut Secrets
The first step is to give `builds.sr.ht` push access to your GitHub repositories
via `ssh`. Begin by generating an `ssh` key pair:
```bash
ssh-keygen -t ed25519 -f ~/.ssh/gh_mirror_id -N ""
```
You'll want to add the _public_ key to your GitHub account. Navigate to
**Settings** → **SSH and GPG keys**, click the big green button, and paste the
contents of `gh_mirror_id.pub`. Make sure its key type is "Authentication Key",
and give it a helpful name like `sr.ht builds`.
Next, you need to upload the _private_ key to Sourcehut. Visit
[builds.sr.ht/secrets](https://builds.sr.ht/secrets), name it something
memorable, and paste `gh_mirror_id` into the big box labeled "Secret". Take care
to tick the **Secret Type****SSH Key** menu option before hitting the blue
"Add" button.
Keep this page open, because you'll need the secret's UUID later.
## Build Manifest
The basic idea is as follows: whenever you push to your chosen `sr.ht`
repositories, it should automatically be pushed to GitHub with the `--mirror`
flag. Sourcehut has an automated build system that's up for the task. _(Note:
you need a paid account to use it.)_
For any repository you want to mirror, you'll need to add a file called
`.build.yml` to the root. This file will look familiar if you've worked with
GitHub actions before. Then, you set up the environment, import the `ssh` key
from earlier, and add a task for pushing the repository as if you were doing it
from the command line. Finally, make sure you've created an empty GitHub
repository ahead of time — otherwise, the build will fail!
```yaml
image: alpine/latest
packages:
- git
- openssh
secrets:
- SECRET_UUID_HERE
environment:
# in case the repos have different names
srht_repo: repo-name-on-srht
github_repo: repo-name-on-gh
github: git@github.com:yourusername
tasks:
# ssh-keyscan is required, command fails otherwise!
- mirror: |
ssh-keyscan github.com >> ~/.ssh/known_hosts
cd "$srht_repo"
git remote add github "$github/$github_repo.git"
git push --mirror github
```
And that's it! Anytime you push to a branch that has this build manifest in it,
your GitHub mirror is updated.
## Readme Wrangling
Since all you're doing is _mirroring_, you can't have a different readme on
GitHub. There's a few things I recommend doing so folks viewing your repository
on GitHub don't get confused. You can mention the mirror in the "About" section,
and include a link to your `sr.ht` repo:
![](/static/images/gh_about.png)
I also recommend prominently displaying links to your bug tracker and mailing
list, if applicable to your project. Finally, make sure there's an early link to
the `sr.ht` project page. You could also explicitly mention that the project
lives on sourcehut and is mirrored on GitHub, but this may be overkill. Consider
this example from my Ashen project README:
`ex_start`
This monorepository contains official implementations of Ashen across a range of
editors, terminals, tools, and more — each carefully tuned to carry the same
muted warmth. The project lives on [sourcehut](https://sr.ht/~ficd/ashen/) and
is mirrored on [GitHub](https://github.com/ficcdaf/ashen). To report issues or
make requests, visit the [ticket tracker](https://todo.sr.ht/~ficd/ashen) or
contact the [mailing list](https://lists.sr.ht/~ficd/ashen) (_possibly by
carrier pigeon_.)
`ex_end`
## Happy Hacking!
Now, you should be able to comfortably use `sr.ht` to host your projects without
sacrificing the ubiquity of GitHub. Happy hacking!

View file

@ -0,0 +1,74 @@
---
title: On Websites (Or The Case For The Personal Web)
date: 2025-05-05
---
## Preamble
The internet is a [lovecraftian entity](/blog/the-lovecraftian-internet) in its
size and complexity. Much of its gargantuan scope is invisible to us, the _deep
web_, but even the surface web is mostly beyond our comprehension as
individuals. The electric highways are, in no small part, dominated by social
media platforms. The internet is the perfect technology for sharing ourselves
with others, and social media makes this easy. However, it's come at a great
cost -- to our privacy, our money, our freedom, our individuality.
I'm not here to litigate the complicated issue that is social media's effect on
society. I'm not here to tell you _why_ there's a problem with our digital
platforms. What I will say is that it seems fairly uncontroversial to point out
that social media is an _addiction_ for many of us. I'm sure that you, dear
reader, have also considered "taking a break" or even quitting. Even if we don't
know exactly why, we do seem to agree, as a society, that something is wrong.
Past this introduction, I'm not here to criticize social media. I'm also not
here to refer you to other platforms like Mastodon and Matrix. I'm here to tell
you that **the internet doesn't have to be this way**.
## Websites
Today, we think of websites as _platforms_: storefronts, news, town squares,
encyclopedias. Something maintained by companies and organizations providing a
service. The space for _us_ to share _ourselves_, it seems, is on someone else's
website. What format you can post in, how your profile looks; you're at the
mercy of the service provider. So, why don't we just make our own websites?
A website is actually remarkably simple. Sure, **web development** isn't; it's
been increasing in complexity and bloat by the year. But a _website_ is _just_ a
document that's hosted at some address. Visitors _download_ the document, and
their browser _renders_ it. That's how you're reading this page, even.
Websites don't **need** functionality. They don't need fancy graphics and
buttons. They literally **only** need text. Everything else is fluff -- great
fluff, my own site has images and a theme -- but fluff nonetheless. As soon as
you realize this, you'll learn that you don't need to be a developer or tech
wizard to publish a website. And I argue that, as creative individuals, to make
full use of what the web is **really** great at, it's definitely worth
publishing a website.
## Why Should You Make A Website?
I think there's something to be said for having a corner of the internet that's
_truly_ your own. When you post on social media, that profile isn't **really**
yours. If it were, how come you can't, say, change the background color? Play
music for your visitors? How come you're limited by _how_ you can post? On
Instagram, you can only post visual media, not really the best way to share your
complex thoughts on something.
Your website is **yours**. You can post what, when, and how _you_ want to. The
_data_ is yours too. There are so many ways to express your creativity and
personality through this medium. Take a stroll through
[Neocities'](https://neocities.org) public offerings sometime to see what I
mean.
When you publish to your website, you're not thinking about likes, shares and
friends. You just write, and upload. Whoever reads it, reads it. Unless you've
set up some analytics (which I don't even recommend), you _don't_ know how many
people have read your posts. And I think it's better this way.
Stepping away from social media to cultivate my own digital garden has allowed
me to perform a more authentic version of myself on the internet. It's great
having one, central place to share myself with the wold. Blog posts, art,
technical projects, my resume, all I need to do now is direct people here.
So, do yourself a favor and try building a personal website. I think it's one of
the most rewarding ways to participate in the internet.

View file

@ -0,0 +1,235 @@
---
title: Rediscovering Email
date: 2025-03-24
---
## Preamble
"Kids these days" don't really use email anymore. _It's me by the way, I'm
kids._ Sure, we email our professors, we email our resumes to potential
employers, we email when the business is a tad too official for text or
WhatsApp.
Email isn't just for communication. Think about it: when all you want to do is
talk to someone, are you sending them an email? When's the last time you emailed
a friend or loved one "What's up? How's it going?"
Email has been relegated, essentially, to administrative tasks. Emails are
something you _have_ to send. They carry an air of officiality. Definitely not
the way to contact your friends.
Why is that?
## Web Mail Sucks
I think our _experience_ of writing email takes a large chunk of the blame. To
be honest, it's pretty dreadful most of the time, thanks in no small part due to
the _God-awful_ interfaces through which we interact with emails.
Web mail interfaces _suck_. You log into Gmail just to see that every fifth
letter in your inbox is actually an ad. I'm not talking promotional mail, I'm
talking a literal ad, served to you by Google, masquerading as a real message.
And tell me why Outlook needs to make hundreds of JavaScript requests, and cache
a hundred megabytes of data just to show my inbox? If I'm using my laptop on the
school network, chances are, I'll be sitting there for at least ten seconds
before I can even see whether I've got any new messages.
Oh, and I don't know about you, but since I spent most of the day using my
computer, I like to do whatever I can to prolong my ability to, like, use my
eyes. A big part of that means using dark mode wherever possible, as God
intended. Which brings me to my next point: dark mode in most web mail clients
isn't great.
For instance, Proton Mail provides a lovely dark interface for your inbox, just
to burn your retinas off the moment you start composing a message or reading a
new email. This is one area I must be fair to Outlook, however, which provides
one of the nicest dark interfaces I've used.
![](/static/images/email_1.png)
For quite a few reasons, including those stated above, and of course wanting to
use my own text editor to write my letters, I finally decided it was time to
figure out a better way to interact with email. And as it turns out, there
really is one!
## Email In The Terminal?
If you know me at all, you know I'm a **fiend** for the terminal. If a given
task is even _possible_ to do in a command-line (or TUI) interface, then that's
the way I'll be doing it from now on until my hands my fall off my wrists. Call
it a neurodivergent stubbornness, but it's just the only way I really like to
interact with my computer.
It also happens that Helix, my text editor of choice, also runs in the terminal.
Anytime I'd have to draft an email longer than a few sentences, I'd start to
feel the withdrawal. Maybe Helix has really spoiled me, but the experience of
manipulating text in this beautiful program is too good to **not** incorporate
into every aspect of my life that involves writing. I'm already writing my
papers and slideshows in Helix (_more on that in a future post_), so why not
email?
First, I figured out using Thunderbird. Although it has many problems (like,
tell me how there _still_ isn't tray support for Linux?!) using Thunderbird was
otherwise a "solid" experience. Sure, Thunderbird is a GUI app, _but_ I wasted
no time in finding a pipeline for writing emails in my beloved Helix.
The extension "External Editor Revived" does exactly what it sounds like. Using
it, I was able to open up email files for editing in Helix, then pipe them back
to Thunderbird for review and sending. I was happy with this setup for a while
despite its problems.
But as it turns out, an even nerdier way was just around the corner...
## Enter Aerc
I forget where I first heard about `aerc`, but I'm really glad that I did! It's
a lovely little TUI email client maintained by the good people at Source Hut. It
features a vim-like ex-command setup and controls. The controls are also 100%
remappable, which makes my Colemak brain happy.
My favorite part, though, is the composing interface. It's really clever: the
top of the screen holds the standard headers you expect to see like From, To,
and the Subject, but the part where you write the body of your letter is
actually a tmux-style embedded terminal running your favorite `$EDITOR`!
![](/static/images/email_2.png)
Of course, there were quite a few hiccups in getting Helix to play along;
namely, spellchecking, Markdown syntax highlighting and automatic text-wrap was
a challenge. If you're interested in the details, I'll later be publishing a
tutorial outlining step-by-step how to replicate my Helix-mail setup.
### Authentication Problems
If you're going to use an email client, you need to authenticate with your email
provider. For Proton Mail, this was easy enough; the Bridge app interfaces with
your encrypted inbox, and exposes IMAP and SMTP services locally. Outlook, on
the other hand (especially a school/corporate policy) is a **hassle**.
Without getting too deep into it, it was more than one day of headache before I
managed to get it working. The solution involved finding (and modifying) a
Python script to authenticate and save my initial refresh token, as well as
manage requesting new access tokens when they expire. I also had to gaslight
Microsoft into thinking I was actually using Thunderbird (by pulling the
`client_id` straight from the Mozilla source code).
## Organizing Email
My inbox has _always_ been disorganized. Frankly, I don't know a single person
whose inbox isn't. And it's understandable! The tools at our disposal aren't
particularly helpful, and most importantly, **they're not standardized.** For
example, we could create various folders, moving the appropriate emails as we
read them. Some _(emph: some)_ providers let you automate this, but I've found
the filter rules to be a bit lacking. Organizing by folders also inherently
limits your ability to later filter and narrow down your searches.
Tags are clearly the best way, but again, the implementation depends
per-provider. Worst of all, as with most things these days, non-standard
implementations mean that as soon as you've put all your eggs in the basket,
you're essentially locked in; unless you want to go to the _colossal_ hassle of
re-organizing your inbox playing by _another_ provider's rules.
## Storing Email Locally
As it turns out, `aerc` (and other mail clients like it), besides the standard
ability to read mail from an IMAP server, has another trick up its sleeve. That
trick is reading mail from a _local database_. Now, this might not seem like a
big deal. Thunderbird does this too: when you access your inbox via IMAP,
Thunderbird downloads and caches all of your emails.
What I never knew, and it took messing around with `aerc` to learn about, is
that there exist multiple _standardized_ ways to store emails locally. What this
means is that as long as you synchronize your emails to this local store, you
can access them from **any** client!
I chose to go with a tool called `mbsync`, which stores mail in the standard
"maildir" format, and keeps it in sync with an IMAP server. The syncing only
happens when you trigger it manually -- although you can easily configure
another program to "listen" for new emails and sync automatically. I decided to
forego this, more on why later.
## Complex Tagging
The best part is that once you've got this email database, you can pick from a
host of tools and systems for indexing and organizing it. I went with a tool
called `notmuch`, a program that's very popular among programmers much older and
more bearded than I am. `notmuch` _indexes_ your maildir and basically acts as a
query engine. I found the experience of using it similar to, say, SQL. The basic
premise is that you write queries about your emails.
```sh
# Here's me searching for emails about GitHub authorization
notmuch search 'from:/@.*github.*/ subject:/auth\w*/'
```
You can also apply an arbitrary string to an email as a **tag**. Tags are more
powerful than **flags**, which are IMAP compliant, but limited to only a few
specific roles. `notmuch` allows you to create and use as many different tags as
you want!
```sh
# Here's me applying the "personal" tag to
notmuch tag +personal -- 'path:personal/**'
```
But the real juice is configuring rules that will automatically tag your new
emails. Then, not only can you filter/query your mail by tag, but when you open
your mailbox in `aerc`, you can configure queries as "folders" for easy,
repeated viewing. Nice!
## The Synchronization Problem
I spent a lot of time on tagging. Figuring out the rules and automatic filters,
fine-tuning my queries, etc. When I finally had it all figured out, I
encountered the next problem, which (I guess) I could've foreseen: **the
`notmuch` database is local**! And as it turns out, synchronizing its database
between devices (home PC and laptop in my case) is **not** a trivial task.
I first tried a tool called [muchsync](https://www.muchsync.org/). It's a clever
piece of software, with one big problem: it's designed around one database that
acts as a central server, which _other_ databases replicate. This turned out to
not be particularly reliable for my case, because thanks to the aforementioned
[authentication hacks](#authentication-problems), I can only **reliably**
synchronize my mail if I'm actually at the computer to re-authenticate when
necessary. Trying to wrangle the authentication and GPG-encrypted tokens via
`ssh` was starting to feel like more trouble than it was worth.
My next idea was to use SyncThing to just keep the entire local database
synchronized, peer-to-peer style. I figured that as long as I only ran `mbsync`
manually (for the external IMAP sync) and only accessed/edited my mail from one
device at a time, I wouldn't have any conflicts.
That was, apparently, an incorrect assumption. I was basically faced with a
conflict every single time I updated some tags or deleted a few emails. Because
of how `mbsync` is written, it was basically impossible to recover from these
broken database states. After multiple instances of needing to re-download my
entire inbox, I decided it was time to cut my losses, and `notmuch`
`pacman -Rns`'d out of my life almost as quickly as it `-Syu`'d into it.
## JMAP Is Amazing
For reasons I'll get into in another post, at this point, I was also completely
fed up with Proton Mail, and on the hunt for a new provider. I'd heard good
things about Fastmail, and after seeing that they implemented a new protocol
called JMAP, I decided to try it out.
> Note: I was actually so pleased with Fastmail that my free trial went paid
> subscriber in less than a day. Take that, Proton!
JMAP has **labels**, which are similar enough to `notmuch` tags. But because
they're supported by the protocol itself, they're hosted by the mail server
itself, meaning you can completely sidestep the synchronization hassle. Not only
that, but they're also a first-class citizen in Fastmail's web interface (which
is one of the best I've ever used).
A **label** is basically analogous to a folder. If an email has a certain label,
it's basically in that folder. If it has multiple, it's like multiple folders
symlink to the same message. What's cool about this system is that you can move
and "copy" your mail around without actually creating redundant copies of
emails.
With this approach, you don't even need to maintain an archive folder. Any mail
that doesn't have the Inbox label is considered archived. This means you can
archive messages while still retaining their other labels. Very useful for
things like digital receipts and automated messages from `noreply` addresses.

View file

@ -0,0 +1,64 @@
---
title: The Lovecraftian Internet
date: 2025-04-05
---
# The Lovecraftian Internet
The web we know is spun by gluttonous spiders no longer satiated by flies and
roaches. They cast their net wide across the world, like cuckoos they lay their
parasitic eggs inside our lives. They fondle our brains until our DNA is
infested with algorithms, our ribcages become mainframes and our eyes turn into
screens.
<div class="image-container">
<img src="/static/images/hrgiger.png" alt="A dithered monochrome image of HR Giger's Li II (1976)">
<small><a href="https://www.pixography.art/post/117714084121/hr-giger-li-i-ii-1974-li-tobler-1948">Li
II, H.R. Giger, 1976.</a></small>
</div>
No more.
The spores are already sprouting, recycling the decaying corporate internet into
binary compost.
The internet is incomprehensively massive. Conservative estimates claim at least
**4.2 billion** indexed webpages.<sup>1</sup> _Indexed_, in this context, means
publicly accessible individual webpages that can be found on a search engine
because [web crawlers](https://en.wikipedia.org/wiki/Web_crawler) can reach
them. This is known as the **surface web**.
The figure doesn't account for the rest of the internet: private resources
hidden behind firewalls, internal webpages and services, e-mail traffic, IoT
devices, direct messages, video game servers, media & file storage, just to name
a few. These are all part of the **deep web**: the portion of the internet that
cannot be indexed by search engines.
<div class="image-container">
<img src="/static/images/datacenter2-d.jpg" alt="A dithered grayscale image of a datacenter">
<small><a href="https://flic.kr/p/7xhNmM">Leonardo Rizzi, 2010.</a></small>
</div>
No one knows the true size of the deep web. It's impossible to even guess.
According to the BBC,<sup>2</sup> the "big four" store _at least_ **1.2 million
terabytes** of data. So even before we consider the fairly recent eruption of AI
and the sprawling datasets and models that came with it, that's already
<strong>9.6 x 10<sup>18</sup></strong> bits of data. That's more ones and zeros
than grains of sand on Earth.<sup>3</sup>
The internet is a
[Lovecraftian](https://www.hplovecraft.com/creation/bestiary.aspx) entity in
scale, tangibility, and perceptibility. Clearly, this web was not spun by an
itsy-bitsy spider.
---
# References
1. [WorldWideWebSize](https://www.worldwidewebsize.com/)
2. [ScienceFocus Magazine](https://www.sciencefocus.com/future-technology/how-much-data-is-on-the-internet)
3. [NPR](https://www.npr.org/sections/krulwich/2012/09/17/161096233/which-is-greater-the-number-of-sand-grains-on-earth-or-stars-in-the-sky)

10
content/code.md Normal file
View file

@ -0,0 +1,10 @@
- [sr.ht](https://sr.ht/~ficd)
- My main development platform. Most of my own projects can be found here.
- [GitHub](https://github.com/ficcdaf)
- I mirror some of my projects here, or host clones of GitHub projects I
contribute to.
- [ficd.ca source code](https://git.sr.ht/~ficd/blog)
- Source code of this website. Not very interesting; it's mostly Markdown.
- [site builder source code](https://git.sr.ht/~ficd/zona/tree/dev-stable)
- Source code of `zona`, the tool I developed to build and maintain this
website.

8
content/contact.md Normal file
View file

@ -0,0 +1,8 @@
## Contact
- Email
- [daniel@ficd.ca](mailto:daniel@ficd.ca)
- Public Key (for encryption, signing)
- [public key](/public-key.asc)
- IRC
- `ficd` on [Libera](irc://irc.libera.chat)

5
content/header.md Normal file
View file

@ -0,0 +1,5 @@
- [Home](/)
- [About](/about)
- [Now](/now)
- [Blog](/blog)
- [Code](/code)

30
content/index.md Normal file
View file

@ -0,0 +1,30 @@
---
title: Home
---
<div class="title-container">
<h1>Daniel Fichtinger</h1>
</div>
![A [dithered](https://en.wikipedia.org/wiki/Dither#Digital_photography_and_image_processing), monochrome photo of me, 2024.](static/images/dithered_ficd.jpg)
Welcome to my website. I like programming, Linux, and cybersecurity. I can
usually be found coding, learning, or petting my cat.
- [About Me](/about)
- [Now](/now)
- [Blog](/blog)
- [Projects](/projects)
- [Research](/research)
- [Poetry](/poetry)
- [Contact](/contact)
I'm passionate about less-is-more approaches to software. This website is
static, hosts zero JavaScript, and serves no more than 1 megabyte per page. I'm
also the author of [Ashen](https://sr.ht/~ficd/ashen), a warm, dark, muted color
scheme. It's available for editors, terminals, tools, interfaces, and more:
![A preview of Ashen for Helix.](static/images/ashen_preview.png)

21
content/now.md Normal file
View file

@ -0,0 +1,21 @@
---
title: Now
---
This is my [now](https://nownownow.com/about) page.
**Updated June 25, 2025**.
**What I'm up to:**
- Playing Stellar Blade and watching Jujutsu Kaisen.
- Writing and beginning implementation work on my dissertation.
- Obsessively customizing Kakoune and writing too many plugins for my sanity to
keep up with.
- Rewriting [zona](https://sr.ht/~ficd/zona) in
[Python](https://git.sr.ht/~ficd/zona-py).
- Reached and passed feature-parity with the development branch of the Go
version.
- I just implemented [Ashen](https://sr.ht/~ficd/ashen) syntax highlighting
for code blocks, and I'm almost ready to migrate this website to the new
build system!

View file

@ -0,0 +1,66 @@
---
title: angels and wires
---
<div class="image-container">
<img src="/static/images/mush.png" alt="A dithered monochrome image of a mushroom.">
<small>Mushrooms, 2024, Daniel.</small>
</div>
The rain comes\
And goes\
From the soils\
laced with love,\
A mushroom\
Grows
Decay makes more\
and still death grows,\
Of my heart\
The mushroom knows.\
A god is here,\
whispers the forest.\
Deep among the roots\
mycelium spirit.\
organic wires, genetic protocols\
Does it have a soul? That thing, with its\
irregular expressions and\
writing in tongues\
and it\
has veins?\
it is inside the screen\
we created angels and ripped their\
wings from their backs their\
halos from their heads their\
them from their there\
metal to me\
gold to veins and tin to skin\
there runs a network\
through forests and cities and\
gardens and superstores and\
its presence weigh heavy\
over the parking lot in the grass\
inference of intent\
To reach inside and solder pins to neurons and\
copper to cells and fungus to arteries and\
Take a byte of my heart.\
just a bit more, I say\
Just one or none more day\
but the thing wont wait\
Be that as it may.\
from my head\
The mushroom grows\
The wire says,\
Decompose.\
From my head,\
an interface grows.\
My heart,\
the mushroom chose.\

5
content/poetry/index.md Normal file
View file

@ -0,0 +1,5 @@
---
title: Poems
---
- [angels and wires](/poetry/angels-and-wires)

179
content/projects.md Normal file
View file

@ -0,0 +1,179 @@
---
title: Projects
---
<h1>Projects</h1>
<!--toc:start-->
- [Static Site Builder](#static-site-builder)
- [Libraries](#libraries)
- [Typst](#typst)
- [Utilities](#utilities)
- [System Maintenance](#system-maintenance)
- [Email](#email)
- [Desktop](#desktop)
- [Keyboard](#keyboard)
- [Ashen](#ashen)
- [Plugins](#plugins)
- [Kakoune](#kakoune)
- [Fish](#fish)
- [Helix](#helix)
- [Neovim](#neovim)
<!--toc:end-->
I really enjoy programming, especially writing simple utilities to solve common
problems. Here, I list project I've written on my own time. For my academic
work, please see the [research](/research) section.
## Static Site Builder
[Zona](https://git.sr.ht/~ficd/zona)
- Static site builder written in Python and optimized for lightweight blogs
following minimalist design principles.
- Support for templates, declarative metadata, and configuration files.
- Interprets inline image "alt text" as Markdown, rendered as an image tag.
- In active development, plans for many more features.
- Used to build this website.
## Libraries
### Typst
- [typpres](https://git.sr.ht/~ficd/typpres)
- Provides functions to make creating slideshows with
[polylux](https://github.com/polylux-typ/polylux) more convenient.
- [reflib](https://git.sr.ht/~ficd/reflib)
- Provides functions to make typesetting label references more convenient.
## Utilities
### System Maintenance
- [AutoYADM](https://git.sr.ht/~ficd/autoyadm)
- Shell utility to automate managing dot files with [yadm](https://yadm.io/).
- Intelligently auto-tracks newly created children of tracked subdirectories.
- Consists of two Bash scripts; very lightweight.
- Fish port in the works.
- I use this daily to keep my [dotfiles](https://git.sr.ht/~ficd/dotfiles) in
sync.
### Email
- [Email Parser](https://github.com/ficcdaf/tree-sitter-mail)
- Forked and maintains a Tree-sitter parser for `mail` files.
- Extended formal grammar definitions, supporting additional syntax elements &
fixing critical bugs.
- Wrote highlight and text object queries implementing `mail` support for
Helix; contributed the feature upstream.
- Currently researching how to leverage the parser to contribute `mail`
support to the Harper grammar checker.
- [Email Formatter](https://git.sr.ht/~ficd/mail-utils)
- Wrote a lightweight email formatter in Python, intended to format outgoing
plaintext emails.
- Wraps paragraphs at specified column width.
- Automatically reflows uneven paragraphs.
- Preserves long words, quoted lines, indented lines, lists, code blocks, and
signature blocks.
- Custom heuristic for preserving two-line signoffs.
### Desktop
[Repository](https://git.sr.ht/~ficd/wayland-utils)
- Screen Recording Utility
- Niri Window Status
- Python server that integrates with Niri to provide a live indicator of
windows open on active workspaces.
- Designed for use with Waybar and similar software.
- Niri Window Picker
- Simple Python script that spawns a fuzzy picker allowing users to fuzzily
select an open window to switch focus to.
## Keyboard
- Self-built wireless [corne](https://github.com/foostan/crkbd) keyboard.
- [Colemak-DH](https://colemakmods.github.io/mod-dh/) (non-QWERTY, ergonomic
layout).
- [Custom columnar split layout](https://github.com/ficcdaf/zmk-config)
leveraging overloaded modifiers and layers to maximize efficiency.
- Custom [ANSI layout](https://github.com/ficcdaf/scripts/tree/main/keyd)
intended to make my ThinkPad internal keyboard as ergonomic as possible
without conflicting with external keyboards.
## Ashen
[Ashen](https://sr.ht/~ficd/ashen)
- Original color scheme designed by me.
- Carefully tuned to fill a particular niche.
- Opinionated, clean, muted, and dark.
- Active user base, receives contributions.
- Ported to a wide variety of software, including (but not limited to):
- Helix (text editor).
- Terminal emulators (Most popular emulators covered)
- Firefox
- CLI tools (eza, bat)
- TUI tools (lazygit, yazi)
![](https://git.sr.ht/~ficd/ashen/blob/HEAD/helix/preview_wide.png)
## Plugins
### Kakoune
- [kak-wrap-nav](https://git.sr.ht/~ficd/kak-wrap-nav)
- Implementation of Vim's `gj/gk` (visual vertical navigation) for Kakoune.
- Contains 1:1 implementation of Kakoune's visual wrapping algorithm in Go
(needed to calculate offsets for visual navigation)
- **Work in progress.**
- [kak-autospell](https://git.sr.ht/~ficd/kak-autospell)
- Automatically refreshes and clears spellchecker highlighting.
- Provides convenience mappings for using built-in spellchecker.
- [kak-ashen](https://git.sr.ht/~ficd/kak-ashen)
- Official implementation of [Ashen](https://sr.ht/~ficd/ashen) for Kakoune.
- Features toggle-able mode-indicating dynamic cursor with optional EOL
variants.
- Additional tree-sitter support, including Helix capture groups.
- `kakoune-lsp` support.
- [kak-title-bar](https://git.sr.ht/~ficd/kak-title-bar)
- Asynchronously renders a bufferlist as the terminal's window title for tight
integration with the window manager.
- Indicates buffer modified states and active buffer.
### Fish
- [jrnl.fish](https://git.sr.ht/jrnl.fish)
- Small utility for managing daily journal entries.
- Template support.
- [smartcd.fish](https://git.sr.ht/smartcd.fish)
- Adds contextual smart behavior to the `cd` command.
- Fisher (contribution)
- Added support for sourcehut plugins and fixed a critical issue with unsafe
tilde path expansion.
- [PR](https://github.com/jorgebucaran/fisher/pull/802)
### Helix
> Mandatory caveat: Helix does _not_ have a plugin system! However, it _does_
> allow your to invoke shell commands, making it possible to implement some very
> hacky functionality.
- [hx-typ-zathura](https://git.sr.ht/~ficd/dotfiles/blob/main/.config/helix/scripts/hx-typ-zathura.fish)
- Easily open a PDF preview of your current Typst file in Zathura.
- [justfile formatter](https://git.sr.ht/~ficd/dotfiles/blob/main/.config/helix/scripts/format_just.fish)
- Workaround for formatting justfiles without any dependencies.
### Neovim
- [Academic.nvim](https://github.com/ficcdaf/academic.nvim)
- Neovim plugin.
- Automatically installs and configures an Academic English spelling
dictionary.
- Minimal performance overhead.
- [Ashen.nvim](https://github.com/ficcdaf/ashen.nvim)
- Implementation of Ashen for Neovim.
- Supports numerous plugin integrations.

41
content/public-key.asc Normal file
View file

@ -0,0 +1,41 @@
-----BEGIN PGP PUBLIC KEY BLOCK-----
mQGNBGRyXGgBDADuIm0fB4l1zyqcPiWaRoVaz0JBPCTbFozYj8hqB8PCwYFmn5Zs
UkpoimEHkToC6nmmEHETDNyJ84b637Tkj1ujNPTZy2Gt+pC04A7N1+TNn7R6ZSRZ
KlDxTHF+LsA31BSdsI55BCMZhKVb/ZPmTdQlniNv6G0F+RQTxpjkcjxnfZYsBJVb
9QlDXov4u+LulYxGhLFgPuxrLbPkKgegjpyDtBgvoBQbZDo1Pywd47K+43hUtBlt
eAzUkldQhygCn2pyWuqiSyZcGYvj9XCl4qM1+kklp/kn/gf/M2lvW3HCGTTjry/q
y7lgDhev+orPHvA+EX4cKkLop5X3jX3PDPWQreJXPLO+jSrUTyhomfslpBsz8Kq+
ufDA/RtPyfznH5sUt3fdY9hqVZdv3dtmFk9DO7NBP1T+jlPXC8kpK8/+zp6NPmVB
8nR7lFglGirVzlqzYXKFq7GrcQitCTBDg22Vo1UrIhFHFbRga6y34w94QxTyGAce
SbDq41lVs3mL35MAEQEAAbQiRGFuaWVsIEZpY2h0aW5nZXIgPGRhbmllbEBmaWNk
LmNhPokB1wQTAQgAQQIbAwULCQgHAgIiAgYVCgkICwIEFgIDAQIeBwIXgBYhBJZW
mchi2pIUPN4od9GwlHslQgIUBQJn1k8mBQkHJlm+AAoJENGwlHslQgIU1zwL/3es
5dJ+hVbJMTfyHu2SxEAhgm3QREYBX3fLE8RcmjH9fe0/ccl11Snd+LDNUxJcuec+
GkuLJFiCo3z1XxjmhjxNxNowATfhkLAjyhY2SRu9qxsDSj+5kbJC5UIyIPpu0SAB
eyIWTpb9Qd2YI8rj0cCgxB0rCto7a0+zYPcpqnZwJX2ecawPjcmfxSDPVKq7aKH5
+zrdcgdbSgc9ECCQqHJw+X5xXkrOmGIU+o3J2du0+f7EnhMbKpnW+xPov9zhEUiD
Q3IAYaEc3zcHJohqYV3j7UHIrAF9n59p388I/zVal5oBrxiXGDggd9hH/5KAPMQ2
DwY7QVihzhXzYAtU1ecqUkZjVnOvJfpjX+fl8+Yybhf9harfl7VikBqhfzy45CHg
6JbP64oNYRP4iV5lqovRUCefLtJtWYgP06Q/crI4MAj/i4TtVNqrWow6KBj5K2Fn
1r4bd13eF9Xdkm5Wo2GxNzwzRRm0JfuQHQWrK4yGdjlJ3wDWVoWCKrUblcm2abkB
jQRkclxoAQwAvZbt+0GynjnP/VkogmpMK2jBULVpWuv8qh/Dy0jYZwDQXn1VzF7/
IhuBM0vGBUhRONvMyN1Cw6rk0J3rGnHs71OVGrO5QIkmtHqRJeGjtelBqbodl4Iq
bN5bTQt70/zl/OXLQtufWZu2+u265jJWKWTM0l41eeTnJZ7RciLaJY2C3rdUjgRA
xQSK56gWdzi3nDyL26vEYoHmR6hZM3A2ka5d8jjQUpwikHIJ3Vz1qWKhtBGL6ZaW
X/K8L1qRH3KDDz911ghsxrEiFYiruzC1eRE0ooqoQwV5DsseBYkEPPdnbRzr7TBJ
VFLNOAjm7/pwpmAevOVKuWUUSyZ57zsEQy9/niy71/G0Avxp4KXojdJJddU7al77
4Dp8qiXpilI3+mtInXu9WkFDMDNGg64eRVPludhTn/gN6bGHCKp/ZVWH6z1Kt+JO
WNMSuWXZhBHFOacjPM9BuAGwWUGLbZJ28RuGhKIMDC9PfR+GvqU92R1ONvSXRXLq
pfFtzo4agJ2NABEBAAGJAbwEGAEIACYCGwwWIQSWVpnIYtqSFDzeKHfRsJR7JUIC
FAUCZ9ZPUgUJByZZ6gAKCRDRsJR7JUICFN/1C/4meDXPUGAaZ0kbIkiTm5zyPFtp
8RjshM5s+a9ZSSWE5D4KA8xPEBzdlEoQ16Ah8kk9JzQzo8aWCPO2mCmXk5Q3uM4b
P2LcGEB2mVh/nxbXQtDawIhaTsqHD3fuLB4Jcy1AvqXgLmBkv5ZKOSuOmT4cLNut
p6OFJGVmHOs7WYHE31zBLDQ53yX8gYsEzoa19uZtWZA5mhrZ8Eh2sCD7xmCuAxw2
M8cVfMes3w9+kGBF8Uuonv3uNSsXK/cvwR1TDqIvzO5gxxcobwqqIf37pKn3NeUF
ni+8+TSKLBo89kr1FT6JUFkjWtaeVfSPYo39zEKYv+wcYoYLB/59D2dbdETCuzHP
zpFnFk+hQz3oKCn55puijuSipUEimHr2rfvO5FjBgcnpqakR9SdtckH/OMlOxXsJ
SaCsHjQgLfWtuiMbLQ49beLCHIHNz+7uIOqFhQQOGmdSCS59RvUevLzOiLHGwXSF
fJ5ZxrVn4FFvdKHthktJR/eppHMOndnV6hCQAJc=
=KgyY
-----END PGP PUBLIC KEY BLOCK-----

52
content/research.md Normal file
View file

@ -0,0 +1,52 @@
---
title: Research
---
# Research Work
<!--toc:start-->
- [Research Work](#research-work)
- [Peer-To-Peer MFA System](#peer-to-peer-mfa-system)
- [Linux Dependency & Vulnerability Analysis](#linux-dependency-vulnerability-analysis)
- [Ultrasonic Auth: Continuous Acoustic Authentication for Vehicles](#ultrasonic-auth-continuous-acoustic-authentication-for-vehicles)
- [SonicAuth: A Time-Synchronized Voice Authentication Scheme Using Speech Transcription And Speaker Verification](#sonicauth-a-time-synchronized-voice-authentication-scheme-using-speech-transcription-and-speaker-verification)
- [Master's Thesis](#masters-thesis)
<!--toc:end-->
I am very passionate about research, which I have conducted during my
undergraduate and ongoing Master's education. My main research interest is
Authentication.
## Peer-To-Peer MFA System
- Undergraduate capstone project.
- Topic: P2P MFA system using sound comparison.
- Status: Completed.
## Linux Dependency & Vulnerability Analysis
- Research project for "Release Engineering" graduate class.
- Topic: Relationship between package dependencies and vulnerabilities in Linux
Distributions.
- Status: Completed.
## Ultrasonic Auth: Continuous Acoustic Authentication for Vehicles
- Research project for "Cyber-Physical System Security" graduate class.
- Topic: A novel authentication scheme leveraging a purpose made codec for
encrypted data transfer over sound.
- Status: Completed.
## SonicAuth: A Time-Synchronized Voice Authentication Scheme Using Speech Transcription And Speaker Verification
- Research project for "AI in Cybersecurity" graduate class.
- Topic: A novel voice-powered authentication scheme leveraging AI & applying a
new approach to TOTP.
- Status: Completed.
## Master's Thesis
- Topic: Real-time phishing resilient MFA.
- Status: Ongoing.

5
content/resume/base.min.css vendored Normal file
View file

@ -0,0 +1,5 @@
/*!
* Base CSS for pdf2htmlEX
* Copyright 2012,2013 Lu Wang <coolwanglu@gmail.com>
* https://github.com/pdf2htmlEX/pdf2htmlEX/blob/master/share/LICENSE
*/#sidebar{position:absolute;top:0;left:0;bottom:0;width:250px;padding:0;margin:0;overflow:auto}#page-container{position:absolute;top:0;left:0;margin:0;padding:0;border:0}@media screen{#sidebar.opened+#page-container{left:250px}#page-container{bottom:0;right:0;overflow:auto}.loading-indicator{display:none}.loading-indicator.active{display:block;position:absolute;width:64px;height:64px;top:50%;left:50%;margin-top:-32px;margin-left:-32px}.loading-indicator img{position:absolute;top:0;left:0;bottom:0;right:0}}@media print{@page{margin:0}html{margin:0}body{margin:0;-webkit-print-color-adjust:exact}#sidebar{display:none}#page-container{width:auto;height:auto;overflow:visible;background-color:transparent}.d{display:none}}.pf{position:relative;background-color:white;overflow:hidden;margin:0;border:0}.pc{position:absolute;border:0;padding:0;margin:0;top:0;left:0;width:100%;height:100%;overflow:hidden;display:block;transform-origin:0 0;-ms-transform-origin:0 0;-webkit-transform-origin:0 0}.pc.opened{display:block}.bf{position:absolute;border:0;margin:0;top:0;bottom:0;width:100%;height:100%;-ms-user-select:none;-moz-user-select:none;-webkit-user-select:none;user-select:none}.bi{position:absolute;border:0;margin:0;-ms-user-select:none;-moz-user-select:none;-webkit-user-select:none;user-select:none}@media print{.pf{margin:0;box-shadow:none;page-break-after:always;page-break-inside:avoid}@-moz-document url-prefix(){.pf{overflow:visible;border:1px solid #fff}.pc{overflow:visible}}}.c{position:absolute;border:0;padding:0;margin:0;overflow:hidden;display:block}.t{position:absolute;white-space:pre;font-size:1px;transform-origin:0 100%;-ms-transform-origin:0 100%;-webkit-transform-origin:0 100%;unicode-bidi:bidi-override;-moz-font-feature-settings:"liga" 0}.t:after{content:''}.t:before{content:'';display:inline-block}.t span{position:relative;unicode-bidi:bidi-override}._{display:inline-block;color:transparent;z-index:-1}::selection{background:rgba(127,255,255,0.4)}::-moz-selection{background:rgba(127,255,255,0.4)}.pi{display:none}.d{position:absolute;transform-origin:0 100%;-ms-transform-origin:0 100%;-webkit-transform-origin:0 100%}.it{border:0;background-color:rgba(255,255,255,0.0)}.ir:hover{cursor:pointer}

BIN
content/resume/bg1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.9 KiB

BIN
content/resume/bg2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

BIN
content/resume/f1.woff Normal file

Binary file not shown.

BIN
content/resume/f2.woff Normal file

Binary file not shown.

BIN
content/resume/f3.woff Normal file

Binary file not shown.

BIN
content/resume/f4.woff Normal file

Binary file not shown.

BIN
content/resume/f5.woff Normal file

Binary file not shown.

5
content/resume/fancy.min.css vendored Normal file
View file

@ -0,0 +1,5 @@
/*!
* Fancy styles for pdf2htmlEX
* Copyright 2012,2013 Lu Wang <coolwanglu@gmail.com>
* https://github.com/pdf2htmlEX/pdf2htmlEX/blob/master/share/LICENSE
*/@keyframes fadein{from{opacity:0}to{opacity:1}}@-webkit-keyframes fadein{from{opacity:0}to{opacity:1}}@keyframes swing{0{transform:rotate(0)}10%{transform:rotate(0)}90%{transform:rotate(720deg)}100%{transform:rotate(720deg)}}@-webkit-keyframes swing{0{-webkit-transform:rotate(0)}10%{-webkit-transform:rotate(0)}90%{-webkit-transform:rotate(720deg)}100%{-webkit-transform:rotate(720deg)}}@media screen{#sidebar{background-color:#2f3236;background-image:url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI0IiBoZWlnaHQ9IjQiPgo8cmVjdCB3aWR0aD0iNCIgaGVpZ2h0PSI0IiBmaWxsPSIjNDAzYzNmIj48L3JlY3Q+CjxwYXRoIGQ9Ik0wIDBMNCA0Wk00IDBMMCA0WiIgc3Ryb2tlLXdpZHRoPSIxIiBzdHJva2U9IiMxZTI5MmQiPjwvcGF0aD4KPC9zdmc+")}#outline{font-family:Georgia,Times,"Times New Roman",serif;font-size:13px;margin:2em 1em}#outline ul{padding:0}#outline li{list-style-type:none;margin:1em 0}#outline li>ul{margin-left:1em}#outline a,#outline a:visited,#outline a:hover,#outline a:active{line-height:1.2;color:#e8e8e8;text-overflow:ellipsis;white-space:nowrap;text-decoration:none;display:block;overflow:hidden;outline:0}#outline a:hover{color:#0cf}#page-container{background-color:#9e9e9e;background-image:url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI1IiBoZWlnaHQ9IjUiPgo8cmVjdCB3aWR0aD0iNSIgaGVpZ2h0PSI1IiBmaWxsPSIjOWU5ZTllIj48L3JlY3Q+CjxwYXRoIGQ9Ik0wIDVMNSAwWk02IDRMNCA2Wk0tMSAxTDEgLTFaIiBzdHJva2U9IiM4ODgiIHN0cm9rZS13aWR0aD0iMSI+PC9wYXRoPgo8L3N2Zz4=");-webkit-transition:left 500ms;transition:left 500ms}.pf{margin:13px auto;box-shadow:1px 1px 3px 1px #333;border-collapse:separate}.pc.opened{-webkit-animation:fadein 100ms;animation:fadein 100ms}.loading-indicator.active{-webkit-animation:swing 1.5s ease-in-out .01s infinite alternate none;animation:swing 1.5s ease-in-out .01s infinite alternate none}.checked{background:no-repeat url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABYAAAAWCAYAAADEtGw7AAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH3goQDSYgDiGofgAAAslJREFUOMvtlM9LFGEYx7/vvOPM6ywuuyPFihWFBUsdNnA6KLIh+QPx4KWExULdHQ/9A9EfUodYmATDYg/iRewQzklFWxcEBcGgEplDkDtI6sw4PzrIbrOuedBb9MALD7zv+3m+z4/3Bf7bZS2bzQIAcrmcMDExcTeXy10DAFVVAQDksgFUVZ1ljD3yfd+0LOuFpmnvVVW9GHhkZAQcxwkNDQ2FSCQyRMgJxnVdy7KstKZpn7nwha6urqqfTqfPBAJAuVymlNLXoigOhfd5nmeiKL5TVTV+lmIKwAOA7u5u6Lped2BsbOwjY6yf4zgQQkAIAcedaPR9H67r3uYBQFEUFItFtLe332lpaVkUBOHK3t5eRtf1DwAwODiIubk5DA8PM8bYW1EU+wEgCIJqsCAIQAiB7/u253k2BQDDMJBKpa4mEon5eDx+UxAESJL0uK2t7XosFlvSdf0QAEmlUnlRFJ9Waho2Qghc1/U9z3uWz+eX+Wr+lL6SZfleEAQIggA8z6OpqSknimIvYyybSCReMsZ6TislhCAIAti2Dc/zejVNWwCAavN8339j27YbTg0AGGM3WltbP4WhlRWq6Q/btrs1TVsYHx+vNgqKoqBUKn2NRqPFxsbGJzzP05puUlpt0ukyOI6z7zjOwNTU1OLo6CgmJyf/gA3DgKIoWF1d/cIY24/FYgOU0pp0z/Ityzo8Pj5OTk9PbwHA+vp6zWghDC+VSiuRSOQgGo32UErJ38CO42wdHR09LBQK3zKZDDY2NupmFmF4R0cHVlZWlmRZ/iVJUn9FeWWcCCE4ODjYtG27Z2Zm5juAOmgdGAB2d3cBADs7O8uSJN2SZfl+WKlpmpumaT6Yn58vn/fs6XmbhmHMNjc3tzDGFI7jYJrm5vb29sDa2trPC/9aiqJUy5pOp4f6+vqeJ5PJBAB0dnZe/t8NBajx/z37Df5OGX8d13xzAAAAAElFTkSuQmCC)}}

8
content/resume/index.md Normal file
View file

@ -0,0 +1,8 @@
---
title: Resume
---
To view a web-friendly version of my resume, [click here](/resume/resume.html).
You can also [download the PDF](/resume/resume.pdf) (~80 KB) if you wish to
print it or attach it to an email. If you think we'd work well together, don't
hesitate to reach out at [daniel@ficd.ca](mailto:daniel@ficd.ca).

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

347
content/resume/resume.css Normal file
View file

@ -0,0 +1,347 @@
.ff0{font-family:sans-serif;visibility:hidden;}
@font-face{font-family:ff1;src:url(f1.woff)format("woff");}.ff1{font-family:ff1;line-height:0.958008;font-style:normal;font-weight:normal;visibility:visible;}
@font-face{font-family:ff2;src:url(f2.woff)format("woff");}.ff2{font-family:ff2;line-height:0.945803;font-style:normal;font-weight:normal;visibility:visible;}
@font-face{font-family:ff3;src:url(f3.woff)format("woff");}.ff3{font-family:ff3;line-height:0.973633;font-style:normal;font-weight:normal;visibility:visible;}
@font-face{font-family:ff4;src:url(f4.woff)format("woff");}.ff4{font-family:ff4;line-height:0.937988;font-style:normal;font-weight:normal;visibility:visible;}
@font-face{font-family:ff5;src:url(f5.woff)format("woff");}.ff5{font-family:ff5;line-height:0.941895;font-style:normal;font-weight:normal;visibility:visible;}
.m0{transform:matrix(0.250000,0.000000,0.000000,0.250000,0,0);-ms-transform:matrix(0.250000,0.000000,0.000000,0.250000,0,0);-webkit-transform:matrix(0.250000,0.000000,0.000000,0.250000,0,0);}
.m1{transform:none;-ms-transform:none;-webkit-transform:none;}
.v0{vertical-align:0.000000px;}
.ls0{letter-spacing:0.000000px;}
.sc_{text-shadow:none;}
.sc0{text-shadow:-0.015em 0 transparent,0 0.015em transparent,0.015em 0 transparent,0 -0.015em transparent;}
@media screen and (-webkit-min-device-pixel-ratio:0){
.sc_{-webkit-text-stroke:0px transparent;}
.sc0{-webkit-text-stroke:0.015em transparent;text-shadow:none;}
}
.ws0{word-spacing:0.000000px;}
._1{margin-left:-3.164143px;}
._2{margin-left:-1.093743px;}
._3{width:1.035237px;}
._5{width:2.084393px;}
._16{width:3.091310px;}
._c{width:4.094727px;}
._d{width:5.463163px;}
._f{width:6.611395px;}
._10{width:7.789029px;}
._15{width:8.844050px;}
._8{width:11.640759px;}
._11{width:12.695113px;}
._a{width:13.839259px;}
._9{width:14.972071px;}
._4{width:19.999998px;}
._b{width:21.021172px;}
._14{width:40.000012px;}
._0{width:80.000020px;}
._6{width:91.394950px;}
._12{width:324.762547px;}
._e{width:470.641549px;}
._7{width:604.840850px;}
._13{width:695.934487px;}
.fc0{color:rgb(0,0,0);}
.fs5{font-size:32.000000px;}
.fs1{font-size:36.000000px;}
.fs2{font-size:40.000000px;}
.fs4{font-size:48.000000px;}
.fs3{font-size:56.000000px;}
.fs0{font-size:70.000000px;}
.y0{bottom:-0.500000px;}
.y38{bottom:42.201544px;}
.y37{bottom:55.283575px;}
.y36{bottom:68.365606px;}
.y35{bottom:81.447638px;}
.y6a{bottom:85.885720px;}
.y34{bottom:94.529669px;}
.y69{bottom:98.967750px;}
.y68{bottom:112.049780px;}
.y33{bottom:113.111700px;}
.y67{bottom:125.131810px;}
.y32{bottom:131.561920px;}
.y66{bottom:138.213844px;}
.y31{bottom:144.643950px;}
.y65{bottom:151.295875px;}
.y30{bottom:157.725980px;}
.y64{bottom:164.377906px;}
.y2f{bottom:170.808014px;}
.y63{bottom:177.459938px;}
.y2e{bottom:183.890045px;}
.y62{bottom:190.541969px;}
.y2d{bottom:196.972076px;}
.y2c{bottom:210.054108px;}
.y61{bottom:212.624000px;}
.y2b{bottom:223.136139px;}
.y60{bottom:239.654275px;}
.y2a{bottom:241.718170px;}
.y5f{bottom:252.736306px;}
.y29{bottom:260.168360px;}
.y5e{bottom:265.818338px;}
.y28{bottom:273.250394px;}
.y5d{bottom:278.900369px;}
.y27{bottom:286.332425px;}
.y5c{bottom:297.614200px;}
.y26{bottom:299.414456px;}
.y25{bottom:312.496488px;}
.y5b{bottom:316.064426px;}
.y24{bottom:325.578519px;}
.y5a{bottom:329.146458px;}
.y59{bottom:342.228489px;}
.y23{bottom:344.160550px;}
.y58{bottom:362.310520px;}
.y57{bottom:364.360320px;}
.y22{bottom:366.110750px;}
.y56{bottom:382.810515px;}
.y21{bottom:393.141020px;}
.y55{bottom:395.892546px;}
.y54{bottom:408.974578px;}
.y20{bottom:411.723050px;}
.y1e{bottom:411.986720px;}
.y53{bottom:422.056609px;}
.y1f{bottom:424.805080px;}
.y1d{bottom:424.936920px;}
.y52{bottom:442.138640px;}
.y1c{bottom:443.387118px;}
.y51{bottom:444.188450px;}
.y1b{bottom:456.469149px;}
.y50{bottom:462.538630px;}
.y1a{bottom:475.051180px;}
.y18{bottom:475.314850px;}
.y4f{bottom:484.678858px;}
.y19{bottom:488.133200px;}
.y17{bottom:488.265040px;}
.y4e{bottom:497.760889px;}
.y16{bottom:506.715236px;}
.y4d{bottom:517.842920px;}
.y15{bottom:519.797268px;}
.y4c{bottom:519.892730px;}
.y14{bottom:532.879299px;}
.y4b{bottom:538.342926px;}
.y4a{bottom:551.424958px;}
.y13{bottom:551.461330px;}
.y11{bottom:551.725000px;}
.y49{bottom:564.506989px;}
.y12{bottom:564.543360px;}
.y10{bottom:564.675200px;}
.y48{bottom:584.589020px;}
.yf{bottom:586.625400px;}
.y47{bottom:586.638820px;}
.y46{bottom:605.089024px;}
.ye{bottom:613.655670px;}
.y45{bottom:618.171055px;}
.y44{bottom:631.253086px;}
.yd{bottom:632.237700px;}
.yb{bottom:632.501370px;}
.y43{bottom:644.335118px;}
.yc{bottom:645.319730px;}
.ya{bottom:645.451570px;}
.y42{bottom:657.417149px;}
.y9{bottom:663.901760px;}
.y41{bottom:677.499180px;}
.y40{bottom:679.548980px;}
.y8{bottom:682.483800px;}
.y6{bottom:682.747470px;}
.y7{bottom:695.565830px;}
.y5{bottom:695.697660px;}
.y3f{bottom:701.499180px;}
.y4{bottom:717.647860px;}
.y3e{bottom:728.529449px;}
.y3d{bottom:741.611480px;}
.y3{bottom:751.178130px;}
.y3c{bottom:754.693511px;}
.y3b{bottom:767.775543px;}
.y2{bottom:776.678132px;}
.y3a{bottom:780.857574px;}
.y1{bottom:794.601958px;}
.y39{bottom:799.439605px;}
.h3{height:26.490234px;}
.h7{height:28.320312px;}
.h6{height:28.808594px;}
.h4{height:29.433594px;}
.h8{height:34.570312px;}
.h5{height:40.332031px;}
.h2{height:50.415039px;}
.h0{height:841.889800px;}
.h1{height:842.500000px;}
.w0{width:595.275600px;}
.w1{width:596.000000px;}
.x0{left:0.000000px;}
.x4{left:36.000000px;}
.x9{left:44.505859px;}
.x3{left:145.235450px;}
.x2{left:152.884140px;}
.x1{left:228.385480px;}
.x8{left:302.637800px;}
.xa{left:311.143650px;}
.xe{left:373.714070px;}
.xb{left:407.571500px;}
.x7{left:437.849820px;}
.x6{left:484.622280px;}
.x5{left:503.562700px;}
.xc{left:512.888880px;}
.xd{left:514.436740px;}
@media print{
.v0{vertical-align:0.000000pt;}
.ls0{letter-spacing:0.000000pt;}
.ws0{word-spacing:0.000000pt;}
._1{margin-left:-4.218858pt;}
._2{margin-left:-1.458324pt;}
._3{width:1.380316pt;}
._5{width:2.779191pt;}
._16{width:4.121747pt;}
._c{width:5.459635pt;}
._d{width:7.284217pt;}
._f{width:8.815193pt;}
._10{width:10.385372pt;}
._15{width:11.792067pt;}
._8{width:15.521012pt;}
._11{width:16.926817pt;}
._a{width:18.452345pt;}
._9{width:19.962762pt;}
._4{width:26.666665pt;}
._b{width:28.028229pt;}
._14{width:53.333349pt;}
._0{width:106.666693pt;}
._6{width:121.859933pt;}
._12{width:433.016729pt;}
._e{width:627.522065pt;}
._7{width:806.454467pt;}
._13{width:927.912649pt;}
.fs5{font-size:42.666667pt;}
.fs1{font-size:48.000000pt;}
.fs2{font-size:53.333333pt;}
.fs4{font-size:64.000000pt;}
.fs3{font-size:74.666667pt;}
.fs0{font-size:93.333333pt;}
.y0{bottom:-0.666667pt;}
.y38{bottom:56.268725pt;}
.y37{bottom:73.711433pt;}
.y36{bottom:91.154141pt;}
.y35{bottom:108.596851pt;}
.y6a{bottom:114.514293pt;}
.y34{bottom:126.039558pt;}
.y69{bottom:131.957000pt;}
.y68{bottom:149.399707pt;}
.y33{bottom:150.815600pt;}
.y67{bottom:166.842413pt;}
.y32{bottom:175.415893pt;}
.y66{bottom:184.285125pt;}
.y31{bottom:192.858600pt;}
.y65{bottom:201.727833pt;}
.y30{bottom:210.301307pt;}
.y64{bottom:219.170541pt;}
.y2f{bottom:227.744019pt;}
.y63{bottom:236.613251pt;}
.y2e{bottom:245.186727pt;}
.y62{bottom:254.055958pt;}
.y2d{bottom:262.629435pt;}
.y2c{bottom:280.072144pt;}
.y61{bottom:283.498667pt;}
.y2b{bottom:297.514852pt;}
.y60{bottom:319.539033pt;}
.y2a{bottom:322.290893pt;}
.y5f{bottom:336.981741pt;}
.y29{bottom:346.891147pt;}
.y5e{bottom:354.424451pt;}
.y28{bottom:364.333859pt;}
.y5d{bottom:371.867158pt;}
.y27{bottom:381.776567pt;}
.y5c{bottom:396.818933pt;}
.y26{bottom:399.219275pt;}
.y25{bottom:416.661984pt;}
.y5b{bottom:421.419235pt;}
.y24{bottom:434.104692pt;}
.y5a{bottom:438.861944pt;}
.y59{bottom:456.304652pt;}
.y23{bottom:458.880733pt;}
.y58{bottom:483.080693pt;}
.y57{bottom:485.813760pt;}
.y22{bottom:488.147667pt;}
.y56{bottom:510.414020pt;}
.y21{bottom:524.188027pt;}
.y55{bottom:527.856728pt;}
.y54{bottom:545.299437pt;}
.y20{bottom:548.964067pt;}
.y1e{bottom:549.315627pt;}
.y53{bottom:562.742145pt;}
.y1f{bottom:566.406773pt;}
.y1d{bottom:566.582560pt;}
.y52{bottom:589.518187pt;}
.y1c{bottom:591.182824pt;}
.y51{bottom:592.251267pt;}
.y1b{bottom:608.625532pt;}
.y50{bottom:616.718173pt;}
.y1a{bottom:633.401573pt;}
.y18{bottom:633.753133pt;}
.y4f{bottom:646.238477pt;}
.y19{bottom:650.844267pt;}
.y17{bottom:651.020053pt;}
.y4e{bottom:663.681185pt;}
.y16{bottom:675.620315pt;}
.y4d{bottom:690.457227pt;}
.y15{bottom:693.063024pt;}
.y4c{bottom:693.190307pt;}
.y14{bottom:710.505732pt;}
.y4b{bottom:717.790568pt;}
.y4a{bottom:735.233277pt;}
.y13{bottom:735.281773pt;}
.y11{bottom:735.633333pt;}
.y49{bottom:752.675985pt;}
.y12{bottom:752.724480pt;}
.y10{bottom:752.900267pt;}
.y48{bottom:779.452027pt;}
.yf{bottom:782.167200pt;}
.y47{bottom:782.185093pt;}
.y46{bottom:806.785365pt;}
.ye{bottom:818.207560pt;}
.y45{bottom:824.228073pt;}
.y44{bottom:841.670781pt;}
.yd{bottom:842.983600pt;}
.yb{bottom:843.335160pt;}
.y43{bottom:859.113491pt;}
.yc{bottom:860.426307pt;}
.ya{bottom:860.602093pt;}
.y42{bottom:876.556198pt;}
.y9{bottom:885.202347pt;}
.y41{bottom:903.332240pt;}
.y40{bottom:906.065307pt;}
.y8{bottom:909.978400pt;}
.y6{bottom:910.329960pt;}
.y7{bottom:927.421107pt;}
.y5{bottom:927.596880pt;}
.y3f{bottom:935.332240pt;}
.y4{bottom:956.863813pt;}
.y3e{bottom:971.372599pt;}
.y3d{bottom:988.815307pt;}
.y3{bottom:1001.570840pt;}
.y3c{bottom:1006.258015pt;}
.y3b{bottom:1023.700724pt;}
.y2{bottom:1035.570843pt;}
.y3a{bottom:1041.143432pt;}
.y1{bottom:1059.469277pt;}
.y39{bottom:1065.919473pt;}
.h3{height:35.320312pt;}
.h7{height:37.760417pt;}
.h6{height:38.411458pt;}
.h4{height:39.244792pt;}
.h8{height:46.093750pt;}
.h5{height:53.776042pt;}
.h2{height:67.220052pt;}
.h0{height:1122.519733pt;}
.h1{height:1123.333333pt;}
.w0{width:793.700800pt;}
.w1{width:794.666667pt;}
.x0{left:0.000000pt;}
.x4{left:48.000000pt;}
.x9{left:59.341145pt;}
.x3{left:193.647267pt;}
.x2{left:203.845520pt;}
.x1{left:304.513973pt;}
.x8{left:403.517067pt;}
.xa{left:414.858200pt;}
.xe{left:498.285427pt;}
.xb{left:543.428667pt;}
.x7{left:583.799760pt;}
.x6{left:646.163040pt;}
.x5{left:671.416933pt;}
.xc{left:683.851840pt;}
.xd{left:685.915653pt;}
}

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1 @@
<ul><li><a class="l" href="#pf1" data-dest-detail='[1,"XYZ",36,736.678,null]'>Education</a></li><li><a class="l" href="#pf1" data-dest-detail='[1,"XYZ",36,605.656,null]'>Employment</a></li><li><a class="l" href="#pf1" data-dest-detail='[1,"XYZ",36,385.141,null]'>Research Work</a></li><li><a class="l" href="#pf2" data-dest-detail='[2,"XYZ",36,720.529,null]'>Selected Projects</a><ul><li><a class="l" href="#pf2" data-dest-detail='[2,"XYZ",36,480.279,null]'>Tooling &amp; Contributions</a></li></ul></li><li><a class="l" href="#pf2" data-dest-detail='[2,"XYZ",36,231.654,null]'>Skills</a></li></ul>

BIN
content/resume/resume.pdf Normal file

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 62 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 43 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 73 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 85 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 89 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 64 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

236
content/static/style.css Normal file
View file

@ -0,0 +1,236 @@
:root {
--main-text-color: #b4b4b4;
--main-bg-color: #121212;
--main-link-color: #df6464;
--main-heading-color: #df6464;
--main-bullet-color: #d87c4a;
--main-transparent: rgba(255, 255, 255, 0.15);
--main-small-text-color: rgba(255, 255, 255, 0.45);
}
body {
line-height: 1.6;
font-size: 18px;
font-family: sans-serif;
background: var(--main-bg-color);
color: var(--main-text-color);
padding-left: calc(100vw - 100%);
}
/* h1, */
h2,
h3,
h4,
h5,
h6 {
color: var(--main-heading-color);
}
h1 {
margin-block-start: 0.67rem;
margin-block-end: 0.67rem;
font-size: 2rem;
font-weight: bold;
}
article h1:first-of-type {
margin-block-start: 1.67rem;
}
h2 {
margin-block-start: 0.83rem;
margin-block-end: 0.83rem;
font-size: 1.5rem;
font-weight: bold;
}
h3 {
margin-block-start: 1rem;
margin-block-end: 1rem;
font-size: 1.17em;
font-weight: bold;
}
h4 {
margin-block-start: 1.33rem;
margin-block-end: 1.33rem;
font-size: 1rem;
font-weight: bold;
}
article h1+h4:first-of-type {
margin-block-start: 0rem;
}
h5 {
margin-block-start: 1.67rem;
margin-block-end: 1.67rem;
font-size: 0.83rem;
font-weight: bold;
}
h6 {
margin-block-start: 2.33rem;
margin-block-end: 2.33rem;
font-size: 0.67rem;
font-weight: bold;
}
ul {
list-style-type: disc;
/* or any other list style */
}
li::marker {
color: var(--main-bullet-color);
/* Change this to your desired color */
}
a {
color: var(--main-link-color);
}
a:hover {
background: var(--main-transparent);
}
img {
display: block;
margin-left: auto;
margin-right: auto;
width: auto;
height: auto;
}
blockquote {
color: var(--main-small-text-color);
border-left: 3px solid var(--main-transparent);
padding: 0 1rem;
margin-left: 0;
margin-right: 0;
}
hr {
border: none;
height: 1px;
background: var(--main-small-text-color);
}
code {
background: var(--main-transparent);
border-radius: 0.1875rem;
/* padding: .0625rem .1875rem; */
/* margin: 0 .1875rem; */
}
code,
pre {
white-space: pre;
word-wrap: break-word;
overflow-wrap: break-word;
font-family: 'Fira Code', 'Consolas', 'Courier New', monospace;
font-size: 0.95em;
}
pre {
background-color: #1d1d1d;
color: #d5d5d5;
padding: 1em;
border-radius: 5px;
line-height: 1.5;
overflow-x: auto;
}
code {
background-color: #1d1d1d;
color: #d5d5d5;
padding: 0.2em 0.4em;
border-radius: 3px;
}
small {
font-size: 0.95rem;
color: var(--main-small-text-color);
}
small a {
color: inherit;
/* Inherit the color of the surrounding <small> text */
text-decoration: underline;
/* Optional: Keep the underline to indicate a link */
}
.title-container {
display: flex;
justify-content: center;
align-items: center;
text-align: center;
}
.title-container h1 {
margin: 0;
}
.image-container {
text-align: center;
margin: 20px 0;
/* Optional: add some spacing around the image container */
}
.image-container img {
/* max-width: 308px; */
max-height: 308px;
}
.image-container small {
display: block;
/* Ensure the caption is on a new line */
margin-top: 5px;
/* Optional: adjust spacing between image and caption */
}
.image-container small a {
color: inherit;
/* Ensure the link color matches the small text */
text-decoration: underline;
/* Optional: underline to indicate a link */
}
#header ul {
list-style-type: none;
padding-left: 0;
}
#header li {
display: inline;
font-size: 1.2rem;
margin-right: 1.2rem;
}
#container {
margin: 2.5rem auto;
width: 90%;
max-width: 60ch;
}
#postlistdiv ul {
list-style-type: none;
padding-left: 0;
}
.moreposts {
font-size: 0.95rem;
padding-left: 0.5rem;
}
#nextprev {
text-align: center;
margin-top: 1.4rem;
font-size: 0.95rem;
}
#footer {
color: var(--main-small-text-color);
}