commit 5a4b9d42e275e1afa3ab32dd7796748c637b89e5
parent bfd3ecaa0d8d0c481db0a844ea9e999a1337f1c4
Author: Beau <cbeauhilton@gmail.com>
Date: Tue, 30 Apr 2024 13:41:50 -0500
update
Diffstat:
59 files changed, 8299 insertions(+), 1 deletion(-)
diff --git a/.gitignore b/.gitignore
@@ -1,4 +1,3 @@
-build/
.devenv/*
.soupault-cache
nohup.out
diff --git a/build/about/index.html b/build/about/index.html
@@ -0,0 +1,317 @@
+<!DOCTYPE html>
+<html lang="en">
+ <head>
+ <link rel="stylesheet" href="/style.css" type="text/css">
+ <meta charset="utf-8">
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
+ <link rel="stylesheet" type="text/css" href="/style.css">
+ <link rel="icon" href="data:image/svg+xml,<svg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 100 100%22><text y=%22.9em%22 font-size=%2290%22>đď¸</text></svg>">
+ <title></title>
+ </head>
+ <body>
+ <div id="page-wrapper">
+ <div id="header" role="banner">
+ <header class="banner">
+ <div id="banner-text">
+ <span class="banner-title"><a href="/">beauhilton</a></span>
+ </div>
+ </header>
+ <nav>
+ <a class="nav-active" href="/about">about</a>
+<a href="/now">now</a>
+<a href="/thanks">thanks</a>
+<a href="/posts">posts</a>
+<a href="https://notes.beauhilton.com">notes</a>
+<a href="https://talks.beauhilton.com">talks</a>
+<a href="https://git.beauhilton.com">git</a>
+<a href="/contact">contact</a>
+<a href="/atom.xml">rss</a>
+ </nav>
+ </div>
+ <main>
+ <h2>
+ husband and father
+ </h2>
+ <p>
+ Talented, beautiful people surround me. The <a href="/now">now
+page</a> usually has the most current updates in this arena.
+ </p>
+ <h2>
+ physician
+ </h2>
+ <p>
+ Oncology fellow, Vanderbilt 2022-2025.<br>
+Internal medicine resident, Vanderbilt 2020-2022.<br>
+Medical school, Cleveland Clinic Lerner College of Medicine of Case
+Western Reserve University 2015-2020.
+ </p>
+ <p>
+ I enjoy treating people with any cancer, but have a particular
+affinity for head-and-neck and upper GI cancers (together, 2/3 of the
+âaerodigestiveâ cancers, the other 1/3 being lung). There are many right
+ways to be a doctor, but the way I understand my role is this: to be
+with people in their suffering and their joy (suffering is everywhere,
+but there is a special joy known only in the oncology clinic), to see
+and know the soul within the body (whatever the tumor or the scalpel or
+the radiation beam or the drug has done to that body), to cure when I
+can (and deal with the fallout from that cure), and help always (to the
+end and beyond).
+ </p>
+ <p>
+ There are glimmers of hope and serious advances in recent years, but
+these remain horrible diseases, many of which have few treatment options
+once theyâve reached an advanced stage, and the treatments we do have
+tend to be quite difficult to tolerate. Most cancers can be disfiguring,
+but these especially so, whether from the tumors themselves or from the
+therapies. Aerodigestive cancers also disproportionately affect folks
+who live out in the country, or in the cities but with few resources,
+and these folks are my folks.
+ </p>
+ <p>
+ We need to help each other, and there is much to do.
+ </p>
+ <h2>
+ educator
+ </h2>
+ <p>
+ Harvard Macy Institute faculty, 2018-2020. Health Care Education
+2.0.
+ </p>
+ <p>
+ <a href="https://vimbook.org">https://vimbook.org</a>,
+2020-present.<br>
+The Vanderbilt Internal Medicine Handbook was started by Mike Neuss,
+MD/PhD in the late 2010s when he was a resident. Itâs an incredible
+resource, primarily envisioned as a physical book to keep in your white
+coat pocket for quick, authoritative reference. It had a website when I
+came to Vandy, but the UX⌠left something to be desired. I rebuilt it
+into its current state (website and infrastructure only - each section
+has its own author(s)), and help maintain the back end.
+ </p>
+ <p>
+ Chase Webber is the faculty support, and has been amazing.
+ </p>
+ <p>
+ Itâs used globally, and one of my goals is to make it easier for
+smaller, particularly international programs to have their own versions.
+It uses only free and open-source software, and fits comfortably into
+pretty much any free server despite being a fairly large book with
+multimedia.
+ </p>
+ <p>
+ The main problem is that updating the content, while it is just in
+Markdown (a very simple text format you can learn in ~7 minutes), feels
+a little too tech-y to be comfortable for people who havenât spent time
+in a code text editor. What it really needs is funding, and a part-time
+developer with protected time.
+ </p>
+ <h2>
+ data scientist
+ </h2>
+ <p>
+ <a href="https://scholar.google.com/citations?user=Ng5AgXAAAAAJ">Google
+Scholar profile</a>
+ </p>
+ <p>
+ <em>If you are interested data science consulting, <a href="/contact">contact me</a>. Current rate is listed at that
+link.</em>
+ </p>
+ <p>
+ <em>Major projects are listed below in reverse chronological order
+(roughly), newest projects at the top.</em>
+ </p>
+ <h3>
+ overview
+ </h3>
+ <p>
+ My work has morphed over the years, as everyoneâs does, but the
+consistent thread and drive throughout has been on coaxing large, messy,
+complex data to tell us a story about ourselves, about all of us as
+societies and neighborhoods as well as each one of us individually, to
+empower us to speak our own sequels.
+ </p>
+ <p>
+ To translate that into buzzwords, for your bingo game: Iâm an
+oncologist who uses explainable artificial intelligence among other
+techniques to diagnose and address healthcare disparities, including
+democratizing personalized medicine and pursuing synergies in the global
+academic-industrial complex.
+ </p>
+ <p>
+ I was trained as an anthropologist, where reductionism is an insult,
+at the same time that I was trained as a scientist, where reductionism
+is the central conceit. Despite the way I set up that last sentence,
+there is no true conflict, as the goal for most scientists and
+anthropologists is the same: to make things at least a little better for
+someone, but hopefully a lot better for everyone. Modern anthropology is
+inherently activist, far from the crusty sepia-toned image of a staid
+researcher sitting just outside the village campfire furiously
+scribbling in a notebook, and so is modern medical research (we all read
+Tuskegee and are appalled and want to do better, though precious few
+become <a href="https://en.wikipedia.org/wiki/Paul_Farmer">Paul
+Farmer</a>).
+ </p>
+ <p>
+ Data science was an unexpected boon, a set of tools that lets me deal
+with staggering complexity in a disciplined way, to a degree unifying
+the anthropologistâs drive to let the data be itself (messy, human) with
+the scientistâs drive to simplify.
+ </p>
+ <p>
+ I became acquainted with using code to model the world when I was
+doing physics research (equivalent circuit modeling and scanning laser
+doppler vibrometry on a Nigerian-style clay pot drum, total hoot, I <a href="https://doi.org/10.1121/1.3654998">presented</a> it at the
+Acoustical Society of America Annual Meeting and we published it in <a href="https://doi.org/10.1121/1.4789892">JASA</a>), and the
+research-centric medical school at Cleveland Clinic gave me the better
+part of five years and a supportive environment to dive in deeper to
+computer science, machine learning, etc.
+ </p>
+ <p>
+ Now that have the freedom to choose my own direction, data science
+projects that were informed by anthropology but had centroids in other
+disciplines have become squarely within the overlap of my personal Venn
+diagram.
+ </p>
+ <p>
+ Additionally, as I have moved from academia to the worlds of private
+practice and industry, I am increasingly inspired toward using these
+interests to hit cancer where it needs it the most: in the clinic of the
+community oncologist, where the vast majority of cancer patients receive
+care, by bringing timely insights from every relevant axis to bear on
+every visit.
+ </p>
+ <p>
+ <a href="https://en.wikipedia.org/wiki/Information_wants_to_be_free">Information
+almost wants to be free</a>, and there is now so much of it, that a lot
+can be done for free or at a low cost. (Iâm take special glee in
+byproducts, âdigital waste,â some say, but there is gold in them there
+hills - <a href="https://en.wikipedia.org/wiki/Shigeru_Ban">Shigeru
+Ban</a> is my hero). There are abstracts from conferences aplenty
+describing the cutting edge of everything, usually seen as jots and
+tiddles on the march of science forward but forgotten when the journal
+article gets published, and lab values and imaging results and clinic
+notes generated in the usual course of patient care, used once or a few
+times and then forgotten and discarded in the wake of what comes next -
+in all of this digital refuse I believe there are insights to be gained,
+efficiencies to be achieved, lives to be saved.
+ </p>
+ <hr>
+ <h3>
+ disparities in cancer research across space and time
+ </h3>
+ <p>
+ This ongoing project starts with a custom metadata archive of all the
+abstracts from the two big annual cancer meetings (ASH and ASCO - as a
+starting point), made machine-readable and hence more easily accessible
+en masse. Hereâs a <a href="https://ash-abstracts.vercel.app/abstracts_small/abstracts">rough
+prelim</a> of what that looks like, with an interactive map and
+sorting/search/export (you can hit JSON or CSV endpoints trivially to
+get nicely formatted data, as opposed to the hulking web scrapers and
+HTML wranglers I wrote to get the data the first time). Analyses are
+planned on the authors and affiliations (global mapping, with a time
+component), and how those overlap with disease states (e.g. how much
+sickle cell research comes out of Sub-Saharan Africa? We know itâs bad,
+but nobody has quantified how bad - the idea is to have a platform for
+answering these questions easily), before branching out into things like
+conflicts of interest and various analyses using NLP, etc.
+ </p>
+ <hr>
+ <h3>
+ Cleveland Clinic Center for Clinical Artificial Intelligence
+ </h3>
+ <h3>
+ explainable machine learning for readmissions, with a focus on
+sociodemographics
+ </h3>
+ <p>
+ While at Cleveland Clinic, I was one of the founding members of the
+Center for Clinical Artificial Intelligence, and its first dedicated
+analyst. We had the delightful opportunity to work with a rich dataset
+from one of the worldâs largest hospitals, focused on predicting the
+risk of readmission (discharging from the hospital and âbouncing backâ
+too soon) and extended length of stay. We had access to not only health
+data, but socioeconomic data, for millions of patients, and I further
+enriched this with census data.
+ </p>
+ <p>
+ With only an address and a date, one can learn about a personâs
+neighborhood in incredible detail (though not the person themselves -
+the US Census is wise about privacy in the data they publish). It turns
+out that a personâs neighborhood is a major predictor in their health
+outcomes, as is their insurance provider, in addition to a host of
+health parameters and hospital process clues.
+ </p>
+ <p>
+ I used interpretable machine learning techniques, with a focus on
+revealing actionable items that the patients and medical teams could
+hope to influence, as well as to call out structural issues that
+organizations and governments need to know. One of the problems with
+machine learning is that it can only ever restate (and in some cases, as
+it feeds back on itself, more firmly entrench) the biases that led to
+the historical data you fed to it. If you design it to show you these
+biases, show you <em>all</em> of its biases, explicitly, to tell you
+exactly how much a personâs race, ethnicity, gender, and neighborhood
+played a role in its predictions (alongside medical diagnoses and lab
+values), you have transformed an algorithm from a potentially
+destructive tool, a heinous thing that pushes hurting people farther
+down, into a tool for positive change. If these biases are shown in an
+easy-to-read visual, that patients, clinicians, and administrators can
+all understand, all the better. See what it looks like <a href="https://doi.org/10.1038/s41746-020-0249-z">here</a>.
+ </p>
+ <hr>
+ <h3>
+ Cleveland Clinic Taussig Cancer Institute
+ </h3>
+ <h3>
+ explainable machine learning for blood cancer diagnostics
+ </h3>
+ <p>
+ Initially, when I was going to be a malignant hematologist (I still
+think it is a beautiful field, but was drawn away to other pastures), I
+wanted to level the playing field for advanced diagnostics.
+ </p>
+ <p>
+ A world-class hematopathologist together with a world-class
+clinician, preferably a whole group of these together, are required to
+make certain diagnoses, and these only after at least one invasive
+biopsy. What if we could mobilize the rich genetic and phenotypic data
+available in simple blood samples and from the electronic medical record
+to support diagnostics, and, eventually, democratize them? Further, what
+if the answer the machine gives could be not only accurate, but
+interpretable?
+ </p>
+ <p>
+ What if we could get the machine to explain itself and its reasoning,
+both as a check against biological implausibility (and more insidious
+problems such as systemic racism), and to reveal more areas for
+research? What if a high resolution bone marrow biopsy image could be
+read in moments by a smart phone in rural
+Arkansas/Kandahar/Mogadishu/Kushalnagar/etc., instead of having to be
+shipped to one of a handful of academic centers while the patient waits,
+still sick, for an answer?
+ </p>
+ <p>
+ We made <a href="https://doi.org/10.1182/blood-2019-126967">some</a>
+<a href="https://doi.org/10.1182/bloodadvances.2021004755">progress</a>,
+but these problems remain largely unsolved.
+ </p>
+ <hr>
+ <h2>
+ internal links
+ </h2>
+ <p>
+ If you want to know which tools I use, visit <a href="/uses">/uses</a>.
+ </p>
+ <p>
+ If you are interested in the tech stack for this website, visit <a href="/colophon">/colophon</a>.
+ </p>
+ <p>
+ If you would like to throw money at me, for whatever reason, visit <a href="/pay">/pay</a>.
+ </p>
+ </main>
+ <div id="footnotes"></div>
+ <footer></footer>
+ </div>
+ </body>
+</html>
diff --git a/build/atom.xml b/build/atom.xml
@@ -0,0 +1,263 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
+ <id>https://beauhilton.com/atom.xml</id>
+ <title>beauhilton</title>
+ <updated>2024-04-12T00:00:00+00:00</updated>
+ <author>
+ <name>beau hilton</name>
+ <email>beau@beauhilton.com</email>
+ </author>
+ <generator uri="https://soupault.app" version="4.8.0">soupault</generator>
+ <subtitle>beau's website</subtitle>
+ <entry>
+ <id>https://beauhilton.com/posts/choaked</id>
+ <title>The first detailed description of living with esophageal cancer -
+John Casaubonâs 1690 diary</title>
+ <updated>2024-04-12T00:00:00+00:00</updated>
+ <content type="html">
+ John Casaubon was an English surgeon in the late 1600s
+who developed an esophageal tumor in late 1690
+and wrote about it in his diary
+before dying in January of 1691.
+It's harrowing, enlightening, and strangely beautiful.
+This blog post is the only place in the world you can read the full transcription of the diary entry.
+ </content>
+ <link href="https://beauhilton.com/posts/choaked" rel="alternate"/>
+ </entry>
+
+ <entry>
+ <id>https://beauhilton.com/posts/claude-notes</id>
+ <title>Writing clinical notes using AI - a practical experience</title>
+ <updated>2024-04-09T00:00:00+00:00</updated>
+ <content type="html">
+ With Claude 3 Opus (a newish ChatGPT4 competitor) as my copilot, I wrote a pretty darn good SOAP note
+ for an (invented yet realistic) new consult visit. It took a little massaging to get it right,
+ but boy howdy, it did a great job. Here are the prompts and outputs.
+ This stuff has serious potential for streamlining the boring and tedious parts of the job.
+ </content>
+ <link href="https://beauhilton.com/posts/claude-notes" rel="alternate"/>
+ </entry>
+
+ <entry>
+ <id>https://beauhilton.com/posts/s1</id>
+ <title>Drugs we canât get: S1</title>
+ <updated>2024-03-29T00:00:00+00:00</updated>
+ <content type="html">
+ There are a number of interesting drugs used in the global market that,
+ for one reason or another, do not have FDA approval and are therefore inaccessible
+ in the US, at least outside of clinical trials. S1 is one of them: a better capecitabine.
+ </content>
+ <link href="https://beauhilton.com/posts/s1" rel="alternate"/>
+ </entry>
+
+ <entry>
+ <id>https://beauhilton.com/posts/pp-tech-infra</id>
+ <title>Patient-facing slide decks</title>
+ <updated>2024-03-23T00:00:00+00:00</updated>
+ <content type="html">
+ While I plan on being a physician-scientist forever, I'm not going to work in academia.
+Over the past few years I've put together very cool infrastructure for giving academic talks (click "talks" above),
+and it was making me sad that it might not get much use after I leave the university.
+But then, a ray of sunshine: Why not use my slide deck infrastructure to help in patient conversations?
+ </content>
+ <link href="https://beauhilton.com/posts/pp-tech-infra" rel="alternate"/>
+ </entry>
+
+ <entry>
+ <id>https://beauhilton.com/posts/cad-fish</id>
+ <title>Cold agglutinin disease: fish out of water?</title>
+ <updated>2024-03-22T00:00:00+00:00</updated>
+ <content type="html">
+ Cold agglutinin disease is a fascinating and strange phenomenon, and might happen because we're fish.
+ </content>
+ <link href="https://beauhilton.com/posts/cad-fish" rel="alternate"/>
+ </entry>
+
+ <entry>
+ <id>https://beauhilton.com/posts/history-egc</id>
+ <title>A timeline of esophageal cancer</title>
+ <updated>2023-10-20T00:00:00+00:00</updated>
+ <content type="html">
+ A couple of friends and I wrote a review article on the history of esophageal cancer.
+The timeline was so interesting I thought I'd share it here, in a place where it can be easily found and updated.
+ </content>
+ <link href="https://beauhilton.com/posts/history-egc" rel="alternate"/>
+ </entry>
+
+ <entry>
+ <id>https://beauhilton.com/posts/add-zfs-mirror</id>
+ <title>How to add a mirror to a single ZFS disk</title>
+ <updated>2023-10-19T00:00:00+00:00</updated>
+ <content type="html">
+ tl;dr:â
<code>zpoolâ
attachâ
dataâ
/dev/disk/by-partlabel/zfs-3a1xxâ
/dev/sdx0</code>. Adjust for your own pool and disks.
+ </content>
+ <link href="https://beauhilton.com/posts/add-zfs-mirror" rel="alternate"/>
+ </entry>
+
+ <entry>
+ <id>https://beauhilton.com/posts/yt-dlp</id>
+ <title>yt-dlp Nix config</title>
+ <updated>2023-10-18T00:00:00+00:00</updated>
+ <content type="html">
+ yt-dlp is an incredibly useful and customizable tool
+for downloading online videos
+from YouTube and elsewhere.
+Here's my setup
+(declared in Nix, but easily generalizable).
+ </content>
+ <link href="https://beauhilton.com/posts/yt-dlp" rel="alternate"/>
+ </entry>
+
+ <entry>
+ <id>https://beauhilton.com/posts/subsonic-cli</id>
+ <title>Command-line interfaces for self-hosted music</title>
+ <updated>2023-09-28T00:00:00+00:00</updated>
+ <content type="html">
+ Self-hosting a music server is great.
+Listening to the tunes via the command line is the way.
+ </content>
+ <link href="https://beauhilton.com/posts/subsonic-cli" rel="alternate"/>
+ </entry>
+
+ <entry>
+ <id>https://beauhilton.com/posts/pixel6screen</id>
+ <title>Pixel 6 DIY screen replacement, with fingerprint reader calibration
+using Linux</title>
+ <updated>2023-09-19T00:00:00+00:00</updated>
+ <content type="html">
+ The internet, up to now, says you need Windows or MacOS to calibrate the Pixel's fingerprint reader after installing a new screen and digitizer.
+The internet, up to now, was wrong.
+ </content>
+ <link href="https://beauhilton.com/posts/pixel6screen" rel="alternate"/>
+ </entry>
+
+ <entry>
+ <id>https://beauhilton.com/posts/pagecrypt</id>
+ <title>password protecting static web pages</title>
+ <updated>2023-01-12T00:00:00+00:00</updated>
+ <content type="html">
+ Static site generators, by and large, do not have support for password protecting individual pages.
+This post shows a strategy that works for any SSG and does not require server access controls.
+ </content>
+ <link href="https://beauhilton.com/posts/pagecrypt" rel="alternate"/>
+ </entry>
+
+ <entry>
+ <id>https://beauhilton.com/posts/oo-et-al</id>
+ <title>good machine learning in medicine</title>
+ <updated>2022-12-29T00:00:00+00:00</updated>
+ <content type="html">
+ Because most machine learning in medicine sucks, I thought you might like to see an example of it done well.
+ </content>
+ <link href="https://beauhilton.com/posts/oo-et-al" rel="alternate"/>
+ </entry>
+
+ <entry>
+ <id>https://beauhilton.com/posts/medical-humanities-org</id>
+ <title>medical-humanities.org</title>
+ <updated>2022-12-26T00:00:00+00:00</updated>
+ <content type="html">
+ I made a static website as an electronic learning system and forum,
+with the option for password protected posts and a controlled editing workflow,
+for free and without a dedicated server. This post has the highlights.
+ </content>
+ <link href="https://beauhilton.com/posts/medical-humanities-org" rel="alternate"/>
+ </entry>
+
+ <entry>
+ <id>https://beauhilton.com/posts/thanks</id>
+ <title>I made a thanks page</title>
+ <updated>2022-12-19T00:00:00+00:00</updated>
+ <content type="html">
+ A public, running journal of "hey, thanks"
+to the folks who make my life better, in big and small ways.
+Check it out .
+ </content>
+ <link href="https://beauhilton.com/posts/thanks" rel="alternate"/>
+ </entry>
+
+ <entry>
+ <id>https://beauhilton.com/posts/mime</id>
+ <title>fix MIME Types to unbreak RSS feeds served by OpenBSDâs
+httpd(8)</title>
+ <updated>2022-11-13T00:00:00+00:00</updated>
+ <content type="html">
+ I've been getting back into RSS lately.
+Turns out, my own RSS feed was broken.
+ </content>
+ <link href="https://beauhilton.com/posts/mime" rel="alternate"/>
+ </entry>
+
+ <entry>
+ <id>https://beauhilton.com/posts/ugbsd</id>
+ <title>Upgrading out-of-date OpenBSD installs</title>
+ <updated>2022-11-11T00:00:00+00:00</updated>
+ <content type="html">
+ First of all, don't do how I do.
+Upgrade your installs regularly.
+OpenBSD makes it very easy.
+ </content>
+ <link href="https://beauhilton.com/posts/ugbsd" rel="alternate"/>
+ </entry>
+
+ <entry>
+ <id>https://beauhilton.com/posts/geocheatcode</id>
+ <title>geocheatcode</title>
+ <updated>2022-04-22T00:00:00+00:00</updated>
+ <content type="html">
+ Here is background and code
+for a trick I use to get
+Google to give me best-in-class guesses
+for latitude and longitude,
+despite goofy and/or downright bad location searches.
+ </content>
+ <link href="https://beauhilton.com/posts/geocheatcode" rel="alternate"/>
+ </entry>
+
+ <entry>
+ <id>https://beauhilton.com/posts/intake-2022-03-25</id>
+ <title>Intake presentation on candidal esophagitis</title>
+ <updated>2022-03-25T00:00:00+00:00</updated>
+ <content type="html">
+ candidal esophagitis, achalasia, H Pylori PUD
+ </content>
+ <link href="https://beauhilton.com/posts/intake-2022-03-25" rel="alternate"/>
+ </entry>
+
+ <entry>
+ <id>https://beauhilton.com/posts/employee-wifi</id>
+ <title>Set Up Enterprise Wifi on Arch Linux</title>
+ <updated>2021-09-17T00:00:00+00:00</updated>
+ <content type="html">
+ Most big institutions have guest and employee wifi networks.
+Guest wifi is usually fine, fast enough for the basics,
+but far inferior to employee wifi.
+On a custom-built OS, such as a fairly minimalist Linux distribution,
+getting the employee wifi to work
+can be a beast.
+ </content>
+ <link href="https://beauhilton.com/posts/employee-wifi" rel="alternate"/>
+ </entry>
+
+ <entry>
+ <id>https://beauhilton.com/posts/mr-2021</id>
+ <title>Morning Report 08/23/2021</title>
+ <updated>2021-08-23T00:00:00+00:00</updated>
+ <content type="html">
+ Diagnosis is... MDS/MPN/MF NOS.
+i.e., who knows.
+ </content>
+ <link href="https://beauhilton.com/posts/mr-2021" rel="alternate"/>
+ </entry>
+
+ <entry>
+ <id>https://beauhilton.com/posts/rmd-py</id>
+ <title>R Markdown is my spirit animal</title>
+ <updated>2019-10-20T00:00:00+00:00</updated>
+ <content type="html">
+ Turns out that a better way does exist, and it is R Markdown.
+ </content>
+ <link href="https://beauhilton.com/posts/rmd-py" rel="alternate"/>
+ </entry>
+
+</feed>
+\ No newline at end of file
diff --git a/build/camplist/index.html b/build/camplist/index.html
@@ -0,0 +1,201 @@
+<!DOCTYPE html>
+<html lang="en">
+ <head>
+ <link rel="stylesheet" href="/style.css" type="text/css">
+ <meta charset="utf-8">
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
+ <link rel="stylesheet" type="text/css" href="/style.css">
+ <link rel="icon" href="data:image/svg+xml,<svg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 100 100%22><text y=%22.9em%22 font-size=%2290%22>đď¸</text></svg>">
+ <title></title>
+ </head>
+ <body>
+ <div id="page-wrapper">
+ <div id="header" role="banner">
+ <header class="banner">
+ <div id="banner-text">
+ <span class="banner-title"><a href="/">beauhilton</a></span>
+ </div>
+ </header>
+ <nav>
+ <a href="/about">about</a>
+<a href="/now">now</a>
+<a href="/thanks">thanks</a>
+<a href="/posts">posts</a>
+<a href="https://notes.beauhilton.com">notes</a>
+<a href="https://talks.beauhilton.com">talks</a>
+<a href="https://git.beauhilton.com">git</a>
+<a href="/contact">contact</a>
+<a href="/atom.xml">rss</a>
+ </nav>
+ </div>
+ <main>
+ <h1>
+ Camping Checklist
+ </h1>
+ <p>
+ Adapted from REIâs.
+ </p>
+ <h2>
+ Campsite
+ </h2>
+ <ul>
+ <li>
+ [ ] Tent (and footprint, stakes)
+ </li>
+ <li>
+ [ ] Tarp
+ </li>
+ <li>
+ [ ] Stakes
+ </li>
+ <li>
+ [ ] Sleeping bags
+ </li>
+ <li>
+ [ ] Sleeping pads
+ </li>
+ <li>
+ [ ] Camping pillow
+ </li>
+ <li>
+ [ ] Headlamps or flashlights (and extra batteries)
+ </li>
+ <li>
+ [ ] Camp chairs
+ </li>
+ <li>
+ [ ] Camp table (if no picnic table)
+ </li>
+ <li>
+ [ ] Lantern (and mantles and fuel/batteries if needed)
+ </li>
+ </ul>
+ <p>
+ Optional:
+ </p>
+ <ul>
+ <li>
+ [ ] Sunshade, tarp or screen house
+ </li>
+ <li>
+ [ ] Hammock
+ </li>
+ <li>
+ [ ] Cots
+ </li>
+ <li>
+ [ ] Sleeping bag liners
+ </li>
+ <li>
+ [ ] Firewood sourced near campsite
+ </li>
+ <li>
+ [ ] Camp rug
+ </li>
+ <li>
+ [ ] Tablecloth and clips (or tape)
+ </li>
+ <li>
+ [ ] Clothesline with clips
+ </li>
+ </ul>
+ <h2>
+ Tools & Repair Items
+ </h2>
+ <ul>
+ <li>
+ [ ] Multi-tool
+ </li>
+ <li>
+ [ ] Duct tape
+ </li>
+ <li>
+ [ ] Extra cord
+ </li>
+ <li>
+ [ ] Tent-pole repair sleeve
+ </li>
+ <li>
+ [ ] Pad/Mattress repair kit
+ </li>
+ <li>
+ [ ] Mallet or hammer (for hammering tent stakes)
+ </li>
+ <li>
+ [ ] Saw or axe (for cutting firewood)
+ </li>
+ <li>
+ [ ] Small broom and dustpan
+ </li>
+ </ul>
+ <p>
+ camp mug icon Kitchen Many campgrounds have drinkable water. If not,
+bring your own, or be prepared to treat water if thereâs a water source.
+Also, for even more ideas and food suggestions, see our separate Camp
+Kitchen Checklist.
+ </p>
+ <p>
+ Stove and fuel Matches/light/firestarter Cook pots (and pot holder)
+Frying pan Eating utensils Cooking utensils Bottle opener, can opener,
+corkscrew Sharp knife Plates/bowls Mugs/cups Cutting board Cooler Ice or
+ice substitutes Water bottles Camp sink or wash bins Biodegradable soap
+Pot scrubber/sponge(s) Trash/recycling bags Dish towel Optional:
+ </p>
+ <p>
+ Camp grill and fuel Grill rack Griddle Dutch oven Charcoal Portable
+coffee/tea maker Rolling ice cream maker Marshmallow/hot dog roasting
+forks Small food-storage containers/bags/foil Large water jugs Large,
+clear plastic bins to store kitchen gear
+ </p>
+ <p>
+ pen and pencil icon Campsite Extras Most of the following items are
+optional, though depending on how remote your campsite is, navigation
+tools such as a map, compass and/or GPS may be required (for more info,
+read about the Ten Essentials).
+ </p>
+ <p>
+ Solar and portable power Binoculars Navigation tools Field guides
+(flowers, insects) Star chart/night-sky identifier Book/reading material
+Notebook and pen/pencil Music player with headphones Games and toys Dog
+gear Dry bags, stuff sacks or clear plastic bins to store items
+ </p>
+ <p>
+ puffy vest icon Clothing & Footwear Moisture-wicking underwear
+Moisture-wicking T-shirts Quick-drying pants/shorts Long-sleeve shirts
+(for sun, bugs) Lightweight fleece or jacket Boots or shoes suited to
+terrain Socks (synthetic or wool) Sleepwear Additional items for rainy
+and/or cold weather:
+ </p>
+ <p>
+ Rainwear (jacket and pants) Long underwear Warm insulated jacket or
+vest Fleece pants Gloves or mittens Warm hat Optional:
+ </p>
+ <p>
+ Swimsuits Water sandals In-camp sandals or booties Bandanas
+ </p>
+ <p>
+ soap icon Health & Hygiene Toilet paper Hand sanitizer Toothbrush
+and toothpaste Toiletry kit Quick-dry towel Menstrual products
+Prescription medications First-aid kit or first-aid supplies (see
+First-Aid Checklist) Sun and bug protection:
+ </p>
+ <p>
+ Sunscreen Sunglasses (and sunglasses straps) Sun hat Lip balm Insect
+repellent Insect repellent device Optional:
+ </p>
+ <p>
+ Urinary products Sanitation trowel (if no toilets) Baby wipes Alcohol
+or antiseptic wipes Mirror Brush/comb Cosmetics Spare eyeglasses/contact
+lens supplies Eyeshades Earplugs Portable camp shower
+ </p>
+ <p>
+ personal ID and credit card icon Personal Items Credit card and/or
+cash ID Cellphone Campsite reservation confirmation (if required)*
+ </p>
+ </main>
+ <div id="footnotes"></div>
+ <footer></footer>
+ </div>
+ </body>
+</html>
diff --git a/build/church/luke-15-11-32/index.html b/build/church/luke-15-11-32/index.html
@@ -0,0 +1,306 @@
+<!DOCTYPE html>
+<html lang="en">
+ <head>
+ <link rel="stylesheet" href="/style.css" type="text/css">
+ <meta charset="utf-8">
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
+ <link rel="stylesheet" type="text/css" href="/style.css">
+ <link rel="icon" href="data:image/svg+xml,<svg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 100 100%22><text y=%22.9em%22 font-size=%2290%22>đď¸</text></svg>">
+ <title></title>
+ </head>
+ <body>
+ <div id="page-wrapper">
+ <div id="header" role="banner">
+ <header class="banner">
+ <div id="banner-text">
+ <span class="banner-title"><a href="/">beauhilton</a></span>
+ </div>
+ </header>
+ <nav>
+ <a href="/about">about</a>
+<a href="/now">now</a>
+<a href="/thanks">thanks</a>
+<a href="/posts">posts</a>
+<a href="https://notes.beauhilton.com">notes</a>
+<a href="https://talks.beauhilton.com">talks</a>
+<a href="https://git.beauhilton.com">git</a>
+<a href="/contact">contact</a>
+<a href="/atom.xml">rss</a>
+ </nav>
+ </div>
+ <main>
+ <h1>
+ Luke 15:11-32
+ </h1>
+ <h2>
+ Introduction
+ </h2>
+ <p>
+ One of the nice things about being asked to give a ten minute talk on
+one of Jesusâ parables, in addition to the inherent beauty and depth of
+the things, is that the parables are short.
+ </p>
+ <p>
+ This allows a luxurious classical exegesis, meaning we can give some
+context, read the whole text, then circle back and examine details.
+ </p>
+ <p>
+ (this written version is much more than 10 minutes, btw - the actual
+talk was just the highlights, as the Spirit grabbed me)
+ </p>
+ <h2>
+ Context
+ </h2>
+ <p>
+ Luke 15 opens with Jesus hanging out with some reprobates, called the
+âpublicans and sinnersâ in the KJV.
+ </p>
+ <p>
+ Luke 15:2 And both the Pharisees and the scribes murmured a great
+deal, saying: âThis man welcomes sinners and eats with them.â
+ </p>
+ <p>
+ To put it simply, the faithful members of the Godâs church were
+disturbed at this upstart rabbiâs lunch crew.
+ </p>
+ <p>
+ Publicans are tax-collectors. In the New Testament, this refers
+specifically to Jewish people who had taken jobs with the Roman
+government to collect taxes, mostly from their fellow Jews.
+ </p>
+ <p>
+ Everyone hates taxes. The situation around the year 0 was especially
+rough, not far off from what we see in the classic Robin Hood movies,
+with the Sheriff of Nottingham tapping the last few pennies out of the
+old beggarâs boot.
+ </p>
+ <p>
+ Publicans were hated even when they were just doing their job as
+instructed, and had the additional reputation of lining their own
+pockets. There was no good way to find out what the actual decreed tax
+law should be, so people had to pay whatever the publican demanded, and
+folks often guessed (sometimes rightly) that the publican was on a
+little âCost Plusâ action. The publicans were therefore seen as
+traitors, worldly and godless people who had sold out to The Man and
+were getting rich off the suffering of Godâs people.
+ </p>
+ <p>
+ To bring us up to date and make this story real, we can use our
+heated political climate to approximate how the scribes and Pharisees
+felt - imagine the publicans are your most hated political rivals, the
+folks about which you find yourself saying, âGee Marge, I donât know how
+so-and-so can be a member of political party X, or hold a job doing Y,
+and still consider herself a Christian.â
+ </p>
+ <p>
+ It was at least that bad, if not worse.
+ </p>
+ <h2>
+ David Bentley Hart translation, Luke 15:11-32
+ </h2>
+ <p>
+ Now Iâm going to read the whole parable, using a wonderful
+translation from David Bentley Hart, both because his translation is
+faithful and honest, and also because I think itâs valuable to hear the
+words anew by making them just alien enough to wake up old ears that
+have heard the KJV version a thousand times.
+ </p>
+ <p>
+ 11 And he said, âA certain man had two sons.
+ </p>
+ <p>
+ 12 And the younger of them said to the father, âFather, give me the
+share of the property falling to me.â And he divided his living between
+them.
+ </p>
+ <p>
+ 13 And not many days later, the younger son, having collected
+everything, departed for a far country, and dissipated his property by
+living prodigally.
+ </p>
+ <p>
+ 14 When he had spent everything a severe famine spread throughout
+that country, and he began to be in need.
+ </p>
+ <p>
+ 15 And he went and attached himself to one of that countryâs
+citizens, and he sent him into his fields to feed the pigs;
+ </p>
+ <p>
+ 16 And he longed to fill his stomach with the carob pods that the
+pigs ate, and no one gave him anything.
+ </p>
+ <p>
+ 17 And coming to himself he said, âHow many of my fatherâs hired men
+are overflowing with bread, but I am here perishing from famine.
+ </p>
+ <p>
+ 18 I will get up and go to my father, and I will say to him, âI have
+sinned against heaven and before you,
+ </p>
+ <p>
+ 19 I am no longer worthy to be called your son.ââ
+ </p>
+ <p>
+ 20 And he rose and went to his own father. And while he was yet far
+away his father saw him and was inwardly moved with pity, and ran and
+fell upon his neck and kissed him fervently.
+ </p>
+ <p>
+ 21 And his son said to him, âFather, I have sinned against heaven and
+before you, I am no longer worthy to be called your son.â
+ </p>
+ <p>
+ 22 But the father said to his slaves, âQuickly bring out the best
+robe and put it on him, and place a ring on his finger and sandals on
+his feet,
+ </p>
+ <p>
+ 23 And bring the fattened calf and kill it, and let us sit and have
+good cheer,
+ </p>
+ <p>
+ 24 Because this son of mine was dead and has come to life again, was
+lost and has been found.â And they began to celebrate.
+ </p>
+ <p>
+ 25 But his older son was in a field; and as he came and drew near the
+house he heard music and dancing,
+ </p>
+ <p>
+ 26 And calling one of the servants over he asked what all this might
+be.
+ </p>
+ <p>
+ 27 And he told him that âYour brother has come, and your father has
+killed the fattened calf, because he has got him back in good
+health.â
+ </p>
+ <p>
+ 28 But in his response he was indignant and did not wish to go in;
+and his father came out and pleaded with him.
+ </p>
+ <p>
+ 29 But in reply he said to the father, âLook, for so many years I am
+slaving for you, and I have never disobeyed a command of yours, and you
+never gave me a goat so that I could make merry with my friends,
+ </p>
+ <p>
+ 30 But when this son of yours came, he who has devoured your
+livelihood with whores, you killed the fattened calf for him.â
+ </p>
+ <p>
+ 31 And he said to him, âChild, you are always with me, and all my
+things are yours.
+ </p>
+ <p>
+ 32 But we had to celebrate and rejoice, because this brother of yours
+was dead and came to life, and was lost, and has been found.ââ
+ </p>
+ <h2>
+ Some notes on the text
+ </h2>
+ <p>
+ If we go back to the beginning of the parable, we see a son who is
+impatient and bored living at home, who wants to see the world and
+party. He talks Dad into giving him his inheritance early so he can do
+just that.
+ </p>
+ <p>
+ This translation uses the word âprodigally,â which doesnât show up in
+the KJV but does show up repeatedly in classical Christian writings on
+this parable. The KJV uses the phrase âriotous living,â others use the
+word âwildâ or âreckless,â but âprodigalâ probably is the best word we
+have for what he was up to - the Greek áźĎĎĎĎĎ (asĂłtĂłs) means, literally,
+ânot saved,â which is exactly what the son did with his inheritance
+before landing the job as a pig farmer.
+ </p>
+ <p>
+ Prodigality, in itself, is not necessarily a bad thing. Great
+generosity can also be called âprodigal.â But we found out what the son
+was spending his money on - prostitutes (the Greek is ĎÎżĎν῜ν - pornĹn)
+and parties.
+ </p>
+ <p>
+ When the son returns to repent, it is as a man down on his luck,
+looking to take a humble yet stable (ha) job with benefits, not as a
+prince trying to reclaim his throne. He states he is âno longer worthy
+to be calledâ a son of his father. Before he can even try to talk pops
+into giving him a job mucking stables for a bed and three square a day,
+before he can say a word, Dad <em>runs</em> to him and brings him in
+close. He crashes through forgiving, straight to celebrating, and gets a
+prodigal party of his own started. He dresses the kid in their best
+clothes and new shoes and kicks off a barbecue, complete with a band and
+dance-off.
+ </p>
+ <p>
+ The older kid is in the field working, hears whatâs happening, and is
+not having it. Heâs been doing all the things for all the years,
+including right now, and he never got a party.
+ </p>
+ <p>
+ Dad is generous and patient, and doesnât scold the understandably
+self-righteous and hurt older son, but gently affirms that he is still
+his son, has lost nothing, and tries to help him see the cause for
+celebration.
+ </p>
+ <p>
+ At the end, we never find out the older sonâs response.
+ </p>
+ <p>
+ The older son is the primary target of the tale, the same kind of guy
+as the Pharisees and scribes, who kept all the rules and couldnât help
+getting miffed when the bad kids seemingly get rewarded for being
+bad.
+ </p>
+ <h2>
+ Conclusion
+ </h2>
+ <p>
+ When I read the scriptures, I find it much more useful to see myself
+as the butt of the joke, particularly when someone is getting reamed. Of
+course it feels nice to think of myself as the Nephi and not the Laman
+or Lemuel, but what good does that do me? Jesusâ parables, especially
+those in Luke, are harshest on those who cannot see the way they are
+painting the outside of their sepulchre with such care, fancy-ass paint,
+while the inside is rotting flesh and moldering bones.
+ </p>
+ <p>
+ Jesusâ parables are rich and faceted, endless - thereâs something
+here for the prodigal, the one who has wasted all and is scared to hell
+of coming back to ask for forgiveness: see how forgiveness is the thing
+the Father does most easily, and what He really wants is not just to
+forgive, but to celebrate, with his own positive prodigality. Also note
+the types of sin he was explicitly forgiving in this parable and its
+context - the prodigal wasting money and morality with prostitutes, the
+publicans cheating honest people - Jesusâ Atonement doesnât just forgive
+nabbing a candy bar from the gas station and glancing at your
+classmateâs exam sheet, he gets right in there with the intense
+stuff.
+ </p>
+ <p>
+ Thereâs something here for the good kids, the ones who have been
+keeping the letter of the law, and probably doing an ok job with the
+spirit of it too, but, <em>because</em> of how good they have been, can
+be quick to judge, and even cross over into hate, when they meet someone
+from the other side of the tracks. Learn to see that foul-mouthed
+so-and-so as God does, as one of His own, and join the party: celebrate
+every win, whether or not it looks like your own, and be gentle to every
+defeat (whether or not it looks like your own).
+ </p>
+ <p>
+ Thereâs something here for the parent, who has been hurt by the poor
+choices of a child and isnât sure how to deal with their plea for
+forgiveness. Treat the kid like the queen she is, fire up the grill,
+call the neighbors, and get her gussied up for the party. (and if a
+certain someone is pissed that the black sheep is now wearing the new
+Nikes and dancing all night, try to help them see that they are still
+every bit as valuable, and feel what a joy it is that sheâs back).
+ </p>
+ </main>
+ <div id="footnotes"></div>
+ <footer></footer>
+ </div>
+ </body>
+</html>
diff --git a/build/colophon/index.html b/build/colophon/index.html
@@ -0,0 +1,129 @@
+<!DOCTYPE html>
+<html lang="en">
+ <head>
+ <link rel="stylesheet" href="/style.css" type="text/css">
+ <meta charset="utf-8">
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
+ <link rel="stylesheet" type="text/css" href="/style.css">
+ <link rel="icon" href="data:image/svg+xml,<svg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 100 100%22><text y=%22.9em%22 font-size=%2290%22>đď¸</text></svg>">
+ <title></title>
+ </head>
+ <body>
+ <div id="page-wrapper">
+ <div id="header" role="banner">
+ <header class="banner">
+ <div id="banner-text">
+ <span class="banner-title"><a href="/">beauhilton</a></span>
+ </div>
+ </header>
+ <nav>
+ <a href="/about">about</a>
+<a href="/now">now</a>
+<a href="/thanks">thanks</a>
+<a href="/posts">posts</a>
+<a href="https://notes.beauhilton.com">notes</a>
+<a href="https://talks.beauhilton.com">talks</a>
+<a href="https://git.beauhilton.com">git</a>
+<a href="/contact">contact</a>
+<a href="/atom.xml">rss</a>
+ </nav>
+ </div>
+ <main>
+ <h1>
+ Colophon
+ </h1>
+ <p>
+ This site is hosted on an <a href="https://www.openbsd.org/">OpenBSD</a> server on <a href="https://vultr.com">vultr</a>, built using plain text files
+processed by <a href="https://soupault.app">soupault</a> and auto-<a href="https://en.wikipedia.org/wiki/Rsync">rsyncâd</a> to the server as
+part of a pre-commit hook.
+ </p>
+ <p>
+ The source files are available on <a href="https://git.beauhilton.com/site/">my git server</a> and <a href="https://github.com/cbeauhilton/beauhilton.com">GitHub</a>.
+ </p>
+ <p>
+ I also use <a href="https://eradman.com/entrproject/">entr</a> (on
+Nix) or <a href="https://github.com/grego/caretaker">caretaker</a> (on
+Arch) during development to auto-rebuild as I edit the source files.
+ </p>
+ <p>
+ Regarding the design, the focus is on simplicity and a small
+footprint. Itâs the kind thing to do, for the user and the planet. No
+Javascript, just static HTML. I used to specify fonts, e.g. one of my
+favorites, <a href="https://www.ibm.com/plex/">IBM Plex</a>, but in an
+effort to keep things light and tidy, I now just use system fonts.
+ </p>
+ <p>
+ <a href="https://talks.beauhilton.com">https://talks.beauhilton.com</a> and
+<a href="https://notes.beauhilton.com">https://notes.beauhilton.com</a>
+are not part of the website proper, but are rather generated using
+GitHub Pages. The talks are built using <a href="https://sli.dev/">slidev</a>, which translates markdown files into
+beautiful web-first slide decks (I now only use PowerPoint under great
+duress), and the notes use <a href="https://quartz.jzhao.xyz/">quartz</a>, which translates <a href="https://obsidian.md/">Obsidian</a>-style markdown files (see a
+theme here?) into a website of interconnected notes a la <a href="https://en.wikipedia.org/wiki/Zettelkasten">Zettelkasten</a>.
+ </p>
+ <h2>
+ Nix Workflow
+ </h2>
+ <p>
+ As of 2023-10-10 or so, I use a Nix-based workflow with flakes and <a href="https://devenv.sh/">devenv.sh</a>. The basic steps are similar to
+what is included below in the Non-Nix section, though more conveniently
+packaged and portable.
+ </p>
+ <p>
+ Itâs delightful.
+ </p>
+ <p>
+ I may write it up at some point, but for now, look at <a href="https://git.beauhilton.com/site/file/flake.nix.html">flake.nix</a>
+in the source code. One of the great things about Nix is that itâs
+self-documenting and self-contained.
+ </p>
+ <p>
+ On my non-Nix laptop running Arch, I still use the workflow below,
+though at some point Iâll probably install Nix on Arch and unify my
+approach.
+ </p>
+ <h2>
+ Non-Nix Workflow
+ </h2>
+ <p>
+ The workflow is terminal-based and pretty basic.
+ </p>
+ <p>
+ It amounts to:
+ </p>
+ <pre tabindex="0"><code class="language-shell">cd src/site
+./sh.sh
+$EDITOR site/gulag_archipelago.md
+</code></pre>
+ <p>
+ <code>sh.sh</code> contains the following:
+ </p>
+ <pre tabindex="0"><code class="language-shell">$TERMINAL -e caretaker &>/dev/null & disown
+$TERMINAL -e python3 -m http.server --directory build &>/dev/null & disown
+$TERMINAL -e $BROWSER http://localhost:8000 &>/dev/null & disown
+</code></pre>
+ <p>
+ This will open three new terminals running: a caretaker instance for
+auto-rebuild (I recently activated caching in soupault, rebuilds are
+lightning quick), a web server for preview, and a browser pointing to
+the server.
+ </p>
+ <p>
+ At that point I will usually throw the terminals running the server
+and <code>caretaker</code> to another desktop to achieve a clean editing
+environment.
+ </p>
+ <p>
+ When itâs ready to go live, I use an alias called <code>glazy</code>:
+<code>git add . && git commit -m "update" && git push</code>.
+This will trigger the pre-commit hook, which rebuilds the site again and
+activates rsync to send the built site to the web server, before pushing
+the source files to GitHub and my git server.
+ </p>
+ </main>
+ <div id="footnotes"></div>
+ <footer></footer>
+ </div>
+ </body>
+</html>
diff --git a/build/contact/index.html b/build/contact/index.html
@@ -0,0 +1,60 @@
+<!DOCTYPE html>
+<html lang="en">
+ <head>
+ <link rel="stylesheet" href="/style.css" type="text/css">
+ <meta charset="utf-8">
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
+ <link rel="stylesheet" type="text/css" href="/style.css">
+ <link rel="icon" href="data:image/svg+xml,<svg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 100 100%22><text y=%22.9em%22 font-size=%2290%22>đď¸</text></svg>">
+ <title></title>
+ </head>
+ <body>
+ <div id="page-wrapper">
+ <div id="header" role="banner">
+ <header class="banner">
+ <div id="banner-text">
+ <span class="banner-title"><a href="/">beauhilton</a></span>
+ </div>
+ </header>
+ <nav>
+ <a href="/about">about</a>
+<a href="/now">now</a>
+<a href="/thanks">thanks</a>
+<a href="/posts">posts</a>
+<a href="https://notes.beauhilton.com">notes</a>
+<a href="https://talks.beauhilton.com">talks</a>
+<a href="https://git.beauhilton.com">git</a>
+<a class="nav-active" href="/contact">contact</a>
+<a href="/atom.xml">rss</a>
+ </nav>
+ </div>
+ <main>
+ <p>
+ This website is my social media account.
+ </p>
+ <p>
+ If you want to get in touch, email: <a href="mailto:beau@beauhilton.com">beau@beauhilton.com</a>.
+ </p>
+ <p>
+ Iâll respond within the week.
+ </p>
+ <h2>
+ Consulting
+ </h2>
+ <p>
+ If you are contacting me to request data science consulting, write to
+the email above with âconsultingâ somewhere in the subject line.
+ </p>
+ <p>
+ I am currently willing to discuss engagements, pending specifics.
+Minimum $350/h for consulting, unless youâre a student, in which case,
+if the project is interesting and I can truly be of assistance, itâs
+free.
+ </p>
+ </main>
+ <div id="footnotes"></div>
+ <footer></footer>
+ </div>
+ </body>
+</html>
diff --git a/build/feed.xml b/build/feed.xml
@@ -0,0 +1,263 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
+ <id>https://beauhilton.com/atom.xml</id>
+ <title>beauhilton</title>
+ <updated>2024-04-12T00:00:00+00:00</updated>
+ <author>
+ <name>beau hilton</name>
+ <email>beau@beauhilton.com</email>
+ </author>
+ <generator uri="https://soupault.app" version="4.8.0">soupault</generator>
+ <subtitle>beau's website</subtitle>
+ <entry>
+ <id>https://beauhilton.com/posts/choaked</id>
+ <title>The first detailed description of living with esophageal cancer -
+John Casaubonâs 1690 diary</title>
+ <updated>2024-04-12T00:00:00+00:00</updated>
+ <content type="html">
+ John Casaubon was an English surgeon in the late 1600s
+who developed an esophageal tumor in late 1690
+and wrote about it in his diary
+before dying in January of 1691.
+It's harrowing, enlightening, and strangely beautiful.
+This blog post is the only place in the world you can read the full transcription of the diary entry.
+ </content>
+ <link href="https://beauhilton.com/posts/choaked" rel="alternate"/>
+ </entry>
+
+ <entry>
+ <id>https://beauhilton.com/posts/claude-notes</id>
+ <title>Writing clinical notes using AI - a practical experience</title>
+ <updated>2024-04-09T00:00:00+00:00</updated>
+ <content type="html">
+ With Claude 3 Opus (a newish ChatGPT4 competitor) as my copilot, I wrote a pretty darn good SOAP note
+ for an (invented yet realistic) new consult visit. It took a little massaging to get it right,
+ but boy howdy, it did a great job. Here are the prompts and outputs.
+ This stuff has serious potential for streamlining the boring and tedious parts of the job.
+ </content>
+ <link href="https://beauhilton.com/posts/claude-notes" rel="alternate"/>
+ </entry>
+
+ <entry>
+ <id>https://beauhilton.com/posts/s1</id>
+ <title>Drugs we canât get: S1</title>
+ <updated>2024-03-29T00:00:00+00:00</updated>
+ <content type="html">
+ There are a number of interesting drugs used in the global market that,
+ for one reason or another, do not have FDA approval and are therefore inaccessible
+ in the US, at least outside of clinical trials. S1 is one of them: a better capecitabine.
+ </content>
+ <link href="https://beauhilton.com/posts/s1" rel="alternate"/>
+ </entry>
+
+ <entry>
+ <id>https://beauhilton.com/posts/pp-tech-infra</id>
+ <title>Patient-facing slide decks</title>
+ <updated>2024-03-23T00:00:00+00:00</updated>
+ <content type="html">
+ While I plan on being a physician-scientist forever, I'm not going to work in academia.
+Over the past few years I've put together very cool infrastructure for giving academic talks (click "talks" above),
+and it was making me sad that it might not get much use after I leave the university.
+But then, a ray of sunshine: Why not use my slide deck infrastructure to help in patient conversations?
+ </content>
+ <link href="https://beauhilton.com/posts/pp-tech-infra" rel="alternate"/>
+ </entry>
+
+ <entry>
+ <id>https://beauhilton.com/posts/cad-fish</id>
+ <title>Cold agglutinin disease: fish out of water?</title>
+ <updated>2024-03-22T00:00:00+00:00</updated>
+ <content type="html">
+ Cold agglutinin disease is a fascinating and strange phenomenon, and might happen because we're fish.
+ </content>
+ <link href="https://beauhilton.com/posts/cad-fish" rel="alternate"/>
+ </entry>
+
+ <entry>
+ <id>https://beauhilton.com/posts/history-egc</id>
+ <title>A timeline of esophageal cancer</title>
+ <updated>2023-10-20T00:00:00+00:00</updated>
+ <content type="html">
+ A couple of friends and I wrote a review article on the history of esophageal cancer.
+The timeline was so interesting I thought I'd share it here, in a place where it can be easily found and updated.
+ </content>
+ <link href="https://beauhilton.com/posts/history-egc" rel="alternate"/>
+ </entry>
+
+ <entry>
+ <id>https://beauhilton.com/posts/add-zfs-mirror</id>
+ <title>How to add a mirror to a single ZFS disk</title>
+ <updated>2023-10-19T00:00:00+00:00</updated>
+ <content type="html">
+ tl;dr:â
<code>zpoolâ
attachâ
dataâ
/dev/disk/by-partlabel/zfs-3a1xxâ
/dev/sdx0</code>. Adjust for your own pool and disks.
+ </content>
+ <link href="https://beauhilton.com/posts/add-zfs-mirror" rel="alternate"/>
+ </entry>
+
+ <entry>
+ <id>https://beauhilton.com/posts/yt-dlp</id>
+ <title>yt-dlp Nix config</title>
+ <updated>2023-10-18T00:00:00+00:00</updated>
+ <content type="html">
+ yt-dlp is an incredibly useful and customizable tool
+for downloading online videos
+from YouTube and elsewhere.
+Here's my setup
+(declared in Nix, but easily generalizable).
+ </content>
+ <link href="https://beauhilton.com/posts/yt-dlp" rel="alternate"/>
+ </entry>
+
+ <entry>
+ <id>https://beauhilton.com/posts/subsonic-cli</id>
+ <title>Command-line interfaces for self-hosted music</title>
+ <updated>2023-09-28T00:00:00+00:00</updated>
+ <content type="html">
+ Self-hosting a music server is great.
+Listening to the tunes via the command line is the way.
+ </content>
+ <link href="https://beauhilton.com/posts/subsonic-cli" rel="alternate"/>
+ </entry>
+
+ <entry>
+ <id>https://beauhilton.com/posts/pixel6screen</id>
+ <title>Pixel 6 DIY screen replacement, with fingerprint reader calibration
+using Linux</title>
+ <updated>2023-09-19T00:00:00+00:00</updated>
+ <content type="html">
+ The internet, up to now, says you need Windows or MacOS to calibrate the Pixel's fingerprint reader after installing a new screen and digitizer.
+The internet, up to now, was wrong.
+ </content>
+ <link href="https://beauhilton.com/posts/pixel6screen" rel="alternate"/>
+ </entry>
+
+ <entry>
+ <id>https://beauhilton.com/posts/pagecrypt</id>
+ <title>password protecting static web pages</title>
+ <updated>2023-01-12T00:00:00+00:00</updated>
+ <content type="html">
+ Static site generators, by and large, do not have support for password protecting individual pages.
+This post shows a strategy that works for any SSG and does not require server access controls.
+ </content>
+ <link href="https://beauhilton.com/posts/pagecrypt" rel="alternate"/>
+ </entry>
+
+ <entry>
+ <id>https://beauhilton.com/posts/oo-et-al</id>
+ <title>good machine learning in medicine</title>
+ <updated>2022-12-29T00:00:00+00:00</updated>
+ <content type="html">
+ Because most machine learning in medicine sucks, I thought you might like to see an example of it done well.
+ </content>
+ <link href="https://beauhilton.com/posts/oo-et-al" rel="alternate"/>
+ </entry>
+
+ <entry>
+ <id>https://beauhilton.com/posts/medical-humanities-org</id>
+ <title>medical-humanities.org</title>
+ <updated>2022-12-26T00:00:00+00:00</updated>
+ <content type="html">
+ I made a static website as an electronic learning system and forum,
+with the option for password protected posts and a controlled editing workflow,
+for free and without a dedicated server. This post has the highlights.
+ </content>
+ <link href="https://beauhilton.com/posts/medical-humanities-org" rel="alternate"/>
+ </entry>
+
+ <entry>
+ <id>https://beauhilton.com/posts/thanks</id>
+ <title>I made a thanks page</title>
+ <updated>2022-12-19T00:00:00+00:00</updated>
+ <content type="html">
+ A public, running journal of "hey, thanks"
+to the folks who make my life better, in big and small ways.
+Check it out .
+ </content>
+ <link href="https://beauhilton.com/posts/thanks" rel="alternate"/>
+ </entry>
+
+ <entry>
+ <id>https://beauhilton.com/posts/mime</id>
+ <title>fix MIME Types to unbreak RSS feeds served by OpenBSDâs
+httpd(8)</title>
+ <updated>2022-11-13T00:00:00+00:00</updated>
+ <content type="html">
+ I've been getting back into RSS lately.
+Turns out, my own RSS feed was broken.
+ </content>
+ <link href="https://beauhilton.com/posts/mime" rel="alternate"/>
+ </entry>
+
+ <entry>
+ <id>https://beauhilton.com/posts/ugbsd</id>
+ <title>Upgrading out-of-date OpenBSD installs</title>
+ <updated>2022-11-11T00:00:00+00:00</updated>
+ <content type="html">
+ First of all, don't do how I do.
+Upgrade your installs regularly.
+OpenBSD makes it very easy.
+ </content>
+ <link href="https://beauhilton.com/posts/ugbsd" rel="alternate"/>
+ </entry>
+
+ <entry>
+ <id>https://beauhilton.com/posts/geocheatcode</id>
+ <title>geocheatcode</title>
+ <updated>2022-04-22T00:00:00+00:00</updated>
+ <content type="html">
+ Here is background and code
+for a trick I use to get
+Google to give me best-in-class guesses
+for latitude and longitude,
+despite goofy and/or downright bad location searches.
+ </content>
+ <link href="https://beauhilton.com/posts/geocheatcode" rel="alternate"/>
+ </entry>
+
+ <entry>
+ <id>https://beauhilton.com/posts/intake-2022-03-25</id>
+ <title>Intake presentation on candidal esophagitis</title>
+ <updated>2022-03-25T00:00:00+00:00</updated>
+ <content type="html">
+ candidal esophagitis, achalasia, H Pylori PUD
+ </content>
+ <link href="https://beauhilton.com/posts/intake-2022-03-25" rel="alternate"/>
+ </entry>
+
+ <entry>
+ <id>https://beauhilton.com/posts/employee-wifi</id>
+ <title>Set Up Enterprise Wifi on Arch Linux</title>
+ <updated>2021-09-17T00:00:00+00:00</updated>
+ <content type="html">
+ Most big institutions have guest and employee wifi networks.
+Guest wifi is usually fine, fast enough for the basics,
+but far inferior to employee wifi.
+On a custom-built OS, such as a fairly minimalist Linux distribution,
+getting the employee wifi to work
+can be a beast.
+ </content>
+ <link href="https://beauhilton.com/posts/employee-wifi" rel="alternate"/>
+ </entry>
+
+ <entry>
+ <id>https://beauhilton.com/posts/mr-2021</id>
+ <title>Morning Report 08/23/2021</title>
+ <updated>2021-08-23T00:00:00+00:00</updated>
+ <content type="html">
+ Diagnosis is... MDS/MPN/MF NOS.
+i.e., who knows.
+ </content>
+ <link href="https://beauhilton.com/posts/mr-2021" rel="alternate"/>
+ </entry>
+
+ <entry>
+ <id>https://beauhilton.com/posts/rmd-py</id>
+ <title>R Markdown is my spirit animal</title>
+ <updated>2019-10-20T00:00:00+00:00</updated>
+ <content type="html">
+ Turns out that a better way does exist, and it is R Markdown.
+ </content>
+ <link href="https://beauhilton.com/posts/rmd-py" rel="alternate"/>
+ </entry>
+
+</feed>
+\ No newline at end of file
diff --git a/build/gifs/index.html b/build/gifs/index.html
@@ -0,0 +1,60 @@
+<!DOCTYPE html>
+<html lang="en">
+ <head>
+ <link rel="stylesheet" href="/style.css" type="text/css">
+ <meta charset="utf-8">
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
+ <link rel="stylesheet" type="text/css" href="/style.css">
+ <link rel="icon" href="data:image/svg+xml,<svg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 100 100%22><text y=%22.9em%22 font-size=%2290%22>đď¸</text></svg>">
+ <title></title>
+ </head>
+ <body>
+ <div id="page-wrapper">
+ <div id="header" role="banner">
+ <header class="banner">
+ <div id="banner-text">
+ <span class="banner-title"><a href="/">beauhilton</a></span>
+ </div>
+ </header>
+ <nav>
+ <a href="/about">about</a>
+<a href="/now">now</a>
+<a href="/thanks">thanks</a>
+<a href="/posts">posts</a>
+<a href="https://notes.beauhilton.com">notes</a>
+<a href="https://talks.beauhilton.com">talks</a>
+<a href="https://git.beauhilton.com">git</a>
+<a href="/contact">contact</a>
+<a href="/atom.xml">rss</a>
+ </nav>
+ </div>
+ <main>
+ <h1>
+ GIFs
+ </h1>
+ <p>
+ Ladies and gentleman of great culture and impeccable taste also call
+them DAVEs.
+ </p>
+ <p>
+ <a href=""><img src="/images/gifs/mr-bean-cupcake.gif#center" alt="mr-bean-cupcake"></a>
+ </p>
+ <p>
+ <a href=""><img src="/images/gifs/mr-bean-cupcake-double-take.gif#center" alt="mr-bean-cupcake-double-take"></a>
+ </p>
+ <p>
+ <a href=""><img src="/images/gifs/jimi.gif#center" alt="jimi"></a>
+ </p>
+ <p>
+ <a href=""><img src="/images/gifs/soul-train.gif#center" alt="soul-train"></a>
+ </p>
+ <p>
+ <a href=""><img src="/images/gifs/bueller-ferrari-crash.gif#center" alt="bueller-ferrari-crash"></a>
+ </p>
+ </main>
+ <div id="footnotes"></div>
+ <footer></footer>
+ </div>
+ </body>
+</html>
diff --git a/build/images/cashapp.png b/build/images/cashapp.png
Binary files differ.
diff --git a/build/images/gifs/bueller-ferrari-crash.gif b/build/images/gifs/bueller-ferrari-crash.gif
Binary files differ.
diff --git a/build/images/gifs/jimi.gif b/build/images/gifs/jimi.gif
Binary files differ.
diff --git a/build/images/gifs/mr-bean-cupcake-double-take.gif b/build/images/gifs/mr-bean-cupcake-double-take.gif
Binary files differ.
diff --git a/build/images/gifs/mr-bean-cupcake.gif b/build/images/gifs/mr-bean-cupcake.gif
Binary files differ.
diff --git a/build/images/gifs/soul-train.gif b/build/images/gifs/soul-train.gif
Binary files differ.
diff --git a/build/images/hatchimals-glow-in-the-dark.jpg b/build/images/hatchimals-glow-in-the-dark.jpg
Binary files differ.
diff --git a/build/images/ncmpcpp-mopidy-full.png b/build/images/ncmpcpp-mopidy-full.png
Binary files differ.
diff --git a/build/images/ncmpcpp-mopidy-selector.png b/build/images/ncmpcpp-mopidy-selector.png
Binary files differ.
diff --git a/build/images/ncmpcpp-mopidy-tracks.png b/build/images/ncmpcpp-mopidy-tracks.png
Binary files differ.
diff --git a/build/images/s1-cape-hfs.jpg b/build/images/s1-cape-hfs.jpg
Binary files differ.
diff --git a/build/images/s1-is.png b/build/images/s1-is.png
Binary files differ.
diff --git a/build/images/stuffy_pterodactyl.jpg b/build/images/stuffy_pterodactyl.jpg
Binary files differ.
diff --git a/build/images/venmo.jpg b/build/images/venmo.jpg
Binary files differ.
diff --git a/build/images/yt-dlp-downloading-example.png b/build/images/yt-dlp-downloading-example.png
Binary files differ.
diff --git a/build/images/yt-dlp-filename-example.jpg b/build/images/yt-dlp-filename-example.jpg
Binary files differ.
diff --git a/build/index.html b/build/index.html
@@ -0,0 +1,68 @@
+<!DOCTYPE html>
+<html lang="en">
+ <head>
+ <link rel="stylesheet" href="/style.css" type="text/css">
+ <meta charset="utf-8">
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
+ <link rel="stylesheet" type="text/css" href="/style.css">
+ <link rel="icon" href="data:image/svg+xml,<svg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 100 100%22><text y=%22.9em%22 font-size=%2290%22>đď¸</text></svg>">
+ <title></title>
+ </head>
+ <body>
+ <div id="page-wrapper">
+ <div id="header" role="banner">
+ <header class="banner">
+ <div id="banner-text">
+ <span class="banner-title"><a href="/">beauhilton</a></span>
+ </div>
+ </header>
+ <nav>
+ <a href="/about">about</a>
+<a href="/now">now</a>
+<a href="/thanks">thanks</a>
+<a href="/posts">posts</a>
+<a href="https://notes.beauhilton.com">notes</a>
+<a href="https://talks.beauhilton.com">talks</a>
+<a href="https://git.beauhilton.com">git</a>
+<a href="/contact">contact</a>
+<a href="/atom.xml">rss</a>
+ </nav>
+ </div>
+ <main>
+ <br>
+ Hi there. My name is Beau Hilton.
+<br>
+<br>
+ I'm a cancer doctor and data scientist.
+<br>
+<br>
+ The <a href="/thanks">thanks page</a> is the most interesting thing on this website.
+<br>
+<br>
+ For a quick personal update, see the
+ <a href="/now">now</a> page.
+<br>
+<br>
+ For a bit more depth, see the
+ <a href="/about">about</a> page.
+ It has extended summaries of major projects,
+ and a few links at the bottom to things folks on the internet often like to know about.
+<br>
+<br>
+ You can also see
+ <a href="/posts">blog posts</a>,
+ <a href="https://notes.beauhilton.com">notes</a>,
+ slides from public <a href="https://talks.beauhilton.com">talks</a>,
+ and <a href="https://git.beauhilton.com">code</a> for personal projects and configuration
+ (<a href="https://github.com/cbeauhilton">GitHub</a> has more of my public projects).
+<br>
+<br>
+ I'd love to chat.
+ Don't hesitate to <a href="/contact">reach out</a>.
+ </main>
+ <div id="footnotes"></div>
+ <footer></footer>
+ </div>
+ </body>
+</html>
diff --git a/build/liesel/index.html b/build/liesel/index.html
@@ -0,0 +1,73 @@
+<!DOCTYPE html>
+<html lang="en">
+ <head>
+ <link rel="stylesheet" href="/style.css" type="text/css">
+ <meta charset="utf-8">
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
+ <link rel="stylesheet" type="text/css" href="/style.css">
+ <link rel="icon" href="data:image/svg+xml,<svg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 100 100%22><text y=%22.9em%22 font-size=%2290%22>đď¸</text></svg>">
+ <title></title>
+ </head>
+ <body>
+ <div id="page-wrapper">
+ <div id="header" role="banner">
+ <header class="banner">
+ <div id="banner-text">
+ <span class="banner-title"><a href="/">beauhilton</a></span>
+ </div>
+ </header>
+ <nav>
+ <a href="/about">about</a>
+<a href="/now">now</a>
+<a href="/thanks">thanks</a>
+<a href="/posts">posts</a>
+<a href="https://notes.beauhilton.com">notes</a>
+<a href="https://talks.beauhilton.com">talks</a>
+<a href="https://git.beauhilton.com">git</a>
+<a href="/contact">contact</a>
+<a href="/atom.xml">rss</a>
+ </nav>
+ </div>
+ <main>
+ <h1>
+ Lieselâs wishlist
+ </h1>
+ <hr>
+ <p>
+ <a href="https://www.walmart.com/ip/NECA-GREMLINS-Movie-Gizmo-Mogwai-Dancing-Musical-8-Plush-Toy-Doll-Figure-NEW/791742706">Dancing
+Gizmo plush doll</a>
+ </p>
+ <p>
+ <a href="https://www.walmart.com/ip/NECA-GREMLINS-Movie-Gizmo-Mogwai-Dancing-Musical-8-Plush-Toy-Doll-Figure-NEW/791742706"><img src="https://i5.walmartimages.com/asr/73fa2830-15f3-4443-a2c1-2af0fdcf5e7c_1.d15d42112b8a2771d5f3d63788249fa2.jpeg#center" alt="Dancing Gizmo plush doll"></a>
+ </p>
+ <hr>
+ <p>
+ <a href="https://www.walmart.com/ip/Small-Brown-Bunny-Miyoni-Plush-by-Aurora-10911/38676885">Brown
+bunny stuffy</a>
+ </p>
+ <p>
+ <a href="https://www.walmart.com/ip/Small-Brown-Bunny-Miyoni-Plush-by-Aurora-10911/38676885"><img src="https://i5.walmartimages.com/asr/1357a985-b74d-4d1c-a4c6-7526373baaf2.f3cc5037c611b9c1eef846676ff1028f.jpeg?odnHeight=612&odnWidth=612&odnBg=FFFFFF" alt="brown bunny"></a>
+ </p>
+ <hr>
+ <p>
+ <a href="https://www.amazon.com/Tribello-Pterodactyl-Stuffed-Animal-Dinosaur/dp/B096D4GHD5">Pterodactyl
+stuffy</a>
+ </p>
+ <p>
+ <a href="https://www.amazon.com/Tribello-Pterodactyl-Stuffed-Animal-Dinosaur/dp/B096D4GHD5"><img src="/images/stuffy_pterodactyl.jpg#center" alt="stuffy"></a>
+ </p>
+ <hr>
+ <p>
+ <a href="https://www.amazon.com/Hatchimals-CollEGGtibles-Nightglow-12-Pack-Exclusive/dp/B07B83HP9K">Glow-in-the-dark
+Hatchimals</a>
+ </p>
+ <p>
+ <a href="https://www.amazon.com/Hatchimals-CollEGGtibles-Nightglow-12-Pack-Exclusive/dp/B07B83HP9K"><img src="/images/hatchimals-glow-in-the-dark.jpg#center" alt="hatchimals"></a>
+ </p>
+ </main>
+ <div id="footnotes"></div>
+ <footer></footer>
+ </div>
+ </body>
+</html>
diff --git a/build/now/index.html b/build/now/index.html
@@ -0,0 +1,69 @@
+<!DOCTYPE html>
+<html lang="en">
+ <head>
+ <link rel="stylesheet" href="/style.css" type="text/css">
+ <meta charset="utf-8">
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
+ <link rel="stylesheet" type="text/css" href="/style.css">
+ <link rel="icon" href="data:image/svg+xml,<svg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 100 100%22><text y=%22.9em%22 font-size=%2290%22>đď¸</text></svg>">
+ <title></title>
+ </head>
+ <body>
+ <div id="page-wrapper">
+ <div id="header" role="banner">
+ <header class="banner">
+ <div id="banner-text">
+ <span class="banner-title"><a href="/">beauhilton</a></span>
+ </div>
+ </header>
+ <nav>
+ <a href="/about">about</a>
+<a class="nav-active" href="/now">now</a>
+<a href="/thanks">thanks</a>
+<a href="/posts">posts</a>
+<a href="https://notes.beauhilton.com">notes</a>
+<a href="https://talks.beauhilton.com">talks</a>
+<a href="https://git.beauhilton.com">git</a>
+<a href="/contact">contact</a>
+<a href="/atom.xml">rss</a>
+ </nav>
+ </div>
+ <main>
+ <h2>
+ home
+ </h2>
+ <p>
+ 6 humans, 1 dog, an ever-changing number of chickens.
+ </p>
+ <p>
+ Everyone is healthy and happy.
+ </p>
+ <p>
+ Summer garden is going in.
+ </p>
+ <p>
+ Hendersonville, TN.
+ </p>
+ <h2>
+ work
+ </h2>
+ <p>
+ Nearing the end of the second out of three years of oncology
+fellowship. Iâm going into private practice, and super psyched about it.
+Weâre working with some incredible groups across the South and Southeast
+to find the right fit. Itâs going to be tough to decide - the modern
+oncology private practice has the potential to be a magical place, and
+so many groups are Doing Things Right.
+ </p>
+ <hr>
+ <p>
+ This <a href="https://nownownow.com/about">now page</a> was last
+updated 2024-04-12.
+ </p>
+ </main>
+ <div id="footnotes"></div>
+ <footer></footer>
+ </div>
+ </body>
+</html>
diff --git a/build/pay/index.html b/build/pay/index.html
@@ -0,0 +1,55 @@
+<!DOCTYPE html>
+<html lang="en">
+ <head>
+ <link rel="stylesheet" href="/style.css" type="text/css">
+ <meta charset="utf-8">
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
+ <link rel="stylesheet" type="text/css" href="/style.css">
+ <link rel="icon" href="data:image/svg+xml,<svg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 100 100%22><text y=%22.9em%22 font-size=%2290%22>đď¸</text></svg>">
+ <title></title>
+ </head>
+ <body>
+ <div id="page-wrapper">
+ <div id="header" role="banner">
+ <header class="banner">
+ <div id="banner-text">
+ <span class="banner-title"><a href="/">beauhilton</a></span>
+ </div>
+ </header>
+ <nav>
+ <a href="/about">about</a>
+<a href="/now">now</a>
+<a href="/thanks">thanks</a>
+<a href="/posts">posts</a>
+<a href="https://notes.beauhilton.com">notes</a>
+<a href="https://talks.beauhilton.com">talks</a>
+<a href="https://git.beauhilton.com">git</a>
+<a href="/contact">contact</a>
+<a href="/atom.xml">rss</a>
+ </nav>
+ </div>
+ <main>
+ <h1>
+ Pay me!
+ </h1>
+ <hr>
+ <h2>
+ Cash App (preferred)
+ </h2>
+ <p>
+ <a href="https://cash.app/$cbeauhilton"><img src="/images/cashapp.png#center" alt="cashappQR"></a>
+ </p>
+ <hr>
+ <h2>
+ Venmo
+ </h2>
+ <p>
+ <a href="https://venmo.com/u/Beau-Hilton-1"><img src="/images/venmo.jpg#center" alt="venmoQR"></a>
+ </p>
+ </main>
+ <div id="footnotes"></div>
+ <footer></footer>
+ </div>
+ </body>
+</html>
diff --git a/build/posts/add-zfs-mirror/index.html b/build/posts/add-zfs-mirror/index.html
@@ -0,0 +1,195 @@
+<!DOCTYPE html>
+<html lang="en">
+ <head>
+ <link rel="stylesheet" href="/style.css" type="text/css">
+ <meta charset="utf-8">
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
+ <link rel="stylesheet" type="text/css" href="/style.css">
+ <link rel="icon" href="data:image/svg+xml,<svg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 100 100%22><text y=%22.9em%22 font-size=%2290%22>đď¸</text></svg>">
+ <title></title>
+ </head>
+ <body>
+ <div id="page-wrapper">
+ <div id="header" role="banner">
+ <header class="banner">
+ <div id="banner-text">
+ <span class="banner-title"><a href="/">beauhilton</a></span>
+ </div>
+ </header>
+ <nav>
+ <a href="/about">about</a>
+<a href="/now">now</a>
+<a href="/thanks">thanks</a>
+<a class="nav-active" href="/posts">posts</a>
+<a href="https://notes.beauhilton.com">notes</a>
+<a href="https://talks.beauhilton.com">talks</a>
+<a href="https://git.beauhilton.com">git</a>
+<a href="/contact">contact</a>
+<a href="/atom.xml">rss</a>
+ </nav>
+ </div>
+ <main>
+ <h1>
+ How to add a mirror to a single ZFS disk
+ </h1>
+ <p>
+ <time id="post-date">2023-10-19</time>
+ </p>
+ <p id="post-excerpt">
+ tl;dr:â
<code>zpoolâ
attachâ
dataâ
/dev/disk/by-partlabel/zfs-3a1xxâ
/dev/sdx0</code>. Adjust for your own pool and disks.
+ </p>
+ <h2>
+ A mirror is a Very Good Thing
+ </h2>
+ <p>
+ I got a second identical disk to add as a ZFS mirror to my existing
+setup.
+ </p>
+ <p>
+ Redundancy FTW. ZFS is king and queen. Needs at least two disks to
+reap the full benefit (though a single-disk setup is still rad - CoW
+with snapshots and send/receive are worth it, and NixOS makes it easy to
+set up).
+ </p>
+ <h2>
+ Itâs all about the disk path
+ </h2>
+ <p>
+ The basic command is (as a super user, or using sudo):
+ </p>
+ <pre tabindex="0"><code class="language-sh">zpool attach name<span class="hl kwb">-of-the-pool</span> disk<span class="hl kwb">-you-already-had</span> disk<span class="hl kwb">-you-want-to-add</span>
+</code></pre>
+ <p>
+ On Linux, with a new drive, no need for formatting or any other disk
+preparation. Just plug it in.
+ </p>
+ <p>
+ But how to specify which disks to use in the command? I saw several
+guides that just used <code>/dev/sdx</code>, but it didnât work.
+ </p>
+ <p>
+ I donât know what it is about my setup that differs from the guides I
+found online (if you have a hint, <a href="beauhilton.com/contact">lmk</a>), so YMMV, but below is some of
+what I tried and what eventually worked, mostly for my own
+reference.
+ </p>
+ <p>
+ In my setup, <code>/dev/sdb</code> was my existing drive and
+<code>/dev/sda</code> is the one I was trying to add (these names are
+determined at boot time and can vary from boot to boot - ZFS takes care
+of finding things again on the back end after youâve added a drive,
+regardless of the label you used to add it, so using the
+<code>/dev/sdx</code> name is just fine in many situations).
+ </p>
+ <p>
+ However, using
+ </p>
+ <pre tabindex="0"><code class="language-sh">zpool attach data <span class="hl opt">/</span>dev<span class="hl opt">/</span>sdb dev<span class="hl opt">/</span>sda
+</code></pre>
+ <p>
+ gave me:
+ </p>
+ <pre tabindex="0"><code class="language-sh">cannot attach <span class="hl opt">/</span>dev<span class="hl opt">/</span>sda to <span class="hl opt">/</span>dev<span class="hl opt">/</span>sdb<span class="hl opt">:</span> no such device <span class="hl kwa">in</span> pool
+</code></pre>
+ <p>
+ I tried a bunch of different things, from just the lsblk name with
+the partition (âsdb1â), to by-id (âata-ST1400âŚâ), to full path
+combinations, etc.
+ </p>
+ <p>
+ What finally worked was the by-partlabel identifier for the existing
+disk, combined with the /dev/sdx0 name of the new one.
+ </p>
+ <p>
+ A little <code>zdb -l</code> on the existing drive gave me the path I
+wanted:
+ </p>
+ <pre tabindex="0"><code class="language-sh">zdb <span class="hl kwb">-l</span> <span class="hl opt">/</span>dev<span class="hl opt">/</span>sdb1
+<span class="hl kwb">------------------------------------</span>
+LABEL <span class="hl num">0</span>
+<span class="hl kwb">------------------------------------</span>
+ version<span class="hl opt">:</span> <span class="hl num">5000</span>
+ name<span class="hl opt">:</span> <span class="hl sng">'data'</span>
+ state<span class="hl opt">:</span> <span class="hl num">0</span>
+ txg<span class="hl opt">:</span> <span class="hl num">170113</span>
+ pool_guid<span class="hl opt">:</span> <span class="hl num">8237228336559358688</span>
+ errata<span class="hl opt">:</span> <span class="hl num">0</span>
+ hostid<span class="hl opt">:</span> <span class="hl num">3236406100</span>
+ hostname<span class="hl opt">:</span> <span class="hl sng">'dell7050'</span>
+ top_guid<span class="hl opt">:</span> <span class="hl num">11182661003591634341</span>
+ guid<span class="hl opt">:</span> <span class="hl num">11182661003591634341</span>
+ vdev_children<span class="hl opt">:</span> <span class="hl num">1</span>
+ vdev_tree<span class="hl opt">:</span>
+ <span class="hl kwb">type</span><span class="hl opt">:</span> <span class="hl sng">'disk'</span>
+ id<span class="hl opt">:</span> <span class="hl num">0</span>
+ guid<span class="hl opt">:</span> <span class="hl num">11182661003591634341</span>
+ path<span class="hl opt">:</span> <span class="hl sng">'/dev/disk/by-partlabel/zfs-3a1e459c75dc9b74'</span>
+ whole_disk<span class="hl opt">:</span> <span class="hl num">1</span>
+ metaslab_array<span class="hl opt">:</span> <span class="hl num">128</span>
+ metaslab_shift<span class="hl opt">:</span> <span class="hl num">34</span>
+ ashift<span class="hl opt">:</span> <span class="hl num">12</span>
+ asize<span class="hl opt">:</span> <span class="hl num">14000504438784</span>
+ is_log<span class="hl opt">:</span> <span class="hl num">0</span>
+ DTL<span class="hl opt">:</span> <span class="hl num">3865</span>
+ create_txg<span class="hl opt">:</span> <span class="hl num">4</span>
+ features_for_read<span class="hl opt">:</span>
+ com.delphix<span class="hl opt">:</span>hole_birth
+ com.delphix<span class="hl opt">:</span>embedded_data
+ labels <span class="hl opt">=</span> <span class="hl num">0 1 2 3</span>
+</code></pre>
+ <p>
+ So I tried:
+ </p>
+ <pre tabindex="0"><code class="language-sh">zpool attach data <span class="hl opt">/</span>dev<span class="hl opt">/</span>disk<span class="hl opt">/</span>by<span class="hl kwb">-partlabel</span><span class="hl opt">/</span>zfs<span class="hl kwb">-3a1e459c75dc9b74</span> <span class="hl opt">/</span>dev<span class="hl opt">/</span>sda1
+</code></pre>
+ <h2>
+ Great success
+ </h2>
+ <pre tabindex="0"><code class="language-conf">->> zpool status
+ pool<span class="hl opt">:</span> data
+ state<span class="hl opt">:</span> ONLINE
+<span class="hl kwa">status</span><span class="hl opt">:</span> One or more devices is currently being resilvered<span class="hl opt">.</span> The pool will
+ continue to function<span class="hl opt">,</span> possibly in a degraded state<span class="hl opt">.</span>
+<span class="hl kwa">action</span><span class="hl opt">:</span> Wait for the resilver to complete<span class="hl opt">.</span>
+ scan<span class="hl opt">:</span> resilver in progress since Thu Oct <span class="hl kwb">19 17</span><span class="hl opt">:</span><span class="hl kwb">05</span><span class="hl opt">:</span><span class="hl kwb">26 2023</span>
+ <span class="hl kwb">2.33</span>T scanned at <span class="hl kwb">1.90</span>G/s<span class="hl opt">,</span> <span class="hl kwb">252</span>G issued at <span class="hl kwb">205</span>M/s<span class="hl opt">,</span> <span class="hl kwb">3.77</span>T total
+ <span class="hl kwb">252</span>G resilvered<span class="hl opt">,</span> <span class="hl kwb">6.53</span>% done<span class="hl opt">,</span> <span class="hl kwb">04</span><span class="hl opt">:</span><span class="hl kwb">59</span><span class="hl opt">:</span><span class="hl kwb">42</span> to go
+<span class="hl kwa">config</span><span class="hl opt">:</span>
+
+ NAME STATE READ WRITE CKSUM
+ data ONLINE <span class="hl kwb">0 0 0</span>
+ mirror-<span class="hl kwb">0</span> ONLINE <span class="hl kwb">0 0 0</span>
+ zfs-<span class="hl kwb">3</span>a1e459c75dc9b74 ONLINE <span class="hl kwb">0 0 0</span>
+ sda1 ONLINE <span class="hl kwb">0 0 0</span> (resilvering)
+
+<span class="hl kwa">errors</span><span class="hl opt">:</span> No known data errors
+</code></pre>
+ <p>
+ âŚand the next day, after resilvering completed (and a reboot to make
+sure the disk came online):
+ </p>
+ <pre tabindex="0"><code class="language-conf">->> zpool status
+ pool<span class="hl opt">:</span> data
+ state<span class="hl opt">:</span> ONLINE
+ scan<span class="hl opt">:</span> resilvered <span class="hl kwb">3.77</span>T in <span class="hl kwb">05</span><span class="hl opt">:</span><span class="hl kwb">13</span><span class="hl opt">:</span><span class="hl kwb">53</span> with <span class="hl kwb">0</span> errors on Thu Oct <span class="hl kwb">19 22</span><span class="hl opt">:</span><span class="hl kwb">19</span><span class="hl opt">:</span><span class="hl kwb">19 2023</span>
+<span class="hl kwa">config</span><span class="hl opt">:</span>
+
+ NAME STATE READ WRITE CKSUM
+ data ONLINE <span class="hl kwb">0 0 0</span>
+ mirror-<span class="hl kwb">0</span> ONLINE <span class="hl kwb">0 0 0</span>
+ zfs-<span class="hl kwb">3</span>a1e459c75dc9b74 ONLINE <span class="hl kwb">0 0 0</span>
+ zfs-e2937e0fc8ebe95a ONLINE <span class="hl kwb">0 0 0</span>
+
+<span class="hl kwa">errors</span><span class="hl opt">:</span> No known data errors
+</code></pre>
+ <p>
+ (notice that what was <code>sda1</code> is now referred to by
+partlabel)
+ </p>
+ </main>
+ <div id="footnotes"></div>
+ <footer></footer>
+ </div>
+ </body>
+</html>
diff --git a/build/posts/cad-fish/index.html b/build/posts/cad-fish/index.html
@@ -0,0 +1,203 @@
+<!DOCTYPE html>
+<html lang="en">
+ <head>
+ <link rel="stylesheet" href="/style.css" type="text/css">
+ <meta charset="utf-8">
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
+ <link rel="stylesheet" type="text/css" href="/style.css">
+ <link rel="icon" href="data:image/svg+xml,<svg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 100 100%22><text y=%22.9em%22 font-size=%2290%22>đď¸</text></svg>">
+ <title></title>
+ </head>
+ <body>
+ <div id="page-wrapper">
+ <div id="header" role="banner">
+ <header class="banner">
+ <div id="banner-text">
+ <span class="banner-title"><a href="/">beauhilton</a></span>
+ </div>
+ </header>
+ <nav>
+ <a href="/about">about</a>
+<a href="/now">now</a>
+<a href="/thanks">thanks</a>
+<a class="nav-active" href="/posts">posts</a>
+<a href="https://notes.beauhilton.com">notes</a>
+<a href="https://talks.beauhilton.com">talks</a>
+<a href="https://git.beauhilton.com">git</a>
+<a href="/contact">contact</a>
+<a href="/atom.xml">rss</a>
+ </nav>
+ </div>
+ <main>
+ <h1>
+ Cold agglutinin disease: fish out of water?
+ </h1>
+ <p>
+ <time id="post-date">2024-03-22</time>
+ </p>
+ <p id="post-excerpt">
+ Cold agglutinin disease is a fascinating and strange phenomenon, and might happen because we're fish.
+ </p>
+ <h2>
+ CAD: a matter of degree
+ </h2>
+ <p>
+ CAD is a disease of the cells that make the immune system, in which
+they overproduce a protein called cold agglutinin, resulting in a
+cascade of unfortunate events that are typically triggered by the blood
+getting slightly too cold (going outside in the winter, getting ice
+cream out of the freezer, drinking a Slurpie, etc.). Red blood cells
+clump together and cause painful, blue fingers/toes/etc., sometimes so
+severe the affected bits die and fall off, and an autoimmune attack on
+the red blood cells begins, resulting in some of them being eaten alive
+by the liver and spleen and others being (literally) exploded while
+still in the blood vessels.
+ </p>
+ <p>
+ Everybody has cold agglutinins, these proteins that cause the
+clumping (âagglutinationâ), at some low level. Theyâre a type of IgM, a
+class of large proteins that are a key part of the immune system. IgM is
+really good at sticking things together, which is exactly what you want
+to happen in certain infections, etc., but which happens aberrantly, and
+sometimes dramatically, with red blood cells in CAD.
+ </p>
+ <p>
+ All red blood will agglutinate at 0-5C. This has been known since, at
+the latest, 1903. Karl Landsteiner figured it out. Heâs the guy who won
+the Nobel Prize for discovering blood types, which was based on
+experiments with âiso-agglutination.â With blood typing came the ability
+to cross-match blood for safe transfusion, which resulted in a huge leap
+forward in our ability to help people who lose a lot of it, as in
+surgery and trauma. We think of Landsteiner as the blood typing dude,
+but itâs probably more accurate and expansive to think of him as the
+dude who first exhaustively characterized the different situations in
+which blood agglutinates.
+ </p>
+ <p>
+ Landsteinerâs discoveries came just in time for the World Wars, and
+folks got to collecting blood in earnest, on a massive scale. We went
+from a few laboratory fridges with dozens or hundreds of blood samples
+for experiments, to blood banks worldwide, collectively full of hundreds
+of thousands of units of blood for use in the operating room and
+battlefield. Some oddities about human existence are only found when the
+numbers grow to this size: blood bank technicians found that some blood
+agglutinates all the way up to 25C (~77F, âroom temperatureâ). This
+resulted in difficulty with accurately typing blood, which led to a
+number of deaths.
+ </p>
+ <p>
+ In 1946 Lubinski and Goldbloom at Johns Hopkins published a paper
+describing seven patients with blood that would agglutinate all the way
+up to 37C (98.6F). All of these patients had brisk hemolysis (red blood
+cell explosion).
+ </p>
+ <p>
+ Putting it together, we have three categories of blood agglutination
+in response to temperature: everyoneâs blood will agglutinate in a
+freezer, a small but significant portion of people have blood that
+agglutinates at room temperature, and there are an unfortunate few who
+have blood that agglutinates while still (relatively) warm in their
+bodies. In all of these cases, itâs a cold agglutinin, a certain IgM
+protein, that coordinates the clumping.
+ </p>
+ <p>
+ As a doctor I can accept that sometimes the body does horrible
+things, about which the most that can be fairly said, despite all that
+science can provide, is that they are random. A personâs blood deciding
+to turn on them at the slightest cold provocation is well within the
+realm of crazy things we deal with on a daily basis. I would love to
+understand why everything horrible happens, but often have to move
+forward only knowing that it does happen, and hope that there might be a
+thing or two I can do to offset the horribleness.
+ </p>
+ <p>
+ I can also accept that unnatural environments lead to unnatural
+phenomena, such as blood clumping in a freezer. Thatâs a
+physical/chemical situation that never happens in a living animal (at
+least, in vertebrates. Donât get me started on the Antarctic midge).
+There doesnât need to be an evolutionary justification for the clumping
+in this case, just a biochemical one.
+ </p>
+ <p>
+ Itâs the room temperature thing that bothers me. In physiologic
+findings that are so clearly a matter of degree, with an obvious sliding
+scale, I wonder: what in our deep past created the affordance for this
+thing in the first place? Why do we have cold agglutinins at all?
+ </p>
+ <h2>
+ Whence cold agglutinins? Probably fish. And fish are us.
+ </h2>
+ <p>
+ Sigbjorn Berentsen is a Norwegian physician and researcher (CAD is,
+as you might expect, much more common in colder climates), and is The
+Man when it comes to understanding and treating CAD in the modern
+era.
+ </p>
+ <p>
+ A recent paper from him had this to say about the most likely
+possibility of the origin of cold agglutinins:
+ </p>
+ <blockquote>
+ <p>
+ âŚthe physiological function of CAs has not been clarified. It is
+difficult to envision a functional role of antibodies with a temperature
+optimum way below body temperature. Comparative studies, however, have
+strongly indicated that the evolution of the adaptive immune system
+began with the jawed vertebrates. Cartilaginous fish, which are
+phylogenetically ancient and considered closely related to the first
+jawed vertebrates, have only one immunoglobulin class in common with
+humans: IgM⌠[T]he temperature optimum of CAs is much closer to the
+environmental and body temperature of non-mammal sea vertebrates.
+Furthermore, CAs can react with antigens other than RBC surface
+macromolecules, and structures closely related to the I antigen are
+present on some microorganisms such as Streptococcus and Listeria
+species. Thus, one might explain human CAs as remnants of a primitive
+vertebrate immune system.
+ </p>
+ </blockquote>
+ <p>
+ <a href="https://doi.org/10.3389/fimmu.2020.00590">https://doi.org/10.3389/fimmu.2020.00590</a>
+ </p>
+ <p>
+ So, ancient fish, swimming in room temperature or colder water, had
+to fight certain bacteria. The fish are us, if you go back far enough.
+We happened to have held on to this ability, these proteins, an
+immunologic vestigial tail. Certain proteins on our red blood cells look
+an awful lot like the proteins on those bacteria, and, if you are
+unlucky enough that your vestigial tail grows out more than the average
+bear, friendly fire ensues. (That last sentence has a staggering number
+of mixed metaphors. Smiling, tongue firmly in cheek, he turned to you
+and said, âHumans <em>are</em> mixed metaphors.â)
+ </p>
+ <h2>
+ Conclusion, prefaced by an aside on Jaron Lanier
+ </h2>
+ <p>
+ Jaron Lanier is a computer scientist, ethnomusicologist, and
+all-around wonderful weirdo who was behind a lot of the early virtual
+reality experiments in the 70s-80s (and now works on VR with Microsoft
+when heâs not putting on concerts showcasing Chinese mouth-organs). He
+would do this thing where he would create VR avatars with many more
+limbs than humans (lobster is a classic one) and attach sensors to the
+participants to allow them to control all the limbs with various subtle
+movements (hips, elbows, knees, etc.). They found that it didnât take
+long for the humans to achieve surprising proficiency acting as a
+>4-limbed creature, and he would wax poetic about the ancient
+phylogenetic compatibility still hidden in the motor centers of the
+brain, and other related, delicious ideas (maybe itâs not four limbs and
+20 digits that are mapped discretely and <em>a priori</em> into the
+human brain, maybe itâs the capacity to map any number of prehensile
+bits that is inherent, etc. The therapeutic and geeky possibilities
+leading from this are way too much fun to contain in an aside).
+ </p>
+ <p>
+ Anyway, the point it this: I love it when the answer is, âidk, maybe
+weâre fish. Whatâs a fish, anyway?â
+ </p>
+ </main>
+ <div id="footnotes"></div>
+ <footer></footer>
+ </div>
+ </body>
+</html>
diff --git a/build/posts/choaked/index.html b/build/posts/choaked/index.html
@@ -0,0 +1,162 @@
+<!DOCTYPE html>
+<html lang="en">
+ <head>
+ <link rel="stylesheet" href="/style.css" type="text/css">
+ <meta charset="utf-8">
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
+ <link rel="stylesheet" type="text/css" href="/style.css">
+ <link rel="icon" href="data:image/svg+xml,<svg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 100 100%22><text y=%22.9em%22 font-size=%2290%22>đď¸</text></svg>">
+ <title></title>
+ </head>
+ <body>
+ <div id="page-wrapper">
+ <div id="header" role="banner">
+ <header class="banner">
+ <div id="banner-text">
+ <span class="banner-title"><a href="/">beauhilton</a></span>
+ </div>
+ </header>
+ <nav>
+ <a href="/about">about</a>
+<a href="/now">now</a>
+<a href="/thanks">thanks</a>
+<a class="nav-active" href="/posts">posts</a>
+<a href="https://notes.beauhilton.com">notes</a>
+<a href="https://talks.beauhilton.com">talks</a>
+<a href="https://git.beauhilton.com">git</a>
+<a href="/contact">contact</a>
+<a href="/atom.xml">rss</a>
+ </nav>
+ </div>
+ <main>
+ <h1>
+ The first detailed description of living with esophageal cancer -
+John Casaubonâs 1690 diary
+ </h1>
+ <p>
+ <time id="post-date">2024-04-12</time>
+ </p>
+ <p id="post-excerpt">
+ John Casaubon was an English surgeon in the late 1600s
+who developed an esophageal tumor in late 1690
+and wrote about it in his diary
+before dying in January of 1691.
+It's harrowing, enlightening, and strangely beautiful.
+This blog post is the only place in the world you can read the full transcription of the diary entry.
+ </p>
+ <h2>
+ John Casaubonâs diary
+ </h2>
+ <blockquote>
+ <p>
+ Monday Dec 29. 90.
+ </p>
+ </blockquote>
+ <blockquote>
+ <p>
+ At dinner I was almost choaked by swallowing a bit of a roasted Sd of
+mutton which as I thought stuck in the passage about the mouth of the
+stomach. But it suffered noething to goe downe and the stomach threw all
+up, though never soe small in quantitie, to all our amazements the
+sckilfull not knowing what 2 make of my condition. It being an unusuall
+afflixion wch. my melancholi suggested it an extraordinarie judgment. I
+could swallow about 2 spoonfulls about half way (as I thought) and then
+it would flush up in spite of my hart. Some small humiditie or dropps of
+what I dranck, rather distilld, or dropt into the stomach which afforded
+a bare living nourishment and on a sudden I grew lean as a skeleton and
+at some tymes very faint and feeble, although I recouerd in some measure
+and had stomach 2 eate, my meate doeth noe gt. good and I am in a kind
+of atrophie. What warme weather may do I cantâ tell, but hope well.
+Alwayes after I have bine at Stoole I am for a whyle very faint or weake
+which I much wonder at. It is a sine of gt weakenes certainly and of
+insoaed decay.
+ </p>
+ </blockquote>
+ <h2>
+ Context
+ </h2>
+ <p>
+ A couple of friends and I wrote a <a href="https://doi.org/10.3390/cancers16030618">paper</a> on the history
+of esophageal cancer, mentioned elsewhere on this blog.
+ </p>
+ <p>
+ One of the neat things in the paper is the first full transcription
+of a diary entry from John Casaubon, which is the first first-person
+detailing of esophageal cancer I can find. Itâs the last entry in the
+diary, and from what I could gather he died within the next week or two.
+It has been transcribed in partial form in <a href="https://doi.org/10.1016/j.gtc.2009.01.003">other</a> <a href="https://pubmed.ncbi.nlm.nih.gov/28952239/">papers</a>, but I had
+to know what I was missing in the ellipses, so wrote to the archivist at
+the Southampton City Archives in the United Kingdom, who was great and
+sent me a scan of the relevant page. The copyright for the microfilm
+scan of the diary is owned by the British Library (oh, the complexities
+of copyright), but the text itself is ancient and therefore public
+domain, so I finished the transcription and included it in the paper. My
+transcription also does not attempt to modernize or âcorrectâ any of the
+spelling or punctuation: this is exactly what he wrote (including using
+â2â instead of âto,â and the absolutely delightful 1600s British
+phonetic spelling of the word âinsideâ as âinsoaedâ).
+ </p>
+ <p>
+ However! I should say, âOne of the neat things in the paper was
+<em>supposed</em> to beâŚâ
+ </p>
+ <p>
+ Somehow, at some point in the revision process, a line in the
+transcription disappeared. None of us noticed the omission, focused as
+we were on other things the reviewers wanted tuned up. The transcription
+is also present in full in my authorâs working copy, so I have no idea
+how a small chunk was omitted. There was no copy-pasta, I sent the
+working copy to the journal in full. In any case, I wrote to the journal
+to ask that the missing line be added, and, after a review process, was
+refused. It doesnât change the scientific conclusions of the paper, and
+would require publishing a correction, so they said no. I pushed back,
+as it is the only truly unique discrete data in the whole paper
+(everything else is contextualization, arrangement, and interpretation
+of prior publications). Alas, I suppose my humanistâs heart has
+different priorities than the scientific journalâs editors.
+ </p>
+ <p>
+ So, now, this blog post is the only public place you can find the
+whole transcription. Thatâs a bummer, I wish it was immortalized in a
+PubMed-indexed journal article, but this is the next best thing.
+ </p>
+ <p>
+ If you are interested in what was omitted in the journal articleâs
+version, I split out the missing section below.
+ </p>
+ <blockquote>
+ <p>
+ At dinner I was almost choaked by swallowing a bit of a roasted Sd of
+mutton which as I thought stuck in the passage about the mouth of the
+stomach. But it suffered noething to goe downe and the stomach threw all
+up, though never soe small in quantitie, to all our amazements the
+sckilfull not knowing what 2 make of my condition. It being an unusuall
+afflixion wch. my melancholi suggested it an extraordinarie judgment. I
+could swallow about 2 spoonfulls about half way (as I thought) and then
+it would flush up in spite of my hart. Some small humiditie or dropps of
+what I dranck, rather distilld, or dropt into the stomach which
+afforded
+ </p>
+ </blockquote>
+ <blockquote>
+ <p>
+ <em>a bare living nourishment and on a sudden I grew lean as a
+skeleton and at some tymes very faint and feeble, although I recouerd in
+some measure and had stomach 2 eate, my</em>
+ </p>
+ </blockquote>
+ <blockquote>
+ <p>
+ meate doeth noe gt. good and I am in a kind of atrophie. What warme
+weather may do I cantâ tell, but hope well. Alwayes after I have bine at
+Stoole I am for a whyle very faint or weake which I much wonder at. It
+is a sine of gt weakenes certainly and of insoaed decay.
+ </p>
+ </blockquote>
+ </main>
+ <div id="footnotes"></div>
+ <footer></footer>
+ </div>
+ </body>
+</html>
diff --git a/build/posts/claude-notes/index.html b/build/posts/claude-notes/index.html
@@ -0,0 +1,448 @@
+<!DOCTYPE html>
+<html lang="en">
+ <head>
+ <link rel="stylesheet" href="/style.css" type="text/css">
+ <meta charset="utf-8">
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
+ <link rel="stylesheet" type="text/css" href="/style.css">
+ <link rel="icon" href="data:image/svg+xml,<svg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 100 100%22><text y=%22.9em%22 font-size=%2290%22>đď¸</text></svg>">
+ <title></title>
+ </head>
+ <body>
+ <div id="page-wrapper">
+ <div id="header" role="banner">
+ <header class="banner">
+ <div id="banner-text">
+ <span class="banner-title"><a href="/">beauhilton</a></span>
+ </div>
+ </header>
+ <nav>
+ <a href="/about">about</a>
+<a href="/now">now</a>
+<a href="/thanks">thanks</a>
+<a class="nav-active" href="/posts">posts</a>
+<a href="https://notes.beauhilton.com">notes</a>
+<a href="https://talks.beauhilton.com">talks</a>
+<a href="https://git.beauhilton.com">git</a>
+<a href="/contact">contact</a>
+<a href="/atom.xml">rss</a>
+ </nav>
+ </div>
+ <main>
+ <h1>
+ Writing clinical notes using AI - a practical experience
+ </h1>
+ <p>
+ <time id="post-date">2024-04-09</time>
+ </p>
+ <p id="post-excerpt">
+ With Claude 3 Opus (a newish ChatGPT4 competitor) as my copilot, I wrote a pretty darn good SOAP note
+ for an (invented yet realistic) new consult visit. It took a little massaging to get it right,
+ but boy howdy, it did a great job. Here are the prompts and outputs.
+ This stuff has serious potential for streamlining the boring and tedious parts of the job.
+ </p>
+ <h2>
+ LLM, the Great and Terrible
+ </h2>
+ <p>
+ <a href="https://www.anthropic.com/claude">Claude</a> is one of
+several new kids on the block in the land of highly capable Large
+Language Models (LLMs), and is comparable to (but exceeding in certain
+aspects) the incumbent ChatGPT4.
+ </p>
+ <p>
+ I decided to see how it would do writing a SOAP note for an imaginary
+(but common and realistic) new patient consult in an oncology
+clinic.
+ </p>
+ <p>
+ Why âthe Great and Terrible?â Everybody knows by now that LLMs are
+great at a lot of things, including writing coherent and fluent English
+and conforming to pretty much any common text format you can find online
+(from legal documents to Python or JavaScript code). Most folks also
+know that LLMs aim to please, and will make up the details they lack in
+order to satisfy your request, so their output cannot be trusted too
+far, particularly in technical areas. My goal in this was to see how
+close I could get to a usable clinic note, with full awareness that it
+was going to hallucinate and require a tune-up on the back end. In other
+words, I am confident LLMs are âterribleâ in certain ways, but needed
+convincing that they are âgreatâ in this particular arena.
+ </p>
+ <h2>
+ Round 1: The Initial Prompt
+ </h2>
+ <p>
+ I asked Claude for the following:
+ </p>
+ <blockquote>
+ <p>
+ please write a maximally billable SOAP-style medical note for an
+office visit with a new patient with likely stage III esophageal
+squamous cell carcinoma. Note that we discussed the need for full
+staging with FDG-PET CT to determine the final course of action, and the
+risks and benefits of a CROSS-style chemoradiotherapy regimen if stage
+III disease is confirmed vs systemic therapy if stage IV disease is
+confirmed. The patient describes mild dysphagia to solid foods but
+minimal weight loss, has no notable physical exam findings, and labs are
+unremarkable other than mild anemia. I reviewed the available
+cross-sectional imaging and concur with the radiologistâs report.
+ </p>
+ </blockquote>
+ <p>
+ And hereâs the output:
+ </p>
+ <hr>
+ <p>
+ Here is a maximally billable SOAP-style medical note for the patient
+encounter you described:
+ </p>
+ <p>
+ S (Subjective): 62 yo M with newly diagnosed esophageal cancer
+presents to oncology clinic to establish care and discuss treatment
+options. Reports mild dysphagia to solid foods x 3 weeks but denies
+significant weight loss, odynophagia, chest pain, nausea/vomiting,
+hematemesis, melena, hematochezia, or other GI symptoms. ROS negative
+except as above. PMH notable for HTN, HLD, and GERD. FH neg for GI
+malignancies. SH former smoker, quit 10 years ago, 30 pack-year history.
+Married, retired accountant, lives at home with wife. Medications
+include lisinopril, atorvastatin, omeprazole. No known allergies.
+ </p>
+ <p>
+ O (Objective):<br>
+Vitals: Temp 98.6 F, BP 128/78, HR 72, RR 14, 98% RA, Wt 180 lb, Ht 70
+in<br>
+General: NAD, well-appearing. HEENT: PERRL, EOMI, oral mucosa moist.
+Neck: no LAD. CV: RRR, no m/r/g. Pulm: CTAB. Abd: soft, NT/ND, no
+masses. Ext: no c/c/e, 2+ pulses.<br>
+Recent EGD: Esophageal mass 30 cm from incisors, partially obstructing
+lumen, biopsies c/w squamous cell carcinoma. CT chest/abd/pelvis: 5 cm
+distal esophageal mass, obliterating 75% of lumen. 2 cm regional lymph
+node. No distant metastases identified. Radiologist assessment: T3N1M0,
+clinical stage III. Labs: CBC: WBC 6.8, Hgb 11.5, Plt 225. CMP nl except
+Alb 3.2. CEA 5.2.
+ </p>
+ <p>
+ A (Assessment):
+ </p>
+ <ul>
+ <li>
+ Esophageal squamous cell carcinoma, clinical stage III (T3N1M0).
+Awaiting PET/CT for full staging and treatment planning.
+ </li>
+ <li>
+ Dysphagia secondary to above. Tolerating po currently without
+significant loss. Monitor symptoms, intake closely.
+ </li>
+ <li>
+ H/o GERD on omeprazole. Continue current therapy.
+ </li>
+ <li>
+ Anemia, likely anemia of chronic disease but will evaluate as
+outpatient.
+ </li>
+ </ul>
+ <p>
+ P (Plan):
+ </p>
+ <ol type="1">
+ <li>
+ Will obtain FDG-PET/CT scan to complete staging.
+ </li>
+ <li>
+ If no distant metastatic disease, recommend neoadjuvant
+chemoradiotherapy per CROSS regimen (carboplatin/paclitaxel q week x 5 +
+41.4 Gy in 23 fractions). Discussed expected toxicities including
+fatigue, esophagitis, nausea, neutropenia and importance of close
+monitoring.
+ </li>
+ <li>
+ If metastatic disease identified, will pursue systemic chemotherapy,
+likely FOLFOX or EOX regimen, rather than local therapy. May require
+palliative measures for dysphagia (stent, dilation prn).
+ </li>
+ <li>
+ Check iron studies, B12, folate. Replace as indicated.
+ </li>
+ <li>
+ Nutrition consult. Encourage high calorie/protein foods.
+ </li>
+ <li>
+ RTC in 1 week to review PET/CT results and finalize treatment plan.
+Sooner prn for worsening dysphagia, intolerance of po.
+ </li>
+ </ol>
+ <hr>
+ <p>
+ The LLM has added in a host of things I didnât ask it for
+specifically but do appreciate it including, which is what I hoped for
+when I asked for a âmaximally billable noteâ - e.g. the review of
+systems, PMH, FH, SH, a reasonable assessment and plan for the anemia,
+RTC, etc. Certain aspects are completely fabricated (age, vital signs,
+the specifics of the radiology report, labs). Some things are
+technically correct but not what I would do (e.g. very few people in the
+US use the EOX regimen), so would need adjusting. I was a bit surprised
+that it went ahead and put in the general plan for CROSS too - those
+details are correct.
+ </p>
+ <h2>
+ Round 2: The Placeholder Marks
+ </h2>
+ <p>
+ I asked Claude to replace the invented values with placeholder marks
+so I could fill them in later:
+ </p>
+ <blockquote>
+ <p>
+ Thatâs pretty good. Instead of inventing vital signs, imaging
+reports, and lab values, please write it again to instead put in ***
+placeholder marks in these areas so I can fill them in later.
+ </p>
+ </blockquote>
+ <p>
+ Claude obliged, creating a SOAP note template with *** all over the
+place. It was a bit too much, as you can see:
+ </p>
+ <hr>
+ <p>
+ Sure, hereâs the revised SOAP note with placeholder marks:
+ </p>
+ <p>
+ S (Subjective): *** yo M with newly diagnosed esophageal cancer
+presents to oncology clinic to establish care and discuss treatment
+options. Reports mild dysphagia to solid foods x *** weeks but denies
+significant weight loss, odynophagia, chest pain, nausea/vomiting,
+hematemesis, melena, hematochezia, or other GI symptoms. ROS negative
+except as above. PMH notable for ***. FH *** for GI malignancies. SH ***
+smoker, quit *** years ago, *** pack-year history. ***, ***, lives ***.
+Medications include ***. *** allergies.
+ </p>
+ <p>
+ O (Objective): Vitals: Temp *** F, BP *<strong>/</strong>, HR ***, RR
+***, ***% RA, Wt *** lb, Ht *** in General: ***. HEENT: ***. Neck: ***.
+CV: ***. Pulm: ***. Abd: <em><strong>. Ext: <em><strong>. Recent EGD:
+Esophageal mass *** cm from incisors, partially obstructing lumen,
+biopsies c/w squamous cell carcinoma. CT chest/abd/pelvis: *** cm distal
+esophageal mass, obliterating <em><strong>% of lumen. *** cm regional
+lymph node. No distant metastases identified. Radiologist assessment:
+T</strong></em>N</strong></em>M</strong></em>, clinical stage ***. Labs:
+CBC: WBC ***, Hgb ***, Plt ***. CMP *** except ***. CEA ***.
+ </p>
+ <p>
+ A (Assessment):
+ </p>
+ <ul>
+ <li>
+ Esophageal squamous cell carcinoma, clinical stage ***
+(T<em><strong>N</strong></em>M***). Awaiting PET/CT for full staging and
+treatment planning.
+ </li>
+ <li>
+ Dysphagia secondary to above. *** tolerating po currently without
+significant *** loss. Monitor symptoms, intake closely.
+ </li>
+ <li>
+ *** on ***. Continue current therapy.
+ </li>
+ <li>
+ Anemia, likely anemia of chronic disease but will evaluate as
+outpatient.
+ </li>
+ </ul>
+ <p>
+ P (Plan):
+ </p>
+ <ol type="1">
+ <li>
+ Will obtain FDG-PET/CT scan to complete staging.
+ </li>
+ <li>
+ If no distant metastatic disease, recommend neoadjuvant
+chemoradiotherapy per CROSS regimen (carboplatin/paclitaxel q week x 5 +
+41.4 Gy in 23 fractions). Discussed expected toxicities including
+fatigue, esophagitis, nausea, neutropenia and importance of close
+monitoring.
+ </li>
+ <li>
+ If metastatic disease identified, will pursue systemic chemotherapy,
+likely FOLFOX or EOX regimen, rather than local therapy. May require
+palliative measures for dysphagia (stent, dilation prn).
+ </li>
+ <li>
+ Check iron studies, B12, folate. Replace as indicated.
+ </li>
+ <li>
+ Nutrition consult. Encourage high calorie/protein foods.
+ </li>
+ <li>
+ RTC in *** week(s) to review PET/CT results and finalize treatment
+plan. Sooner prn for worsening dysphagia, intolerance of po.
+ </li>
+ </ol>
+ <hr>
+ <h2>
+ Round 3: The Goldilocks Zone
+ </h2>
+ <p>
+ Finally, I hit what seems to be a sweet spot:
+ </p>
+ <blockquote>
+ <p>
+ Forget what I said, please only put in *** placeholders for vital
+signs and imaging. Itâs ok to make up values for everything else.
+ </p>
+ </blockquote>
+ <p>
+ It still needs fixing, but isnât so full of *** that itâs jarring (or
+impossible to parse - what does â*** on ***â mean? Anything, and
+nothing, thatâs what.)
+ </p>
+ <hr>
+ <p>
+ Understood. Hereâs the updated SOAP note with *** placeholders for
+vital signs and imaging only:
+ </p>
+ <p>
+ S (Subjective): 62 yo M with newly diagnosed esophageal cancer
+presents to oncology clinic to establish care and discuss treatment
+options. Reports mild dysphagia to solid foods x 3 weeks but denies
+significant weight loss, odynophagia, chest pain, nausea/vomiting,
+hematemesis, melena, hematochezia, or other GI symptoms. ROS negative
+except as above. PMH notable for HTN, HLD, and GERD. FH neg for GI
+malignancies. SH former smoker, quit 10 years ago, 30 pack-year history.
+Married, retired accountant, lives at home with wife. Medications
+include lisinopril, atorvastatin, omeprazole. No known allergies.
+ </p>
+ <p>
+ O (Objective): Vitals: Temp *** F, BP *<strong>/</strong>, HR ***, RR
+<em><strong>, <em><strong>% RA, Wt 180 lb, Ht 70 in General: NAD,
+well-appearing. HEENT: PERRL, EOMI, oral mucosa moist. Neck: no LAD. CV:
+RRR, no m/r/g. Pulm: CTAB. Abd: soft, NT/ND, no masses. Ext: no c/c/e,
+2+ pulses. Recent EGD: Esophageal mass *** cm from incisors, partially
+obstructing lumen, biopsies c/w squamous cell carcinoma. CT
+chest/abd/pelvis: *** cm distal esophageal mass, obliterating
+<em><strong>% of lumen. *** cm regional lymph node. No distant
+metastases identified. Radiologist assessment:
+T</strong></em>N</strong></em>M</strong></em>, clinical stage ***. Labs:
+CBC: WBC 6.8, Hgb 11.5, Plt 225. CMP nl except Alb 3.2. CEA 5.2.
+ </p>
+ <p>
+ A (Assessment):
+ </p>
+ <ul>
+ <li>
+ Esophageal squamous cell carcinoma, clinical stage III (T3N1M0).
+Awaiting PET/CT for full staging and treatment planning.
+ </li>
+ <li>
+ Dysphagia secondary to above. Tolerating po currently without
+significant weight loss. Monitor symptoms, intake closely.
+ </li>
+ <li>
+ H/o GERD on omeprazole. Continue current therapy.
+ </li>
+ <li>
+ Anemia, likely anemia of chronic disease but will evaluate as
+outpatient.
+ </li>
+ </ul>
+ <p>
+ P (Plan):
+ </p>
+ <ol type="1">
+ <li>
+ Will obtain FDG-PET/CT scan to complete staging.
+ </li>
+ <li>
+ If no distant metastatic disease, recommend neoadjuvant
+chemoradiotherapy per CROSS regimen (carboplatin/paclitaxel q week x 5 +
+41.4 Gy in 23 fractions). Discussed expected toxicities including
+fatigue, esophagitis, nausea, neutropenia and importance of close
+monitoring.
+ </li>
+ <li>
+ If metastatic disease identified, will pursue systemic chemotherapy,
+likely FOLFOX or EOX regimen, rather than local therapy. May require
+palliative measures for dysphagia (stent, dilation prn).
+ </li>
+ <li>
+ Check iron studies, B12, folate. Replace as indicated.
+ </li>
+ <li>
+ Nutrition consult. Encourage high calorie/protein foods.
+ </li>
+ <li>
+ RTC in 1 week to review PET/CT results and finalize treatment plan.
+Sooner prn for worsening dysphagia, intolerance of po.
+ </li>
+ </ol>
+ <hr>
+ <h2>
+ The Verdict
+ </h2>
+ <p>
+ Overall, writing the first LLM prompt, copying the result into the
+chart, and adjusting it for correctness would take about 5 minutes.
+Improving the prompt as I did adds some time, but you can keep whatever
+prompt engineering bits you figure out for future use. You could also
+build yourself a custom template and ask it to fill it out, which would
+likely prevent many of the hallucinations (e.g. prepopulate placeholders
+for the vitals, labs, imaging, and tell the LLM to leave those
+alone).
+ </p>
+ <p>
+ Really, not bad for concise yet comprehensive documentation of a new
+consult. For subsequent visits, copying the note forward and adjusting
+for new details would be more efficient than going back to the LLM.
+ </p>
+ <p>
+ Hereâs the crazy thing about all of the above: the LLM did not ingest
+any PHI whatsoever - I gave it a general description of the case only.
+No HIPAA is violated. No EMR integration is necessary - this would work
+as well in CPRS as it would in Epic. Together, these two features are
+powerful, and means you can use this starting today.
+ </p>
+ <p>
+ I know a lot of organizations are nervous about LLMs and AI in
+medicine in general, but Iâm not certain I understand the hesitation in
+this particular arena. The responsibility is still yours for accurate
+documentation. The plan is also still yours, developed together with the
+patient. Many efficiencies can be gained without needing HIPAA-violating
+specifics, and without somehow asking the AI to become the doctor.
+ </p>
+ <p>
+ Also, as a friend pointed out the other day, many, many clinical
+notes are chock full of mistakes, whether typos or things copied forward
+and not corrected, or more egregious things like true mistakes in
+clinical reasoning. It seems to me, based on my brief experience, that
+using a smarter Clippy would serve more to cut down these kinds of
+errors, rather than propagating sins worse than those we already commit.
+No electronic tool, whether a copy button in Epic or a powerful LLM, is
+any kind of replacement for being a good clinician or an excuse for
+shoddy work. But, on the same token*, I also donât insist on counting
+RBCs myself for every CBC I order - this is a good technological
+cognate, since I need to be able to recognize the situations in which
+the automated counter doesnât tell the whole truth, know when the
+results in the computer are fishy, and be able to do the visual
+inspection myself if necessary, but most of the time I can just order
+the CBC and go on my merry way.
+ </p>
+ <p>
+ * ha, âtoken.â Thereâs an LLM dad joke for ya.
+ </p>
+ <p>
+ P.S. I asked Claude to write a blog post summarizing my experience
+and including the prompts and outputs. It mostly sucked and needed a
+complete rewrite. But then again, I didnât try very hard on the prompt.
+Iâve tried asking it to write insurance request letters (e.g. for the
+FDG-PET CT, which sometimes gets rejected out of hand even though itâs
+2024), consult request letters, consult response letters, and patient
+summary letters. Those were all pretty good, minimal tweaking
+needed.
+ </p>
+ </main>
+ <div id="footnotes"></div>
+ <footer></footer>
+ </div>
+ </body>
+</html>
diff --git a/build/posts/employee-wifi/index.html b/build/posts/employee-wifi/index.html
@@ -0,0 +1,241 @@
+<!DOCTYPE html>
+<html lang="en">
+ <head>
+ <link rel="stylesheet" href="/style.css" type="text/css">
+ <meta charset="utf-8">
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
+ <link rel="stylesheet" type="text/css" href="/style.css">
+ <link rel="icon" href="data:image/svg+xml,<svg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 100 100%22><text y=%22.9em%22 font-size=%2290%22>đď¸</text></svg>">
+ <title></title>
+ </head>
+ <body>
+ <div id="page-wrapper">
+ <div id="header" role="banner">
+ <header class="banner">
+ <div id="banner-text">
+ <span class="banner-title"><a href="/">beauhilton</a></span>
+ </div>
+ </header>
+ <nav>
+ <a href="/about">about</a>
+<a href="/now">now</a>
+<a href="/thanks">thanks</a>
+<a class="nav-active" href="/posts">posts</a>
+<a href="https://notes.beauhilton.com">notes</a>
+<a href="https://talks.beauhilton.com">talks</a>
+<a href="https://git.beauhilton.com">git</a>
+<a href="/contact">contact</a>
+<a href="/atom.xml">rss</a>
+ </nav>
+ </div>
+ <main>
+ <h1>
+ Set Up Enterprise Wifi on Arch Linux
+ </h1>
+ <p>
+ <time id="post-date">2021-09-17</time>
+ </p>
+ <p id="post-excerpt">
+ Most big institutions have guest and employee wifi networks.
+Guest wifi is usually fine, fast enough for the basics,
+but far inferior to employee wifi.
+On a custom-built OS, such as a fairly minimalist Linux distribution,
+getting the employee wifi to work
+can be a beast.
+ </p>
+ <p>
+ This was a little tricky to get working but very worth it, so hereâs
+an outline, mostly for my own later benefit.
+ </p>
+ <p></p>
+ <p>
+ This post is specific to <a href="https://www.vumc.org">VUMC</a>,
+with the VUMCEmployee network.
+ </p>
+ <p>
+ Similar steps should be applicable for other enterprise wifi users,
+though this post will unquestionably be out of date before long, and the
+intricacies of enterprise wifi are infinite.
+ </p>
+ <h2>
+ VUMCGuest is fine
+ </h2>
+ <p>
+ As with other public networks at large institutions, VUMCGuest is
+just a little slow and finicky, and itâs annoying to have to
+re-authenticate repeatedly to use all the HIPAA-compliant things.
+ </p>
+ <h2>
+ VUMCEmployee is better
+ </h2>
+ <p>
+ Iâll probably put a screenshot here at some point comparing speedtest
+scores. VUMCEmployee gives over 100 Mbps down, and around 100 up.
+ </p>
+ <p>
+ Itâs also more stable, and latency is around 10ms.
+ </p>
+ <p>
+ Most practical gain, other than faster everything: When I use
+VUMCGuest, the keyboard shortcut I use to launch and automatically login
+to Epic only works intermittently. On VUMCEmployee, it works reliably.
+No more typing! Itâs faster and, again, more reliable than tapping the
+badge-readers at the VUMC workstations.
+ </p>
+ <h2>
+ Backend
+ </h2>
+ <p>
+ The personal networking stack of greatest beauty on Linux at this
+point is:
+ </p>
+ <p>
+ <code>systemd-networkd</code> +<code>systemd-resolved</code> +
+<code>iwd</code>
+ </p>
+ <p>
+ Disable and delete <code>NetworkManager</code> and other such
+nonsense, if you are unwise like me and installed conflicting and
+useless things.
+ </p>
+ <p>
+ If youâd like a GUI, <a href="https://github.com/J-Lentz/iwgtk">iwgtk</a> is nice, but the CLI
+shipped with <code>iwd</code> (<code>iwctl</code>) is intuitive,
+friendly, and well-documented. I keep the GUI version around for quickly
+checking on things via a keyboard shortcut, but use the CLI for any
+heavy lifting, which has thankfully become rare since landing on this
+setup.
+ </p>
+ <h2>
+ Start with VUMCEmployeeSetup
+ </h2>
+ <p>
+ First, log on to the VUMCEmployeeSetup wifi. Then navigate to one of
+my favorite websites, <a href="http://neverssl.com/">http://neverssl.com/</a>. This will force
+the redirect to the VUMCEmployee enrollment page (I also use this site
+for connecting to public wifi at airports, libraries, coffee shops,
+etc.). Agree to the terms and conditions. Then click the âShow all
+operating systemsâ link at the bottom, followed by the âOther Operating
+Systemsâ tab that pops up at the bottom of the list.
+ </p>
+ <p>
+ The âOther Operating Systemsâ tab has three steps listed, which are
+simply the pieces that the various installers put together for you. The
+first two are downloads for certificates, and the third is a
+template.
+ </p>
+ <p>
+ Finding this tab was the gold mine - initially I repackaged one of
+the other Linux installers for Arch, because I thought that (since there
+was an installer) the process must be complicated, and repackaging
+things from Debian-based systems for Arch-based systems is easy enough.
+The repackaged version of the installer was decent at first, but it
+turns out that the manual process is easier and more reliable. I also
+learned more about enterprise networks in the process, which was an
+added bonus (Iâm honestly not sure about the sarcasm:sincerity ratio in
+the previous sentence).
+ </p>
+ <p>
+ Download the <code>PEM</code> files listed under Steps 1 (root
+certificate) and 2 (client certificate).
+ </p>
+ <h2>
+ Make your own <code>iwd</code> profile
+ </h2>
+ <p>
+ Hereâs where it goes:
+<code>/var/lib/iwd/VUMCEmployee.8021x</code>
+ </p>
+ <p>
+ Below are the contents, sensitive info redacted, then weâll go
+through some of the key parts and one nicety.
+ </p>
+ <pre tabindex="0"><code class="language-toml"><span class="hl kwa">[IPv6]</span>
+<span class="hl kwb">Enabled</span><span class="hl opt">=</span><span class="hl kwd">true</span>
+
+<span class="hl kwa">[Security]</span>
+<span class="hl kwb">EAP-Method</span><span class="hl opt">=</span>PEAP
+<span class="hl kwb">EAP-Identity</span><span class="hl opt">=</span>username
+<span class="hl kwb">EAP-PEAP-CACert</span><span class="hl opt">=</span>embed<span class="hl opt">:</span>root_cert
+<span class="hl kwb">EAP-PEAP-ServerDomainMask</span><span class="hl opt">=*</span>.radius.service.vumc.org
+<span class="hl kwb">EAP-PEAP-Phase2-Method</span><span class="hl opt">=</span>MSCHAPV2
+<span class="hl kwb">EAP-PEAP-Phase2-Identity</span><span class="hl opt">=</span>username
+<span class="hl kwb">EAP-PEAP-Phase2-Password</span><span class="hl opt">=</span>password
+
+<span class="hl kwa">[Settings]</span>
+<span class="hl kwb">AutoConnect</span><span class="hl opt">=</span><span class="hl kwd">true</span>
+
+<span class="hl kwa">[@pem@root_cert]</span>
+<span class="hl opt">-----</span>BEGIN CERTIFICATE<span class="hl opt">-----</span>
+<span class="hl opt">*</span>lots of gobbledigook goes here<span class="hl opt">*</span>
+<span class="hl opt">-----</span>END CERTIFICATE<span class="hl opt">-----</span>
+</code></pre>
+ <p>
+ Most of these options are outlined in Step 3 from the
+VUMCEmployeeSetup, cross-referenced against the Arch Wiki page on
+<code>iwd</code>, subsection <a href="https://wiki.archlinux.org/title/Iwd#EAP-PEAP">Network
+configuration</a>, and the <a href="https://iwd.wiki.kernel.org/networkconfigurationsettings"><code>iwd</code>
+wiki proper</a>.
+ </p>
+ <p>
+ An easy-to-miss step: The <code>EAP-PEAP-Phase2-Method</code>
+requirement for <code>MSCHAPV2</code> leads to another required install,
+check the wiki for current instructions.
+ </p>
+ <p>
+ Put in your own username and password.
+ </p>
+ <p>
+ My favorite trick in this file is directly embedding the root
+certificate in the line <code>EAP-PEAP-CACert=</code> with the syntax
+<code>embed:root_cert</code> (any name is fine, doesnât have to be
+<code>root_cert</code>, itâs just a pointer). Then you add a definition
+of <code>root_cert</code> in a <code>[@pem@root_cert]</code> section.
+Insert the contents of the root certificate directly via copy-paste or
+<code>cat</code>, etc.
+ </p>
+ <p>
+ Easiest method, as root:
+ </p>
+ <pre tabindex="0"><code class="language-shell">cat /home/beau/dl/root_cert.PEM >> /var/lib/iwd/VUMCEmployee.8021x
+</code></pre>
+ <p>
+ With the direct embed method, you donât need to point to the root
+certificate file or keep it around at all.
+ </p>
+ <p>
+ Needless to say, <code>VUMCEmployee.8021x</code> is a sensitive file
+and should be protected appropriately. However, this file or a version
+of it is what the automated tools would have made anyway, so thereâs no
+special risk here - AND since you did it all yourself you know there was
+no funny business coming from a black-box installer.
+ </p>
+ <h2>
+ The other certificate (Client)
+ </h2>
+ <p>
+ I canât remember what I had to do with the client cert, probably
+added using the Chrome/Firefox certificate managers.
+ </p>
+ <p>
+ I had to do this before when getting set up for VA remote access, the
+Arch Wiki comes through again with an article on <a href="https://wiki.archlinux.org/title/Common_Access_Card">Common Access
+Cards</a> that includes instructions on adding certs to browsers.
+ </p>
+ <p>
+ Thereâs a chance itâs not even needed? The <a href="https://iwd.wiki.kernel.org/networkconfigurationsettings">specification</a>
+no longer supports adding a client cert field without a key, which I
+donât have, and do not, apparently, need (see the section âEAP-PEAP with
+tunneled EAP-MSCHAPV2â). At any rate, this setup is working now and I
+wonât futz with it further until something breaks.
+ </p>
+ <h2>
+ -> ~~Profit~~ Prosper
+ </h2>
+ </main>
+ <div id="footnotes"></div>
+ <footer></footer>
+ </div>
+ </body>
+</html>
diff --git a/build/posts/geocheatcode/index.html b/build/posts/geocheatcode/index.html
@@ -0,0 +1,244 @@
+<!DOCTYPE html>
+<html lang="en">
+ <head>
+ <link rel="stylesheet" href="/style.css" type="text/css">
+ <meta charset="utf-8">
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
+ <link rel="stylesheet" type="text/css" href="/style.css">
+ <link rel="icon" href="data:image/svg+xml,<svg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 100 100%22><text y=%22.9em%22 font-size=%2290%22>đď¸</text></svg>">
+ <title></title>
+ </head>
+ <body>
+ <div id="page-wrapper">
+ <div id="header" role="banner">
+ <header class="banner">
+ <div id="banner-text">
+ <span class="banner-title"><a href="/">beauhilton</a></span>
+ </div>
+ </header>
+ <nav>
+ <a href="/about">about</a>
+<a href="/now">now</a>
+<a href="/thanks">thanks</a>
+<a class="nav-active" href="/posts">posts</a>
+<a href="https://notes.beauhilton.com">notes</a>
+<a href="https://talks.beauhilton.com">talks</a>
+<a href="https://git.beauhilton.com">git</a>
+<a href="/contact">contact</a>
+<a href="/atom.xml">rss</a>
+ </nav>
+ </div>
+ <main>
+ <h1>
+ geocheatcode
+ </h1>
+ <p>
+ <time id="post-date">2022-04-22</time>
+ </p>
+ <p id="post-excerpt">
+ Here is background and code
+for a trick I use to get
+Google to give me best-in-class guesses
+for latitude and longitude,
+despite goofy and/or downright bad location searches.
+ </p>
+ <h2>
+ Map all the things
+ </h2>
+ <p>
+ I love maps.
+ </p>
+ <p>
+ Several of my projects involve mapping things at scale.
+ </p>
+ <p>
+ When you want to map a few things, you type searches into Google Maps
+and get addresses and/or latitudes and longitudes quickly and
+reliably.
+ </p>
+ <p>
+ But what if youâd like to map 90,000 things whose locations you donât
+yet know?
+ </p>
+ <p>
+ <a href="https://developers.google.com/maps">Google</a> and <a href="https://www.openstreetmap.org/">OpenStreetMap</a>, as well as
+others, provide mapping services you can call programmatically from your
+software. You send in some query, such as âVUMC Internal Medicine,â and
+they return information relevant to that query, such as street address
+and latitude and longitude. Up to a certain number of queries per day or
+hour, the services are free, and since my work is academic, rather than
+real-time mapping for some for-profit app, I am happy to send in small
+batches to stay under the limits in the free tier.
+ </p>
+ <p>
+ Iâve used these services to make large maps, and they work pretty
+well.
+ </p>
+ <p>
+ <em>Pretty</em> well.
+ </p>
+ <h2>
+ But mapping is hard
+ </h2>
+ <p>
+ Problems with these services:
+ </p>
+ <ol type="1">
+ <li>
+ they expected well-formed and reasonable queries
+ </li>
+ <li>
+ if they didnât know the answer, the guesses were often wildly off,
+or they would refuse to guess at all
+ </li>
+ </ol>
+ <p>
+ If Iâm mapping 90,000 things, Iâm going to write some code to go
+through each of those 90,000 things and ask the mapping services to
+kindly tell me what I want to know. Though I write sanitation code to
+clean up the 90,000 things, Iâm not going to quality check each of those
+90,000 things. Sometimes things among the 90,000 things are kinda nuts
+(misspelled, inclusive of extraneous data, oddly formatted), in
+idiosyncratic ways that are impossible to completely cover, no matter
+how much code I write to catch the weird cases.
+ </p>
+ <p>
+ I would like a solution that is fairly tolerant of weirdnesses, and
+makes good guesses.
+ </p>
+ <h2>
+ Google is really good at search
+ </h2>
+ <p>
+ I noticed that when I manually typed things into the Google Maps
+search bar, it forgave a myriad of sins and did a great job centering
+the map on its best guess. When I copied and pasted some of the weird
+things among the 90,000 into the Google Maps search bar (the same things
+that made the official mapping services - including Googleâs - go all
+Poltergeist), <em>voila!</em>, the right answer appeared, success rates
+nearing 100%.
+ </p>
+ <p>
+ I thought there must be a way to repeat this process with code, in a
+scalable way.
+ </p>
+ <p>
+ Turns out there is, and itâs easy.
+ </p>
+ <h2>
+ <code>geocheatcode.py</code>
+ </h2>
+ <pre tabindex="0"><code class="language-python">
+<span class="hl kwa">from</span> requests_html <span class="hl kwa">import</span> HTMLSession
+
+session <span class="hl opt">=</span> <span class="hl kwd">HTMLSession</span><span class="hl opt">()</span>
+
+
+<span class="hl kwa">def</span> <span class="hl kwd">google_lat_lon</span><span class="hl opt">(</span>query<span class="hl opt">:</span> <span class="hl kwb">str</span><span class="hl opt">):</span>
+
+ url <span class="hl opt">=</span> <span class="hl sng">"https://www.google.com/maps/search/?api=1"</span>
+ params <span class="hl opt">= {}</span>
+ params<span class="hl opt">[</span><span class="hl sng">"query"</span><span class="hl opt">] =</span> query
+
+ r <span class="hl opt">=</span> session<span class="hl opt">.</span><span class="hl kwd">get</span><span class="hl opt">(</span>url<span class="hl opt">,</span> params<span class="hl opt">=</span>params<span class="hl opt">)</span>
+
+ reg <span class="hl opt">=</span> <span class="hl sng">"APP_INITIALIZATION_STATE=[[[{}]"</span>
+ res <span class="hl opt">=</span> r<span class="hl opt">.</span>html<span class="hl opt">.</span><span class="hl kwd">search</span><span class="hl opt">(</span>reg<span class="hl opt">)[</span><span class="hl num">0</span><span class="hl opt">]</span>
+ lat <span class="hl opt">=</span> res<span class="hl opt">.</span><span class="hl kwd">split</span><span class="hl opt">(</span><span class="hl sng">","</span><span class="hl opt">)[</span><span class="hl num">2</span><span class="hl opt">]</span>
+ lon <span class="hl opt">=</span> res<span class="hl opt">.</span><span class="hl kwd">split</span><span class="hl opt">(</span><span class="hl sng">","</span><span class="hl opt">)[</span><span class="hl num">1</span><span class="hl opt">]</span>
+
+ <span class="hl kwa">return</span> lat<span class="hl opt">,</span> lon
+
+
+extraneous <span class="hl opt">=</span> <span class="hl sng">""" something something</span>
+<span class="hl sng"> the earth is banana shaped</span>
+<span class="hl sng"> latitude and longitude </span>
+<span class="hl sng"> wouldn't you like to know, maybe """</span>
+
+relevant <span class="hl opt">=</span> <span class="hl sng">""" Vanderbilt University Medical Center </span>
+<span class="hl sng"> Internal Medicine """</span>
+
+query <span class="hl opt">=</span> extraneous <span class="hl opt">+</span> relevant
+
+lat<span class="hl opt">,</span> lon <span class="hl opt">=</span> <span class="hl kwd">google_lat_lon</span><span class="hl opt">(</span>query<span class="hl opt">)</span>
+
+<span class="hl kwa">print</span><span class="hl opt">(</span>
+ <span class="hl sng">"Hello. "</span>
+ <span class="hl sng">"My name is Google. "</span>
+ <span class="hl sng">"I am really good at guessing what you meant. "</span>
+ f<span class="hl sng">"Your query was '</span><span class="hl ipl">{query}</span><span class="hl sng">'. "</span>
+ <span class="hl sng">"Here are the coordinates you probably wanted. "</span>
+ f<span class="hl sng">"The latitude is</span> <span class="hl ipl">{lat}</span><span class="hl sng">, and the longitude is</span> <span class="hl ipl">{lon}</span><span class="hl sng">. "</span>
+ <span class="hl sng">"Don't believe me? "</span>
+ <span class="hl sng">"Here it is again, "</span>
+ <span class="hl sng">"in a format you can paste into the search bar:</span> <span class="hl esc">\n</span><span class="hl sng">"</span>
+ f<span class="hl sng">"</span><span class="hl ipl">{lat}</span><span class="hl sng">,</span> <span class="hl ipl">{lon}</span> <span class="hl sng"></span><span class="hl esc">\n</span><span class="hl sng">"</span>
+ <span class="hl sng">"Told ya. "</span>
+<span class="hl opt">)</span>
+</code></pre>
+ <p>
+ Despite having all that extra junk in the query, this returns the
+right answer. Because Google is many things good and evil, but of these
+one is certain: Google is <em>really</em> good at search.
+ </p>
+ <h2>
+ How does the code work?
+ </h2>
+ <p>
+ If you inspect the source HTML on the Google Maps website after you
+search for something and it centers the map on its best guess, and you
+scroll way on down (or Ctrl-F search for it) youâll find
+<code>APP_INITIALIZATION_STATE</code>, which contains latitude and
+longitude for the place the map centered on.
+ </p>
+ <ul>
+ <li>
+ <a href="https://www.google.com/maps?q=something+whose+latitude+and+longitude+you+would+like+to+know,+maybe+VUMC+Internal+Medicine">example
+search</a>
+ </li>
+ <li>
+ <a href="view-source:https://www.google.com/maps/search/something+whose+latitude+and+longitude+you+would+like+to+know,+maybe+VUMC+Internal+Medicine/">example
+source</a> (you have to copy and paste this link into a new tab
+manually, clicking wonât work)
+ </li>
+ </ul>
+ <p>
+ I use the lovely <a href="https://docs.python-requests.org/projects/requests-html/en/latest/"><code>requests-html</code></a>
+Python library to send the query to Google, receive the response, and
+search through the response for the part I want to extract. Then I use a
+little standard Python to parse the extracted part and save the
+important bits.
+ </p>
+ <h2>
+ With great powerâŚ
+ </h2>
+ <p>
+ Donât go crazy with this.
+ </p>
+ <p>
+ The trick is good for leisurely automation of location retrieval when
+you have squirrelly queries.
+ </p>
+ <p>
+ If you need real-time mapping of many things, you donât want this
+solution. Use the actual APIs, and work instead on formatting the
+queries properly before sending them to Google/OSM.
+ </p>
+ <p>
+ Also, if you try to query too much/too quickly, Google will shut you
+out after a little while. Put a few seconds of delay between each
+request and run it overnight and/or in automated batches.
+ </p>
+ <h2>
+ Know a better way?
+ </h2>
+ <p>
+ Iâd love to know. Drop me a line.
+ </p>
+ </main>
+ <div id="footnotes"></div>
+ <footer></footer>
+ </div>
+ </body>
+</html>
diff --git a/build/posts/history-egc/index.html b/build/posts/history-egc/index.html
@@ -0,0 +1,563 @@
+<!DOCTYPE html>
+<html lang="en">
+ <head>
+ <link rel="stylesheet" href="/style.css" type="text/css">
+ <meta charset="utf-8">
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
+ <link rel="stylesheet" type="text/css" href="/style.css">
+ <link rel="icon" href="data:image/svg+xml,<svg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 100 100%22><text y=%22.9em%22 font-size=%2290%22>đď¸</text></svg>">
+ <title></title>
+ </head>
+ <body>
+ <div id="page-wrapper">
+ <div id="header" role="banner">
+ <header class="banner">
+ <div id="banner-text">
+ <span class="banner-title"><a href="/">beauhilton</a></span>
+ </div>
+ </header>
+ <nav>
+ <a href="/about">about</a>
+<a href="/now">now</a>
+<a href="/thanks">thanks</a>
+<a class="nav-active" href="/posts">posts</a>
+<a href="https://notes.beauhilton.com">notes</a>
+<a href="https://talks.beauhilton.com">talks</a>
+<a href="https://git.beauhilton.com">git</a>
+<a href="/contact">contact</a>
+<a href="/atom.xml">rss</a>
+ </nav>
+ </div>
+ <main>
+ <h1>
+ A timeline of esophageal cancer
+ </h1>
+ <p>
+ <time id="post-date">2023-10-20</time>
+ </p>
+ <p id="post-excerpt">
+ A couple of friends and I wrote a review article on the history of esophageal cancer.
+The timeline was so interesting I thought I'd share it here, in a place where it can be easily found and updated.
+ </p>
+ <p>
+ Iâll put a link to the article when itâs published.
+ </p>
+ <p>
+ For now, Iâm not including any references, and this is an abbreviated
+version. I hope to fix both of these things in the future, with the goal
+of a definitive, comprehensive list with a clear paper trail (though a
+list such as this does require some curation - Iâm not interested in
+every small technical advance, only major firsts and practice-changing
+updates).
+ </p>
+ <p>
+ As a side note, it would be cool if <a href="hemonc.org">HemOnc.org</a> had tables (<em>a</em> table? for
+comparative work?) of all oncologic drug approvals, with dates and
+indications, for every global approval agency. Maybe with a link to the
+trial that led to each approval? (Itâs not always 1:1 between
+trial:approval, but would be nice to know for the majority of cases
+where that pattern holds). Itâs a huge task, but would be so useful for
+clinicians, researchers, and investors. Iâm amazed nobody has done this
+yet, though there are some partial lists that were helpful. HemOnc does
+have a few wiki entries on dates of drug approvals, but theyâre sparse.
+(Itâs not an easy task, particularly for the Chinese approvals - the
+only definitive source for the Chinese NMPA appears to be a pdf that is
+in Chinese only. If you read Chinese and would like to help, please
+shoot me an email - see the contact link above)
+ </p>
+ <p>
+ If you are several steps ahead and beat me to building the drug
+approval tables: brava/bravo/brave/bravi, please lmk and Iâll send you a
+string of happy, grateful emojis, and we can talk about
+collaboration.
+ </p>
+ <p>
+ Likewise, if you know of an important event in esophageal cancer
+history, have a reference, and think I should add it here, please
+contact me.
+ </p>
+ <h2>
+ Early History
+ </h2>
+ <table>
+ <thead>
+ <tr>
+ <th colspan="3">
+ Key events in the early history of esophageal cancer
+ </th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr>
+ <td>
+ Date
+ </td>
+ <td>
+ Event
+ </td>
+ <td>
+ Notes
+ </td>
+ </tr>
+ <tr>
+ <td>
+ 3000 BCE
+ </td>
+ <td>
+ First description of esophageal surgery, written in Egypt.
+ </td>
+ <td>
+ Smith Surgical Papyrus.
+ </td>
+ </tr>
+ <tr>
+ <td>
+ 0 BCE
+ </td>
+ <td>
+ First description of EC, written in China.
+ </td>
+ <td>
+ Epidemiologic links to EC described between alcohol, hot drinks, and advanced age.
+ </td>
+ </tr>
+ <tr>
+ <td>
+ 131-200
+ </td>
+ <td>
+ First descriptions of EC written in the West.
+ </td>
+ <td>
+ Dates are the life of Galen, Roman Greek physician who wrote extensively. Poor prognosis described.
+ </td>
+ </tr>
+ <tr>
+ <td>
+ 1090 - 1162
+ </td>
+ <td>
+ First palliative methods for EC described, including esophagogastric feeding tubes.
+ </td>
+ <td>
+ Dates are the life of Ibn Zuhr, Arabian physician who described these methods.
+ </td>
+ </tr>
+ <tr>
+ <td>
+ 1543
+ </td>
+ <td>
+ First detailed illustrations and descriptions of the upper gastrointestinal tract.
+ </td>
+ <td>
+ Vesalius, <i>De Humanis Corporis Fabrica</i>
+ </td>
+ </tr>
+ <tr>
+ <td>
+ 1690
+ </td>
+ <td>
+ First personal description of living with EC.
+ </td>
+ <td>
+ Diary of John Casaubon, English surgeon.
+ </td>
+ </tr>
+ <tr>
+ <td>
+ 1770
+ </td>
+ <td>
+ First written Western hypothesis of the epidemiologic link between alcohol and EC.
+ </td>
+ <td>
+ Ernst Gottfried Gyser, <i>Medical inaugural dissertation on the fatal hunger, caused by callous narrowing of the esophagus, with phenomena worthy of attention which are detected in certain abdominal viscera.</i>
+ </td>
+ </tr>
+ <tr>
+ <td>
+ 1857
+ </td>
+ <td>
+ First described EC operation.
+ </td>
+ <td>
+ Albrecht Theodor von Middeldorph, Breslau surgeon.
+ </td>
+ </tr>
+ <tr>
+ <td>
+ 1868
+ </td>
+ <td>
+ Esophagoscope invented.
+ </td>
+ <td>
+ Adolf Kussmaul, German surgeon.
+ </td>
+ </tr>
+ <tr>
+ <td>
+ 1872
+ </td>
+ <td>
+ First known esophagectomy.
+ </td>
+ <td>
+ Christian Billroth, Austrian surgeon, with Vincenz Czerny assisting.
+ </td>
+ </tr>
+ <tr>
+ <td>
+ 1877
+ </td>
+ <td>
+ First known cervical esophagectomy.
+ </td>
+ <td>
+ Vincenz Czerny. Post-operative survival of 15 months.
+ </td>
+ </tr>
+ <tr>
+ <td>
+ 1913
+ </td>
+ <td>
+ First known curative EC resection.
+ </td>
+ <td>
+ Franz Torek, United States surgeon. Post-operative survival of 12 years.
+ </td>
+ </tr>
+ <tr>
+ <td>
+ 1933
+ </td>
+ <td>
+ First report on a series of EC resections.
+ </td>
+ <td>
+ Tohru Oshawa, Japanese surgeon. 18 resections, 56% mortality.
+ </td>
+ </tr>
+ <tr>
+ <td>
+ 1947
+ </td>
+ <td>
+ First large report on a series of EC resections in the West.
+ </td>
+ <td>
+ Richard Sweet, United States surgeon. 213 resections, 17% mortality, 8% 5-year survival.
+ </td>
+ </tr>
+ <tr>
+ <td>
+ 1959
+ </td>
+ <td>
+ First report with <10% operative mortality
+ </td>
+ <td>
+ Komei Nakayama, Japanese surgeon. 953 resections, 5.8% mortality.
+ </td>
+ </tr>
+ <tr>
+ <td>
+ 1981
+ </td>
+ <td>
+ First report with <5% operative mortality
+ </td>
+ <td>
+ Hiroshi Akiyama, Japanese surgeon. 210 resections, 1.4% mortality, 34.6% 5-year survival.
+ </td>
+ </tr>
+ <tr>
+ <td colspan="3">
+ Acronyms: BCE - Before Common Era. EC - Esophageal Cancer.
+ </td>
+ </tr>
+ </tbody>
+ </table>
+ <h2>
+ Key clinical trials and approvals
+ </h2>
+ <table>
+ <thead>
+ <tr>
+ <th colspan="3">
+ Key clinical trials and approvals
+ </th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr>
+ <td>
+ 1981
+ </td>
+ <td>
+ First neoadjuvant RT trial for EC
+ </td>
+ <td>
+ Launois et al. 40 Gy. Results were negative.
+ </td>
+ </tr>
+ <tr>
+ <td>
+ 1984
+ </td>
+ <td>
+ First neoadjuvant CRT trial for EC
+ </td>
+ <td>
+ Leichman et al. 30 Gy, cisplatin. pCR 37%, operative mortality 27%, no survival benefit.
+ </td>
+ </tr>
+ <tr>
+ <td>
+ 1988
+ </td>
+ <td>
+ First perioperative chemotherapy trial for EC
+ </td>
+ <td>
+ Roth et al. No benefit for cohort overall. mOS of responders 20mo, non-responders 6.2mo, surgery alone 8mo.
+ </td>
+ </tr>
+ <tr>
+ <td>
+ 2002
+ </td>
+ <td>
+ First whole-cohort positive perioperative chemotherapy trial
+ </td>
+ <td>
+ Lancet, United Kingdom. Cisplatin+fluorouracil. mOS 16.8mo vs 13.3mo for surgery alone.
+ </td>
+ </tr>
+ <tr>
+ <td>
+ 2010
+ </td>
+ <td>
+ Trastuzumab shown to have benefit for HER2+ GC and GEJC
+ </td>
+ <td>
+ ToGA trial. Trastuzumab+chemotherapy. mOS 13.8mo vs 11.1mo for chemotherapy alone.
+ </td>
+ </tr>
+ <tr>
+ <td>
+ 2012
+ </td>
+ <td>
+ CROSS trial first report
+ </td>
+ <td>
+ Van Hagen et al. 40 Gy, carboplatin+paclitaxel. mOS 49.4mo vs 24.0mo for surgery alone.
+ </td>
+ </tr>
+ <tr>
+ <td>
+ 2017-09-22
+ </td>
+ <td>
+ First FDA approval for IO for EGC
+ </td>
+ <td>
+ KEYNOTE-059, pembrolizumab monotherapy, approved for 3rd line. Approval was later withdrawn as pembrolizumab moved to earlier lines.
+ </td>
+ </tr>
+ <tr>
+ <td>
+ 2019-07-30
+ </td>
+ <td>
+ First FDA approval for 2nd line IO for EGC
+ </td>
+ <td>
+ KEYNOTE-181, pembrolizumab monotherapy. ESCC with CPS >=10. mOS 8.2mo vs 7.1mo for chemotherapy.
+ </td>
+ </tr>
+ <tr>
+ <td>
+ 2020-06-10
+ </td>
+ <td>
+ First FDA approval for 2nd line IO for EGC, agnostic of CPS
+ </td>
+ <td>
+ ATTRACTION-3, nivolumab monotherapy. ESCC. mOS 10.9mo vs 8.4mo for chemotherapy.
+ </td>
+ </tr>
+ <tr>
+ <td>
+ 2020-06-19
+ </td>
+ <td>
+ First NMPA approval for locally-produced IO, 2nd line camrelizumab for ESCC
+ </td>
+ <td>
+ ESCORT, camrelizumab monotherapy. ESCC. mOS 8.3mo vs 6.2mo for chemotherapy.
+ </td>
+ </tr>
+ <tr>
+ <td>
+ 2021-01-15
+ </td>
+ <td>
+ First FDA approval for antibody drug conjugate in EGC
+ </td>
+ <td>
+ DESTINY-Gastric01, fam-trastuzumab deruxtecan-nxki. EGC, AC, HER2+, 2nd line. mOS 12.5mo vs 8.4mo for chemotherapy.
+ </td>
+ </tr>
+ <tr>
+ <td>
+ 2021-03-22
+ </td>
+ <td>
+ First FDA approval for 1st line IO for EGC
+ </td>
+ <td>
+ KEYNOTE-590, pembrolizumab with chemotherapy, EGC, AC and SCC, CPS agnostic. mOS 13.9mo (ESCC w CPS >=10) vs 8.8mo for chemotherapy alone.
+ </td>
+ </tr>
+ <tr>
+ <td>
+ 2021-04-16
+ </td>
+ <td>
+ Second FDA approval for 1st line IO for EGC
+ </td>
+ <td>
+ CheckMate 649, nivolumab with chemotherapy, similar setting to KEYNOTE-590. mOS 13.8 vs 11.1mo for chemotherapy alone.
+ </td>
+ </tr>
+ <tr>
+ <td>
+ 2021-05-05
+ </td>
+ <td>
+ First FDA approval for 1st line IO + chemotherapy + HER2-targeted therapy
+ </td>
+ <td>
+ KEYNOTE-811, pembrolizumab + trastuzumab + chemotherapy. ORR 74.4% vs 51.9% for trastuzumab + chemotherapy alone. CR 11.3% vs 3.1%, respectively.
+ </td>
+ </tr>
+ <tr>
+ <td>
+ 2021-05-20
+ </td>
+ <td>
+ First FDA approval for adjuvant IO monotherapy
+ </td>
+ <td>
+ CheckMate 577, nivolumab after CROSS, EGC, AC and SCC, CPS agnostic. ESCC mDFS 29.7mo vs 11mo for placebo, EAC 19.4mo vs 11mo.
+ </td>
+ </tr>
+ <tr>
+ <td>
+ 2021-12-10
+ </td>
+ <td>
+ NMPA approval for 1st line camrelizumab + chemotherapy for ESCC
+ </td>
+ <td>
+ ESCORT-1st, camrelizumab with chemotherapy. mOS 15.3mo vs 12.0mo for chemotherapy alone.
+ </td>
+ </tr>
+ <tr>
+ <td>
+ 2022-02-21
+ </td>
+ <td>
+ NMPA approval for 1st line tislelizumab monotherapy for GC and GEJC
+ </td>
+ <td>
+ Based on phase I/II studies.
+ </td>
+ </tr>
+ <tr>
+ <td>
+ 2022-04-13
+ </td>
+ <td>
+ NMPA approval for 2nd line tislelizumab monotherapy for ESCC
+ </td>
+ <td>
+ RATIONALE-302, tislelizumab monotherapy vs chemotherapy, ESCC, PD-L1 agnostic. mOS 8.6mo vs 6.3mo for chemotherapy.
+ </td>
+ </tr>
+ <tr>
+ <td>
+ 2022-05-19
+ </td>
+ <td>
+ NMPA approval for 1st line tislelizumab + chemotherapy for ESCC
+ </td>
+ <td>
+ RATIONALE-306, tislelizumab with chemotherapy, ESCC, PD-L1 agnostic. mOS 17.2mo vs 10.6mo for chemotherapy alone.
+ </td>
+ </tr>
+ <tr>
+ <td>
+ 2022-05-27
+ </td>
+ <td>
+ First FDA approval for 1st line dual IO
+ </td>
+ <td>
+ CheckMate 648, nivolumab with ipilimumab, ESCC, PD-L1 >=1%. mOS 13.2mo for IO + chemotherapy vs 12.8mo for IO + IO vs 10.7mo for chemotherapy alone.
+ </td>
+ </tr>
+ <tr>
+ <td>
+ 2022-06-20
+ </td>
+ <td>
+ NMPA approval for 1st line sintilimab + chemotherapy for GC and GEJC, agnostic of CPS.
+ </td>
+ <td>
+ ORIENT-16, sintilimab + chemotherapy vs chemotherapy, AC. For CPS >= 5, mOS 19.2mo vs 12.9mo for chemotherapy alone. For unselected CPS, mOS 15.2mo vs 12.3mo for chemotherapy alone.
+ </td>
+ </tr>
+ <tr>
+ <td>
+ 2023-01-24
+ </td>
+ <td>
+ First OS data available for HER2 vaccine therapy
+ </td>
+ <td>
+ HERIZON study, HER-Vaxx (IMU-131)+chemotherapy, metastatic or advanced HER2+ GC and GEJC. mOS 13.9mo for vaccine+chemotherapy vs 8.3mo for chemotherapy alone.
+ </td>
+ </tr>
+ <tr>
+ <td>
+ 2023-02-24
+ </td>
+ <td>
+ NMPA approval for 1st line tislelizumab + chemotherapy for GC and GEJC.
+ </td>
+ <td>
+ RATIONALE-305, tislelizumab + chemotherapy vs chemotherapy, AC. For PD-L1 >=5%, mOS 17.2mo for IO + chemotherapy vs 12.6mo for chemotherapy alone.
+ </td>
+ </tr>
+ <tr>
+ <td colspan="3">
+ Acronyms and abbreviations: CPS - combined positive score. (C)RT - (chemo)radiotherapy. (E)AC - (esophageal) adenocarcinoma. EC - Esophageal Cancer. EGC - esophagogastric cancers. (E)SCC - (esophageal) squamous cell carcinoma. FDA - United States Food and Drug Administration.IO - immuno-oncologic therapy. pCR - pathologic complete response. PD-L1 - programmed death-ligand 1.mDFS - median disease-free survival. mo - month(s). mOS - median overall survival. NMPA - Chinaâs National Medical Products Administration. ORR - overall response rate.
+ </td>
+ </tr>
+ </tbody>
+ </table>
+ </main>
+ <div id="footnotes"></div>
+ <footer></footer>
+ </div>
+ </body>
+</html>
diff --git a/build/posts/index.html b/build/posts/index.html
@@ -0,0 +1,340 @@
+<!DOCTYPE html>
+<html lang="en">
+ <head>
+ <link rel="stylesheet" href="/style.css" type="text/css">
+ <meta charset="utf-8">
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
+ <link rel="stylesheet" type="text/css" href="/style.css">
+ <link rel="icon" href="data:image/svg+xml,<svg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 100 100%22><text y=%22.9em%22 font-size=%2290%22>đď¸</text></svg>">
+ <title></title>
+ </head>
+ <body>
+ <div id="page-wrapper">
+ <div id="header" role="banner">
+ <header class="banner">
+ <div id="banner-text">
+ <span class="banner-title"><a href="/">beauhilton</a></span>
+ </div>
+ </header>
+ <nav>
+ <a href="/about">about</a>
+<a href="/now">now</a>
+<a href="/thanks">thanks</a>
+<a class="nav-active" href="/posts">posts</a>
+<a href="https://notes.beauhilton.com">notes</a>
+<a href="https://talks.beauhilton.com">talks</a>
+<a href="https://git.beauhilton.com">git</a>
+<a href="/contact">contact</a>
+<a href="/atom.xml">rss</a>
+ </nav>
+ </div>
+ <main>
+ <h1 id="title">
+ Posts
+ </h1>
+ <p>
+ You can subscribe to the <a href="/atom.xml">Atom feed</a> to receive updates.
+ </p>
+ <hr style="opacity:0.2; margin-top:2em">
+ <div id="posts-index">
+ <h2>
+ <a href="/posts/choaked">The first detailed description of living with esophageal cancer -
+John Casaubonâs 1690 diary</a>
+ </h2>
+ <p>
+ <strong>Last update:</strong> 2024-04-12.
+ </p>
+ <p>
+ John Casaubon was an English surgeon in the late 1600s
+who developed an esophageal tumor in late 1690
+and wrote about it in his diary
+before dying in January of 1691.
+It's harrowing, enlightening, and strangely beautiful.
+This blog post is the only place in the world you can read the full transcription of the diary entry.
+ </p>
+ <a href="/posts/choaked">Read more</a>
+ <hr style="opacity:0.2; margin-top: 3em">
+ <br>
+ <h2>
+ <a href="/posts/claude-notes">Writing clinical notes using AI - a practical experience</a>
+ </h2>
+ <p>
+ <strong>Last update:</strong> 2024-04-09.
+ </p>
+ <p>
+ With Claude 3 Opus (a newish ChatGPT4 competitor) as my copilot, I wrote a pretty darn good SOAP note
+ for an (invented yet realistic) new consult visit. It took a little massaging to get it right,
+ but boy howdy, it did a great job. Here are the prompts and outputs.
+ This stuff has serious potential for streamlining the boring and tedious parts of the job.
+ </p>
+ <a href="/posts/claude-notes">Read more</a>
+ <hr style="opacity:0.2; margin-top: 3em">
+ <br>
+ <h2>
+ <a href="/posts/s1">Drugs we canât get: S1</a>
+ </h2>
+ <p>
+ <strong>Last update:</strong> 2024-03-29.
+ </p>
+ <p>
+ There are a number of interesting drugs used in the global market that,
+ for one reason or another, do not have FDA approval and are therefore inaccessible
+ in the US, at least outside of clinical trials. S1 is one of them: a better capecitabine.
+ </p>
+ <a href="/posts/s1">Read more</a>
+ <hr style="opacity:0.2; margin-top: 3em">
+ <br>
+ <h2>
+ <a href="/posts/pp-tech-infra">Patient-facing slide decks</a>
+ </h2>
+ <p>
+ <strong>Last update:</strong> 2024-03-23.
+ </p>
+ <p>
+ While I plan on being a physician-scientist forever, I'm not going to work in academia.
+Over the past few years I've put together very cool infrastructure for giving academic talks (click "talks" above),
+and it was making me sad that it might not get much use after I leave the university.
+But then, a ray of sunshine: Why not use my slide deck infrastructure to help in patient conversations?
+ </p>
+ <a href="/posts/pp-tech-infra">Read more</a>
+ <hr style="opacity:0.2; margin-top: 3em">
+ <br>
+ <h2>
+ <a href="/posts/cad-fish">Cold agglutinin disease: fish out of water?</a>
+ </h2>
+ <p>
+ <strong>Last update:</strong> 2024-03-22.
+ </p>
+ <p>
+ Cold agglutinin disease is a fascinating and strange phenomenon, and might happen because we're fish.
+ </p>
+ <a href="/posts/cad-fish">Read more</a>
+ <hr style="opacity:0.2; margin-top: 3em">
+ <br>
+ <h2>
+ <a href="/posts/history-egc">A timeline of esophageal cancer</a>
+ </h2>
+ <p>
+ <strong>Last update:</strong> 2023-10-20.
+ </p>
+ <p>
+ A couple of friends and I wrote a review article on the history of esophageal cancer.
+The timeline was so interesting I thought I'd share it here, in a place where it can be easily found and updated.
+ </p>
+ <a href="/posts/history-egc">Read more</a>
+ <hr style="opacity:0.2; margin-top: 3em">
+ <br>
+ <h2>
+ <a href="/posts/add-zfs-mirror">How to add a mirror to a single ZFS disk</a>
+ </h2>
+ <p>
+ <strong>Last update:</strong> 2023-10-19.
+ </p>
+ <p>
+ tl;dr:â
<code>zpoolâ
attachâ
dataâ
/dev/disk/by-partlabel/zfs-3a1xxâ
/dev/sdx0</code>. Adjust for your own pool and disks.
+ </p>
+ <a href="/posts/add-zfs-mirror">Read more</a>
+ <hr style="opacity:0.2; margin-top: 3em">
+ <br>
+ <h2>
+ <a href="/posts/yt-dlp">yt-dlp Nix config</a>
+ </h2>
+ <p>
+ <strong>Last update:</strong> 2023-10-18.
+ </p>
+ <p>
+ yt-dlp is an incredibly useful and customizable tool
+for downloading online videos
+from YouTube and elsewhere.
+Here's my setup
+(declared in Nix, but easily generalizable).
+ </p>
+ <a href="/posts/yt-dlp">Read more</a>
+ <hr style="opacity:0.2; margin-top: 3em">
+ <br>
+ <h2>
+ <a href="/posts/subsonic-cli">Command-line interfaces for self-hosted music</a>
+ </h2>
+ <p>
+ <strong>Last update:</strong> 2023-09-28.
+ </p>
+ <p>
+ Self-hosting a music server is great.
+Listening to the tunes via the command line is the way.
+ </p>
+ <a href="/posts/subsonic-cli">Read more</a>
+ <hr style="opacity:0.2; margin-top: 3em">
+ <br>
+ <h2>
+ <a href="/posts/pixel6screen">Pixel 6 DIY screen replacement, with fingerprint reader calibration
+using Linux</a>
+ </h2>
+ <p>
+ <strong>Last update:</strong> 2023-09-19.
+ </p>
+ <p>
+ The internet, up to now, says you need Windows or MacOS to calibrate the Pixel's fingerprint reader after installing a new screen and digitizer.
+The internet, up to now, was wrong.
+ </p>
+ <a href="/posts/pixel6screen">Read more</a>
+ <hr style="opacity:0.2; margin-top: 3em">
+ <br>
+ <h2>
+ <a href="/posts/pagecrypt">password protecting static web pages</a>
+ </h2>
+ <p>
+ <strong>Last update:</strong> 2023-01-12.
+ </p>
+ <p>
+ Static site generators, by and large, do not have support for password protecting individual pages.
+This post shows a strategy that works for any SSG and does not require server access controls.
+ </p>
+ <a href="/posts/pagecrypt">Read more</a>
+ <hr style="opacity:0.2; margin-top: 3em">
+ <br>
+ <h2>
+ <a href="/posts/oo-et-al">good machine learning in medicine</a>
+ </h2>
+ <p>
+ <strong>Last update:</strong> 2022-12-29.
+ </p>
+ <p>
+ Because most machine learning in medicine sucks, I thought you might like to see an example of it done well.
+ </p>
+ <a href="/posts/oo-et-al">Read more</a>
+ <hr style="opacity:0.2; margin-top: 3em">
+ <br>
+ <h2>
+ <a href="/posts/medical-humanities-org">medical-humanities.org</a>
+ </h2>
+ <p>
+ <strong>Last update:</strong> 2022-12-26.
+ </p>
+ <p>
+ I made a static website as an electronic learning system and forum,
+with the option for password protected posts and a controlled editing workflow,
+for free and without a dedicated server. This post has the highlights.
+ </p>
+ <a href="/posts/medical-humanities-org">Read more</a>
+ <hr style="opacity:0.2; margin-top: 3em">
+ <br>
+ <h2>
+ <a href="/posts/thanks">I made a thanks page</a>
+ </h2>
+ <p>
+ <strong>Last update:</strong> 2022-12-19.
+ </p>
+ <p>
+ A public, running journal of "hey, thanks"
+to the folks who make my life better, in big and small ways.
+Check it out <a href="/thanks">here</a>.
+ </p>
+ <a href="/posts/thanks">Read more</a>
+ <hr style="opacity:0.2; margin-top: 3em">
+ <br>
+ <h2>
+ <a href="/posts/mime">fix MIME Types to unbreak RSS feeds served by OpenBSDâs
+httpd(8)</a>
+ </h2>
+ <p>
+ <strong>Last update:</strong> 2022-11-13.
+ </p>
+ <p>
+ I've been getting back into RSS lately.
+Turns out, my own RSS feed was broken.
+ </p>
+ <a href="/posts/mime">Read more</a>
+ <hr style="opacity:0.2; margin-top: 3em">
+ <br>
+ <h2>
+ <a href="/posts/ugbsd">Upgrading out-of-date OpenBSD installs</a>
+ </h2>
+ <p>
+ <strong>Last update:</strong> 2022-11-11.
+ </p>
+ <p>
+ First of all, don't do how I do.
+Upgrade your installs regularly.
+OpenBSD makes it very easy.
+ </p>
+ <a href="/posts/ugbsd">Read more</a>
+ <hr style="opacity:0.2; margin-top: 3em">
+ <br>
+ <h2>
+ <a href="/posts/geocheatcode">geocheatcode</a>
+ </h2>
+ <p>
+ <strong>Last update:</strong> 2022-04-22.
+ </p>
+ <p>
+ Here is background and code
+for a trick I use to get
+Google to give me best-in-class guesses
+for latitude and longitude,
+despite goofy and/or downright bad location searches.
+ </p>
+ <a href="/posts/geocheatcode">Read more</a>
+ <hr style="opacity:0.2; margin-top: 3em">
+ <br>
+ <h2>
+ <a href="/posts/intake-2022-03-25">Intake presentation on candidal esophagitis</a>
+ </h2>
+ <p>
+ <strong>Last update:</strong> 2022-03-25.
+ </p>
+ <p>
+ candidal esophagitis, achalasia, H Pylori PUD
+ </p>
+ <a href="/posts/intake-2022-03-25">Read more</a>
+ <hr style="opacity:0.2; margin-top: 3em">
+ <br>
+ <h2>
+ <a href="/posts/employee-wifi">Set Up Enterprise Wifi on Arch Linux</a>
+ </h2>
+ <p>
+ <strong>Last update:</strong> 2021-09-17.
+ </p>
+ <p>
+ Most big institutions have guest and employee wifi networks.
+Guest wifi is usually fine, fast enough for the basics,
+but far inferior to employee wifi.
+On a custom-built OS, such as a fairly minimalist Linux distribution,
+getting the employee wifi to work
+can be a beast.
+ </p>
+ <a href="/posts/employee-wifi">Read more</a>
+ <hr style="opacity:0.2; margin-top: 3em">
+ <br>
+ <h2>
+ <a href="/posts/mr-2021">Morning Report 08/23/2021</a>
+ </h2>
+ <p>
+ <strong>Last update:</strong> 2021-08-23.
+ </p>
+ <p>
+ Diagnosis is... MDS/MPN/MF NOS.
+i.e., who knows.
+ </p>
+ <a href="/posts/mr-2021">Read more</a>
+ <hr style="opacity:0.2; margin-top: 3em">
+ <br>
+ <h2>
+ <a href="/posts/rmd-py">R Markdown is my spirit animal</a>
+ </h2>
+ <p>
+ <strong>Last update:</strong> 2019-10-20.
+ </p>
+ <p>
+ Turns out that a better way does exist, and it is R Markdown.
+ </p>
+ <a href="/posts/rmd-py">Read more</a>
+ <hr style="opacity:0.2; margin-top: 3em">
+ <br>
+ </div>
+ </main>
+ <div id="footnotes"></div>
+ <footer></footer>
+ </div>
+ </body>
+</html>
diff --git a/build/posts/intake-2022-03-25/index.html b/build/posts/intake-2022-03-25/index.html
@@ -0,0 +1,99 @@
+<!DOCTYPE html>
+<html lang="en">
+ <head>
+ <link rel="stylesheet" href="/style.css" type="text/css">
+ <meta charset="utf-8">
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
+ <link rel="stylesheet" type="text/css" href="/style.css">
+ <link rel="icon" href="data:image/svg+xml,<svg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 100 100%22><text y=%22.9em%22 font-size=%2290%22>đď¸</text></svg>">
+ <title></title>
+ </head>
+ <body>
+ <div id="page-wrapper">
+ <div id="header" role="banner">
+ <header class="banner">
+ <div id="banner-text">
+ <span class="banner-title"><a href="/">beauhilton</a></span>
+ </div>
+ </header>
+ <nav>
+ <a href="/about">about</a>
+<a href="/now">now</a>
+<a href="/thanks">thanks</a>
+<a class="nav-active" href="/posts">posts</a>
+<a href="https://notes.beauhilton.com">notes</a>
+<a href="https://talks.beauhilton.com">talks</a>
+<a href="https://git.beauhilton.com">git</a>
+<a href="/contact">contact</a>
+<a href="/atom.xml">rss</a>
+ </nav>
+ </div>
+ <main>
+ <h1>
+ Intake presentation on candidal esophagitis
+ </h1>
+ <p>
+ <time id="post-date">2022-03-25</time>
+ </p>
+ <h2>
+ cc: trouble swallowing and weight loss
+ </h2>
+ <p>
+ 28M w few weeks of trouble swallowing (gets stuck âright here,â
+points to mid-sternum), solid/liquids same, gradual over months-weeks,
+some vomiting w/o specific timing. Sometimes has pain when not eating.
+20lb weight loss over months. No skin lesions. ?thrush.
+ </p>
+ <h2>
+ PMHx/PSHx
+ </h2>
+ <p>
+ dx BPD, no other dx or procedures
+ </p>
+ <h2>
+ SHx
+ </h2>
+ <ul>
+ <li>
+ MSM w occasional use of protection, no PrEP
+ </li>
+ <li>
+ occ MJ use, no other substances
+ </li>
+ <li>
+ unemployed, lives w mom
+ </li>
+ <li>
+ no unusual hobbies or travel
+ </li>
+ </ul>
+ <h2>
+ PE
+ </h2>
+ <p>
+ HR 100, SBP 80 -> 100 w 500mL LR, AF cachectic (temporal,
+hypothenar wasting) +skin tenting diffuse abd tenderness
+ </p>
+ <h2>
+ w/u
+ </h2>
+ <p>
+ Hgb 10, MCV 88, WBC ~4, ANC 1500 BMP wnl Alb 3.4 HIV+, VL 15k, rest
+of STI -ve
+ </p>
+ <p>
+ CXR wnl (AP and lateral)
+ </p>
+ <h2>
+ dx
+ </h2>
+ <p id="post-excerpt">
+ candidal esophagitis, achalasia, H Pylori PUD
+ </p>
+ </main>
+ <div id="footnotes"></div>
+ <footer></footer>
+ </div>
+ </body>
+</html>
diff --git a/build/posts/medical-humanities-org/index.html b/build/posts/medical-humanities-org/index.html
@@ -0,0 +1,123 @@
+<!DOCTYPE html>
+<html lang="en">
+ <head>
+ <link rel="stylesheet" href="/style.css" type="text/css">
+ <meta charset="utf-8">
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
+ <link rel="stylesheet" type="text/css" href="/style.css">
+ <link rel="icon" href="data:image/svg+xml,<svg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 100 100%22><text y=%22.9em%22 font-size=%2290%22>đď¸</text></svg>">
+ <title></title>
+ </head>
+ <body>
+ <div id="page-wrapper">
+ <div id="header" role="banner">
+ <header class="banner">
+ <div id="banner-text">
+ <span class="banner-title"><a href="/">beauhilton</a></span>
+ </div>
+ </header>
+ <nav>
+ <a href="/about">about</a>
+<a href="/now">now</a>
+<a href="/thanks">thanks</a>
+<a class="nav-active" href="/posts">posts</a>
+<a href="https://notes.beauhilton.com">notes</a>
+<a href="https://talks.beauhilton.com">talks</a>
+<a href="https://git.beauhilton.com">git</a>
+<a href="/contact">contact</a>
+<a href="/atom.xml">rss</a>
+ </nav>
+ </div>
+ <main>
+ <h1>
+ medical-humanities.org
+ </h1>
+ <p>
+ This post is a work in progress.
+ </p>
+ <p>
+ <time id="post-date">2022-12-26</time>
+ </p>
+ <p id="post-excerpt">
+ I made a static website as an electronic learning system and forum,
+with the option for password protected posts and a controlled editing workflow,
+for free and without a dedicated server. This post has the highlights.
+ </p>
+ <p>
+ Itâs here: <a href="https://medical-humanities.org">medical-humanities.org</a>
+ </p>
+ <h2>
+ First, free as in beer
+ </h2>
+ <p>
+ New educational endeavors are, in my experience anyway, almost always
+bootstrapped. They start with an idea, passion, even erudition, but
+rarely with money.
+ </p>
+ <p>
+ This was no different.
+ </p>
+ <p>
+ Thereâs some funding coming in, including some Iâm grateful for as it
+will recompense the time I spent building the website, but overall this
+thing needs to run for free.
+ </p>
+ <p>
+ Because of that, I used the best suite of free tools I know of:
+GitHub, GitHub Actions, Netlifyâs free tier, NetlifyCMS, Hugo, and
+digital elbow grease.
+ </p>
+ <h2>
+ Second, free as in freedom (of speech, and the ability to choose
+what to share on the open web)
+ </h2>
+ <p>
+ While we have a strict policy against violating HIPAA, we also want
+an open forum that can be honest, vulnerable, critical if need be.
+ </p>
+ <p>
+ Though the students are encouraged to make their writing available
+for all to read, forming a kind of living magazine from the assignments,
+we also want to make it very easy to keep the assignments just within
+the group if desired.
+ </p>
+ <p>
+ This combination of desired features led to a need for selective
+password protection of certain pages, opted into or out of by each
+student writer.
+ </p>
+ <p>
+ Usually, password protection on a website is akin to a lock on a
+door, beyond which is a table that has the stuff you want to read. The
+routes to sensitive data are locked by the server, you need the key to
+get into the room, but once you get in the room you are free to wander
+over to the table and leaf through the dusty stack of papers. Since Iâm
+not paying for a server I fully control, this approach is not going to
+work. Every route is accessible by the whole internet, every door is
+open. So, instead of worrying about a door and a lock, we trade the
+dusty stack of papers for a Rubix cube with a million facets, containing
+a message that only comes to light when you match up all the pieces.
+Anybody can come and check out the toy, but unless you know the secret
+to solving it, itâs just a jumble.
+ </p>
+ <p>
+ To build the Rubix cube I used <a href="https://github.com/Greenheart/pagecrypt">Pagecrypt</a>, which
+encrypts individual HTML pages and provides a dialogue to enter a
+password to decrypt it. To mark which pages should be encrypted, I used
+a simple front-matter key, which a <code>grep</code> command picks out
+on every site rebuild.
+ </p>
+ <p>
+ Another neat aspect of this is that the <em>entire</em> page is
+encrypted, even the comments section, so if a student wants to make a
+post somewhat private and have a personal conversation with the other
+members of the class, itâs comfortably hidden from the view of the
+public internet.
+ </p>
+ </main>
+ <div id="footnotes"></div>
+ <footer></footer>
+ </div>
+ </body>
+</html>
diff --git a/build/posts/mime/index.html b/build/posts/mime/index.html
@@ -0,0 +1,145 @@
+<!DOCTYPE html>
+<html lang="en">
+ <head>
+ <link rel="stylesheet" href="/style.css" type="text/css">
+ <meta charset="utf-8">
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
+ <link rel="stylesheet" type="text/css" href="/style.css">
+ <link rel="icon" href="data:image/svg+xml,<svg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 100 100%22><text y=%22.9em%22 font-size=%2290%22>đď¸</text></svg>">
+ <title></title>
+ </head>
+ <body>
+ <div id="page-wrapper">
+ <div id="header" role="banner">
+ <header class="banner">
+ <div id="banner-text">
+ <span class="banner-title"><a href="/">beauhilton</a></span>
+ </div>
+ </header>
+ <nav>
+ <a href="/about">about</a>
+<a href="/now">now</a>
+<a href="/thanks">thanks</a>
+<a class="nav-active" href="/posts">posts</a>
+<a href="https://notes.beauhilton.com">notes</a>
+<a href="https://talks.beauhilton.com">talks</a>
+<a href="https://git.beauhilton.com">git</a>
+<a href="/contact">contact</a>
+<a href="/atom.xml">rss</a>
+ </nav>
+ </div>
+ <main>
+ <h1>
+ fix MIME Types to unbreak RSS feeds served by OpenBSDâs
+httpd(8)
+ </h1>
+ <p>
+ <time id="post-date">2022-11-13</time>
+ </p>
+ <h2>
+ RSS is life - but mine was broken
+ </h2>
+ <p>
+ As of today (2022-11-13) my website lives on an OpenBSD server hosted
+at <a href="https://vultr.com">vultr</a>.
+ </p>
+ <p>
+ Itâs great, delightfully simple and low-resource, robust, extendable,
+low-maintenance.
+ </p>
+ <p id="post-excerpt">
+ I've been getting back into RSS lately.
+Turns out, my own RSS feed was broken.
+ </p>
+ <p>
+ I knew it was janky, but would have had no idea how broken it was if
+not for the great folks on the <a href="https://datasette.io">datasette</a> Discord, one of whom reached
+out to let me know my RSS link wasnât working.
+ </p>
+ <p>
+ This could not stand!
+ </p>
+ <p>
+ Iâve been meaning to fix my RSS feed anyway, and now I had a good
+reason.
+ </p>
+ <h2>
+ fixing the file itself
+ </h2>
+ <p>
+ I ended up tearing out my previous RSS solution, <a href="https://romanzolotarev.com/rssg.html"><code>rssg</code></a>, which
+is great but made some assumptions about my siteâs layout that arenât
+true. I could have rewritten the script, but Iâm lazy and a little
+strapped for time, so I ended up replacing it with a hand-written RSS
+file.
+ </p>
+ <p>
+ (The RSS spec is easy enough to write by hand, a little copy-paste
+and replace to add a new article - at some point Iâll probably migrate
+to <code>hugo</code> or similar and hand off the feed creation to a more
+flexible script, but for now this works).
+ </p>
+ <p>
+ After I was certain the file format was fine and had the info I
+wanted, I thought I was good.
+ </p>
+ <h2>
+ fixing the MIME Type
+ </h2>
+ <p>
+ The kind soul who reached out to let me know the RSS feed was
+malformed reached out again to let me know he was now getting a MIME
+Type error.
+ </p>
+ <p>
+ My feedreader of choice, <code>newsboat</code>, is very forgiving of
+what it accepts, and didnât throw any errors when I tested it.
+<code>FreshRSS</code>, on the other hand, is more strict, and the feed
+would fail even though the file itself was fine.
+ </p>
+ <p>
+ I looked into it, and found out that <code>httpd(8)</code> only
+supports a handful of MIME Types by default, so my server was sending
+out <code>application/octet-stream</code> (a generic type) instead of
+the <code>rss+xml</code> type, and it was confusing the feedreader.
+ </p>
+ <h2>
+ add all the types
+ </h2>
+ <p>
+ Thank goodness, and as usual in OpenBSD, thereâs a very easy way to
+add all the relevant types one might need.
+ </p>
+ <p>
+ OpenBSD has an internal MIME declaration file you can link to from
+within <code>httpd.conf(5)</code>.
+ </p>
+ <p>
+ Hereâs the relevant bit, just chuck this on the end of the conf
+file:
+ </p>
+ <pre tabindex="0"><code class="language-shell">
+types {
+ include "/usr/share/misc/mime.types"
+}
+</code></pre>
+ <p>
+ And reload <code>httpd(8)</code>.
+ </p>
+ <h2>
+ great success
+ </h2>
+ <p>
+ Much thanks to my new friend on the Datasette Discord, the fantastic
+OpenBSD documentation, as always, and <a href="https://blog.lambda.cx/posts/openbsd-httpd-mime-types/">lambda.cx</a>
+for writing a post almost identical to mine (except that his had nothing
+to do with RSS - he was fixing PDF serving, which should now be fixed on
+my site as well).
+ </p>
+ </main>
+ <div id="footnotes"></div>
+ <footer></footer>
+ </div>
+ </body>
+</html>
diff --git a/build/posts/mr-2021/index.html b/build/posts/mr-2021/index.html
@@ -0,0 +1,420 @@
+<!DOCTYPE html>
+<html lang="en">
+ <head>
+ <link rel="stylesheet" href="/style.css" type="text/css">
+ <meta charset="utf-8">
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
+ <link rel="stylesheet" type="text/css" href="/style.css">
+ <link rel="icon" href="data:image/svg+xml,<svg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 100 100%22><text y=%22.9em%22 font-size=%2290%22>đď¸</text></svg>">
+ <title></title>
+ </head>
+ <body>
+ <div id="page-wrapper">
+ <div id="header" role="banner">
+ <header class="banner">
+ <div id="banner-text">
+ <span class="banner-title"><a href="/">beauhilton</a></span>
+ </div>
+ </header>
+ <nav>
+ <a href="/about">about</a>
+<a href="/now">now</a>
+<a href="/thanks">thanks</a>
+<a class="nav-active" href="/posts">posts</a>
+<a href="https://notes.beauhilton.com">notes</a>
+<a href="https://talks.beauhilton.com">talks</a>
+<a href="https://git.beauhilton.com">git</a>
+<a href="/contact">contact</a>
+<a href="/atom.xml">rss</a>
+ </nav>
+ </div>
+ <main>
+ <h1>
+ Morning Report 08/23/2021
+ </h1>
+ <p>
+ <time id="post-date">2021-08-23</time>
+ </p>
+ <p>
+ Details modified, generalized, and otherwise fudged to be
+HIPAA-compliant.
+ </p>
+ <h2>
+ HPI
+ </h2>
+ <p>
+ 72F with chest pain, abdominal pain, and constipation.
+ </p>
+ <p>
+ 2-3mo weight loss, night sweats.
+ </p>
+ <p>
+ 2-3wk +perineal ?cyst, initially ttp and hurt to walk, but now
+nontender.
+ </p>
+ <p>
+ ~1wk constipation, BRB on TP.
+ </p>
+ <p>
+ +crampy LLQ pain 8/10, x3-4 days, improves with positioning (supine
+with head raised somewhat, 3-4 pillows).
+ </p>
+ <p>
+ +LUQ and left-sided chest pain x1-2 days, radiates to L arm, not
+related to exertion, lasts a few minutes.
+ </p>
+ <h2>
+ OP Meds
+ </h2>
+ <ul>
+ <li>
+ duloxetine 60mg
+ </li>
+ <li>
+ ASA 81mg
+ </li>
+ <li>
+ melatonin 6mg
+ </li>
+ <li>
+ no notable allergies
+ </li>
+ </ul>
+ <h2>
+ PMSHx
+ </h2>
+ <ul>
+ <li>
+ TVH-BSO for fibroids and endometriosis (~20y ago)
+ </li>
+ <li>
+ hemorrhoids (no surgeries)
+ </li>
+ <li>
+ s/p Moderna COVID vaccine (~4wk ago)
+ </li>
+ <li>
+ UTD on mammograms, colonoscopies, no deviations from regular
+schedule
+ </li>
+ </ul>
+ <h2>
+ SHx
+ </h2>
+ <ul>
+ <li>
+ monogamous x45y, G2P2 sons, 6yo grandson, all healthy
+ </li>
+ <li>
+ never smoker
+ </li>
+ <li>
+ social EtOH, none this year
+ </li>
+ <li>
+ no non-Rx medicines
+ </li>
+ <li>
+ previously secretary
+ </li>
+ <li>
+ likes to DIY: painting, home crafts, gardening
+ </li>
+ </ul>
+ <h2>
+ FHx
+ </h2>
+ <ul>
+ <li>
+ M GM: uterine cancer (~40yo)
+ </li>
+ <li>
+ P GF: lung ca, unknown type (~70yo)
+ </li>
+ </ul>
+ <h2>
+ PE
+ </h2>
+ <ul>
+ <li>
+ VS: wnl
+ </li>
+ <li>
+ GEN: NAD
+ </li>
+ <li>
+ HEENT: no LAD
+ </li>
+ <li>
+ PULM: fine
+ </li>
+ <li>
+ CV: fine
+ </li>
+ <li>
+ ABD: NTND, +splenomegaly
+ </li>
+ <li>
+ GYN: 0.5cm lesion R side of anterior perineum, NT, freely
+mobile
+ </li>
+ <li>
+ NEURO: fine
+ </li>
+ </ul>
+ <h2>
+ Labs
+ </h2>
+ <ul>
+ <li>
+ Hgb 12.7
+ </li>
+ <li>
+ WBC 58.3
+ <ul>
+ <li>
+ 0 blasts
+ </li>
+ <li>
+ 0 atypical lymphs
+ </li>
+ <li>
+ <ul>
+ <li>
+ slight L shift
+ </li>
+ </ul>
+ </li>
+ </ul>
+ </li>
+ <li>
+ Plt 490
+ </li>
+ <li>
+ BMP grossly wnl (gluc 202, <a href="https://www.ashclinicalnews.org/viewpoints/editors-corner/illegitimi-epic-non-carborundum-dont-let-epic-bastards-grind/">Cr
+fine</a>)
+ </li>
+ <li>
+ LFTs fine
+ </li>
+ <li>
+ Trop <0.01
+ </li>
+ <li>
+ urate 10.4
+ </li>
+ <li>
+ phos 5.0
+ </li>
+ <li>
+ LDH 330
+ </li>
+ <li>
+ fibrinogen 355
+ </li>
+ </ul>
+ <h2>
+ Other studies
+ </h2>
+ <ul>
+ <li>
+ EKG wnl
+ </li>
+ <li>
+ CT-PE -ve
+ </li>
+ <li>
+ CT a/p wwo
+ <ul>
+ <li>
+ +10x7cm pelvic mass (central/R adnexum, exerting mass effect on
+sigmoid colon)
+ </li>
+ <li>
+ spleen ~20cm largest dimension w ?infarcts x2,
+ </li>
+ <li>
+ L internal iliac vein filling defects c/w nonocclusive DVT
+ </li>
+ </ul>
+ </li>
+ <li>
+ PET/CT
+ <ul>
+ <li>
+ splenomegaly with diffusely increased uptake, diffuse FDG uptake of
+axial and appendicular skeleton, mild uptake of abdominal pelvic lymph
+nodes, and minimal to mild uptake in the pelvic mass.
+ </li>
+ </ul>
+ </li>
+ </ul>
+ <h2>
+ Further notes on hospital course
+ </h2>
+ <ul>
+ <li>
+ CEA 1.7 (wnl), CA-125 52 (-)
+ </li>
+ <li>
+ urate 9.5 5d later w IVF, given rasburicase 3mg x1 -> urate
+3.8
+ </li>
+ <li>
+ phos similarly without movement, sevelamer eventually helpful
+ </li>
+ <li>
+ pelvic mass bx: smooth muscle
+ </li>
+ <li>
+ BMBx: hypercellular >90%, no blasts, +trilineage atypica >
+myeloid, MF-1 fibrosis.
+ </li>
+ <li>
+ JAK2 -ve, BCR/ABL -ve
+ </li>
+ <li>
+ NGS
+ <ul>
+ <li>
+ BRAF 5% (MGUS, MM, hairy cell, hystiocytic/dendritic cell, solid
+tumors, therapy-related myeloid neoplasms)
+ </li>
+ <li>
+ KRAS 39% (MDS, AML, MDS/MPN inc CMML and JMML)
+ </li>
+ <li>
+ BCOR 49% (?, possibly germline since allele fraction ~50%)
+ </li>
+ <li>
+ BCORL1 48% (ditto)
+ </li>
+ <li>
+ EZH2 93% (?, likely germline w loss of heterozygosity)
+ </li>
+ </ul>
+ </li>
+ </ul>
+ <h2>
+ And thenâŚ
+ </h2>
+ <p id="post-excerpt">
+ Diagnosis is... MDS/MPN/MF NOS.
+i.e., who knows.
+ </p>
+ <p>
+ Started on hydroxyurea and decitabine, c/b recurrent bacteremia, so
+currently tx on hold.
+ </p>
+ <hr>
+ <h2>
+ TLS
+ </h2>
+ <p>
+ The big idea, and a few finer points.
+ </p>
+ <p>
+ <a href="https://jamanetwork.com/journals/jamaoncology/fullarticle/2680750">![TLS](https://cdn.jamanetwork.com/ama/content_public/journal/oncology/937239/cpg180002fa.png?Expires=1632594426&Signature=y4M-w5gXSYJCAVMqGVEyfaPaqZocE9nGaWFnmr7GY7vuiD35l7dL-yJLWn4l3huTo4yBhri1nM0KjQ4dZBBjEYH5tPmKExEJ0D6V~WNou9Av-OEwhyQh79y9feHp790YWY6hTKRJJge958meDu~OmNl8Sl0Wn1N4buZZgVNMRdRds9fKbaDr4DhEdCbMgFbbLSeW9h8KIOm49Gog8FREQNntRaN1jILZgKPBTr9sUNv2BUiapZaLPO4teIf33LkJXcStx6o1VVsZJoP-G-sfMKG3ql1O~23E6LFJeirnMt5MYQdfk-LZlieuSw16HzqTXr-jBtOicDtyFzDJ9VcQ~g__&Key-Pair-Id=APKAIE5G5CRDK6RD3PGA
+=500x500 âJAMA Oncology 2018, TLS Reviewâ)</a>
+ </p>
+ <h3>
+ Cairo-Bishop classification system
+ </h3>
+ <p>
+ (Most of the following derived from <a href="https://www.asn-online.org/education/distancelearning/curricula/onco/Chapter4.pdf">Chapter
+4</a> of the American Society of Nephrology online <a href="https://www.asn-online.org/education/distancelearning/curricula/onco/">Onco-Nephrology
+curriculum</a>, which is good and great.)
+ </p>
+ <h3>
+ Laboratory TLS
+ </h3>
+ <p>
+ Definition: Chemotherapy plus the two or more of the following within
+3d before or 7d after initiation (so doesnât account for the spontaneous
+TLS seen in our patient).
+ </p>
+ <p>
+ | Metabolite/Electrolyte | Criterion | | :ââââââââ |
+:ââââââââââââââââââââ: | | Uric Acid | >=8 mg/dL or 25% increase from
+baseline | | Potassium | >=6mEq/L or 25% increase from baseline | |
+Phosphorus | >=4.5mg/dL or 25% increase from baseline | | Calcium |
+25% <em>decrease</em> from baseline |
+ </p>
+ <p>
+ The â25% increase/decreaseâ part is contested, as it may not be
+clinically meaningful if the value stays within the normal range.
+ </p>
+ <h3>
+ Clinical TLS
+ </h3>
+ <p>
+ | Laboratory TLS and one or more of | | :ââââââââââââââââ | |
+creatinine >= 1.5 ULN (Note: just use AKI criteria) | | cardiac
+arrhythmia or sudden death | | seizure |
+ </p>
+ <ul>
+ <li>
+ risk assessment
+ </li>
+ </ul>
+ <h3>
+ Treating TLS
+ </h3>
+ <p>
+ IVF, electrolytes, rasburicase.
+ </p>
+ <p>
+ Rasburicase is the subject of a recent âThings We Do for No
+Reason.â
+ </p>
+ <p>
+ <a href="https://www.journalofhospitalmedicine.com/jhospmed/article/241443/hospital-medicine/things-we-do-no-reasontm-rasburicase-adult-patients-tumor">Pay-walled
+article</a>, <a href="https://cdn.mdedge.com/files/s3fs-public/JHM01607424.PDF">PDF made
+available by the authors</a>
+ </p>
+ <p>
+ TL;DR: the evidence is thin, but could be reasonable to
+ </p>
+ <ul>
+ <li>
+ ppx w IVF and allopurinol for low-med risk,
+ </li>
+ <li>
+ use single 3mg dose rasburicase as ppx in high-risk disease (donât
+use weight-based dosing),
+ </li>
+ <li>
+ tx active TLS (laboratory or clinical) with aggressive fluid
+resuscitation and electrolyte mgmt, possibly single 3mg dose.
+ </li>
+ </ul>
+ <p>
+ Hard outcomes in support of rasburicase are generally lacking, e.g.
+consistently reducing renal injury, renal failure, length of stay.
+ </p>
+ <p>
+ It also seems like the classification criteria need revamping, with a
+larger N. Itâs been a while. However, like redefining fever, itâs
+difficult to get a clean slate, because we act on the established
+criteria so aggressively.
+ </p>
+ <hr>
+ <h2>
+ MDS/MPN overlap syndromes
+ </h2>
+ <p>
+ Not much to say here, except that the dx is not always clear-cut,
+even with BMBx and NGS data, so the clinical picture matters, and
+sometimes we have to shoot in the dark.
+ </p>
+ <hr>
+ <p>
+ Last updated: 2021-08-22
+ </p>
+ </main>
+ <div id="footnotes"></div>
+ <footer></footer>
+ </div>
+ </body>
+</html>
diff --git a/build/posts/oo-et-al/index.html b/build/posts/oo-et-al/index.html
@@ -0,0 +1,168 @@
+<!DOCTYPE html>
+<html lang="en">
+ <head>
+ <link rel="stylesheet" href="/style.css" type="text/css">
+ <meta charset="utf-8">
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
+ <link rel="stylesheet" type="text/css" href="/style.css">
+ <link rel="icon" href="data:image/svg+xml,<svg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 100 100%22><text y=%22.9em%22 font-size=%2290%22>đď¸</text></svg>">
+ <title></title>
+ </head>
+ <body>
+ <div id="page-wrapper">
+ <div id="header" role="banner">
+ <header class="banner">
+ <div id="banner-text">
+ <span class="banner-title"><a href="/">beauhilton</a></span>
+ </div>
+ </header>
+ <nav>
+ <a href="/about">about</a>
+<a href="/now">now</a>
+<a href="/thanks">thanks</a>
+<a class="nav-active" href="/posts">posts</a>
+<a href="https://notes.beauhilton.com">notes</a>
+<a href="https://talks.beauhilton.com">talks</a>
+<a href="https://git.beauhilton.com">git</a>
+<a href="/contact">contact</a>
+<a href="/atom.xml">rss</a>
+ </nav>
+ </div>
+ <main>
+ <h1>
+ good machine learning in medicine
+ </h1>
+ <p>
+ <time id="post-date">2022-12-29</time>
+ </p>
+ <p id="post-excerpt">
+ Because most machine learning in medicine sucks, I thought you might like to see an example of it done well.
+ </p>
+ <p>
+ <a href="https://doi.org/10.1056/CAT.22.0214">https://doi.org/10.1056/CAT.22.0214</a>
+ </p>
+ <p>
+ At least on the surface, this looks good. The article is paywalled so
+I havenât gotten to dig into their methods yet, but will update when I
+am able to read the whole thing. The approach is the thing Iâm keyed in
+on - implementation details of course matter, but the biggest problem
+with machine learning in medicine is not technique, but angle. Too
+often, ML is a new shiny, no meat on its bones (Iâm not discounting some
+of the delightful advances in e.g. automatic read of ophthalmologic
+images, thatâs kickass tech and truly practice-changing, but it does
+amount to image processing. The stuff Iâm talking about here is not a
+smarter camera, but automated gestalt handed to you by a mechanical
+Turk).
+ </p>
+ <h2>
+ ML is mostly for automation, but automating medicine is scary
+ </h2>
+ <p>
+ The big idea is that while machine learning is great for many things,
+the most important thing in industrial machine learning is teaching a
+machine to make independent decisions to make things easier for humans
+who already have too much cognitive load, or not enough hands, and a
+pesky attachment to oxygen, food, and sleep. E.g. if thereâs a knob
+someone needs to turn when a certain complex set of things happens, and
+sometimes the human forgets because they were occupied with all the
+switches and buttons instead, or they were on lunch, or sleeping off the
+Superbowl party, it sure would be nice to make an algorithm that can
+independently assess whether the complex condition has been sufficiently
+met, and go ahead and turn the knob for you (and maybe, while itâs at
+it, get you a few ibuprofen for that hangover headache).
+ </p>
+ <p>
+ In medicine we usually donât want a bot making independent decisions,
+but this paper from UPMC is a great example of the kind of independent
+decision we could stomach, or even welcome.
+ </p>
+ <h2>
+ build a model that is high-yield and low-risk
+ </h2>
+ <p>
+ This system builds a mortality model, which is fun in itself, but
+then goes to the next level to automate an e-consult to the palliative
+care team for patients at highest risk of mortality after discharge.
+ </p>
+ <p>
+ (Avati et al did the same basic thing at Stanford using a neural
+network, which is a fine technology, but their explanatory models were
+these shitty, ugly text-based tables that make you want to stab yourself
+in the eyes - <a href="https://doi.org/10.1186%2Fs12911-018-0677-8">https://doi.org/10.1186%2Fs12911-018-0677-8</a>).
+ </p>
+ <p>
+ Itâs beautiful. Nothing bad bubbles up if the algorithm falls down
+altogether (weâre just back where we were before the model went live).
+Nothing horrible happens if the algorithm makes a weird claim (every
+consult will still be triaged through a human). Possible positives are
+numerous. The conversation itself may be one of the most pivotal in the
+patientâs end-of-life journey, the hospital system will likely have
+reduced readmissions for cases that should be managed at home with
+hospice, and we will have more data to put towards figuring out how to
+identify the modifiable risk factors for early post-discharge death.
+ </p>
+ <p>
+ This team used the same tech I did when I built a mortality model for
+CCF, my favorite kind of algorithm, tree-based models called
+gradient-boosting machines (GBMs).
+ </p>
+ <h2>
+ interpretability - gotta do it, maybe they did
+ </h2>
+ <p>
+ What I canât see yet is if they took the next obvious step, which is
+to apply interpretability models on top. The main reason to use a GBM,
+in my mind, other than theyâre fast to train compared to neural networks
+and perform the same if thereâs enough data and you tune them properly,
+is that theyâre inherently compatible with the best meta-models that
+allow you to interrogate, both on a per-prediction and cohort level, why
+the model is saying whatever itâs saying - theyâre actually less of a
+black box than many standard statistical models, believe it or not.
+ </p>
+ <p>
+ The best tool for doing this is called SHAP, and the output is
+gorgeous - <a href="https://shap.readthedocs.io/en/latest/example_notebooks/overviews/An%20introduction%20to%20explainable%20AI%20with%20Shapley%20values.html">check
+it out</a>. We used it here, I think to lovely effect: <a href="https://www.nature.com/articles/s41746-020-0249-z">https://www.nature.com/articles/s41746-020-0249-z</a>,
+and itâs only gotten better since then)
+ </p>
+ <p>
+ The other thing I love about pairing the interpretability models with
+the predictive models is now you have something you can really learn
+from, and, hence, teach from.
+ </p>
+ <h2>
+ but, will this worsen burnout?
+ </h2>
+ <p>
+ The main issue, (given that the model works and has been proven
+trustworthy) and which I donât think Iâve heard anyone talk about in
+great depth, is the new alert fatigue this kind of system would make,
+for already overworked palliative care teams, and what mitigations they
+are taking to keep the firehose of new possible consults manageable. One
+thing we could do, and I have faith our house staff could do it well,
+would be to implement the same system and have it first trigger an alert
+to the primary team, with a recommendation to have the convo and reach
+out to pall care if there is any hint of a loose end, or an automated
+pivot to pall care if the notes donât document GOC within a certain
+number of days of the alert (or could pop up one of those boxes we love
+so⌠much with a radio button asking you if youâve had âthe talkâ
+yet).
+ </p>
+ <p>
+ Anywho, Iâm not saying I want to actually do this project, Iâve got
+other stuff going on, but if youâre reading this youâre the kind of
+person who is interested in what tech can do for a hospital system, and
+this is a model (ha) combination of the very cutting edge of tech and
+the oldest technique we have, which is to offer a hand to the dying and
+with them face the abyss. My vision of the future is less Skynet, cold
+and isolated, but rather humans forefront, with machines that run in the
+background to nudge us into and help make room for more (non-digital,
+non-Apple mediated) facetime.
+ </p>
+ </main>
+ <div id="footnotes"></div>
+ <footer></footer>
+ </div>
+ </body>
+</html>
diff --git a/build/posts/pagecrypt/index.html b/build/posts/pagecrypt/index.html
@@ -0,0 +1,176 @@
+<!DOCTYPE html>
+<html lang="en">
+ <head>
+ <link rel="stylesheet" href="/style.css" type="text/css">
+ <meta charset="utf-8">
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
+ <link rel="stylesheet" type="text/css" href="/style.css">
+ <link rel="icon" href="data:image/svg+xml,<svg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 100 100%22><text y=%22.9em%22 font-size=%2290%22>đď¸</text></svg>">
+ <title></title>
+ </head>
+ <body>
+ <div id="page-wrapper">
+ <div id="header" role="banner">
+ <header class="banner">
+ <div id="banner-text">
+ <span class="banner-title"><a href="/">beauhilton</a></span>
+ </div>
+ </header>
+ <nav>
+ <a href="/about">about</a>
+<a href="/now">now</a>
+<a href="/thanks">thanks</a>
+<a class="nav-active" href="/posts">posts</a>
+<a href="https://notes.beauhilton.com">notes</a>
+<a href="https://talks.beauhilton.com">talks</a>
+<a href="https://git.beauhilton.com">git</a>
+<a href="/contact">contact</a>
+<a href="/atom.xml">rss</a>
+ </nav>
+ </div>
+ <main>
+ <h1>
+ password protecting static web pages
+ </h1>
+ <p>
+ <time id="post-date">2023-01-12</time>
+ </p>
+ <p id="post-excerpt">
+ Static site generators, by and large, do not have support for password protecting individual pages.
+This post shows a strategy that works for any SSG and does not require server access controls.
+ </p>
+ <p>
+ <a href="https://github.com/Greenheart/pagecrypt">PageCrypt</a> is
+the tool I went with. Itâs a TypeScript library that uses the native
+<code>Web Crypto API</code> to encrypt html pages, stuff the encrypted
+gobbledigook behind a simple password form, and decrypt the page when
+the correct key is given.
+ </p>
+ <p>
+ Iâm using the CLI version, but there are also native TypeScript and
+Node.js versions.
+ </p>
+ <p>
+ The basic idea is this, taken from their docs:
+ </p>
+ <pre tabindex="0"><code class="language-sh">npx pagecrypt <span class="hl opt"><</span>src<span class="hl opt">> <</span>dest<span class="hl opt">> [</span>password<span class="hl opt">] [</span>options<span class="hl opt">]</span>
+</code></pre>
+ <p>
+ Below is an excerpt from a <code>package.json</code> for a Hugo site
+I maintain. First I build the site, then run the <code>postbuild</code>
+command, which stitches together a piece of code that creates a list of
+all the pages weâd like to encrypt and another bit that does the
+encryption proper.
+ </p>
+ <pre tabindex="0"><code class="language-json"><span class="hl kwa">{</span>
+ <span class="hl kwc">"make-pw-files-file"</span><span class="hl opt">:</span> <span class="hl sng">"grep -rlF 'password_required: true' content | sed s+</span><span class="hl esc">\\</span><span class="hl sng">.md+</span><span class="hl esc">\\</span><span class="hl sng">/index.html+g | sed s+content/+public/+g > pw_file"</span><span class="hl opt">,</span>
+ <span class="hl kwc">"protect-files"</span><span class="hl opt">:</span> <span class="hl sng">"cat pw_file | while read f || [[ -n $f ]]; do npx pagecrypt $f $f $PAGECRYPT; done"</span><span class="hl opt">,</span>
+ <span class="hl kwc">"postbuild"</span><span class="hl opt">:</span> <span class="hl sng">"npm run -s make-pw-files-file && npm run -s protect-files "</span><span class="hl opt">,</span>
+<span class="hl kwa">}</span>
+</code></pre>
+<br>
+ <h2>
+ <code>make-pw-files-file</code>
+ </h2>
+ <pre tabindex="0"><code class="language-sh"><span class="hl kwc">grep</span> <span class="hl kwb">-rlF</span> <span class="hl sng">'password_required: true'</span> content <span class="hl opt">|</span> <span class="hl kwc">sed</span> s<span class="hl opt">+</span><span class="hl esc">\\</span>.md<span class="hl opt">+</span><span class="hl esc">\\</span><span class="hl opt">/</span>index.html<span class="hl opt">+</span>g <span class="hl opt">|</span> <span class="hl kwc">sed</span> s<span class="hl opt">+</span>content<span class="hl opt">/+</span>public<span class="hl opt">/+</span>g <span class="hl opt">></span> pw_file
+</code></pre>
+ <p>
+ This part uses a few standard Unix commands, the ubiquitous
+<code>grep</code> and <code>sed</code>.
+ </p>
+ <p>
+ First it creates a list of markdown source files that have the header
+<code>password_required: true</code>.
+ </p>
+ <p>
+ Hereâs how that part works:
+ </p>
+ <pre tabindex="0"><code class="language-sh"><span class="hl kwc">grep</span> <span class="hl kwb">-rlF</span> <span class="hl sng">"text you're looking for"</span> path<span class="hl opt">/</span>to<span class="hl opt">/</span>files<span class="hl opt">/</span>of<span class="hl opt">/</span>interest
+</code></pre>
+ <ul>
+ <li>
+ <code>-r</code> or <code>--recursive</code> searches though the
+sub-directories of whichever path you gave it
+ </li>
+ <li>
+ <code>l</code> or <code>--files-with-matches</code> prints the
+filenames of any files that match the search
+ </li>
+ <li>
+ <code>F</code> or <code>--fixed-strings</code> searches for the
+exact string you ask for, not using regular expressions
+ </li>
+ </ul>
+ <p>
+ This will output something like:
+ </p>
+ <pre tabindex="0"><code class="language-sh">content<span class="hl opt">/</span>file0.md
+content<span class="hl opt">/</span>file7.md
+content<span class="hl opt">/</span>yet_another_file.md
+</code></pre>
+ <p>
+ Next it passes that to <code>sed</code>, which replaces
+<code>.md</code> with <code>/index.html</code>* resulting in:
+ </p>
+ <pre tabindex="0"><code class="language-sh">content<span class="hl opt">/</span>file<span class="hl opt">/</span>index.html
+content<span class="hl opt">/</span>file<span class="hl num">7</span><span class="hl opt">/</span>index.html
+content<span class="hl opt">/</span>yet_another_file<span class="hl opt">/</span>index.html
+</code></pre>
+ <p>
+ * youâd have to adjust this command if you arenât using a
+page-per-folder style
+ </p>
+ <p>
+ Then it switches out <code>content/</code> with <code>public/</code>,
+leading to the final list:
+ </p>
+ <pre tabindex="0"><code class="language-sh">public<span class="hl opt">/</span>file<span class="hl opt">/</span>index.html
+public<span class="hl opt">/</span>file<span class="hl num">7</span><span class="hl opt">/</span>index.html
+public<span class="hl opt">/</span>yet_another_file<span class="hl opt">/</span>index.html
+</code></pre>
+ <p>
+ and sends those to a file.
+ </p>
+ <p>
+ Sending the list to a file is not necessary, could just pipe it again
+to the stuff in <code>protect-files</code>, but I was getting itchy at
+how long the command was getting.
+ </p>
+ <br>
+ <h2>
+ <code>protect-files</code>
+ </h2>
+ <pre tabindex="0"><code class="language-sh"><span class="hl kwc">cat</span> pw_file <span class="hl opt">|</span> <span class="hl kwa">while</span> <span class="hl kwb">read</span> f <span class="hl opt">|| [[</span> <span class="hl kwb">-n</span> <span class="hl kwd">$f</span> <span class="hl opt">]];</span> <span class="hl kwa">do</span> npx pagecrypt <span class="hl kwd">$f $f $PAGECRYPT</span><span class="hl opt">;</span> <span class="hl kwa">done</span>
+</code></pre>
+ <p>
+ This part emits the contents of <code>pw_file</code>, then loops
+through each line (<code>while read f || [[ -n $f ]]</code>) and
+encrypts the corresponding file (<code>do npx pagecrypt</code>), finally
+saving it back to itself (<code>$f $f</code>).
+ </p>
+ <p>
+ <code>$PAGECRYPT</code> is an environment variable that specifies the
+password.
+ </p>
+ <p>
+ You could also set a password-per-page, either auto-generated (but
+youâd have to figure out how to get that password to your users), or
+using something like another header value in the <code>.md</code> files
+that you grep for and save somewhere. For my use case, this is simpler
+and scales well.
+ </p>
+ <br>
+ <h2>
+ and thatâs it
+ </h2>
+ <p>
+ As always, <a href="../../contact">let me know</a> if you have any
+questions or know of a better way.
+ </p>
+ </main>
+ <div id="footnotes"></div>
+ <footer></footer>
+ </div>
+ </body>
+</html>
diff --git a/build/posts/pixel6screen/index.html b/build/posts/pixel6screen/index.html
@@ -0,0 +1,210 @@
+<!DOCTYPE html>
+<html lang="en">
+ <head>
+ <link rel="stylesheet" href="/style.css" type="text/css">
+ <meta charset="utf-8">
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
+ <link rel="stylesheet" type="text/css" href="/style.css">
+ <link rel="icon" href="data:image/svg+xml,<svg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 100 100%22><text y=%22.9em%22 font-size=%2290%22>đď¸</text></svg>">
+ <title></title>
+ </head>
+ <body>
+ <div id="page-wrapper">
+ <div id="header" role="banner">
+ <header class="banner">
+ <div id="banner-text">
+ <span class="banner-title"><a href="/">beauhilton</a></span>
+ </div>
+ </header>
+ <nav>
+ <a href="/about">about</a>
+<a href="/now">now</a>
+<a href="/thanks">thanks</a>
+<a class="nav-active" href="/posts">posts</a>
+<a href="https://notes.beauhilton.com">notes</a>
+<a href="https://talks.beauhilton.com">talks</a>
+<a href="https://git.beauhilton.com">git</a>
+<a href="/contact">contact</a>
+<a href="/atom.xml">rss</a>
+ </nav>
+ </div>
+ <main>
+ <h1>
+ Pixel 6 DIY screen replacement, with fingerprint reader calibration
+using Linux
+ </h1>
+ <p>
+ <time id="post-date">2023-09-19</time>
+ </p>
+ <p id="post-excerpt">
+ The internet, up to now, says you need Windows or MacOS to calibrate the Pixel's fingerprint reader after installing a new screen and digitizer.
+The internet, up to now, was wrong.
+ </p>
+ <h2>
+ Physical install
+ </h2>
+ <p>
+ My wifeâs Pixel 6âs screen stopped working. Phone seemed to be ok
+otherwise.
+ </p>
+ <p>
+ We looked at the cost of replacing the phone vs repairing the
+screen.
+ </p>
+ <p>
+ A similarly capable phone would cost quite a bit more than the
+replacement screen kit, which was ~$130 from <a href="https://www.ifixit.com/products/google-pixel-6-screen-genuine">iFixit</a>.
+ </p>
+ <p>
+ So we bought the replacement screen, watched a few videos on YouTube,
+and were off to the races.
+ </p>
+ <p>
+ The tear-down and physical installation were easy. Kudos to Google
+for making the Pixels easy to work on. I wonât give much detail here:
+just use the videos, whichever ones have a bunch of views.
+ </p>
+ <p>
+ I did waste the included screen adhesive on the first go-around,
+because I didnât realize that the broken screen I removed had been
+separated from its frame (so the old frame was still installed and I
+installed the adhesive to the its top, rather than in the phone casing
+where it belongs, and found out when the phone wouldnât click back
+together with the new screen). It was about $10, including shipping, for
+a second adhesive (also iFixit). Fit like a glove.
+ </p>
+ <p>
+ Total $140, and Verizon sent us a free new Pixel 7 anyway (long
+story), so now my wife has the 7 and I upgraded from my old Pixel 2XL to
+this refurbâd 6. Dang, what an upgrade. Even though the Pixel 6 is
+widely considered the dud of the group, Iâm loving it.
+ </p>
+ <h2>
+ Fingerprint reader calibration is needed
+ </h2>
+ <p>
+ After it was all installed and working well, the next hurdle was
+recalibrating the fingerprint reader. The fingerprint reader is part of
+the new screen, and needs calibrated, or it will not even attempt to
+work (seems more an âactivationâ than a âcalibration,â no?).
+ </p>
+ <p>
+ The website Google provides for calibration is <a href="https://pixelrepair.withgoogle.com/udfps">https://pixelrepair.withgoogle.com/udfps</a>.
+If you look around the internet for troubleshooting related to this
+tool, youâll see a number of old posts recounting various problems, most
+of which seem to have been ironed out by this writing.
+ </p>
+ <p>
+ However, the one problem I couldnât find a fix or happy update for
+was how to use that website if youâre not running Windows or MacOS.
+ </p>
+ <p>
+ <a href="https://www.reddit.com/r/GooglePixel/comments/xq82ri/pixel_6_fingerprint_calibration/">This
+Redditor couldnât get it working on Linux or Windows, bad luck?</a>.
+ </p>
+ <p>
+ <a href="https://issuetracker.google.com/issues/217589152?pli=1">Anon
+is very angry at Google for not supporting Linux for the calibration
+(ctrl-F âlinuxâ to find)</a>.
+ </p>
+ <p>
+ We no longer have anything but Linux/OpenBSD systems in the house
+(while I love FOSS and feel glee in this, it is not entirely on purpose,
+and I donât hate Windows or MacOS - my wifeâs MBP met an early demise at
+the thrown milk cup of a boisterous toddler, or I would have tried that
+machine first to avoid the possible headache of ironing out a solution
+for Linux for a [hopefully] one-time computing event.).
+ </p>
+ <p>
+ The udfps website was finding my phone, but refusing to go further. I
+was in fastboot. Browser didnât matter (tried OG google-chrome-stable,
+vivaldi-stable, firefox). USB-A vs USB-C computer-side connection didnât
+matter (some folks mentioned needing USB-A, so I tried). Activating
+Android developer mode didnât help, and activating USB debugging within
+the developer options didnât either.
+ </p>
+ <p>
+ I saw some posts talking about installing USB drivers to get udfps to
+work for Windows machines, so decided to poke around and see if maybe it
+was a driver issue on Linux as well.
+ </p>
+ <p>
+ It (probably) was.
+ </p>
+ <h2>
+ Android build tools to the rescue
+ </h2>
+ <p>
+ On Arch Linux (these tools are widely available, distro doesnât
+matter, this is just what I used):
+ </p>
+ <pre tabindex="0"><code class="language-sh"><span class="hl slc"># enable multilib - see link below</span>
+paru <span class="hl slc"># make sure things are up to date generally</span>
+paru <span class="hl kwb">-S</span> android<span class="hl kwb">-tools</span> android<span class="hl kwb">-sdk-build-tools</span> <span class="hl slc"># includes adb and other goodies</span>
+reboot
+</code></pre>
+ <p>
+ Re multilib - not sure if this is strictly needed - see <a href="https://wiki.archlinux.org/title/android#Android_Emulator">https://wiki.archlinux.org/title/android#Android_Emulator</a>.
+ </p>
+ <p>
+ After grabbing the Android build tools listed above and rebooting,
+the website found my phone and ran the calibration software without a
+hitch. The website didnât seem to work prior to rebooting, and Iâm a
+lazy cretin/wizened olâ wannabe sysadmin, so fancy a reboot to fix all
+of lifeâs woes.
+ </p>
+ <p>
+ The phone does need at least one reboot to activate the calibration
+and enable the fingerprint reader, but the calibration software tells
+you that, no secret magic here.
+ </p>
+ <p>
+ I donât recall if I used vivaldi-stable or google-chrome-stable to
+run udfps, but I think it was the prior (I bet any Chromium-based
+browser would work, provided the right system tools are in place).
+ </p>
+ <p>
+ I also canât remember if I used USB-A to USB-C or dual-sided USB-C,
+but I think it was the dual USB-C.
+ </p>
+ <p>
+ I do think developer mode and USB debugging active on the phone are
+required, but Iâm not completely certain.
+ </p>
+ <p>
+ I did this all on a Thinkpad T14s.
+ </p>
+ <p>
+ In any case, fingerprint unlock is a go!
+ </p>
+ <p>
+ Almost too easy.
+ </p>
+ <h2>
+ Manual clean up - what, you think this is NixOS?
+ </h2>
+ <p>
+ You probably wonât need these tools again, at least not for a long
+while, so:
+ </p>
+ <pre tabindex="0"><code class="language-sh">paru <span class="hl kwb">-R</span> android<span class="hl kwb">-tools</span> android<span class="hl kwb">-sdk-build-tools</span> <span class="hl slc"># about 156MiB, not much, but it's the principle of the thing</span>
+sudo pacman <span class="hl kwb">-R</span> <span class="hl kwd">$(comm -12 <(pacman -Qq | sort)</span> <span class="hl opt"><(</span>pacman <span class="hl kwb">-Slq</span> multilib <span class="hl opt">|</span> <span class="hl kwc">sort</span><span class="hl opt">))</span> <span class="hl slc"># undo the multilib stuff</span>
+sudo <span class="hl kwc">sed</span> <span class="hl kwb">-i</span> <span class="hl sng">'s/\[multilib\]/\#\[multilib\]/'</span> <span class="hl opt">/</span>etc<span class="hl opt">/</span>pacman.conf <span class="hl slc"># undo more of the multilib stuff</span>
+paru <span class="hl slc"># finish undoing the multilib stuff</span>
+</code></pre>
+ <h2>
+ Next steps
+ </h2>
+ <h3>
+ ? đŚ ?
+ </h3>
+ <p>
+ idk, maybe.
+ </p>
+ </main>
+ <div id="footnotes"></div>
+ <footer></footer>
+ </div>
+ </body>
+</html>
diff --git a/build/posts/pp-tech-infra/index.html b/build/posts/pp-tech-infra/index.html
@@ -0,0 +1,212 @@
+<!DOCTYPE html>
+<html lang="en">
+ <head>
+ <link rel="stylesheet" href="/style.css" type="text/css">
+ <meta charset="utf-8">
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
+ <link rel="stylesheet" type="text/css" href="/style.css">
+ <link rel="icon" href="data:image/svg+xml,<svg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 100 100%22><text y=%22.9em%22 font-size=%2290%22>đď¸</text></svg>">
+ <title></title>
+ </head>
+ <body>
+ <div id="page-wrapper">
+ <div id="header" role="banner">
+ <header class="banner">
+ <div id="banner-text">
+ <span class="banner-title"><a href="/">beauhilton</a></span>
+ </div>
+ </header>
+ <nav>
+ <a href="/about">about</a>
+<a href="/now">now</a>
+<a href="/thanks">thanks</a>
+<a class="nav-active" href="/posts">posts</a>
+<a href="https://notes.beauhilton.com">notes</a>
+<a href="https://talks.beauhilton.com">talks</a>
+<a href="https://git.beauhilton.com">git</a>
+<a href="/contact">contact</a>
+<a href="/atom.xml">rss</a>
+ </nav>
+ </div>
+ <main>
+ <h1>
+ Patient-facing slide decks
+ </h1>
+ <p>
+ <time id="post-date">2024-03-23</time>
+ </p>
+ <p id="post-excerpt">
+ While I plan on being a physician-scientist forever, I'm not going to work in academia.
+Over the past few years I've put together very cool infrastructure for giving academic talks (click "talks" above),
+and it was making me sad that it might not get much use after I leave the university.
+But then, a ray of sunshine: Why not use my slide deck infrastructure to help in patient conversations?
+ </p>
+ <h2>
+ talks.beauhilton.com
+ </h2>
+ <p>
+ Academics give lots of presentations. I gave at least one 15min
+presentation per week in medical school, and still expect a few 15-45min
+presentations per half-year in fellowship.
+ </p>
+ <p>
+ PowerPoint was long ago eschewed in favor of online-first
+presentation platforms, typically Google Slides. (Eventually Office365
+came out and PowerPoint came on par with Google Slides, but I had
+already moved away.) No emailing around files and accidentally sending
+the old version, or running into an incompatible version of the
+software, and the presentation could be modified all the way up to (and,
+occasionally, during) the event itself. All you need is an internet
+connection.
+ </p>
+ <p>
+ Eventually I wanted to move away from proprietary infrastructure
+altogether, so started using <a href="https://sli.dev">Slidev</a>.
+Slidev is geared toward developers, and as such uses all
+industry-standard web technologies, nicely packaged up to make it easy
+to go from a text file to a nice-looking presentation.
+ </p>
+ <p>
+ The defaults are great, and, since itâs all web standards, the sky is
+the limit as far as customization.
+ </p>
+ <p>
+ The presentation lives in a single text file (markdown). This makes
+it easily versionable, tracked by git and backed up to [GitHub, GitLab,
+self-hosted git solutions, etc.]. Since I keep a copy on GitHub, the
+ease of editing while on-the-go approaches the ease of editing a Google
+Slide (all you need is an internet connection and to be logged in).
+ </p>
+ <p>
+ Once the presentation is online, Iâm only ever a click or two away
+from accessing it. I make sure everything is HIPAA-compliant, and to the
+public internet it goes.
+ </p>
+ <p>
+ Itâs been great for making talks in my academic program, and, when I
+thought I would stay in academia forever, it made sense to me to spend
+the time to build out my own infrastructure and subdomain for talks.
+ </p>
+ <h2>
+ emphasizing the âphysicianâ in âphysician-scientistâ
+ </h2>
+ <p>
+ Recently, I realized that Iâd be happier shifting the
+physician-scientist balance more toward physician and less toward
+scientist, at least as measured by days per week dedicated to each.
+While I think Iâll always see myself as as physician-scientist, my
+future oncology job (hopefully not âjobs,â but who knows) will be in
+private practice, where Iâll see patients 3 or 4 days per week and do
+research with the other 0.5-2 days that remain.
+ </p>
+ <p>
+ (The following three paragraphs are an aside on how much time is
+spent on what in academia, and touches on why I decided to leave. I
+should probably move this out and expand it into its own post. It
+doesnât have much to do with the core of this one.)
+ </p>
+ <p>
+ Classic academia is usually patient care 0.5-1 day per week, research
+the remainder - but thatâs somewhat misleading, since academics
+typically have a number of dedicated inpatient weeks, which may or may
+not put a damper on the ability to do research during that time,
+depending on how busy they get and whether itâs July (with brand new
+trainees) or June (with seasoned trainees). Even accounting for this, it
+doesnât even out to the number of patient-care days per year in private
+practice, not by a long shot, but for most folks it isnât so freed from
+day-to-day patient care as it is advertised on the tin. There are a some
+academics who do a few weeks of inpatient care per year and thatâs it,
+no clinic, but thatâs the exception.
+ </p>
+ <p>
+ You also pay your own salary out of your research funding, so thereâs
+a large time burden of not doing research, but writing grants to
+convince funders that your research is cool and worth funding. With the
+research I do and am interested in continuing, a university
+infrastructure adds little, where it isnât actively working against me,
+and Iâd rather pay my salary, which will be much bigger, from taking
+care of people in clinic than working through the weekend to meet grant
+deadlines (while I may also still be on call for the hospital).
+ </p>
+ <p>
+ The university infrastructure is great for basic and clinical
+science, and some flavors of data science, but my scientometric stuff is
+truly better if done vigilante-style, not attached to academiaâs
+politics, and predictive modeling/etc. is available and important to
+private practice collectives (AON, USON, OneOnc), some of whom have more
+robust data infrastructure than the universities do. My most successful
+clinical data science project thus far was actually done under the
+purview of Business Intelligence for Cleveland Clinic, working with the
+Center for Clinical Artificial Intelligence, and the publication was the
+side project - this is much more in line with what I may find myself
+doing with clinical data science with one of the big three onc groups:
+do the thing, do it well, and if you feel like publishing it, gravy. The
+scientometric stuff is more classic research, where publication itself
+is the deliverable, but even here Iâm much more interested in publishing
+a living website and tool than a paper in a journal.
+ </p>
+ <p>
+ (And now, back to our regularly scheduled program.)
+ </p>
+ <p>
+ Outside of academia, thereâs a high chance I wonât give presentations
+nearly as often as I am accustomed to. At first, this made me
+simultaneously happy (presentations are so. much. work.) and sad (aww,
+my cute little talks website will just gather dust. Poor buddy). Then! I
+went to a dinner meeting to learn about renal cancer and get paid to
+hang out with friends and eat, and most of the physicians talked about
+bringing up primary data to help in discussions with patients. Most
+physicians do this when they think it will help, and it certainly wasnât
+the first time Iâd heard people talk about it, but the timing was right.
+I realized that I have a great use for my talks website, and that Iâve
+already been using it this way for some time.
+ </p>
+ <h2>
+ talks in clinic - data for shared decision-making
+ </h2>
+ <p>
+ At least 3 or 4 times in the past few months, Iâve been having
+discussions with patients about their prognosis and various options, and
+wished I had the graphs to show them without having to poke around
+Google and possibly fight with a paywall, then realized I just gave a
+talk on the same thing, the talk is on my website, and it has those
+graphs.
+ </p>
+ <p>
+ It was very useful to go over the primary data with the patient (not
+everybody wants to see this stuff, but a significant number do), and
+having a talk I gave to reference immediately lent an additional modicum
+of trust to the conversation (most trust is built from showing you care,
+but another portion is built from showing you know what youâre
+doing).
+ </p>
+ <p>
+ Hearing the physicians at that dinner meeting talk about how theyâre
+using primary data in their shared decision-making, combined with my
+recent decision to go into private practice, and thoughts about what to
+do with my website, led me to the following idea: for diseases Iâm most
+interested in, and for diseases I treat the most, it will be very useful
+to have a talk I made and maintain, geared toward patients, to
+immediately pull up and have available in clinic, and have the link to
+give the patient for review, particularly in those conversations with
+their loved ones where theyâre trying to remember all the stuff you said
+to make a group decision. It would also be easy and useful to have a
+slide describing the regimen and its schedule, especially if the way
+weâre giving it doesnât quite match up with the published regimen (e.g.
+one of the many regimens that is written as â2 on, 1 offâ but weâre
+giving it every other week instead).
+ </p>
+ <p>
+ Iâm definitely not going to make a talk for every disease or use one
+in every conversation, that would be insane and impossible to maintain,
+but if I pay attention to the data I use repeatedly, a 30-60min session
+adding some of these to a slide deck with a little explanation would
+more than carry its weight in future conversations.
+ </p>
+ </main>
+ <div id="footnotes"></div>
+ <footer></footer>
+ </div>
+ </body>
+</html>
diff --git a/build/posts/rmd-py/index.html b/build/posts/rmd-py/index.html
@@ -0,0 +1,225 @@
+<!DOCTYPE html>
+<html lang="en">
+ <head>
+ <link rel="stylesheet" href="/style.css" type="text/css">
+ <meta charset="utf-8">
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
+ <link rel="stylesheet" type="text/css" href="/style.css">
+ <link rel="icon" href="data:image/svg+xml,<svg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 100 100%22><text y=%22.9em%22 font-size=%2290%22>đď¸</text></svg>">
+ <title></title>
+ </head>
+ <body>
+ <div id="page-wrapper">
+ <div id="header" role="banner">
+ <header class="banner">
+ <div id="banner-text">
+ <span class="banner-title"><a href="/">beauhilton</a></span>
+ </div>
+ </header>
+ <nav>
+ <a href="/about">about</a>
+<a href="/now">now</a>
+<a href="/thanks">thanks</a>
+<a class="nav-active" href="/posts">posts</a>
+<a href="https://notes.beauhilton.com">notes</a>
+<a href="https://talks.beauhilton.com">talks</a>
+<a href="https://git.beauhilton.com">git</a>
+<a href="/contact">contact</a>
+<a href="/atom.xml">rss</a>
+ </nav>
+ </div>
+ <main>
+ <h1>
+ R Markdown is my spirit animal
+ </h1>
+ <p>
+ <time id="post-date">2019-10-20</time>
+ </p>
+ <h2>
+ update 2022-12-02
+ </h2>
+ <p>
+ The R Markdown folks have a new project called <a href="https://quarto.org">Quarto</a>, looks like it does all the things
+RMD does plus more.
+ </p>
+ <h2>
+ original post
+ </h2>
+ <p>
+ In a [previous post]({% post_url 2019-06-10-python-write-my-paper %})
+I talked about how easy it is, if youâre already doing your own stats
+anyway in some research project, to have a Python script output
+paragraphs with all the stats written out and updated for you to add
+into your paper.
+ </p>
+ <p>
+ The main problem with the approach I outlined was how to get those
+nicely updated paragraphs into the document you are sharing with
+colleagues.
+ </p>
+ <p>
+ Medicine, in particular, seems wed to Microsoft Word documents for
+manuscripts. Word does not have a great way to include text from
+arbitrary files, forcing the physician-scientist to manually copy and
+paste those beautifully automated paragraphs. As I struggled with this,
+I thought (here cue Raymond Hettinger), âThere must be a better
+way.â
+ </p>
+ <p id="post-excerpt">
+ Turns out that a better way does exist, and it is R Markdown.
+ </p>
+ <p>
+ Though I was at first resistant to learning about R Markdown, mostly
+because I am proficient in Python and thought the opportunity cost for
+learning R at this point would be too high, as soon as I saw it demoed I
+changed my tune. Hereâs why.
+ </p>
+ <h2>
+ Writing text
+ </h2>
+ <ul>
+ <li>
+ R Markdown is mostly markdown.
+ <ul>
+ <li>
+ Markdown is by far the easiest way to write plaintext documents,
+especially if you want to apply formatting later on without worrying
+about the specifics while youâre writing (e.g. <code>#</code> just
+specifies a header - you can decide how you want the headers to look
+later, and that styling will automatically be applied).
+ </li>
+ <li>
+ Plaintext is beautiful. It costs nearly nothing in terms of raw
+storage, and is easy to keep within a version control system. Markdown
+plaintext is human-readable whether or not the styling has been applied.
+Your ideas will never be hidden in a proprietary format that requires
+special software to read.
+ </li>
+ <li>
+ I had been transitioning to writing in Markdown anyway, so +1 for R
+Markdown.
+ </li>
+ </ul>
+ </li>
+ <li>
+ R Markdown is also a little LaTeX.
+ <ul>
+ <li>
+ LaTeX is <a href="https://tex.stackexchange.com/questions/1319/showcase-of-beautiful-typography-done-in-tex-friends">gorgeous</a>
+and wonderful, the most flexible and expressive of all the typesetting
+tools (though not as fast as our old friend GroffâŚ). It also has a
+steeper learning curve than Markdown, and is not so pretty on the screen
+in its raw form. R Markdown lets you do the bulk of your work in simple
+Markdown, then seamlessly invoke LaTeX when you need something a little
+fancier.
+ </li>
+ </ul>
+ </li>
+ <li>
+ R Markdown is also a little HTML.
+ <ul>
+ <li>
+ HTML is also expressive, and can be gorgeous and wonderful. It is a
+pain to write. As with LaTeX, you can simply drop in some HTML where you
+need it, and R Markdown will deal with it as necessary.
+ </li>
+ </ul>
+ </li>
+ <li>
+ R Markdown is academic-friendly.
+ <ul>
+ <li>
+ Citations and formatting guidelines for different journals are the
+tedious banes of any academicâs existence. R Markdown has robust support
+for adding in citations that will be properly formatted in any desired
+style, just by changing a tag at the top of the document. Got a
+rejection from Journal 1 and want to submit to Journal 2, which has a
+completely different set of citation styles and manuscript formatting?
+NBD.
+ </li>
+ </ul>
+ </li>
+ </ul>
+ <h2>
+ Writing code
+ </h2>
+ <p>
+ R Markdown, as the name implies, can also run R code. Any analysis
+you can dream of in R can be included in your document, and you can
+choose whether you want to show the code and its output, the output
+alone, or the code alone. People will think you went through all the
+work of making that figure, editing it in PowerPoint, screenshotting it
+to a .png, then dropping that .png file into your manuscript, but the
+truth is⌠you scripted all of that, so the manuscript itself made the
+.png and included it where it needed to go.
+ </p>
+ <p>
+ R Markdown is by no means restricted to R code. This is the killer
+app that won me over. Simply by specifying that a given code block is
+Python, and installing a little tool (<code>reticulate</code>) that
+allows R to interface with Python, I can run arbitrary Python code
+within the document and capture the output however I want. That results
+paragraph? Sure. Fancy images of predictions from my machine learning
+model? But of course.
+ </p>
+ <p>
+ If you donât want to use any R code ever, thatâs fine. R Markdown
+doesnât mind. Use SAS, MATLAB (via Octave), heck, even bash scripts -
+the range of language support is fantastic.
+ </p>
+ <h2>
+ Working with friends
+ </h2>
+ <p>
+ R Markdown can be compiled to pretty much any format you can dream
+of. My current setup simultaneously puts out an HTML document (that can
+be opened in any web browser), a PDF (because I love PDFs), and (AND!) a
+.docx Word file, all beautifully formatted, on demand, whenever I hit my
+keyboard shortcut. I can preview the PDF or HTML as I write, have a
+.docx to send to my PI, and life is good.
+ </p>
+ <p>
+ Also, because you can write in any programming language, you can
+easily collaborate between researchers that are comfortable in different
+paradigms. You can pass data back and forth between your chosen
+languages (for me, R and Python), either directly or by saving
+intermediate data to a format that both languages can read.
+ </p>
+ <h2>
+ Automating tasks
+ </h2>
+ <p>
+ Many analyses and their manuscripts, especially if they use similar
+techniques (e.g. survival modeling), are rather formulaic. Many
+researchers have scripts they keep around and tweak for new analyses
+revolving around the same basic subject matter or approach. With R
+Markdown, your entire manuscript becomes a runnable program, further
+automating the boring parts of getting research out into the open.
+ </p>
+ <p>
+ One of the <a href="https://www.youtube.com/watch?v=MIlzQpXlJNk">first
+introductions</a> I had to R Markdown shared the remarkable idea of
+setting the file to run on a regular basis, generating a report based on
+any updated data, and then sending this report to all the interested
+parties automatically. While much academic work could not be so fully
+automated, parts of it certainly can be.
+ </p>
+ <p>
+ Perhaps your team is building a database for outcomes in a given
+disease, and has specified the analysis in great detail beforehand. One
+of my mentors gives the advice that in any project proposal you should
+go as far as to mock up the results section, including all figures, so
+you make sure you are collecting the right data. If this was done in an
+R Markdown document rather than a simple Word document, you could have
+large parts of the template manuscript become the real manuscript as the
+database fleshes out over time. Then when itâs done, look over the data,
+make additions and subtractions as needed, write the discussion
+sections, and send it in.
+ </p>
+ </main>
+ <div id="footnotes"></div>
+ <footer></footer>
+ </div>
+ </body>
+</html>
diff --git a/build/posts/s1/index.html b/build/posts/s1/index.html
@@ -0,0 +1,316 @@
+<!DOCTYPE html>
+<html lang="en">
+ <head>
+ <link rel="stylesheet" href="/style.css" type="text/css">
+ <meta charset="utf-8">
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
+ <link rel="stylesheet" type="text/css" href="/style.css">
+ <link rel="icon" href="data:image/svg+xml,<svg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 100 100%22><text y=%22.9em%22 font-size=%2290%22>đď¸</text></svg>">
+ <title></title>
+ </head>
+ <body>
+ <div id="page-wrapper">
+ <div id="header" role="banner">
+ <header class="banner">
+ <div id="banner-text">
+ <span class="banner-title"><a href="/">beauhilton</a></span>
+ </div>
+ </header>
+ <nav>
+ <a href="/about">about</a>
+<a href="/now">now</a>
+<a href="/thanks">thanks</a>
+<a class="nav-active" href="/posts">posts</a>
+<a href="https://notes.beauhilton.com">notes</a>
+<a href="https://talks.beauhilton.com">talks</a>
+<a href="https://git.beauhilton.com">git</a>
+<a href="/contact">contact</a>
+<a href="/atom.xml">rss</a>
+ </nav>
+ </div>
+ <main>
+ <h1>
+ Drugs we canât get: S1
+ </h1>
+ <p>
+ <time id="post-date">2024-03-29</time>
+ </p>
+ <p id="post-excerpt">
+ There are a number of interesting drugs used in the global market that,
+ for one reason or another, do not have FDA approval and are therefore inaccessible
+ in the US, at least outside of clinical trials. S1 is one of them: a better capecitabine.
+ </p>
+ <h2>
+ What is S1?
+ </h2>
+ <p>
+ S1 is the muy sexy common name of a drug manufactured by Taiho
+Pharmaceutical in Japan. (It did get a brand name a few years after it
+went to market: âTeysunoâ).
+ </p>
+ <p>
+ It is a combination of three drugs, all in a pill.
+ </p>
+ <p>
+ The first is a prodrug, called tegafur or ftorafur (âFTâ in many
+papers), that converts to 5-fluorouracil (5-FU) in the body.
+Capecitabine, the only oral 5-FU agent we use in the US, is also a 5-FU
+prodrug.
+ </p>
+ <p>
+ The second is gimeracil, a drug that inhibits the enzyme
+dyhydropyrimidine dehydrogenase (DPD). This reduces tegafur breakdown in
+the GI tract, which allows it to make its way into the bloodstream.
+(Patients with inherent DPD deficiency cannot break down drugs in this
+family once they make it into the bloodstream, leading to potentially
+lethal side effects from 5-FU and itâs cousins - gimeracil is only
+creating a local DPD deficiency in the gut. Brilliant.).
+ </p>
+ <p>
+ The third is oteracil, which prevents 5-FU activation in the GI
+tract, reducing off-target local adverse effects (capecitabine has
+horrible GI side effects in many patients). Also brilliant.
+ </p>
+ <p>
+ <img src="/images/s1-is.png" alt="The FU drugs, including S1">
+ </p>
+ <p>
+ This is a very rationally conceived drug. Using a prodrug with a
+companion that lets it survive long enough to be absorbed lets us use an
+oral formulation. Oral is so much more convenient than a pump the
+patient has to wear for a couple of days (and which sometimes
+malfunctions in strange ways). In capecitabine we already have an oral
+5-FU agent that works. However, many of the adverse effects of
+capecitabine are local to the GI tract, leading to dose reductions or
+drug switch in many cases, so combining something like capecitabine with
+something that reduces badness in this location also makes a lot of
+sense.
+ </p>
+ <p>
+ This rationality bears out in clinical practice as well (this is not
+always the case - a popular saying amongst clinical trialists is âthe
+road to hell is paved with biological plausibility.â The majority of
+ideas that work out well in a petri dish or animal model do not work out
+at all when we try them in humans. Hence clinical trials.). Trial after
+trial have established S1 as the standard of care in many relevant
+regimens in Asia, pretty much any situation where we would use
+infusional 5-FU or capecitabine in the US. (Iâm sure thereâs nuance
+here, but it appears generally true.) S1 works well, is easier to give,
+and is better tolerated.
+ </p>
+ <h2>
+ So why donât we have it in the US?
+ </h2>
+ <p>
+ Good. Question.
+ </p>
+ <p>
+ Itâs not that it has been completely ignored by researchers in the
+West, as youâll see. The Europeans can get it. And Iâm sure Taiho would
+love to expand their market to the US.
+ </p>
+ <p>
+ Truthfully, I canât say I know all the reasons. These things are
+complex and the FDAâs reasons are not always readily apparent or written
+clearly (though they often are - I have equally strong respect and
+disdain for that particular agency, but the trend in my feeling is
+toward respect. I used to feel only disdain. The more I learn what and
+how they do All The Things, the more I see a bunch of humans really
+trying to do their best, rationally to the extent possible, in difficult
+situations, with many conflicting interested parties).
+ </p>
+ <p>
+ The clearest reason that S1 is a Big Deal in Asia but unknown here is
+a difference in the prevalence of certain versions of enzymes that
+convert the tegafur to 5-FU.
+ </p>
+ <p>
+ <em>Aside: Iâm going to use the terribly imprecise terms âAsianâ and
+âWesterner.â The studies in this area use the terms âAsianâ and
+âCaucasian,â which is worse, as in, âeven more wrong than the
+alternative I chose.â There is huge genetic and biologic variability
+within and across the places we call âAsiaâ and âThe West,â and, if
+humans do anything, humans migrate. This biped was made for walkinâ, and
+thatâs just what it do. Donât take these terms too seriously.</em>
+ </p>
+ <p>
+ Folks from Asian countries tend to have a set of CYP2A6 polymorphisms
+that lead to much slower conversion of this particular drug, or, more
+appropriately said (Taiho is a Japanese company, after all), Westerners
+tend to have a CYP2A6 reality that makes them convert tegafur too damn
+fast. Dose-finding studies correspond well with the known differences in
+enzymes: the recommended daily dose in Asia is 40mg/m2 twice a day,
+whereas the Western dose is 30mg/m2 twice a day.
+ </p>
+ <p>
+ There are other findings from the dosing studies that donât precisely
+line up with differences in processing after absorption. The most severe
+toxicity in Asian populations is bone marrow suppression, whereas it is
+GI toxicity in Western populations. I donât know why the oteracil
+doesnât pull its weight in the guts of Westerners. Then again, it might
+be entirely unrelated to oteracil, I have no idea.
+ </p>
+ <h2>
+ The Dutch, as usual, are leading the way
+ </h2>
+ <p>
+ The most interesting study to-date using S1 in Westerners was done in
+the Netherlands and published as the â<a href="https://doi.org/10.1093/annonc/mdx122">SALTO Study</a>.â
+ </p>
+ <p>
+ (S1 has approvals in Europe, though for a much shorter list of
+indications compared with Japan and China, so folks governed by the EMA
+can get it and play around, whereas there is no provision at all for
+getting it in the US outside of clinical trial - it has orphan
+designation but is not approved for anything)
+ </p>
+ <p>
+ They looked at 161 patients who qualified for 5-FU-based monotherapy
+for metastatic colorectal cancer. Combination drug therapy is the
+standard of care frontline therapy in the metastatic setting, but
+monotherapy is a reasonable option for older and more frail patients,
+which is who this trial enrolled. They were randomized to S1 vs
+capecitabine, and compared efficacy as well as rates of adverse effects.
+Efficacy was comparable, and most adverse effects were also comparable,
+with the notable exception of hand-foot syndrome. The rates of this were
+45% in the S1 group, vs 73% in the capecitabine group. They were also
+better able to maintain dose intensity in the S1 group, which is a good
+surrogate for the <em>je ne sais quoi</em> of all the little things that
+being on therapy does to a person but arenât fully captured in the other
+metrics. Though hand-foot syndrome is not a lethal problem, it can be a
+huge quality-of-life problem, particularly when the point of therapy is
+palliative in the first place.
+ </p>
+ <p>
+ The same group also published a <a href="https://doi.org/10.1080/0284186X.2016.1278459">retrospective</a>
+on 52 patients who had hand-foot syndrome on capecitabine and were
+switched to S1, which they then tolerated beautifully. The graph below
+is from this paper. âBeforeâ is on the left, and âafterâ is on the
+right. The difference is stark.
+ </p>
+ <p>
+ <img src="/images/s1-cape-hfs.jpg" alt="HFS improves significantly after switching from capecitabine to S1">
+ </p>
+ <h2>
+ Why Iâd love to have S1 in the US
+ </h2>
+ <p>
+ One tough part of my job is telling somebody who wants to continue
+therapy but isnât tolerating the âeasiestâ form of therapy, even after
+dose reduction and maximizing supportive care, that their only options
+are to continue to push forward with the poorly tolerated therapy (to a
+degree - Iâm not afraid to say no and refuse to prescribe if I feel like
+Iâm hurting someone), or stop cancer-directed therapy altogether. I love
+hospice and the services it provides, and many patients are relieved to
+make this move, but a significant portion are not. Having another option
+in the armamentarium, something else to try for the patient who wants to
+try something, especially in such a commonly used class of drugs, would
+be great. S1 has clear benefit for patients who have an indication for
+5-FU-based therapy but have developed significant hand-foot syndrome,
+and I would use it in this situation if I had it on formulary.
+ </p>
+ <p>
+ Also, though I practice in âthe West,â not everyone here hails from
+the Caucasus
+ </p>
+ <p>
+ <em>âHarumph,â he roared, suddenly on his feet and staring down at
+me, his tweedâs elbow patches straining as he assumed the pose of a
+portly academic Superman, âmost Caucasians do not, in fact, hail from
+the Caucasus. Very few do. That was proto-eugenic Neo-Platonic foolery.
+If you use the term Caucasian, you have to accept the fallacious
+philosophy upon which it was built, and you are equally obligated to
+accept the terms from which it is inextricable, namely âCaucasoid,â
+âMongoloid,â âNegroid.â Good sir, I do not believe this was your purpose
+nor desire. If you must use an imprecise term, at least let it be one of
+the cardinal directions, which are not unladen but are not actively
+destructive of scientific and societal progress, good sense, morality,
+and decency.â The final word was given in a whisper.</em>
+ </p>
+ <p>
+ so having S1 as an up-front option for folks of Asian ancestry would
+be nice - itâs a clearly better drug in Asian countries, and I doubt it
+was the ground underfoot that made the difference.
+ </p>
+ <p>
+ An idea related to this, with perhaps more biological justification
+than a nebulous definition of ancestry, would be to deploy CYP2A6
+screening of some sort to select folks who may most benefit from S1
+rather than capecitabine.
+ </p>
+ <p>
+ This could be done in several ways, all of which have precedence in
+other types of screening and at some centers. Ideally youâd do trials to
+determine if any of these actually pan out (see above, on the path to
+hell). Theyâre all extrapolations.
+ </p>
+ <p>
+ One option would be to screen all patients with known Asian ancestry,
+as is done in some centers for various indications (e.g. GPD deficiency
+screening for patients of African descent prior to starting potentially
+problematic drugs).
+ </p>
+ <p>
+ Another would be to screen only those who have had dose-limiting GI
+intolerance to capecitabine, to make an argument that perhaps they would
+tolerate S1 better. (Though, in reality, if S1 was suddenly available
+and someoneâs GI adverse effects were particularly horrendous on
+capecitabine, Iâd probably talk with the patient about it and try it if
+they want, rather than what I might normally do, which would be to try
+infusional 5-FU or a drug from a different class, depending on the
+specifics of the situation. I think an empiric approach would be
+appropriate, as it wouldnât require fancy testing which may or may not
+actually be predictive, and is what we do most of the time with other
+cognate drugs, even if they have class-effect toxicities - some folks
+just tolerate Drug A better than Drug B).
+ </p>
+ <p>
+ A third option would be to screen everyone to try and find folks with
+compatible CYP2A6 to select for up-front S1. This is expensive. Only
+fancy places do population-wide pharmacogenomics (etc.) in practice, and
+there are deep debates about how much good this actually does. But hey,
+cool if you can get it, especially if you have data to back it up, but
+even then make youâd have to make sure you donât take it without a grain
+or six of salt.
+ </p>
+ <p>
+ As it is, even if I wanted to test out some of these ideas, or see if
+the Dutch prospective study replicates, Iâd have to go through an insane
+approval process, and it would be expensive and time consuming. If the
+drug was approved and available, studies like the Dutch retrospective
+become almost trivially easy.
+ </p>
+ <p>
+ One day. Maybe when the Big Boss of the FDA starts reading my blog
+and sends me a golden goose for my genius, along with a Christmas basket
+full of S1 and Cadbury. (Thatâs how it works, right?)
+ </p>
+ <h2>
+ Until next time
+ </h2>
+ <p>
+ This kind of thing is one of my favorites, a thoroughly enjoyable
+line of inquiry - what drugs are out there that I canât get? What
+inspiration is there to be had from the practice patterns of other
+countries? Would those drugs and patterns work here - why or why
+not?
+ </p>
+ <p>
+ It pairs nicely with my obsession with the histories of therapies for
+cancers. Love me a critical genealogy,* love me some heteroglossia and
+unfinalizability. Butler and Bakhtin ftw.
+ </p>
+ <hr>
+ <p>
+ * I idly wondered if there had been much movement on that term, which
+I got at least thirdhand from Judith Butler, and it looks like thereâs
+going to be a cool book coming out in the next year or two: <a href="https://absolute-disruption.com/a-genealogy-of-genealogy/">A
+Genealogy of Genealogy</a>
+ </p>
+ </main>
+ <div id="footnotes"></div>
+ <footer></footer>
+ </div>
+ </body>
+</html>
diff --git a/build/posts/subsonic-cli/index.html b/build/posts/subsonic-cli/index.html
@@ -0,0 +1,290 @@
+<!DOCTYPE html>
+<html lang="en">
+ <head>
+ <link rel="stylesheet" href="/style.css" type="text/css">
+ <meta charset="utf-8">
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
+ <link rel="stylesheet" type="text/css" href="/style.css">
+ <link rel="icon" href="data:image/svg+xml,<svg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 100 100%22><text y=%22.9em%22 font-size=%2290%22>đď¸</text></svg>">
+ <title></title>
+ </head>
+ <body>
+ <div id="page-wrapper">
+ <div id="header" role="banner">
+ <header class="banner">
+ <div id="banner-text">
+ <span class="banner-title"><a href="/">beauhilton</a></span>
+ </div>
+ </header>
+ <nav>
+ <a href="/about">about</a>
+<a href="/now">now</a>
+<a href="/thanks">thanks</a>
+<a class="nav-active" href="/posts">posts</a>
+<a href="https://notes.beauhilton.com">notes</a>
+<a href="https://talks.beauhilton.com">talks</a>
+<a href="https://git.beauhilton.com">git</a>
+<a href="/contact">contact</a>
+<a href="/atom.xml">rss</a>
+ </nav>
+ </div>
+ <main>
+ <h1>
+ Command-line interfaces for self-hosted music
+ </h1>
+ <p>
+ <time id="post-date">2023-09-28</time>
+ </p>
+ <p id="post-excerpt">
+ Self-hosting a music server is great.
+Listening to the tunes via the command line is the way.
+ </p>
+ <h2>
+ Subsonic-compatible server backbone
+ </h2>
+ <p>
+ I have <a href="https://www.navidrome.org/">Navidrome</a> installed
+(via Docker on NixOS). Itâs very nice.
+ </p>
+ <p>
+ With a reverse proxy, <a href="https://tailscale.com/">tailscale</a>,
+and LetsEncrypt set up, I can access it via any Subsonic-compatible
+music player at <a href="https://music.beauslab.casa">https://music.beauslab.casa</a> (this
+URL is available only on my tailnet, so it will 404 for everyone
+else).
+ </p>
+ <h2>
+ Desktop GUI interfaces
+ </h2>
+ <p>
+ <a href="https://sublimemusic.app/">Sublime-music</a> is pretty good.
+I also often find myself using the Navidrome web UI.
+ </p>
+ <p>
+ (On mobile, <a href="https://symfonium.app/">Symfonium</a> (paid) or
+<a href="https://substreamerapp.com/">SubStreamer</a> on Android and <a href="http://michaelsapps.dk/playsubapp/">play:Sub</a> (paid) or <a href="https://substreamerapp.com/">SubStreamer</a> on iOS are my go-tos,
+though there are many <a href="http://www.subsonic.org/pages/apps.jsp">others</a>)
+ </p>
+ <h2>
+ CLI interfaces: contenders (STMP, jellycli, sksonic)
+ </h2>
+ <p>
+ If Iâm in programming mode, I prefer command-line interfaces,
+particularly if they let me use keyboard muscle-memory (i.e. vi
+bindings).
+ </p>
+ <p>
+ As such, I tried a few CLI front-ends to access and play my
+Navidrome-served tunes.
+ </p>
+ <p>
+ Iâm sure there are others.
+ </p>
+ <p>
+ <a href="https://github.com/wildeyedskies/stmp/tree/main">STMP</a> is
+clean and works well, but doesnât have vi bindings yet.
+ </p>
+ <p>
+ <a href="https://github.com/tryffel/jellycli/tree/master">jellycli</a> is
+the most polished, and uses vi bindings, but even so the in-app nav is
+finicky and doesnât quite fit my brain (though that might be mostly due
+to conflicts with other terminal keybindings I have set up).
+ </p>
+ <p>
+ <a href="https://gitlab.com/yvelon/sksonic">sksonic</a> is a
+suckless-style implementation in C, e.g. edit config.h and recompile. It
+works, but isnât polished enough for daily usage (though I donât expect
+it to be - the author states itâs a personal project, and I think
+theyâre doing a great job, so will keep an eye on it). Partial vi-key
+support, could easily be added given the suckless style.
+ </p>
+ <h2>
+ CLI interfaces: the one I picked (ncmpcpp with mopidy backend)
+ </h2>
+ <p>
+ After these, I found myself wishing that I could use <a href="https://github.com/ncmpcpp/ncmpcpp">ncmpcpp</a> and hook it up to
+my Subsonic back end.
+ </p>
+ <p>
+ And then I realized: hey, this is a Linux TUI, and ncmpcpp is just a
+front-end for <a href="https://www.musicpd.org/">mpd</a>, of course you
+can switch out mpd for something thatâs Subsonic-aware.
+ </p>
+ <p>
+ ncmpcpp is beautiful, polished, fast, with great vi-key support, and
+Iâve been using it for years for local music playback.
+ </p>
+ <p>
+ <a href="https://mopidy.com/">mopidy</a> is a fairly drop-in mpd
+replacement that is pluggable, with a number of awesome <a href="https://mopidy.com/ext/">extensions</a>.
+ </p>
+ <p>
+ I should have looked here first. Câest la vie.
+ </p>
+ <p>
+ I perused a few blog posts to get a sense of what to do:
+ </p>
+ <ul>
+ <li>
+ <a href="https://fsylum.net/blog/setting-up-ncmpcpp-mopidy-spotify-arch-linux/">fsylumâs
+post</a>
+ </li>
+ <li>
+ <a href="https://blog.deepjyoti30.dev/using-spotify-with-ncmpcpp-mopidy-linux">Deepjyoti
+Barmanâs post</a>
+ </li>
+ <li>
+ <a href="https://www.digitalneanderthal.com/post/ncmpcpp/">Digital
+Neanderthalsâ post</a> (what a great online moniker, well done - his
+physical setup is also a delight, sheer cyberdeck practicality)
+ </li>
+ </ul>
+ <p>
+ Itâs pretty easy.
+ </p>
+ <p>
+ The rad thing is that you can get a unified frontend for all your
+sources, e.g. Subsonic, Spotify, local files, YouTube, SoundCloud, etc.,
+just install a plugin and add a config section and youâre off to the
+races, never having to leave the terminal.
+ </p>
+ <blockquote>
+ <p>
+ Source selection (could have many more items here).
+ </p>
+ </blockquote>
+ <p>
+ <img src="/images/ncmpcpp-mopidy-selector.png" alt="Source selection">
+ </p>
+ <blockquote>
+ <p>
+ Artist selection.
+ </p>
+ </blockquote>
+ <p>
+ <img src="/images/ncmpcpp-mopidy-full.png" alt="Preview">
+ </p>
+ <blockquote>
+ <p>
+ Track view.
+ </p>
+ </blockquote>
+ <p>
+ <img src="/images/ncmpcpp-mopidy-tracks.png" alt="Track view">
+ </p>
+ <h2>
+ Set up
+ </h2>
+ <h3>
+ Install the things
+ </h3>
+ <p>
+ My main laptop still runs Arch (btw). If I ever switch to NixOS on
+this machine, or add this setup to the NixOS server, Iâll probably make
+a new post with the Nix way to do this. I bet itâs hardly different,
+other than the <code>.nix</code> files.
+ </p>
+ <p>
+ e.g. <code>paru -S ncmpcpp mopidy mopidy-subidy mopidy-mpd</code>
+ </p>
+ <p>
+ Also uninstall and stop mpd, if youâre using it.
+ </p>
+ <h3>
+ Config files
+ </h3>
+ <p>
+ (most of the whatâs in the files below is unnecessary for this post,
+but Iâve never been mad that someone posted their whole config)
+ </p>
+ <p>
+ (also note that the mopidy config file doesnât allow # comments, I
+just used them for ease of reading with syntax highlighting, will have
+to delete prior to actually using)
+ </p>
+ <p>
+ <code>~/.config/ncmpcpp/config</code>
+ </p>
+ <pre tabindex="0"><code class="language-sh">ncmpcpp_directory <span class="hl opt">=</span> ~<span class="hl opt">/</span>.config<span class="hl opt">/</span>ncmpcpp
+lyrics_directory <span class="hl opt">=</span> ~<span class="hl opt">/</span>.config<span class="hl opt">/</span>lyrics
+
+progressbar_look <span class="hl opt">= -></span>
+display_volume_level <span class="hl opt">=</span> no
+
+autocenter_mode <span class="hl opt">=</span> <span class="hl kwc">yes</span>
+message_delay_time <span class="hl opt">=</span> <span class="hl num">1</span>
+
+playlist_display_mode <span class="hl opt">=</span> columns
+playlist_editor_display_mode <span class="hl opt">=</span> columns
+browser_display_mode <span class="hl opt">=</span> columns
+
+media_library_primary_tag <span class="hl opt">=</span> album_artist
+media_library_albums_split_by_date <span class="hl opt">=</span> no
+
+ignore_leading_the <span class="hl opt">=</span> <span class="hl kwc">yes</span>
+ignore_diacritics <span class="hl opt">=</span> <span class="hl kwc">yes</span>
+external_editor <span class="hl opt">=</span> vim
+use_console_editor <span class="hl opt">=</span> <span class="hl kwc">yes</span>
+</code></pre>
+ <p>
+ <code>~/.config/mopidy/mopidy.conf</code>
+ </p>
+ <pre tabindex="0"><code class="language-sh"><span class="hl opt">[</span>core<span class="hl opt">]</span>
+cache_dir <span class="hl opt">=</span> <span class="hl kwd">$XDG_CACHE_DIR</span><span class="hl opt">/</span>mopidy
+config_dir <span class="hl opt">=</span> <span class="hl kwd">$XDG_CONFIG_DIR</span><span class="hl opt">/</span>mopidy
+data_dir <span class="hl opt">=</span> <span class="hl kwd">$XDG_DATA_DIR</span><span class="hl opt">/</span>mopidy
+max_tracklist_length <span class="hl opt">=</span> <span class="hl num">10000</span>
+restore_state <span class="hl opt">=</span> true
+
+<span class="hl opt">[</span><span class="hl kwc">file</span><span class="hl opt">]</span> <span class="hl slc"># might switch out for mopidy-local at some point, adds search support via sqlite metadata archive</span>
+enabled <span class="hl opt">=</span> true
+media_dirs <span class="hl opt">=</span>
+ ~<span class="hl opt">/</span>media<span class="hl opt">/</span>tunes
+excluded_file_extensions <span class="hl opt">=</span>
+ .directory
+ .html
+ .jpeg
+ .jpg
+ .log
+ .nfo
+ .pdf
+ .png
+ .txt
+ .<span class="hl kwc">zip</span>
+show_dotfiles <span class="hl opt">=</span> false
+follow_symlinks <span class="hl opt">=</span> false
+metadata_timeout <span class="hl opt">=</span> <span class="hl num">1000</span>
+
+<span class="hl opt">[</span>m3u<span class="hl opt">]</span>
+playlists_dir <span class="hl opt">=</span> <span class="hl kwd">$XDG_CONFIG_DIR</span><span class="hl opt">/</span>mopidy<span class="hl opt">/</span>playlists
+
+<span class="hl opt">[</span>mpd<span class="hl opt">]</span>
+enabled <span class="hl opt">=</span> true
+hostname <span class="hl opt">=</span> <span class="hl num">127.0.0.1</span>
+port <span class="hl opt">=</span> <span class="hl num">6600</span> <span class="hl slc"># defaults ftw - no change to ncmpcpp config needed if defaults are kept</span>
+max_connections <span class="hl opt">=</span> <span class="hl num">20</span>
+connection_timeout <span class="hl opt">=</span> <span class="hl num">60</span>
+
+<span class="hl opt">[</span>subidy<span class="hl opt">]</span>
+enabled <span class="hl opt">=</span> true
+url <span class="hl opt">=</span> https<span class="hl opt">://</span>music.beauslab.casa
+username <span class="hl opt">=</span> admin
+password <span class="hl opt">=</span> admin <span class="hl slc"># behind a tailnet anyway, come at me bro</span>
+api_version <span class="hl opt">=</span> <span class="hl num">1.16</span>
+</code></pre>
+ <h2>
+ Future goals
+ </h2>
+ <ul>
+ <li>
+ snapcast for whole-house audio (<a href="https://www.reddit.com/r/selfhosted/comments/icjmiq/a_music_server_with_a_tli_client/">Reddit
+post</a> with some good tips)
+ </li>
+ </ul>
+ </main>
+ <div id="footnotes"></div>
+ <footer></footer>
+ </div>
+ </body>
+</html>
diff --git a/build/posts/thanks/index.html b/build/posts/thanks/index.html
@@ -0,0 +1,49 @@
+<!DOCTYPE html>
+<html lang="en">
+ <head>
+ <link rel="stylesheet" href="/style.css" type="text/css">
+ <meta charset="utf-8">
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
+ <link rel="stylesheet" type="text/css" href="/style.css">
+ <link rel="icon" href="data:image/svg+xml,<svg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 100 100%22><text y=%22.9em%22 font-size=%2290%22>đď¸</text></svg>">
+ <title></title>
+ </head>
+ <body>
+ <div id="page-wrapper">
+ <div id="header" role="banner">
+ <header class="banner">
+ <div id="banner-text">
+ <span class="banner-title"><a href="/">beauhilton</a></span>
+ </div>
+ </header>
+ <nav>
+ <a href="/about">about</a>
+<a href="/now">now</a>
+<a href="/thanks">thanks</a>
+<a class="nav-active" href="/posts">posts</a>
+<a href="https://notes.beauhilton.com">notes</a>
+<a href="https://talks.beauhilton.com">talks</a>
+<a href="https://git.beauhilton.com">git</a>
+<a href="/contact">contact</a>
+<a href="/atom.xml">rss</a>
+ </nav>
+ </div>
+ <main>
+ <h1>
+ I made a thanks page
+ </h1>
+ <p>
+ <time id="post-date">2022-12-19</time>
+ </p>
+ <p id="post-excerpt">
+ A public, running journal of "hey, thanks"
+to the folks who make my life better, in big and small ways.
+Check it out <a href="/thanks">here</a>.
+ </p>
+ </main>
+ <div id="footnotes"></div>
+ <footer></footer>
+ </div>
+ </body>
+</html>
diff --git a/build/posts/ugbsd/index.html b/build/posts/ugbsd/index.html
@@ -0,0 +1,101 @@
+<!DOCTYPE html>
+<html lang="en">
+ <head>
+ <link rel="stylesheet" href="/style.css" type="text/css">
+ <meta charset="utf-8">
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
+ <link rel="stylesheet" type="text/css" href="/style.css">
+ <link rel="icon" href="data:image/svg+xml,<svg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 100 100%22><text y=%22.9em%22 font-size=%2290%22>đď¸</text></svg>">
+ <title></title>
+ </head>
+ <body>
+ <div id="page-wrapper">
+ <div id="header" role="banner">
+ <header class="banner">
+ <div id="banner-text">
+ <span class="banner-title"><a href="/">beauhilton</a></span>
+ </div>
+ </header>
+ <nav>
+ <a href="/about">about</a>
+<a href="/now">now</a>
+<a href="/thanks">thanks</a>
+<a class="nav-active" href="/posts">posts</a>
+<a href="https://notes.beauhilton.com">notes</a>
+<a href="https://talks.beauhilton.com">talks</a>
+<a href="https://git.beauhilton.com">git</a>
+<a href="/contact">contact</a>
+<a href="/atom.xml">rss</a>
+ </nav>
+ </div>
+ <main>
+ <h1>
+ Upgrading out-of-date OpenBSD installs
+ </h1>
+ <p>
+ <time id="post-date">2022-11-11</time>
+ </p>
+ <p id="post-excerpt">
+ First of all, don't do how I do.
+Upgrade your installs regularly.
+OpenBSD makes it very easy.
+ </p>
+ <p>
+ But, if you do happen to get behindâŚ
+ </p>
+ <p>
+ <code>sysupgrade</code> is very likely to fail.
+ </p>
+ <h2>
+ What happens when you try to upgrade a very old install?
+ </h2>
+ <p>
+ Lots of 404 errors.
+ </p>
+ <p>
+ The <code>sysupgrade</code> utility tries to grab the next version of
+the OS from one of the many mirrors (the specific one your system will
+use is in <code>/etc/installurl</code>.)
+ </p>
+ <p>
+ The default mirrors only keep the last 2 or 3 versions around, so
+when <code>sysupgrade</code> constructs the url and tries to hit it for
+downloads, it will fail.
+ </p>
+ <h2>
+ Where to get old versions?
+ </h2>
+ <p>
+ There are a couple of mirrors that keep almost all the old versions
+around.
+ </p>
+ <p>
+ <a href="https://mirror.yandex.ru/pub/OpenBSD/">https://mirror.yandex.ru/pub/OpenBSD/</a>
+has files going back to OpenBSD 2.x - they seem like the most serious
+archivists, at least of the mirrors I looked at.
+ </p>
+ <p>
+ <a href="https://mirror.sjtu.edu.cn/OpenBSD/">https://mirror.sjtu.edu.cn/OpenBSD/</a>
+has files going back to 6.5 as of this writing (2022-11-11), also not
+too shabby.
+ </p>
+ <p>
+ Do a little <code>vi /etc/installurl</code> and change the link to
+one of the above, depending on how delinquent youâve been.
+ </p>
+ <p>
+ That should allow you to do serial <code>sysupgrade</code> commands
+until you catch up.
+ </p>
+ <p>
+ When you get close to the current version, consider switching back to
+a closer mirror, both for faster installs and to be kind to the folks
+who just saved your bacon.
+ </p>
+ </main>
+ <div id="footnotes"></div>
+ <footer></footer>
+ </div>
+ </body>
+</html>
diff --git a/build/posts/yt-dlp/index.html b/build/posts/yt-dlp/index.html
@@ -0,0 +1,216 @@
+<!DOCTYPE html>
+<html lang="en">
+ <head>
+ <link rel="stylesheet" href="/style.css" type="text/css">
+ <meta charset="utf-8">
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
+ <link rel="stylesheet" type="text/css" href="/style.css">
+ <link rel="icon" href="data:image/svg+xml,<svg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 100 100%22><text y=%22.9em%22 font-size=%2290%22>đď¸</text></svg>">
+ <title></title>
+ </head>
+ <body>
+ <div id="page-wrapper">
+ <div id="header" role="banner">
+ <header class="banner">
+ <div id="banner-text">
+ <span class="banner-title"><a href="/">beauhilton</a></span>
+ </div>
+ </header>
+ <nav>
+ <a href="/about">about</a>
+<a href="/now">now</a>
+<a href="/thanks">thanks</a>
+<a class="nav-active" href="/posts">posts</a>
+<a href="https://notes.beauhilton.com">notes</a>
+<a href="https://talks.beauhilton.com">talks</a>
+<a href="https://git.beauhilton.com">git</a>
+<a href="/contact">contact</a>
+<a href="/atom.xml">rss</a>
+ </nav>
+ </div>
+ <main>
+ <h1>
+ yt-dlp Nix config
+ </h1>
+ <p>
+ <time id="post-date">2023-10-18</time>
+ </p>
+ <p id="post-excerpt">
+ yt-dlp is an incredibly useful and customizable tool
+for downloading online videos
+from YouTube and elsewhere.
+Here's my setup
+(declared in Nix, but easily generalizable).
+ </p>
+ <p>
+ If you just want the config, scroll to the bottom (ignore the
+ramblings under the asterisk).
+ </p>
+ <h2>
+ yt-dlp
+ </h2>
+ <p>
+ youtube-dl was, for years, the de facto standard for retrieving
+videos from YouTube (and other websites - e.g. Vimeo) for local use, but
+eventually it got old and crufty.
+ </p>
+ <p>
+ <a href="https://github.com/yt-dlp/yt-dlp">yt-dlp</a> is a fork of
+youtube-dl that is more actively maintained, with many upgrades.
+ </p>
+ <p>
+ It has sane defaults, but I have a few things I change to make it
+suit my uses.
+ </p>
+ <p>
+ I mostly use it to download instructional videos so theyâre easier to
+use: no getting interrupted by ads whenever I scrub back and forth to
+find or rewatch a particular section, and I can proceed without an
+internet connection.
+ </p>
+ <p>
+ Itâs also a boon for archival of any video you use frequently for any
+reason, e.g. in an educational setting - if you have a lesson plan that
+depends on a clip from an online video, it is wise to have your own copy
+of the video, both to reduce dependence on finicky wifi and to make it
+more likely youâll have the vid for every time you repeat this lesson in
+the future. Videos go offline for strange, sundry, and unpredictable
+reasons.
+ </p>
+ <p>
+ (I maintain that YouTube and related video sites, taken as a whole,
+are the single greatest source of procedural knowledge ever created by
+humankind* - the problems that threaten their utility are, first,
+curation, and second, durability)
+ </p>
+ <h2>
+ configuring
+ </h2>
+ <p>
+ yt-dlp accepts a config file, usually placed at
+<code>~/.config/yt-dlp/config</code>, so you donât have to have a long
+string of flags and options in your shell command to yt-dlp (you can
+override your config file with shell options, so itâs reasonable to set
+your defaults to your most common use and not worry about messing up
+some divergent situation that may come up).
+ </p>
+ <p>
+ For example, to download the whole <a href="https://www.youtube.com/c/JohnWatsonRooney">JohnWatsonRooney
+YouTube channel</a>, all I had do was:
+ </p>
+ <pre tabindex="0"><code class="language-sh"><span class="hl kwb">cd</span> youtube<span class="hl kwb">-downloads</span><span class="hl opt">/</span>JohnWatsonRooney
+yt<span class="hl kwb">-dlp</span> <span class="hl sng">"https://www.youtube.com/c/JohnWatsonRooney"</span>
+</code></pre>
+ <p>
+ And it did something like this:
+ </p>
+ <p>
+ <img src="/images/yt-dlp-downloading-example.png" alt="yt-dlp downloading example">
+ </p>
+ <p>
+ Resulting in:
+ </p>
+ <p>
+ <img src="/images/yt-dlp-filename-example.jpg" alt="yt-dlp filename example">
+ </p>
+ <p>
+ In the second screenshot you can see that some files are still in
+process - when all the parts are downloaded, yt-dlp smushes them into an
+mkv container, so the videos/thumbnails/subtitle files are clean and
+accessible to most video players.
+ </p>
+ <h2>
+ config
+ </h2>
+ <p>
+ Hereâs my config file, with some annotation.
+ </p>
+ <p>
+ Iâm using Nix with Home Manager, but you can translate this into the
+usual yt-dlp config file syntax with ease.
+ </p>
+ <p>
+ One of the great things about Nix is that it lets me group
+installation and configuration for programs that make sense together -
+here, I want to use aria2 as the downloader, so I declare the aria2
+options to pass to yt-dlp, and also make sure aria2 is installed (itâs
+ok if you installed aria2 in another part of your setup - if a program
+is declared for installation in multiple places, Nix is smart enough to
+install it only once, so itâs often wise to err on the side of
+bundling).
+ </p>
+ <p>
+ If I take this config to any other machine with Nix installed, Iâll
+get the whole setup including dependencies. This example is very simple,
+just adding another program, but the principle scales to arbitrarily
+complex setups.
+ </p>
+ <pre tabindex="0"><code class="language-nix"><span class="hl opt">{</span>
+ programs<span class="hl opt">.</span>yt<span class="hl opt">-</span>dlp <span class="hl opt">= {</span>
+ enable <span class="hl opt">=</span> <span class="hl kwb">true</span><span class="hl opt">;</span>
+ settings <span class="hl opt">= {</span>
+ embed<span class="hl opt">-</span>chapters <span class="hl opt">=</span> <span class="hl kwb">true</span><span class="hl opt">;</span> <span class="hl slc"># embed all the things</span>
+ embed<span class="hl opt">-</span>metadata <span class="hl opt">=</span> <span class="hl kwb">true</span><span class="hl opt">;</span>
+ embed<span class="hl opt">-</span>thumbnail <span class="hl opt">=</span> <span class="hl kwb">true</span><span class="hl opt">;</span>
+ convert<span class="hl opt">-</span>thumbnail <span class="hl opt">=</span> <span class="hl sng">"jpg"</span><span class="hl opt">;</span>
+ <span class="hl slc"># so every file manager can show the thumbnail - webp support is not quite universal</span>
+ embed<span class="hl opt">-</span>subs <span class="hl opt">=</span> <span class="hl kwb">true</span><span class="hl opt">;</span>
+ sub<span class="hl opt">-</span>langs <span class="hl opt">=</span> <span class="hl sng">"all"</span><span class="hl opt">;</span>
+ <span class="hl slc"># subtitle files are very small, </span>
+ <span class="hl slc"># and sometimes language names are declared badly, </span>
+ <span class="hl slc"># so worth it to grab them all</span>
+ downloader <span class="hl opt">=</span> <span class="hl sng">"aria2c"</span><span class="hl opt">;</span>
+ downloader<span class="hl opt">-</span>args <span class="hl opt">=</span> <span class="hl sng">"aria2c:'-c -x16 -s16 -k2M'"</span><span class="hl opt">;</span>
+ <span class="hl slc"># -c is resume if interrupted ("continue"), </span>
+ <span class="hl slc"># -x is max connections to a server, </span>
+ <span class="hl slc"># -s is number of connections used for download of a specific file, </span>
+ <span class="hl slc"># -k is size of chunks</span>
+ download<span class="hl opt">-</span>archive <span class="hl opt">=</span> <span class="hl sng">"yt-dlp-archive.txt"</span><span class="hl opt">;</span>
+ <span class="hl slc"># writes a file to the current directory specifying which files have already been downloaded - </span>
+ <span class="hl slc"># nice for updating your collection of a channel's videos </span>
+ <span class="hl slc"># (just run the download command again and it will grab only what you're missing)</span>
+ restrict<span class="hl opt">-</span>filenames <span class="hl opt">=</span> <span class="hl kwb">true</span><span class="hl opt">;</span> <span class="hl slc"># disallow spaces, weird characters, etc.</span>
+ output <span class="hl opt">=</span> <span class="hl sng">"%(upload_date>%Y-%m-%d)s--%(uploader)s--%(title)s--%(id)s.%(ext)s"</span><span class="hl opt">;</span>
+ <span class="hl slc"># I like to be able to sort by date </span>
+ <span class="hl slc"># and have enough info in the filename </span>
+ <span class="hl slc"># so I don't need to open it to find out what it is, </span>
+ <span class="hl slc"># so I include the:</span>
+ <span class="hl slc"># - ISO 8601-style date</span>
+ <span class="hl slc"># - uploader's name</span>
+ <span class="hl slc"># - title of the video</span>
+ <span class="hl slc"># - video ID (for easy copy pasta if I ever want to find it online, </span>
+ <span class="hl slc"># e.g. to see the comment section or show notes.)</span>
+ <span class="hl opt">};</span>
+ <span class="hl opt">};</span>
+ programs<span class="hl opt">.</span>aria2 <span class="hl opt">= {</span>
+ enable <span class="hl opt">=</span> <span class="hl kwb">true</span><span class="hl opt">;</span>
+ <span class="hl opt">};</span>
+<span class="hl opt">}</span>
+</code></pre>
+ <h2>
+ side note
+ </h2>
+ <p>
+ * Contrary to popular belief, things that go online do <em>not</em>
+stay online forever: <a href="https://en.wikipedia.org/wiki/Digital_obsolescence">digital
+obsolescence</a> is real, and is <a href="https://blog.archive.org/2023/03/25/the-fight-continues/">probably
+going to get worse</a> before it gets better (â?betterâ). This section
+is under an asterisk and at the end because it is a side thought, just
+an idea that tools like yt-dlp may have import that goes beyond helping
+me write web scrapers, build saunas, etc. - maybe they have the
+primitives to help build a videographic Whole Earth Catalog for the
+ages. I donât think everything is going to explode any time soon, but
+wouldnât it be interesting to have a digital archive with videos, rather
+than just text, of how to do the basic things (and some not-so-basic
+things) that make life possible and enjoyable? Some kind of all-in-one
+system with redundant storage and a power-supply (hand crank? solar?),
+durable screen and speakers, to help you bootstrap the physical needs of
+a society? Iâm sure the raw content is out there.
+ </p>
+ </main>
+ <div id="footnotes"></div>
+ <footer></footer>
+ </div>
+ </body>
+</html>
diff --git a/build/style.css b/build/style.css
@@ -0,0 +1,317 @@
+:root
+{
+ --Canvas-bg: #201b1b;
+ --Canvas-color: #fff;
+ --Pre-bg: #151515;
+ --Pre-color: #fff;
+ --Pre-border: #222;
+ --Main-color: #f2f2f2;
+ --Code-color: #2adba4;
+ --Accent1-color: #2adba4; /* green */
+ --Accent2-color: #368aeb; /* blue */
+ --Highlight-num: #43a60d;
+ --Highlight-esc: #dfad06;
+ --Highlight-str: #f77f1d;
+ --Highlight-pps: #458759;
+ --Highlight-slc: #a0a0a0;
+ --Highlight-com: #a0a0a0;
+ --Highlight-ppc: #94e39;
+ --Highlight-opt: #ffffff;
+ --Highlight-ipl: #4dc987;
+ --Highlight-lin: #555555;
+ --Highlight-kwa: #d9396a;
+ --Highlight-kwb: #8655e7;
+ --Highlight-kwc: #ffffff;
+ --Highlight-kwd: #00a48f;
+}
+
+img {
+ display: inline-block;
+ max-width: 100%;
+}
+
+img[src*='#center'] {
+ display: block;
+ margin: auto;
+}
+
+pre, code, sample {
+ hyphens: none;
+ color: inherit;
+}
+
+pre
+{
+ overflow-x: scroll;
+ scrollbar-width: thin;
+ scrollbar-color: inherit;
+ padding: 2rem;
+ margin-left: -2rem;
+ margin-right: -2rem;
+ border: 1px solid var(--Pre-border);
+ background: var(--Pre-bg);
+ color: var(--Pre-color);
+}
+
+table {
+ max-width: 100%;
+}
+
+html {
+ font-size: 70.5%;
+}
+
+h2 {
+ font-weight: 200;
+}
+
+h3 {
+ font-weight: 200;
+}
+
+body {
+ line-height: 1.5;
+ font-size: 1.6rem;
+ max-width: 38em;
+ margin: auto;
+ padding: 13px;
+}
+
+.thanks-date {
+ font-weight:bold;
+}
+
+.thanks-to {
+ font-style: italic;
+ font-weight: 200;
+}
+
+.thanks {
+ padding-top:1em;
+ padding-bottom:1em;
+}
+
+/* Structural blocks */
+
+#page-wrapper
+{
+ max-width: 88rem;
+
+ padding: 1rem 2rem 2rem;
+
+ margin-left: auto;
+ margin-right: auto;
+}
+
+
+/* Visual styles */
+
+html
+{
+ background: var(--Canvas-bg);
+ color: var(--Canvas-color);
+}
+
+header
+{
+ text-align: center;
+}
+
+::selection
+{
+ background: var(--Selection-bg);
+ color: var(--Selection-color);
+}
+
+/* shared gradient border */
+nav, footer
+{
+ border-width: 0;
+ border-style: solid;
+ border-color: var(--Accent1-color);
+ border-image: linear-gradient(to right, var(--Accent1-color), var(--Accent2-color)) 2;
+}
+
+nav
+{
+ font-size: 1.8rem;
+ border-bottom-width: 2px;
+ padding-top: 0.5rem;
+ padding-bottom: 0.5rem;
+ word-spacing: 5px;
+ text-align: center;
+}
+
+main
+{
+ color: var(--Main-color);
+ text-rendering: optimizeLegibility;
+}
+
+footer
+{
+ text-align: center;
+ padding-top: 1rem;
+ margin-top: 1rem;
+ border-top-width: 2px;
+}
+
+div#banner-text
+{
+ display: flex;
+ flex-direction: column;
+ justify-content: center;
+ align-items: center;
+}
+
+.banner
+{
+ display: flex;
+ flex-direction: row;
+ gap: 1rem;
+ justify-content: center;
+ align-items: center;
+ line-height: 1;
+}
+
+.banner-title
+{
+ margin: 0;
+ font-size: 3.6rem;
+ font-weight: 200;
+ letter-spacing: 0.425em;
+ /* letter-spacing is applied even to the last letter,
+ so for proper centering, we have to remove it ourselves, sadly */
+ margin-right: -0.425em;
+}
+
+.banner-title a
+{
+ text-decoration:none;
+ color: var(--Main-color);
+}
+
+.banner-title a:hover
+{
+ text-decoration:none;
+ color: var(--Accent1-color);
+}
+
+a {
+ color: var(--Accent2-color);
+}
+
+a:hover, a:focus
+{
+ text-decoration: underline;
+ color: var(--Accent1-color);
+}
+
+a.nav-active {
+ color: var(--Accent1-color);
+ font-weight: 200;
+}
+
+nav a { text-decoration: none; }
+
+a.here { text-decoration: none; }
+
+hr
+{
+ border: 0 none;
+ color: var(--Accent2-color);
+ background-color: currentColor;
+ height: 2px;
+}
+
+hr.footnotes { width: 40%; }
+
+a.footnote
+{
+ text-decoration: none;
+ margin-right: 0.4rem;
+}
+
+ul.toc { list-style: none; }
+
+h5 { font-size: 1.6rem; }
+h6 { font-size: 1.4rem; }
+
+code, kbd, samp
+{
+ color: var(--Code-color);
+}
+
+
+/** Typography */
+
+@supports (hyphens: auto)
+{
+ main
+ {
+ text-align: justify;
+ hyphens: auto;
+ }
+}
+
+body
+{
+ font-family: system-ui, sans-serif;
+ font-weight: 200;
+}
+
+table, th, td
+{
+ border: 1px solid var(--Accent1-color);
+ border-collapse: collapse;
+}
+
+th, td
+{
+ padding: 0.5em;
+ hyphens: none;
+ text-align: left;
+}
+
+.centered { text-align: center; }
+
+/* Style definition file generated by highlight 3.52, http://www.andre-simon.de/ */
+/* highlight theme: Kwrite Editor */
+body.hl { background-color: #e0eaee; }
+pre.hl { color: #000000; background-color:#e0eaee; font-size: 10pt; font-family: monospace; }
+.hl.num { color: var(--Highlight-num); }
+.hl.esc { color: var(--Highlight-esc); }
+.hl.str { color: var(--Highlight-str); }
+.hl.pps { color: var(--Highlight-pps); }
+.hl.slc { color: var(--Highlight-slc); font-style: italic; }
+.hl.com { color: var(--Highlight-com); font-style: italic; }
+.hl.ppc { color: var(--Highlight-ppc); }
+.hl.opt { color: var(--Highlight-opt); }
+.hl.ipl { color: var(--Highlight-ipl); }
+.hl.lin { color: var(--Highlight-lin); }
+.hl.kwa { color: var(--Highlight-kwa); font-weight: bold; }
+.hl.kwb { color: var(--Highlight-kwb); }
+.hl.kwc { color: var(--Highlight-kwc); font-weight: bold; }
+.hl.kwd { color: var(--Highlight-kwd); }
+
+@media screen and (max-width: 34em)
+{
+ .banner, .banner-title
+ {
+ display: block;
+ text-align: center;
+ margin: auto;
+ }
+ .banner
+ {
+ margin-bottom: 2rem;
+ }
+}
+
+@media screen and (max-width: 28em)
+{
+ .banner-title
+ {
+ font-size: 3.2rem;
+ }
+}
diff --git a/build/template/index.html b/build/template/index.html
@@ -0,0 +1,64 @@
+<!DOCTYPE html>
+<html lang="en">
+ <head>
+ <link rel="stylesheet" href="/style.css" type="text/css">
+ <meta charset="utf-8">
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
+ <link rel="stylesheet" type="text/css" href="/style.css">
+ <link rel="icon" href="data:image/svg+xml,<svg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 100 100%22><text y=%22.9em%22 font-size=%2290%22>đď¸</text></svg>">
+ <title></title>
+ </head>
+ <body>
+ <div id="page-wrapper">
+ <div id="header" role="banner">
+ <header class="banner">
+ <div id="banner-text">
+ <span class="banner-title"><a href="/">beauhilton</a></span>
+ </div>
+ </header>
+ <nav>
+ <a href="/about">about</a>
+<a href="/now">now</a>
+<a href="/thanks">thanks</a>
+<a href="/posts">posts</a>
+<a href="https://notes.beauhilton.com">notes</a>
+<a href="https://talks.beauhilton.com">talks</a>
+<a href="https://git.beauhilton.com">git</a>
+<a href="/contact">contact</a>
+<a href="/atom.xml">rss</a>
+ </nav>
+ </div>
+ <main>
+ <h1>
+ Post Template
+ </h1>
+ <p>
+ <time id="post-date">1978-01-01</time>
+ </p>
+ <p id="post-excerpt">
+ Text of the post-excerpt goes here.
+ </p>
+ <h2>
+ Heading
+ </h2>
+ <p>
+ Link example: <a href="https://www.ifixit.com/products/google-pixel-6-screen-genuine">iFixit</a>.
+ </p>
+ <p>
+ Multiline script example:
+ </p>
+ <pre tabindex="0"><code class="language-sh"><span class="hl slc"># enable multilib - see link below</span>
+paru <span class="hl slc"># make sure things are up to date generally</span>
+paru <span class="hl kwb">-S</span> android<span class="hl kwb">-tools</span> android<span class="hl kwb">-sdk-build-tools</span> <span class="hl slc"># includes adb and other goodies</span>
+reboot
+</code></pre>
+ <p>
+ Image example: <img src="/images/ncmpcpp-mopidy-selector.png" alt="Source selection">
+ </p>
+ </main>
+ <div id="footnotes"></div>
+ <footer></footer>
+ </div>
+ </body>
+</html>
diff --git a/build/thanks/index.html b/build/thanks/index.html
@@ -0,0 +1,209 @@
+<!DOCTYPE html>
+<html lang="en">
+ <head>
+ <link rel="stylesheet" href="/style.css" type="text/css">
+ <meta charset="utf-8">
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
+ <link rel="stylesheet" type="text/css" href="/style.css">
+ <link rel="icon" href="data:image/svg+xml,<svg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 100 100%22><text y=%22.9em%22 font-size=%2290%22>đď¸</text></svg>">
+ <title></title>
+ </head>
+ <body>
+ <div id="page-wrapper">
+ <div id="header" role="banner">
+ <header class="banner">
+ <div id="banner-text">
+ <span class="banner-title"><a href="/">beauhilton</a></span>
+ </div>
+ </header>
+ <nav>
+ <a href="/about">about</a>
+<a href="/now">now</a>
+<a class="nav-active" href="/thanks">thanks</a>
+<a href="/posts">posts</a>
+<a href="https://notes.beauhilton.com">notes</a>
+<a href="https://talks.beauhilton.com">talks</a>
+<a href="https://git.beauhilton.com">git</a>
+<a href="/contact">contact</a>
+<a href="/atom.xml">rss</a>
+ </nav>
+ </div>
+ <main>
+ <p>
+ This is a âthanks page.â
+ </p>
+ <p>
+ <a href="/about">About</a>, <a href="https://nownownow.com/about">now</a>, and <a href="https://uses.tech">uses</a> pages are nice formulas, standardized
+yet flexible ways for people visiting your site to get to know you
+better, each from a slightly different angle.
+ </p>
+ <p>
+ The thanks page is also meant to bring the reader and author closer
+together. By saying âhey, thanksâ to folks who made a difference that
+day, it gets back to that old idea that we create each other in our
+relationships. The author gets to reflect on and state the positive
+thing, and the reader, whether or not he or she is the one being
+thanked, can get a kick out of watching joy and kindness flourish in the
+world.
+ </p>
+ <p>
+ Itâs a little more personal and permanent than a thumbs up on a post
+on whichever social media platform dominates at the moment, and fits
+well with a <a href="https://www.jackcheng.com/the-slow-web/">Slow
+Web</a> aesthetic.
+ </p>
+ <p>
+ If you like this idea and decide to make your own thanks page, please
+do, and <a href="/contact">let me know</a>. Iâll link to your page
+here.
+ </p>
+ <br>
+ <hr>
+ <div class="thanks">
+ <time datetime="2023-11-26" class="thanks-date">
+ 2023-11-26
+ </time>
+ <p class="thanks-to">
+ Jen, Cody, et al.
+ </p>
+ <p class="thanks-for">
+ Thanks for hanging out and helping out! It was a blast.
+ </p>
+ </div>
+ <hr>
+ <div class="thanks">
+ <time datetime="2023-11-09" class="thanks-date">
+ 2023-11-09
+ </time>
+ <p class="thanks-to">
+ Jeremy and Travis
+ </p>
+ <p class="thanks-for">
+ Thanks for helping with the LRP.
+ </p>
+ </div>
+ <hr>
+ <div class="thanks">
+ <time datetime="2023-11-08" class="thanks-date">
+ 2023-11-08
+ </time>
+ <p class="thanks-to">
+ the internet
+ </p>
+ <p class="thanks-for">
+ Thanks for absorbing an infinite number of starts and stops.
+ </p>
+ </div>
+ <hr>
+ <div class="thanks">
+ <time datetime="2022-12-24" class="thanks-date">
+ 2022-12-24
+ </time>
+ <p class="thanks-to">
+ Benjamin
+ </p>
+ <p class="thanks-for">
+ Thanks for holding down the fort.
+ </p>
+ </div>
+ <hr>
+ <div class="thanks">
+ <time datetime="2022-12-23" class="thanks-date">
+ 2022-12-23
+ </time>
+ <p class="thanks-to">
+ Forrest, Moriah, Cat
+ </p>
+ <p class="thanks-for">
+ Thanks to Forrest, for being a furry alien.
+ The time was too short buddy.
+ Also, thanks to Moriah and Cat, for holding things down for me until I could talk again.
+ </p>
+ </div>
+ <hr>
+ <div class="thanks">
+ <time datetime="2022-12-22" class="thanks-date">
+ 2022-12-22
+ </time>
+ <p class="thanks-to">
+ Lori
+ </p>
+ <p class="thanks-for">
+ Thanks for making a magic early Christmas.
+ </p>
+ </div>
+ <hr>
+ <div class="thanks">
+ <time datetime="2022-12-21" class="thanks-date">
+ 2022-12-21
+ </time>
+ <p class="thanks-to">
+ Chase
+ </p>
+ <p class="thanks-for">
+ Thanks for reminding me how cool it is, all of it.
+ Especially med ed, and how it interfaces with day-to-day practice.
+ (We should totally do the sick-not-sick button thing.)
+ </p>
+ </div>
+ <hr>
+ <div class="thanks">
+ <time datetime="2022-12-19" class="thanks-date">
+ 2022-12-19
+ </time>
+ <p class="thanks-to">
+ Mark
+ </p>
+ <p class="thanks-for">
+ Thanks for the masterclass on secondary erythrocytosis and itâs management,
+ and candor about how this oncology thing never really gets easier
+ (and may even get harder, as the patients get closer to your own age).
+ </p>
+ </div>
+ <hr>
+ <div class="thanks">
+ <time datetime="2022-12-18" class="thanks-date">
+ 2022-12-18
+ </time>
+ <p class="thanks-to">
+ Moriah
+ </p>
+ <p class="thanks-for">
+ Thanks for being willing to trade a shift later this week
+ so we can do a date-offset Christmas with the family.
+ </p>
+ </div>
+ <hr>
+ <div class="thanks">
+ <time datetime="2022-12-16" class="thanks-date">
+ 2022-12-16
+ </time>
+ <p class="thanks-to">
+ Ronak and Eric
+ </p>
+ <p class="thanks-for">
+ Thanks for jumping in to discuss your
+ experiences with inpatient induction chemo
+ for head and neck cancers - valuable insights, humane, lively.
+ </p>
+ </div>
+ <hr>
+ <div class="thanks">
+ <time datetime="2022-12-15" class="thanks-date">
+ 2022-12-15
+ </time>
+ <p class="thanks-to">
+ The NAVA BMT nurses
+ </p>
+ <p class="thanks-for">
+ Thanks for sticking with me and a veteran
+ who needed to sleep off the extra milligram of sedation.
+ </p>
+ </div>
+ </main>
+ <div id="footnotes"></div>
+ <footer></footer>
+ </div>
+ </body>
+</html>
diff --git a/build/twix/index.html b/build/twix/index.html
@@ -0,0 +1,157 @@
+<!DOCTYPE html>
+<html lang="en">
+ <head>
+ <link rel="stylesheet" href="/style.css" type="text/css">
+ <meta charset="utf-8">
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
+ <link rel="stylesheet" type="text/css" href="/style.css">
+ <link rel="icon" href="data:image/svg+xml,<svg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 100 100%22><text y=%22.9em%22 font-size=%2290%22>đď¸</text></svg>">
+ <title></title>
+ </head>
+ <body>
+ <div id="page-wrapper">
+ <div id="header" role="banner">
+ <header class="banner">
+ <div id="banner-text">
+ <span class="banner-title"><a href="/">beauhilton</a></span>
+ </div>
+ </header>
+ <nav>
+ <a href="/about">about</a>
+<a href="/now">now</a>
+<a href="/thanks">thanks</a>
+<a href="/posts">posts</a>
+<a href="https://notes.beauhilton.com">notes</a>
+<a href="https://talks.beauhilton.com">talks</a>
+<a href="https://git.beauhilton.com">git</a>
+<a href="/contact">contact</a>
+<a href="/atom.xml">rss</a>
+ </nav>
+ </div>
+ <main>
+ <h1>
+ Twix-like cookie recipe
+ </h1>
+ <hr>
+ <p>
+ Lightly modified from this <a href="https://www.dinneratthezoo.com/wprm_print/14720">original
+recipe</a>.
+ </p>
+ <p>
+ <a href="https://www.dinneratthezoo.com/wprm_print/14720"><img src="https://www.dinneratthezoo.com/wp-content/uploads/2018/06/twix-cookies-1.jpg#center" alt="picture from original recipe"></a>
+ </p>
+ <h2>
+ Ingredients
+ </h2>
+ <ul>
+ <li>
+ 1 1/2 cups butter softened
+ </li>
+ <li>
+ 1 cup powdered sugar
+ </li>
+ <li>
+ 1 1/2 teaspoons vanilla extract
+ </li>
+ <li>
+ 3 cups all purpose flour
+ </li>
+ <li>
+ 1/4 teaspoon salt
+ </li>
+ <li>
+ 11 ounces caramels (<em>we made our own, but only because the store
+didnât have any caramels that werenât individually wrapped</em>)
+ </li>
+ <li>
+ 1 tablespoon evaporated milk or cream
+ </li>
+ <li>
+ 2 cups milk chocolate chips
+ </li>
+ <li>
+ 2 teaspoons shortening
+ </li>
+ </ul>
+ <h2>
+ Instructions
+ </h2>
+ <ul>
+ <li>
+ Preheat oven to 350 degrees F. Line a sheet pan with parchment paper
+or a nonstick baking mat.
+ </li>
+ <li>
+ Place the butter in the bowl of a mixer and beat until light and
+fluffy. Add the powdered sugar and beat until combined.
+ </li>
+ <li>
+ Add the vanilla extract, flour and salt to the bowl. Mix until
+combined.
+ </li>
+ <li>
+ Place the dough on a sheet of plastic wrap. Fold the plastic wrap
+around the dough and chill in the freezer for 20 minutes.
+ </li>
+ <li>
+ Flour your work surface and roll out the dough into a 1/2 inch
+sheet.
+ </li>
+ <li>
+ Use a 2 or 3 inch round cookie cutter to cut out cookies (<em>we
+used 8 oz Mason jars</em>).
+ </li>
+ <li>
+ Place the cookies 1 inch apart on the prepared baking sheet.
+ </li>
+ <li>
+ Bake the cookies for 12-13 minutes or until edges are light brown.
+Repeat the process with the remaining dough.
+ </li>
+ <li>
+ Cool the cookies on a rack.
+ </li>
+ <li>
+ Place the caramels and evaporated milk in a bowl. Microwave at 45
+second increments until caramel is melted. Stir until smooth.
+ </li>
+ <li>
+ Place a spoonful of caramel onto each cookie, using the back of the
+spoon to spread it to the edges of the cookie.
+ </li>
+ <li>
+ Let the cookies sit until caramel has firmed up, about 20
+minutes.
+ </li>
+ <li>
+ Place the milk chocolate chips and shortening into a bowl. Microwave
+in 30 second increments until chocolate is melted. Stir until
+smooth.
+ </li>
+ <li>
+ Place a spoonful of melted chocolate onto each cookie and spread it
+over the caramel layer.
+ </li>
+ <li>
+ Let the cookies sit until the chocolate has hardened, then serve or
+store in an airtight container for up to 5 days.
+ </li>
+ </ul>
+ <h2>
+ Notes
+ </h2>
+ <ul>
+ <li>
+ These are super sticky. Wrap in wax paper.
+ </li>
+ <li>
+ Taste better, with better mouthfeel, if moderately chilled.
+ </li>
+ </ul>
+ </main>
+ <div id="footnotes"></div>
+ <footer></footer>
+ </div>
+ </body>
+</html>
diff --git a/build/uses/index.html b/build/uses/index.html
@@ -0,0 +1,280 @@
+<!DOCTYPE html>
+<html lang="en">
+ <head>
+ <link rel="stylesheet" href="/style.css" type="text/css">
+ <meta charset="utf-8">
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
+ <link rel="stylesheet" type="text/css" href="/style.css">
+ <link rel="icon" href="data:image/svg+xml,<svg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 100 100%22><text y=%22.9em%22 font-size=%2290%22>đď¸</text></svg>">
+ <title></title>
+ </head>
+ <body>
+ <div id="page-wrapper">
+ <div id="header" role="banner">
+ <header class="banner">
+ <div id="banner-text">
+ <span class="banner-title"><a href="/">beauhilton</a></span>
+ </div>
+ </header>
+ <nav>
+ <a href="/about">about</a>
+<a href="/now">now</a>
+<a href="/thanks">thanks</a>
+<a href="/posts">posts</a>
+<a href="https://notes.beauhilton.com">notes</a>
+<a href="https://talks.beauhilton.com">talks</a>
+<a href="https://git.beauhilton.com">git</a>
+<a href="/contact">contact</a>
+<a href="/atom.xml">rss</a>
+ </nav>
+ </div>
+ <main>
+ <h1>
+ uses
+ </h1>
+ <h2>
+ operating systems
+ </h2>
+ <ul>
+ <li>
+ <a href="https://wiki.archlinux.org/title/Arch_Linux">Arch Linux</a>
+(daily driver)
+ </li>
+ <li>
+ <a href="https://www.openbsd.org/">OpenBSD</a> (website server)
+ </li>
+ <li>
+ <a href="https://www.nixos.org/">NixOS</a> (personal server + most
+research)
+ </li>
+ <li>
+ <a href="https://www.apple.com/macos/">macOS</a> (most of the
+hospital stuff works better on macOS)
+ </li>
+ </ul>
+ <h2>
+ software
+ </h2>
+ <ul>
+ <li>
+ window managers: <a href="https://dwm.suckless.org/">dwm</a> (on
+Arch), <a href="https://hyprland.org/">Hyprland</a> (on NixOS)
+ </li>
+ <li>
+ $TERMINAL: <a href="https://sw.kovidgoyal.net/kitty/">kitty</a>
+ </li>
+ <li>
+ $EDITOR: <a href="https://www.lunarvim.org/">Lunarvim</a>
+ </li>
+ <li>
+ shell history: <a href="https://github.com/ellie/atuin">Atuin</a>
+ </li>
+ <li>
+ notes: <a href="https://obsidian.md/">Obsidian</a>
+ </li>
+ <li>
+ references: <a href="https://www.zotero.org/">Zotero</a>
+ </li>
+ <li>
+ standalone PDF reader: <a href="https://pwmt.org/projects/zathura/">Zathura</a>
+ </li>
+ <li>
+ terminal-based data file viewer (e.g. CSV): <a href="https://github.com/saulpw/visidata">VisiData</a>
+ </li>
+ <li>
+ wrangling JSON: <a href="https://github.com/stedolan/jq">jq</a>
+ </li>
+ <li>
+ remembery: <a href="https://apps.ankiweb.net/">Anki</a>
+ </li>
+ <li>
+ terminal music player: <a href="https://github.com/ncmpcpp/ncmpcpp">ncmpcpp</a>
+ </li>
+ <li>
+ web music player: <a href="https://navidrome.org/">Navidrome</a>,
+sometimes <a href="https://open.spotify.com/">Spotify</a>
+ </li>
+ <li>
+ bookmarking service: <a href="https://raindrop.io/">Raindrop.io</a>
+ </li>
+ <li>
+ networking: <a href="https://tailscale.com/">Tailscale</a>
+ </li>
+ <li>
+ passwords: <a href="https://bitwarden.com/">Bitwarden</a>
+ </li>
+ </ul>
+ <h2>
+ site-building software
+ </h2>
+ <ul>
+ <li>
+ <a href="https://github.com/Greenheart/pagecrypt">Pagecrypt</a>
+ </li>
+ <li>
+ <a href="https://squidfunk.github.io/mkdocs-material/">mkdocs-material</a>
+ </li>
+ <li>
+ <a href="https://gohugo.io/">Hugo</a>
+ </li>
+ <li>
+ <a href="https://github.com/jackyzha0/quartz">Quartz</a>
+ </li>
+ <li>
+ <a href="https://github.com/giscus/giscus">Giscus</a>
+ </li>
+ <li>
+ <a href="https://datasette.io/">Datasette</a>
+ </li>
+ <li>
+ <a href="https://github.com/slidevjs/slidev">Slidev</a>
+ </li>
+ <li>
+ <a href="https://github.com/tiangolo/sqlmodel">SQLModel</a>
+ </li>
+ </ul>
+ <h2>
+ Mac-specific software
+ </h2>
+ <ul>
+ <li>
+ <a href="https://www.raycast.com/">Raycast</a>
+ </li>
+ <li>
+ <a href="https://iina.io/">IINA</a>
+ </li>
+ </ul>
+ <h2>
+ aesthetics (computer)
+ </h2>
+ <ul>
+ <li>
+ font: <a href="https://www.ibm.com/plex/">IBM Plex</a>
+ </li>
+ <li>
+ colors: Selenized/<a href="https://github.com/wuelnerdotexe/vim-enfocado">Enfocado</a>
+ </li>
+ <li>
+ prompt: <a href="https://starship.rs/">Starship</a>
+ </li>
+ </ul>
+ <h2>
+ SaaS
+ </h2>
+ <ul>
+ <li>
+ <a href="https://vercel.com/">Vercel</a>
+ </li>
+ <li>
+ <a href="https://github.com/features/actions">GitHub
+Actions</a>
+ </li>
+ </ul>
+ <h2>
+ reference
+ </h2>
+ <ul>
+ <li>
+ <a href="https://hemonc.org/wiki/Main_Page">HemOnc.org</a>
+ </li>
+ <li>
+ <a href="https://www.vimbook.org/">vimbook.org</a>
+ </li>
+ <li>
+ <a href="https://chemocare.com/">Chemocare</a>
+ </li>
+ </ul>
+ <h2>
+ phone (multiplatform)
+ </h2>
+ <ul>
+ <li>
+ <a href="https://www.snipd.com/">Snipd</a>
+ </li>
+ </ul>
+ <h2>
+ phone (Android)
+ </h2>
+ <ul>
+ <li>
+ <a href="https://kisslauncher.com/">KISS Launcher</a>
+ </li>
+ <li>
+ <a href="https://github.com/Donnnno/Arcticons">Arcticons</a>
+ </li>
+ <li>
+ <a href="https://newpipe.net/">NewPipe</a>
+ </li>
+ </ul>
+ <h2>
+ phone (iOS)
+ </h2>
+ <ul>
+ <li>
+ <a href="">Working Copy</a>
+ </li>
+ </ul>
+ <h2>
+ computers
+ </h2>
+ <ul>
+ <li>
+ Lenovo Thinkpad T14s
+ </li>
+ <li>
+ Macbook Pro M1
+ </li>
+ <li>
+ Lenovo Thinkpad X220
+ </li>
+ </ul>
+ <h2>
+ phones
+ </h2>
+ <ul>
+ <li>
+ Google Pixel 2 XL (personal)
+ </li>
+ <li>
+ iPhone (whichever one work provides)
+ </li>
+ </ul>
+ <h2>
+ cars
+ </h2>
+ <ul>
+ <li>
+ Toyota Prius Three 2013
+ </li>
+ <li>
+ Honda Pilot 2009
+ </li>
+ </ul>
+ <h2>
+ wearables
+ </h2>
+ <ul>
+ <li>
+ watch: <a href="https://www.casio.com/us/watches/casio/product.F-91W-1/">Casio
+F-91W</a>
+ </li>
+ <li>
+ backpack: <a href="https://www.peakdesign.com/collections/all-bags/products/everyday-backpack">Peak
+Design Everyday Backpack (30L, black)</a>
+ </li>
+ </ul>
+ <h2>
+ software projects Iâm watching
+ </h2>
+ <ul>
+ <li>
+ <a href="https://podverse.fm/">Podverse</a>
+ </li>
+ </ul>
+ </main>
+ <div id="footnotes"></div>
+ <footer></footer>
+ </div>
+ </body>
+</html>
diff --git a/build/wants/index.html b/build/wants/index.html
@@ -0,0 +1,90 @@
+<!DOCTYPE html>
+<html lang="en">
+ <head>
+ <link rel="stylesheet" href="/style.css" type="text/css">
+ <meta charset="utf-8">
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
+ <link rel="stylesheet" type="text/css" href="/style.css">
+ <link rel="icon" href="data:image/svg+xml,<svg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 100 100%22><text y=%22.9em%22 font-size=%2290%22>đď¸</text></svg>">
+ <title></title>
+ </head>
+ <body>
+ <div id="page-wrapper">
+ <div id="header" role="banner">
+ <header class="banner">
+ <div id="banner-text">
+ <span class="banner-title"><a href="/">beauhilton</a></span>
+ </div>
+ </header>
+ <nav>
+ <a href="/about">about</a>
+<a href="/now">now</a>
+<a href="/thanks">thanks</a>
+<a href="/posts">posts</a>
+<a href="https://notes.beauhilton.com">notes</a>
+<a href="https://talks.beauhilton.com">talks</a>
+<a href="https://git.beauhilton.com">git</a>
+<a href="/contact">contact</a>
+<a href="/atom.xml">rss</a>
+ </nav>
+ </div>
+ <main>
+ <h1>
+ Wishlist
+ </h1>
+ <p>
+ While there are always <a href="https://rosewhitemusic.com/piano/writings/ten-thousand-things/#:~:text=%E2%80%9CThe%20Ten%20Thousand%20Things%E2%80%9D%20is,The%20One%20produced%20the%20two.">ten
+thousand material things</a> I want, some of which are in the Amazon
+Wishlist below, Iâm more into digital capability these days.
+ </p>
+ <p>
+ Digital, use-anywhere gift cards are the way to go.
+ </p>
+ <p>
+ E.g. Visa or MasterCard.
+ </p>
+ <h2>
+ beauhilton.com
+ </h2>
+ <p>
+ I use <a href="https://www.vultr.com/">Vultr</a> to host my server,
+which in turn hosts this website. Itâs also $5 a month, which is a great
+deal for a server that I fully manage and is plenty powerful for a
+simple website.
+ </p>
+ <p>
+ Happy to receive any funds to support this going forward.
+ </p>
+ <h2>
+ *.beauhilton.com
+ </h2>
+ <p>
+ There are a bunch of services I would love to add to my website.
+ </p>
+ <p>
+ E.g. <a href="https://github.com/advplyr/audiobookshelf">AudioBookShelf</a>
+could be audiobooks.beauhilton.com, <a href="https://wiki.kavitareader.com/en">Kavita</a> could be
+books.beauhilton.com, <a href="https://github.com/nextcloud/all-in-one#nextcloud-all-in-one">Nextcloud</a>
+could be cloud.beauhilton.com, etc.
+ </p>
+ <p>
+ Would ideally use a little independent server space for each of
+these, e.g. a Linode.
+ </p>
+ <h2>
+ Amazon
+ </h2>
+ <p>
+ And finally:
+ </p>
+ <p>
+ <a href="https://www.amazon.com/hz/wishlist/ls/3AKNW7PDL7STX?ref_=wl_share">Amazon
+Wishlist</a>
+ </p>
+ </main>
+ <div id="footnotes"></div>
+ <footer></footer>
+ </div>
+ </body>
+</html>
diff --git a/build/wip/abstracts/index.html b/build/wip/abstracts/index.html
@@ -0,0 +1,106 @@
+<!DOCTYPE html>
+<html lang="en">
+ <head>
+ <link rel="stylesheet" href="/style.css" type="text/css">
+ <meta charset="utf-8">
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
+ <link rel="stylesheet" type="text/css" href="/style.css">
+ <link rel="icon" href="data:image/svg+xml,<svg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 100 100%22><text y=%22.9em%22 font-size=%2290%22>đď¸</text></svg>">
+ <title></title>
+ </head>
+ <body>
+ <div id="page-wrapper">
+ <div id="header" role="banner">
+ <header class="banner">
+ <div id="banner-text">
+ <span class="banner-title"><a href="/">beauhilton</a></span>
+ </div>
+ </header>
+ <nav>
+ <a href="/about">about</a>
+<a href="/now">now</a>
+<a href="/thanks">thanks</a>
+<a href="/posts">posts</a>
+<a href="https://notes.beauhilton.com">notes</a>
+<a href="https://talks.beauhilton.com">talks</a>
+<a href="https://git.beauhilton.com">git</a>
+<a href="/contact">contact</a>
+<a href="/atom.xml">rss</a>
+ </nav>
+ </div>
+ <main>
+ <h1>
+ Abstracts
+ </h1>
+ <p>
+ <time id="post-date">1978-01-01</time>
+ </p>
+ <p id="post-excerpt">
+ Text of the post-excerpt goes here.
+ </p>
+ <h2>
+ Heading
+ </h2>
+ <blockquote>
+ <p>
+ The assurance of a complete and irrevocable break with everything
+which beclouds the past lies in a true and courageous comprehension of
+its full consequences.
+ </p>
+ <p>
+ â Alexander Tvardovsky, editor of <em>Novy Mir</em>. Foreward to
+<em>One Day in the Life of Ivan Denisovich</em> by Alexander
+Solzhenitsyn. 1963.
+ </p>
+ </blockquote>
+ <p>
+ On the night of December 2nd, 2018, I was too angry to sleep. Iâm not
+easy to ruffle (one of my cofellows dubbed me âBeau âCool-as-a-Cucumberâ
+Hiltonâ - I have many faults, but easy ruffleability is not among them),
+and I have narcolepsy, so I can count the number of nights Iâve spent
+both angry and sleepless on a single finger.
+ </p>
+ <p>
+ That afternoon I was reflecting on the plenary session given by Dr
+Leon Tshilolo at the American Society of Hematology 60th Annual Meeting,
+where he presented data on the use of hydroxyurea in sickle cell disease
+in Africa. It was a beautiful talk, a major advance in the field of
+hematology, and a wakeup call.
+ </p>
+ <p>
+ Hydroxyurea is an inexpensive drug that makes a huge difference for
+many folks with sickle cell disease, and has been used for decades. The
+majority of people with sickle cell disease live in Sub-Saharan Africa.
+(The paper that accompanied Dr Tshiloloâs talk, which was published in
+The New England Journal of Medicine roughly one month later, began with
+the characteristically understated: âHydroxyurea is an effective
+treatment for sickle cell anemia, but few studies have been conducted in
+sub-Saharan Africa, where the burden is greatest.â) This study deserved
+to be the plenary session. Unlike ever-more-expensive targeted therapies
+that benefit a few with rare diseases (I do not disparage these drugs,
+far from it, but the contrast is poignant), this is a cheap therapy that
+can benefit millions. Recognizing the incredible scientific, political,
+and financial maneuvering that led to this study and its positive
+outcomes, as the day went on my initial elation turned to depression,
+then to anger. That this study happened at all is a triumph, that it
+took this long to happen is a tragedy.
+ </p>
+ <p>
+ So I sat in my hotel room, furious, imagining, lost.
+ </p>
+ <p>
+ I was trained as an anthropologist and activist at the same time I
+was trained as a scientist, and here was a disturbing revelation that
+seemed to fit squarely in my Venn Diagram, but what I could do about it,
+how I could make a difference, how I could even know where to start,
+escaped me. Eventually the sun surprised me, and the next day took me
+(thankfully, there were some less-electrifying talks to sleep through
+later that day).
+ </p>
+ </main>
+ <div id="footnotes"></div>
+ <footer></footer>
+ </div>
+ </body>
+</html>
diff --git a/build/wip/template/index.html b/build/wip/template/index.html
@@ -0,0 +1,64 @@
+<!DOCTYPE html>
+<html lang="en">
+ <head>
+ <link rel="stylesheet" href="/style.css" type="text/css">
+ <meta charset="utf-8">
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
+ <link rel="stylesheet" type="text/css" href="/style.css">
+ <link rel="icon" href="data:image/svg+xml,<svg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 100 100%22><text y=%22.9em%22 font-size=%2290%22>đď¸</text></svg>">
+ <title></title>
+ </head>
+ <body>
+ <div id="page-wrapper">
+ <div id="header" role="banner">
+ <header class="banner">
+ <div id="banner-text">
+ <span class="banner-title"><a href="/">beauhilton</a></span>
+ </div>
+ </header>
+ <nav>
+ <a href="/about">about</a>
+<a href="/now">now</a>
+<a href="/thanks">thanks</a>
+<a href="/posts">posts</a>
+<a href="https://notes.beauhilton.com">notes</a>
+<a href="https://talks.beauhilton.com">talks</a>
+<a href="https://git.beauhilton.com">git</a>
+<a href="/contact">contact</a>
+<a href="/atom.xml">rss</a>
+ </nav>
+ </div>
+ <main>
+ <h1>
+ Post Template
+ </h1>
+ <p>
+ <time id="post-date">1978-01-01</time>
+ </p>
+ <p id="post-excerpt">
+ Text of the post-excerpt goes here.
+ </p>
+ <h2>
+ Heading
+ </h2>
+ <p>
+ Link example: <a href="https://www.ifixit.com/products/google-pixel-6-screen-genuine">iFixit</a>.
+ </p>
+ <p>
+ Multiline script example:
+ </p>
+ <pre tabindex="0"><code class="language-sh"><span class="hl slc"># enable multilib - see link below</span>
+paru <span class="hl slc"># make sure things are up to date generally</span>
+paru <span class="hl kwb">-S</span> android<span class="hl kwb">-tools</span> android<span class="hl kwb">-sdk-build-tools</span> <span class="hl slc"># includes adb and other goodies</span>
+reboot
+</code></pre>
+ <p>
+ Image example: <img src="/images/ncmpcpp-mopidy-selector.png" alt="Source selection">
+ </p>
+ </main>
+ <div id="footnotes"></div>
+ <footer></footer>
+ </div>
+ </body>
+</html>